diff options
Diffstat (limited to 'sound')
248 files changed, 18224 insertions, 11750 deletions
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index 762af68c8996..270790d384e2 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c | |||
@@ -1132,15 +1132,4 @@ static struct i2c_driver onyx_driver = { | |||
1132 | .id_table = onyx_i2c_id, | 1132 | .id_table = onyx_i2c_id, |
1133 | }; | 1133 | }; |
1134 | 1134 | ||
1135 | static int __init onyx_init(void) | 1135 | module_i2c_driver(onyx_driver); |
1136 | { | ||
1137 | return i2c_add_driver(&onyx_driver); | ||
1138 | } | ||
1139 | |||
1140 | static void __exit onyx_exit(void) | ||
1141 | { | ||
1142 | i2c_del_driver(&onyx_driver); | ||
1143 | } | ||
1144 | |||
1145 | module_init(onyx_init); | ||
1146 | module_exit(onyx_exit); | ||
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c index fd2188c3df2b..8e63d1f35ce1 100644 --- a/sound/aoa/codecs/tas.c +++ b/sound/aoa/codecs/tas.c | |||
@@ -1026,15 +1026,4 @@ static struct i2c_driver tas_driver = { | |||
1026 | .id_table = tas_i2c_id, | 1026 | .id_table = tas_i2c_id, |
1027 | }; | 1027 | }; |
1028 | 1028 | ||
1029 | static int __init tas_init(void) | 1029 | module_i2c_driver(tas_driver); |
1030 | { | ||
1031 | return i2c_add_driver(&tas_driver); | ||
1032 | } | ||
1033 | |||
1034 | static void __exit tas_exit(void) | ||
1035 | { | ||
1036 | i2c_del_driver(&tas_driver); | ||
1037 | } | ||
1038 | |||
1039 | module_init(tas_init); | ||
1040 | module_exit(tas_exit); | ||
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index b37b702a3a6a..5119fdabcb98 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
@@ -1110,18 +1110,7 @@ static struct amba_driver aaci_driver = { | |||
1110 | .id_table = aaci_ids, | 1110 | .id_table = aaci_ids, |
1111 | }; | 1111 | }; |
1112 | 1112 | ||
1113 | static int __init aaci_init(void) | 1113 | module_amba_driver(aaci_driver); |
1114 | { | ||
1115 | return amba_driver_register(&aaci_driver); | ||
1116 | } | ||
1117 | |||
1118 | static void __exit aaci_exit(void) | ||
1119 | { | ||
1120 | amba_driver_unregister(&aaci_driver); | ||
1121 | } | ||
1122 | |||
1123 | module_init(aaci_init); | ||
1124 | module_exit(aaci_exit); | ||
1125 | 1114 | ||
1126 | MODULE_LICENSE("GPL"); | 1115 | MODULE_LICENSE("GPL"); |
1127 | MODULE_DESCRIPTION("ARM PrimeCell PL041 Advanced Audio CODEC Interface driver"); | 1116 | MODULE_DESCRIPTION("ARM PrimeCell PL041 Advanced Audio CODEC Interface driver"); |
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index dac3633507c9..a68aed7fce02 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c | |||
@@ -441,19 +441,22 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg) | |||
441 | params = kmalloc(sizeof(*params), GFP_KERNEL); | 441 | params = kmalloc(sizeof(*params), GFP_KERNEL); |
442 | if (!params) | 442 | if (!params) |
443 | return -ENOMEM; | 443 | return -ENOMEM; |
444 | if (copy_from_user(params, (void __user *)arg, sizeof(*params))) | 444 | if (copy_from_user(params, (void __user *)arg, sizeof(*params))) { |
445 | return -EFAULT; | 445 | retval = -EFAULT; |
446 | goto out; | ||
447 | } | ||
446 | retval = snd_compr_allocate_buffer(stream, params); | 448 | retval = snd_compr_allocate_buffer(stream, params); |
447 | if (retval) { | 449 | if (retval) { |
448 | kfree(params); | 450 | retval = -ENOMEM; |
449 | return -ENOMEM; | 451 | goto out; |
450 | } | 452 | } |
451 | retval = stream->ops->set_params(stream, params); | 453 | retval = stream->ops->set_params(stream, params); |
452 | if (retval) | 454 | if (retval) |
453 | goto out; | 455 | goto out; |
454 | stream->runtime->state = SNDRV_PCM_STATE_SETUP; | 456 | stream->runtime->state = SNDRV_PCM_STATE_SETUP; |
455 | } else | 457 | } else { |
456 | return -EPERM; | 458 | return -EPERM; |
459 | } | ||
457 | out: | 460 | out: |
458 | kfree(params); | 461 | kfree(params); |
459 | return retval; | 462 | return retval; |
diff --git a/sound/core/control.c b/sound/core/control.c index 819a5c579a39..2487a6bb1c54 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -1313,7 +1313,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file, | |||
1313 | err = -EPERM; | 1313 | err = -EPERM; |
1314 | goto __kctl_end; | 1314 | goto __kctl_end; |
1315 | } | 1315 | } |
1316 | err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); | 1316 | err = kctl->tlv.c(kctl, op_flag, tlv.length, _tlv->tlv); |
1317 | if (err > 0) { | 1317 | if (err > 0) { |
1318 | up_read(&card->controls_rwsem); | 1318 | up_read(&card->controls_rwsem); |
1319 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id); | 1319 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_TLV, &kctl->id); |
diff --git a/sound/core/init.c b/sound/core/init.c index 3ac49b1b7cb8..d8ec849af128 100644 --- a/sound/core/init.c +++ b/sound/core/init.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/device.h> | ||
25 | #include <linux/file.h> | 26 | #include <linux/file.h> |
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
27 | #include <linux/time.h> | 28 | #include <linux/time.h> |
@@ -480,74 +481,104 @@ int snd_card_free(struct snd_card *card) | |||
480 | 481 | ||
481 | EXPORT_SYMBOL(snd_card_free); | 482 | EXPORT_SYMBOL(snd_card_free); |
482 | 483 | ||
483 | static void snd_card_set_id_no_lock(struct snd_card *card, const char *nid) | 484 | /* retrieve the last word of shortname or longname */ |
485 | static const char *retrieve_id_from_card_name(const char *name) | ||
484 | { | 486 | { |
485 | int i, len, idx_flag = 0, loops = SNDRV_CARDS; | 487 | const char *spos = name; |
486 | const char *spos, *src; | 488 | |
487 | char *id; | 489 | while (*name) { |
488 | 490 | if (isspace(*name) && isalnum(name[1])) | |
489 | if (nid == NULL) { | 491 | spos = name + 1; |
490 | id = card->shortname; | 492 | name++; |
491 | spos = src = id; | ||
492 | while (*id != '\0') { | ||
493 | if (*id == ' ') | ||
494 | spos = id + 1; | ||
495 | id++; | ||
496 | } | ||
497 | } else { | ||
498 | spos = src = nid; | ||
499 | } | 493 | } |
500 | id = card->id; | 494 | return spos; |
501 | while (*spos != '\0' && !isalnum(*spos)) | 495 | } |
502 | spos++; | 496 | |
503 | if (isdigit(*spos)) | 497 | /* return true if the given id string doesn't conflict any other card ids */ |
504 | *id++ = isalpha(src[0]) ? src[0] : 'D'; | 498 | static bool card_id_ok(struct snd_card *card, const char *id) |
505 | while (*spos != '\0' && (size_t)(id - card->id) < sizeof(card->id) - 1) { | 499 | { |
506 | if (isalnum(*spos)) | 500 | int i; |
507 | *id++ = *spos; | 501 | if (!snd_info_check_reserved_words(id)) |
508 | spos++; | 502 | return false; |
503 | for (i = 0; i < snd_ecards_limit; i++) { | ||
504 | if (snd_cards[i] && snd_cards[i] != card && | ||
505 | !strcmp(snd_cards[i]->id, id)) | ||
506 | return false; | ||
509 | } | 507 | } |
510 | *id = '\0'; | 508 | return true; |
509 | } | ||
511 | 510 | ||
512 | id = card->id; | 511 | /* copy to card->id only with valid letters from nid */ |
512 | static void copy_valid_id_string(struct snd_card *card, const char *src, | ||
513 | const char *nid) | ||
514 | { | ||
515 | char *id = card->id; | ||
516 | |||
517 | while (*nid && !isalnum(*nid)) | ||
518 | nid++; | ||
519 | if (isdigit(*nid)) | ||
520 | *id++ = isalpha(*src) ? *src : 'D'; | ||
521 | while (*nid && (size_t)(id - card->id) < sizeof(card->id) - 1) { | ||
522 | if (isalnum(*nid)) | ||
523 | *id++ = *nid; | ||
524 | nid++; | ||
525 | } | ||
526 | *id = 0; | ||
527 | } | ||
528 | |||
529 | /* Set card->id from the given string | ||
530 | * If the string conflicts with other ids, add a suffix to make it unique. | ||
531 | */ | ||
532 | static void snd_card_set_id_no_lock(struct snd_card *card, const char *src, | ||
533 | const char *nid) | ||
534 | { | ||
535 | int len, loops; | ||
536 | bool with_suffix; | ||
537 | bool is_default = false; | ||
538 | char *id; | ||
513 | 539 | ||
514 | if (*id == '\0') | 540 | copy_valid_id_string(card, src, nid); |
541 | id = card->id; | ||
542 | |||
543 | again: | ||
544 | /* use "Default" for obviously invalid strings | ||
545 | * ("card" conflicts with proc directories) | ||
546 | */ | ||
547 | if (!*id || !strncmp(id, "card", 4)) { | ||
515 | strcpy(id, "Default"); | 548 | strcpy(id, "Default"); |
549 | is_default = true; | ||
550 | } | ||
516 | 551 | ||
517 | while (1) { | 552 | with_suffix = false; |
518 | if (loops-- == 0) { | 553 | for (loops = 0; loops < SNDRV_CARDS; loops++) { |
519 | snd_printk(KERN_ERR "unable to set card id (%s)\n", id); | 554 | if (card_id_ok(card, id)) |
520 | strcpy(card->id, card->proc_root->name); | 555 | return; /* OK */ |
521 | return; | ||
522 | } | ||
523 | if (!snd_info_check_reserved_words(id)) | ||
524 | goto __change; | ||
525 | for (i = 0; i < snd_ecards_limit; i++) { | ||
526 | if (snd_cards[i] && !strcmp(snd_cards[i]->id, id)) | ||
527 | goto __change; | ||
528 | } | ||
529 | break; | ||
530 | 556 | ||
531 | __change: | ||
532 | len = strlen(id); | 557 | len = strlen(id); |
533 | if (idx_flag) { | 558 | if (!with_suffix) { |
534 | if (id[len-1] != '9') | 559 | /* add the "_X" suffix */ |
535 | id[len-1]++; | 560 | char *spos = id + len; |
536 | else | 561 | if (len > sizeof(card->id) - 3) |
537 | id[len-1] = 'A'; | 562 | spos = id + sizeof(card->id) - 3; |
538 | } else if ((size_t)len <= sizeof(card->id) - 3) { | 563 | strcpy(spos, "_1"); |
539 | strcat(id, "_1"); | 564 | with_suffix = true; |
540 | idx_flag++; | ||
541 | } else { | 565 | } else { |
542 | spos = id + len - 2; | 566 | /* modify the existing suffix */ |
543 | if ((size_t)len <= sizeof(card->id) - 2) | 567 | if (id[len - 1] != '9') |
544 | spos++; | 568 | id[len - 1]++; |
545 | *(char *)spos++ = '_'; | 569 | else |
546 | *(char *)spos++ = '1'; | 570 | id[len - 1] = 'A'; |
547 | *(char *)spos++ = '\0'; | ||
548 | idx_flag++; | ||
549 | } | 571 | } |
550 | } | 572 | } |
573 | /* fallback to the default id */ | ||
574 | if (!is_default) { | ||
575 | *id = 0; | ||
576 | goto again; | ||
577 | } | ||
578 | /* last resort... */ | ||
579 | snd_printk(KERN_ERR "unable to set card id (%s)\n", id); | ||
580 | if (card->proc_root->name) | ||
581 | strcpy(card->id, card->proc_root->name); | ||
551 | } | 582 | } |
552 | 583 | ||
553 | /** | 584 | /** |
@@ -564,7 +595,7 @@ void snd_card_set_id(struct snd_card *card, const char *nid) | |||
564 | if (card->id[0] != '\0') | 595 | if (card->id[0] != '\0') |
565 | return; | 596 | return; |
566 | mutex_lock(&snd_card_mutex); | 597 | mutex_lock(&snd_card_mutex); |
567 | snd_card_set_id_no_lock(card, nid); | 598 | snd_card_set_id_no_lock(card, nid, nid); |
568 | mutex_unlock(&snd_card_mutex); | 599 | mutex_unlock(&snd_card_mutex); |
569 | } | 600 | } |
570 | EXPORT_SYMBOL(snd_card_set_id); | 601 | EXPORT_SYMBOL(snd_card_set_id); |
@@ -596,22 +627,12 @@ card_id_store_attr(struct device *dev, struct device_attribute *attr, | |||
596 | memcpy(buf1, buf, copy); | 627 | memcpy(buf1, buf, copy); |
597 | buf1[copy] = '\0'; | 628 | buf1[copy] = '\0'; |
598 | mutex_lock(&snd_card_mutex); | 629 | mutex_lock(&snd_card_mutex); |
599 | if (!snd_info_check_reserved_words(buf1)) { | 630 | if (!card_id_ok(NULL, buf1)) { |
600 | __exist: | ||
601 | mutex_unlock(&snd_card_mutex); | 631 | mutex_unlock(&snd_card_mutex); |
602 | return -EEXIST; | 632 | return -EEXIST; |
603 | } | 633 | } |
604 | for (idx = 0; idx < snd_ecards_limit; idx++) { | ||
605 | if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1)) { | ||
606 | if (card == snd_cards[idx]) | ||
607 | goto __ok; | ||
608 | else | ||
609 | goto __exist; | ||
610 | } | ||
611 | } | ||
612 | strcpy(card->id, buf1); | 634 | strcpy(card->id, buf1); |
613 | snd_info_card_id_change(card); | 635 | snd_info_card_id_change(card); |
614 | __ok: | ||
615 | mutex_unlock(&snd_card_mutex); | 636 | mutex_unlock(&snd_card_mutex); |
616 | 637 | ||
617 | return count; | 638 | return count; |
@@ -665,7 +686,18 @@ int snd_card_register(struct snd_card *card) | |||
665 | mutex_unlock(&snd_card_mutex); | 686 | mutex_unlock(&snd_card_mutex); |
666 | return 0; | 687 | return 0; |
667 | } | 688 | } |
668 | snd_card_set_id_no_lock(card, card->id[0] == '\0' ? NULL : card->id); | 689 | if (*card->id) { |
690 | /* make a unique id name from the given string */ | ||
691 | char tmpid[sizeof(card->id)]; | ||
692 | memcpy(tmpid, card->id, sizeof(card->id)); | ||
693 | snd_card_set_id_no_lock(card, tmpid, tmpid); | ||
694 | } else { | ||
695 | /* create an id from either shortname or longname */ | ||
696 | const char *src; | ||
697 | src = *card->shortname ? card->shortname : card->longname; | ||
698 | snd_card_set_id_no_lock(card, src, | ||
699 | retrieve_id_from_card_name(src)); | ||
700 | } | ||
669 | snd_cards[card->number] = card; | 701 | snd_cards[card->number] = card; |
670 | mutex_unlock(&snd_card_mutex); | 702 | mutex_unlock(&snd_card_mutex); |
671 | init_info_for_card(card); | 703 | init_info_for_card(card); |
diff --git a/sound/core/jack.c b/sound/core/jack.c index 26edf63b265f..471e1e3b0a99 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <sound/jack.h> | 25 | #include <sound/jack.h> |
26 | #include <sound/core.h> | 26 | #include <sound/core.h> |
27 | 27 | ||
28 | static int jack_switch_types[] = { | 28 | static int jack_switch_types[SND_JACK_SWITCH_TYPES] = { |
29 | SW_HEADPHONE_INSERT, | 29 | SW_HEADPHONE_INSERT, |
30 | SW_MICROPHONE_INSERT, | 30 | SW_MICROPHONE_INSERT, |
31 | SW_LINEOUT_INSERT, | 31 | SW_LINEOUT_INSERT, |
@@ -128,7 +128,7 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, | |||
128 | 128 | ||
129 | jack->type = type; | 129 | jack->type = type; |
130 | 130 | ||
131 | for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) | 131 | for (i = 0; i < SND_JACK_SWITCH_TYPES; i++) |
132 | if (type & (1 << i)) | 132 | if (type & (1 << i)) |
133 | input_set_capability(jack->input_dev, EV_SW, | 133 | input_set_capability(jack->input_dev, EV_SW, |
134 | jack_switch_types[i]); | 134 | jack_switch_types[i]); |
diff --git a/sound/core/misc.c b/sound/core/misc.c index 465f0ce772cb..768167925409 100644 --- a/sound/core/misc.c +++ b/sound/core/misc.c | |||
@@ -72,7 +72,7 @@ void __snd_printk(unsigned int level, const char *path, int line, | |||
72 | char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV"; | 72 | char verbose_fmt[] = KERN_DEFAULT "ALSA %s:%d %pV"; |
73 | #endif | 73 | #endif |
74 | 74 | ||
75 | #ifdef CONFIG_SND_DEBUG | 75 | #ifdef CONFIG_SND_DEBUG |
76 | if (debug < level) | 76 | if (debug < level) |
77 | return; | 77 | return; |
78 | #endif | 78 | #endif |
diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 8928ca871c22..1a3070b4e5b5 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/time.h> | 25 | #include <linux/time.h> |
26 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
27 | #include <linux/device.h> | ||
27 | #include <sound/core.h> | 28 | #include <sound/core.h> |
28 | #include <sound/minors.h> | 29 | #include <sound/minors.h> |
29 | #include <sound/pcm.h> | 30 | #include <sound/pcm.h> |
@@ -650,7 +651,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) | |||
650 | pstr->stream = stream; | 651 | pstr->stream = stream; |
651 | pstr->pcm = pcm; | 652 | pstr->pcm = pcm; |
652 | pstr->substream_count = substream_count; | 653 | pstr->substream_count = substream_count; |
653 | if (substream_count > 0) { | 654 | if (substream_count > 0 && !pcm->internal) { |
654 | err = snd_pcm_stream_proc_init(pstr); | 655 | err = snd_pcm_stream_proc_init(pstr); |
655 | if (err < 0) { | 656 | if (err < 0) { |
656 | snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n"); | 657 | snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n"); |
@@ -674,15 +675,18 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) | |||
674 | pstr->substream = substream; | 675 | pstr->substream = substream; |
675 | else | 676 | else |
676 | prev->next = substream; | 677 | prev->next = substream; |
677 | err = snd_pcm_substream_proc_init(substream); | 678 | |
678 | if (err < 0) { | 679 | if (!pcm->internal) { |
679 | snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n"); | 680 | err = snd_pcm_substream_proc_init(substream); |
680 | if (prev == NULL) | 681 | if (err < 0) { |
681 | pstr->substream = NULL; | 682 | snd_printk(KERN_ERR "Error in snd_pcm_stream_proc_init\n"); |
682 | else | 683 | if (prev == NULL) |
683 | prev->next = NULL; | 684 | pstr->substream = NULL; |
684 | kfree(substream); | 685 | else |
685 | return err; | 686 | prev->next = NULL; |
687 | kfree(substream); | ||
688 | return err; | ||
689 | } | ||
686 | } | 690 | } |
687 | substream->group = &substream->self_group; | 691 | substream->group = &substream->self_group; |
688 | spin_lock_init(&substream->self_group.lock); | 692 | spin_lock_init(&substream->self_group.lock); |
@@ -696,25 +700,9 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) | |||
696 | 700 | ||
697 | EXPORT_SYMBOL(snd_pcm_new_stream); | 701 | EXPORT_SYMBOL(snd_pcm_new_stream); |
698 | 702 | ||
699 | /** | 703 | static int _snd_pcm_new(struct snd_card *card, const char *id, int device, |
700 | * snd_pcm_new - create a new PCM instance | 704 | int playback_count, int capture_count, bool internal, |
701 | * @card: the card instance | 705 | struct snd_pcm **rpcm) |
702 | * @id: the id string | ||
703 | * @device: the device index (zero based) | ||
704 | * @playback_count: the number of substreams for playback | ||
705 | * @capture_count: the number of substreams for capture | ||
706 | * @rpcm: the pointer to store the new pcm instance | ||
707 | * | ||
708 | * Creates a new PCM instance. | ||
709 | * | ||
710 | * The pcm operators have to be set afterwards to the new instance | ||
711 | * via snd_pcm_set_ops(). | ||
712 | * | ||
713 | * Returns zero if successful, or a negative error code on failure. | ||
714 | */ | ||
715 | int snd_pcm_new(struct snd_card *card, const char *id, int device, | ||
716 | int playback_count, int capture_count, | ||
717 | struct snd_pcm ** rpcm) | ||
718 | { | 706 | { |
719 | struct snd_pcm *pcm; | 707 | struct snd_pcm *pcm; |
720 | int err; | 708 | int err; |
@@ -735,6 +723,7 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device, | |||
735 | } | 723 | } |
736 | pcm->card = card; | 724 | pcm->card = card; |
737 | pcm->device = device; | 725 | pcm->device = device; |
726 | pcm->internal = internal; | ||
738 | if (id) | 727 | if (id) |
739 | strlcpy(pcm->id, id, sizeof(pcm->id)); | 728 | strlcpy(pcm->id, id, sizeof(pcm->id)); |
740 | if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) { | 729 | if ((err = snd_pcm_new_stream(pcm, SNDRV_PCM_STREAM_PLAYBACK, playback_count)) < 0) { |
@@ -756,8 +745,59 @@ int snd_pcm_new(struct snd_card *card, const char *id, int device, | |||
756 | return 0; | 745 | return 0; |
757 | } | 746 | } |
758 | 747 | ||
748 | /** | ||
749 | * snd_pcm_new - create a new PCM instance | ||
750 | * @card: the card instance | ||
751 | * @id: the id string | ||
752 | * @device: the device index (zero based) | ||
753 | * @playback_count: the number of substreams for playback | ||
754 | * @capture_count: the number of substreams for capture | ||
755 | * @rpcm: the pointer to store the new pcm instance | ||
756 | * | ||
757 | * Creates a new PCM instance. | ||
758 | * | ||
759 | * The pcm operators have to be set afterwards to the new instance | ||
760 | * via snd_pcm_set_ops(). | ||
761 | * | ||
762 | * Returns zero if successful, or a negative error code on failure. | ||
763 | */ | ||
764 | int snd_pcm_new(struct snd_card *card, const char *id, int device, | ||
765 | int playback_count, int capture_count, struct snd_pcm **rpcm) | ||
766 | { | ||
767 | return _snd_pcm_new(card, id, device, playback_count, capture_count, | ||
768 | false, rpcm); | ||
769 | } | ||
759 | EXPORT_SYMBOL(snd_pcm_new); | 770 | EXPORT_SYMBOL(snd_pcm_new); |
760 | 771 | ||
772 | /** | ||
773 | * snd_pcm_new_internal - create a new internal PCM instance | ||
774 | * @card: the card instance | ||
775 | * @id: the id string | ||
776 | * @device: the device index (zero based - shared with normal PCMs) | ||
777 | * @playback_count: the number of substreams for playback | ||
778 | * @capture_count: the number of substreams for capture | ||
779 | * @rpcm: the pointer to store the new pcm instance | ||
780 | * | ||
781 | * Creates a new internal PCM instance with no userspace device or procfs | ||
782 | * entries. This is used by ASoC Back End PCMs in order to create a PCM that | ||
783 | * will only be used internally by kernel drivers. i.e. it cannot be opened | ||
784 | * by userspace. It provides existing ASoC components drivers with a substream | ||
785 | * and access to any private data. | ||
786 | * | ||
787 | * The pcm operators have to be set afterwards to the new instance | ||
788 | * via snd_pcm_set_ops(). | ||
789 | * | ||
790 | * Returns zero if successful, or a negative error code on failure. | ||
791 | */ | ||
792 | int snd_pcm_new_internal(struct snd_card *card, const char *id, int device, | ||
793 | int playback_count, int capture_count, | ||
794 | struct snd_pcm **rpcm) | ||
795 | { | ||
796 | return _snd_pcm_new(card, id, device, playback_count, capture_count, | ||
797 | true, rpcm); | ||
798 | } | ||
799 | EXPORT_SYMBOL(snd_pcm_new_internal); | ||
800 | |||
761 | static void snd_pcm_free_stream(struct snd_pcm_str * pstr) | 801 | static void snd_pcm_free_stream(struct snd_pcm_str * pstr) |
762 | { | 802 | { |
763 | struct snd_pcm_substream *substream, *substream_next; | 803 | struct snd_pcm_substream *substream, *substream_next; |
@@ -994,7 +1034,7 @@ static int snd_pcm_dev_register(struct snd_device *device) | |||
994 | } | 1034 | } |
995 | for (cidx = 0; cidx < 2; cidx++) { | 1035 | for (cidx = 0; cidx < 2; cidx++) { |
996 | int devtype = -1; | 1036 | int devtype = -1; |
997 | if (pcm->streams[cidx].substream == NULL) | 1037 | if (pcm->streams[cidx].substream == NULL || pcm->internal) |
998 | continue; | 1038 | continue; |
999 | switch (cidx) { | 1039 | switch (cidx) { |
1000 | case SNDRV_PCM_STREAM_PLAYBACK: | 1040 | case SNDRV_PCM_STREAM_PLAYBACK: |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 3420bd3da5d7..4d18941178e6 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -1029,7 +1029,8 @@ static int snd_interval_ratden(struct snd_interval *i, | |||
1029 | * | 1029 | * |
1030 | * Returns non-zero if the value is changed, zero if not changed. | 1030 | * Returns non-zero if the value is changed, zero if not changed. |
1031 | */ | 1031 | */ |
1032 | int snd_interval_list(struct snd_interval *i, unsigned int count, unsigned int *list, unsigned int mask) | 1032 | int snd_interval_list(struct snd_interval *i, unsigned int count, |
1033 | const unsigned int *list, unsigned int mask) | ||
1033 | { | 1034 | { |
1034 | unsigned int k; | 1035 | unsigned int k; |
1035 | struct snd_interval list_range; | 1036 | struct snd_interval list_range; |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 25ed9fe41b89..3fe99e644eb8 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -1586,12 +1586,18 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) | |||
1586 | struct file *file; | 1586 | struct file *file; |
1587 | struct snd_pcm_file *pcm_file; | 1587 | struct snd_pcm_file *pcm_file; |
1588 | struct snd_pcm_substream *substream1; | 1588 | struct snd_pcm_substream *substream1; |
1589 | struct snd_pcm_group *group; | ||
1589 | 1590 | ||
1590 | file = snd_pcm_file_fd(fd); | 1591 | file = snd_pcm_file_fd(fd); |
1591 | if (!file) | 1592 | if (!file) |
1592 | return -EBADFD; | 1593 | return -EBADFD; |
1593 | pcm_file = file->private_data; | 1594 | pcm_file = file->private_data; |
1594 | substream1 = pcm_file->substream; | 1595 | substream1 = pcm_file->substream; |
1596 | group = kmalloc(sizeof(*group), GFP_KERNEL); | ||
1597 | if (!group) { | ||
1598 | res = -ENOMEM; | ||
1599 | goto _nolock; | ||
1600 | } | ||
1595 | down_write(&snd_pcm_link_rwsem); | 1601 | down_write(&snd_pcm_link_rwsem); |
1596 | write_lock_irq(&snd_pcm_link_rwlock); | 1602 | write_lock_irq(&snd_pcm_link_rwlock); |
1597 | if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN || | 1603 | if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN || |
@@ -1604,11 +1610,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) | |||
1604 | goto _end; | 1610 | goto _end; |
1605 | } | 1611 | } |
1606 | if (!snd_pcm_stream_linked(substream)) { | 1612 | if (!snd_pcm_stream_linked(substream)) { |
1607 | substream->group = kmalloc(sizeof(struct snd_pcm_group), GFP_ATOMIC); | 1613 | substream->group = group; |
1608 | if (substream->group == NULL) { | ||
1609 | res = -ENOMEM; | ||
1610 | goto _end; | ||
1611 | } | ||
1612 | spin_lock_init(&substream->group->lock); | 1614 | spin_lock_init(&substream->group->lock); |
1613 | INIT_LIST_HEAD(&substream->group->substreams); | 1615 | INIT_LIST_HEAD(&substream->group->substreams); |
1614 | list_add_tail(&substream->link_list, &substream->group->substreams); | 1616 | list_add_tail(&substream->link_list, &substream->group->substreams); |
@@ -1620,7 +1622,10 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) | |||
1620 | _end: | 1622 | _end: |
1621 | write_unlock_irq(&snd_pcm_link_rwlock); | 1623 | write_unlock_irq(&snd_pcm_link_rwlock); |
1622 | up_write(&snd_pcm_link_rwsem); | 1624 | up_write(&snd_pcm_link_rwsem); |
1625 | _nolock: | ||
1623 | fput(file); | 1626 | fput(file); |
1627 | if (res < 0) | ||
1628 | kfree(group); | ||
1624 | return res; | 1629 | return res; |
1625 | } | 1630 | } |
1626 | 1631 | ||
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c index 9d8379aedf40..712110561082 100644 --- a/sound/core/seq/seq.c +++ b/sound/core/seq/seq.c | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/device.h> | ||
24 | #include <sound/core.h> | 25 | #include <sound/core.h> |
25 | #include <sound/initval.h> | 26 | #include <sound/initval.h> |
26 | 27 | ||
diff --git a/sound/core/timer.c b/sound/core/timer.c index 8e7561dfc5fc..6ddcf06f52f9 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/time.h> | 25 | #include <linux/time.h> |
26 | #include <linux/mutex.h> | 26 | #include <linux/mutex.h> |
27 | #include <linux/device.h> | ||
27 | #include <linux/module.h> | 28 | #include <linux/module.h> |
28 | #include <linux/string.h> | 29 | #include <linux/string.h> |
29 | #include <sound/core.h> | 30 | #include <sound/core.h> |
diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c index 130cfe677d60..14a286a7bf2b 100644 --- a/sound/core/vmaster.c +++ b/sound/core/vmaster.c | |||
@@ -37,6 +37,8 @@ struct link_master { | |||
37 | struct link_ctl_info info; | 37 | struct link_ctl_info info; |
38 | int val; /* the master value */ | 38 | int val; /* the master value */ |
39 | unsigned int tlv[4]; | 39 | unsigned int tlv[4]; |
40 | void (*hook)(void *private_data, int); | ||
41 | void *hook_private_data; | ||
40 | }; | 42 | }; |
41 | 43 | ||
42 | /* | 44 | /* |
@@ -126,7 +128,9 @@ static int master_init(struct link_master *master) | |||
126 | master->info.count = 1; /* always mono */ | 128 | master->info.count = 1; /* always mono */ |
127 | /* set full volume as default (= no attenuation) */ | 129 | /* set full volume as default (= no attenuation) */ |
128 | master->val = master->info.max_val; | 130 | master->val = master->info.max_val; |
129 | return 0; | 131 | if (master->hook) |
132 | master->hook(master->hook_private_data, master->val); | ||
133 | return 1; | ||
130 | } | 134 | } |
131 | return -ENOENT; | 135 | return -ENOENT; |
132 | } | 136 | } |
@@ -329,6 +333,8 @@ static int master_put(struct snd_kcontrol *kcontrol, | |||
329 | slave_put_val(slave, uval); | 333 | slave_put_val(slave, uval); |
330 | } | 334 | } |
331 | kfree(uval); | 335 | kfree(uval); |
336 | if (master->hook && !err) | ||
337 | master->hook(master->hook_private_data, master->val); | ||
332 | return 1; | 338 | return 1; |
333 | } | 339 | } |
334 | 340 | ||
@@ -408,3 +414,41 @@ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, | |||
408 | return kctl; | 414 | return kctl; |
409 | } | 415 | } |
410 | EXPORT_SYMBOL(snd_ctl_make_virtual_master); | 416 | EXPORT_SYMBOL(snd_ctl_make_virtual_master); |
417 | |||
418 | /** | ||
419 | * snd_ctl_add_vmaster_hook - Add a hook to a vmaster control | ||
420 | * @kcontrol: vmaster kctl element | ||
421 | * @hook: the hook function | ||
422 | * | ||
423 | * Adds the given hook to the vmaster control element so that it's called | ||
424 | * at each time when the value is changed. | ||
425 | */ | ||
426 | int snd_ctl_add_vmaster_hook(struct snd_kcontrol *kcontrol, | ||
427 | void (*hook)(void *private_data, int), | ||
428 | void *private_data) | ||
429 | { | ||
430 | struct link_master *master = snd_kcontrol_chip(kcontrol); | ||
431 | master->hook = hook; | ||
432 | master->hook_private_data = private_data; | ||
433 | return 0; | ||
434 | } | ||
435 | EXPORT_SYMBOL_GPL(snd_ctl_add_vmaster_hook); | ||
436 | |||
437 | /** | ||
438 | * snd_ctl_sync_vmaster_hook - Sync the vmaster hook | ||
439 | * @kcontrol: vmaster kctl element | ||
440 | * | ||
441 | * Call the hook function to synchronize with the current value of the given | ||
442 | * vmaster element. NOP when NULL is passed to @kcontrol or the hook doesn't | ||
443 | * exist. | ||
444 | */ | ||
445 | void snd_ctl_sync_vmaster_hook(struct snd_kcontrol *kcontrol) | ||
446 | { | ||
447 | struct link_master *master; | ||
448 | if (!kcontrol) | ||
449 | return; | ||
450 | master = snd_kcontrol_chip(kcontrol); | ||
451 | if (master->hook) | ||
452 | master->hook(master->hook_private_data, master->val); | ||
453 | } | ||
454 | EXPORT_SYMBOL_GPL(snd_ctl_sync_vmaster_hook); | ||
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c index cd094ecaca3b..d428ffede4f3 100644 --- a/sound/firewire/isight.c +++ b/sound/firewire/isight.c | |||
@@ -611,7 +611,6 @@ static void isight_card_free(struct snd_card *card) | |||
611 | 611 | ||
612 | fw_iso_resources_destroy(&isight->resources); | 612 | fw_iso_resources_destroy(&isight->resources); |
613 | fw_unit_put(isight->unit); | 613 | fw_unit_put(isight->unit); |
614 | fw_device_put(isight->device); | ||
615 | mutex_destroy(&isight->mutex); | 614 | mutex_destroy(&isight->mutex); |
616 | } | 615 | } |
617 | 616 | ||
@@ -644,7 +643,7 @@ static int isight_probe(struct device *unit_dev) | |||
644 | isight->card = card; | 643 | isight->card = card; |
645 | mutex_init(&isight->mutex); | 644 | mutex_init(&isight->mutex); |
646 | isight->unit = fw_unit_get(unit); | 645 | isight->unit = fw_unit_get(unit); |
647 | isight->device = fw_device_get(fw_dev); | 646 | isight->device = fw_dev; |
648 | isight->audio_base = get_unit_base(unit); | 647 | isight->audio_base = get_unit_base(unit); |
649 | if (!isight->audio_base) { | 648 | if (!isight->audio_base) { |
650 | dev_err(&unit->device, "audio unit base not found\n"); | 649 | dev_err(&unit->device, "audio unit base not found\n"); |
@@ -681,7 +680,6 @@ static int isight_probe(struct device *unit_dev) | |||
681 | 680 | ||
682 | err_unit: | 681 | err_unit: |
683 | fw_unit_put(isight->unit); | 682 | fw_unit_put(isight->unit); |
684 | fw_device_put(isight->device); | ||
685 | mutex_destroy(&isight->mutex); | 683 | mutex_destroy(&isight->mutex); |
686 | error: | 684 | error: |
687 | snd_card_free(card); | 685 | snd_card_free(card); |
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c index cbe6bb9e53b6..297244e658d9 100644 --- a/sound/firewire/speakers.c +++ b/sound/firewire/speakers.c | |||
@@ -656,12 +656,10 @@ static u32 fwspk_read_firmware_version(struct fw_unit *unit) | |||
656 | static void fwspk_card_free(struct snd_card *card) | 656 | static void fwspk_card_free(struct snd_card *card) |
657 | { | 657 | { |
658 | struct fwspk *fwspk = card->private_data; | 658 | struct fwspk *fwspk = card->private_data; |
659 | struct fw_device *dev = fw_parent_device(fwspk->unit); | ||
660 | 659 | ||
661 | amdtp_out_stream_destroy(&fwspk->stream); | 660 | amdtp_out_stream_destroy(&fwspk->stream); |
662 | cmp_connection_destroy(&fwspk->connection); | 661 | cmp_connection_destroy(&fwspk->connection); |
663 | fw_unit_put(fwspk->unit); | 662 | fw_unit_put(fwspk->unit); |
664 | fw_device_put(dev); | ||
665 | mutex_destroy(&fwspk->mutex); | 663 | mutex_destroy(&fwspk->mutex); |
666 | } | 664 | } |
667 | 665 | ||
@@ -718,7 +716,6 @@ static int __devinit fwspk_probe(struct device *unit_dev) | |||
718 | fwspk = card->private_data; | 716 | fwspk = card->private_data; |
719 | fwspk->card = card; | 717 | fwspk->card = card; |
720 | mutex_init(&fwspk->mutex); | 718 | mutex_init(&fwspk->mutex); |
721 | fw_device_get(fw_dev); | ||
722 | fwspk->unit = fw_unit_get(unit); | 719 | fwspk->unit = fw_unit_get(unit); |
723 | fwspk->device_info = fwspk_detect(fw_dev); | 720 | fwspk->device_info = fwspk_detect(fw_dev); |
724 | if (!fwspk->device_info) { | 721 | if (!fwspk->device_info) { |
@@ -767,7 +764,6 @@ err_connection: | |||
767 | cmp_connection_destroy(&fwspk->connection); | 764 | cmp_connection_destroy(&fwspk->connection); |
768 | err_unit: | 765 | err_unit: |
769 | fw_unit_put(fwspk->unit); | 766 | fw_unit_put(fwspk->unit); |
770 | fw_device_put(fw_dev); | ||
771 | mutex_destroy(&fwspk->mutex); | 767 | mutex_destroy(&fwspk->mutex); |
772 | error: | 768 | error: |
773 | snd_card_free(card); | 769 | snd_card_free(card); |
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index 6b68c8206805..a63faec5e7fd 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c | |||
@@ -25,21 +25,20 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/version.h> | 28 | #include <linux/sched.h> |
29 | #include <media/v4l2-device.h> | ||
29 | #include <media/v4l2-dev.h> | 30 | #include <media/v4l2-dev.h> |
31 | #include <media/v4l2-fh.h> | ||
30 | #include <media/v4l2-ioctl.h> | 32 | #include <media/v4l2-ioctl.h> |
33 | #include <media/v4l2-event.h> | ||
31 | #include <sound/tea575x-tuner.h> | 34 | #include <sound/tea575x-tuner.h> |
32 | 35 | ||
33 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); | 36 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); |
34 | MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips"); | 37 | MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips"); |
35 | MODULE_LICENSE("GPL"); | 38 | MODULE_LICENSE("GPL"); |
36 | 39 | ||
37 | static int radio_nr = -1; | 40 | #define FREQ_LO (76U * 16000) |
38 | module_param(radio_nr, int, 0); | 41 | #define FREQ_HI (108U * 16000) |
39 | |||
40 | #define RADIO_VERSION KERNEL_VERSION(0, 0, 2) | ||
41 | #define FREQ_LO (50UL * 16000) | ||
42 | #define FREQ_HI (150UL * 16000) | ||
43 | 42 | ||
44 | /* | 43 | /* |
45 | * definitions | 44 | * definitions |
@@ -90,7 +89,7 @@ static void snd_tea575x_write(struct snd_tea575x *tea, unsigned int val) | |||
90 | tea->ops->set_pins(tea, 0); | 89 | tea->ops->set_pins(tea, 0); |
91 | } | 90 | } |
92 | 91 | ||
93 | static unsigned int snd_tea575x_read(struct snd_tea575x *tea) | 92 | static u32 snd_tea575x_read(struct snd_tea575x *tea) |
94 | { | 93 | { |
95 | u16 l, rdata; | 94 | u16 l, rdata; |
96 | u32 data = 0; | 95 | u32 data = 0; |
@@ -121,11 +120,13 @@ static unsigned int snd_tea575x_read(struct snd_tea575x *tea) | |||
121 | return data; | 120 | return data; |
122 | } | 121 | } |
123 | 122 | ||
124 | static void snd_tea575x_get_freq(struct snd_tea575x *tea) | 123 | static u32 snd_tea575x_get_freq(struct snd_tea575x *tea) |
125 | { | 124 | { |
126 | unsigned long freq; | 125 | u32 freq = snd_tea575x_read(tea) & TEA575X_BIT_FREQ_MASK; |
126 | |||
127 | if (freq == 0) | ||
128 | return freq; | ||
127 | 129 | ||
128 | freq = snd_tea575x_read(tea) & TEA575X_BIT_FREQ_MASK; | ||
129 | /* freq *= 12.5 */ | 130 | /* freq *= 12.5 */ |
130 | freq *= 125; | 131 | freq *= 125; |
131 | freq /= 10; | 132 | freq /= 10; |
@@ -135,14 +136,13 @@ static void snd_tea575x_get_freq(struct snd_tea575x *tea) | |||
135 | else | 136 | else |
136 | freq -= TEA575X_FMIF; | 137 | freq -= TEA575X_FMIF; |
137 | 138 | ||
138 | tea->freq = freq * 16; /* from kHz */ | 139 | return clamp(freq * 16, FREQ_LO, FREQ_HI); /* from kHz */ |
139 | } | 140 | } |
140 | 141 | ||
141 | static void snd_tea575x_set_freq(struct snd_tea575x *tea) | 142 | static void snd_tea575x_set_freq(struct snd_tea575x *tea) |
142 | { | 143 | { |
143 | unsigned long freq; | 144 | u32 freq = tea->freq; |
144 | 145 | ||
145 | freq = clamp(tea->freq, FREQ_LO, FREQ_HI); | ||
146 | freq /= 16; /* to kHz */ | 146 | freq /= 16; /* to kHz */ |
147 | /* crystal fixup */ | 147 | /* crystal fixup */ |
148 | if (tea->tea5759) | 148 | if (tea->tea5759) |
@@ -167,12 +167,14 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
167 | { | 167 | { |
168 | struct snd_tea575x *tea = video_drvdata(file); | 168 | struct snd_tea575x *tea = video_drvdata(file); |
169 | 169 | ||
170 | strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver)); | 170 | strlcpy(v->driver, tea->v4l2_dev->name, sizeof(v->driver)); |
171 | strlcpy(v->card, tea->card, sizeof(v->card)); | 171 | strlcpy(v->card, tea->card, sizeof(v->card)); |
172 | strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card)); | 172 | strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card)); |
173 | strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info)); | 173 | strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info)); |
174 | v->version = RADIO_VERSION; | 174 | v->device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO; |
175 | v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; | 175 | if (!tea->cannot_read_data) |
176 | v->device_caps |= V4L2_CAP_HW_FREQ_SEEK; | ||
177 | v->capabilities = v->device_caps | V4L2_CAP_DEVICE_CAPS; | ||
176 | return 0; | 178 | return 0; |
177 | } | 179 | } |
178 | 180 | ||
@@ -191,18 +193,24 @@ static int vidioc_g_tuner(struct file *file, void *priv, | |||
191 | v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; | 193 | v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; |
192 | v->rangelow = FREQ_LO; | 194 | v->rangelow = FREQ_LO; |
193 | v->rangehigh = FREQ_HI; | 195 | v->rangehigh = FREQ_HI; |
194 | v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; | 196 | v->rxsubchans = tea->stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO; |
195 | v->audmode = tea->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO; | 197 | v->audmode = (tea->val & TEA575X_BIT_MONO) ? |
198 | V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO; | ||
196 | v->signal = tea->tuned ? 0xffff : 0; | 199 | v->signal = tea->tuned ? 0xffff : 0; |
197 | |||
198 | return 0; | 200 | return 0; |
199 | } | 201 | } |
200 | 202 | ||
201 | static int vidioc_s_tuner(struct file *file, void *priv, | 203 | static int vidioc_s_tuner(struct file *file, void *priv, |
202 | struct v4l2_tuner *v) | 204 | struct v4l2_tuner *v) |
203 | { | 205 | { |
204 | if (v->index > 0) | 206 | struct snd_tea575x *tea = video_drvdata(file); |
207 | |||
208 | if (v->index) | ||
205 | return -EINVAL; | 209 | return -EINVAL; |
210 | tea->val &= ~TEA575X_BIT_MONO; | ||
211 | if (v->audmode == V4L2_TUNER_MODE_MONO) | ||
212 | tea->val |= TEA575X_BIT_MONO; | ||
213 | snd_tea575x_write(tea, tea->val); | ||
206 | return 0; | 214 | return 0; |
207 | } | 215 | } |
208 | 216 | ||
@@ -214,7 +222,6 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
214 | if (f->tuner != 0) | 222 | if (f->tuner != 0) |
215 | return -EINVAL; | 223 | return -EINVAL; |
216 | f->type = V4L2_TUNER_RADIO; | 224 | f->type = V4L2_TUNER_RADIO; |
217 | snd_tea575x_get_freq(tea); | ||
218 | f->frequency = tea->freq; | 225 | f->frequency = tea->freq; |
219 | return 0; | 226 | return 0; |
220 | } | 227 | } |
@@ -227,33 +234,72 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
227 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | 234 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) |
228 | return -EINVAL; | 235 | return -EINVAL; |
229 | 236 | ||
230 | if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) | 237 | tea->val &= ~TEA575X_BIT_SEARCH; |
231 | return -EINVAL; | 238 | tea->freq = clamp(f->frequency, FREQ_LO, FREQ_HI); |
232 | |||
233 | tea->freq = f->frequency; | ||
234 | |||
235 | snd_tea575x_set_freq(tea); | 239 | snd_tea575x_set_freq(tea); |
236 | |||
237 | return 0; | 240 | return 0; |
238 | } | 241 | } |
239 | 242 | ||
240 | static int vidioc_g_audio(struct file *file, void *priv, | 243 | static int vidioc_s_hw_freq_seek(struct file *file, void *fh, |
241 | struct v4l2_audio *a) | 244 | struct v4l2_hw_freq_seek *a) |
242 | { | 245 | { |
243 | if (a->index > 1) | 246 | struct snd_tea575x *tea = video_drvdata(file); |
244 | return -EINVAL; | 247 | unsigned long timeout; |
245 | 248 | int i; | |
246 | strcpy(a->name, "Radio"); | ||
247 | a->capability = V4L2_AUDCAP_STEREO; | ||
248 | return 0; | ||
249 | } | ||
250 | 249 | ||
251 | static int vidioc_s_audio(struct file *file, void *priv, | 250 | if (tea->cannot_read_data) |
252 | struct v4l2_audio *a) | 251 | return -ENOTTY; |
253 | { | 252 | if (a->tuner || a->wrap_around) |
254 | if (a->index != 0) | ||
255 | return -EINVAL; | 253 | return -EINVAL; |
256 | return 0; | 254 | |
255 | /* clear the frequency, HW will fill it in */ | ||
256 | tea->val &= ~TEA575X_BIT_FREQ_MASK; | ||
257 | tea->val |= TEA575X_BIT_SEARCH; | ||
258 | if (a->seek_upward) | ||
259 | tea->val |= TEA575X_BIT_UPDOWN; | ||
260 | else | ||
261 | tea->val &= ~TEA575X_BIT_UPDOWN; | ||
262 | snd_tea575x_write(tea, tea->val); | ||
263 | timeout = jiffies + msecs_to_jiffies(10000); | ||
264 | for (;;) { | ||
265 | if (time_after(jiffies, timeout)) | ||
266 | break; | ||
267 | if (schedule_timeout_interruptible(msecs_to_jiffies(10))) { | ||
268 | /* some signal arrived, stop search */ | ||
269 | tea->val &= ~TEA575X_BIT_SEARCH; | ||
270 | snd_tea575x_set_freq(tea); | ||
271 | return -ERESTARTSYS; | ||
272 | } | ||
273 | if (!(snd_tea575x_read(tea) & TEA575X_BIT_SEARCH)) { | ||
274 | u32 freq; | ||
275 | |||
276 | /* Found a frequency, wait until it can be read */ | ||
277 | for (i = 0; i < 100; i++) { | ||
278 | msleep(10); | ||
279 | freq = snd_tea575x_get_freq(tea); | ||
280 | if (freq) /* available */ | ||
281 | break; | ||
282 | } | ||
283 | if (freq == 0) /* shouldn't happen */ | ||
284 | break; | ||
285 | /* | ||
286 | * if we moved by less than 50 kHz, or in the wrong | ||
287 | * direction, continue seeking | ||
288 | */ | ||
289 | if (abs(tea->freq - freq) < 16 * 50 || | ||
290 | (a->seek_upward && freq < tea->freq) || | ||
291 | (!a->seek_upward && freq > tea->freq)) { | ||
292 | snd_tea575x_write(tea, tea->val); | ||
293 | continue; | ||
294 | } | ||
295 | tea->freq = freq; | ||
296 | tea->val &= ~TEA575X_BIT_SEARCH; | ||
297 | return 0; | ||
298 | } | ||
299 | } | ||
300 | tea->val &= ~TEA575X_BIT_SEARCH; | ||
301 | snd_tea575x_set_freq(tea); | ||
302 | return -EAGAIN; | ||
257 | } | 303 | } |
258 | 304 | ||
259 | static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl) | 305 | static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl) |
@@ -273,23 +319,27 @@ static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl) | |||
273 | static const struct v4l2_file_operations tea575x_fops = { | 319 | static const struct v4l2_file_operations tea575x_fops = { |
274 | .owner = THIS_MODULE, | 320 | .owner = THIS_MODULE, |
275 | .unlocked_ioctl = video_ioctl2, | 321 | .unlocked_ioctl = video_ioctl2, |
322 | .open = v4l2_fh_open, | ||
323 | .release = v4l2_fh_release, | ||
324 | .poll = v4l2_ctrl_poll, | ||
276 | }; | 325 | }; |
277 | 326 | ||
278 | static const struct v4l2_ioctl_ops tea575x_ioctl_ops = { | 327 | static const struct v4l2_ioctl_ops tea575x_ioctl_ops = { |
279 | .vidioc_querycap = vidioc_querycap, | 328 | .vidioc_querycap = vidioc_querycap, |
280 | .vidioc_g_tuner = vidioc_g_tuner, | 329 | .vidioc_g_tuner = vidioc_g_tuner, |
281 | .vidioc_s_tuner = vidioc_s_tuner, | 330 | .vidioc_s_tuner = vidioc_s_tuner, |
282 | .vidioc_g_audio = vidioc_g_audio, | ||
283 | .vidioc_s_audio = vidioc_s_audio, | ||
284 | .vidioc_g_frequency = vidioc_g_frequency, | 331 | .vidioc_g_frequency = vidioc_g_frequency, |
285 | .vidioc_s_frequency = vidioc_s_frequency, | 332 | .vidioc_s_frequency = vidioc_s_frequency, |
333 | .vidioc_s_hw_freq_seek = vidioc_s_hw_freq_seek, | ||
334 | .vidioc_log_status = v4l2_ctrl_log_status, | ||
335 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | ||
336 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
286 | }; | 337 | }; |
287 | 338 | ||
288 | static struct video_device tea575x_radio = { | 339 | static const struct video_device tea575x_radio = { |
289 | .name = "tea575x-tuner", | ||
290 | .fops = &tea575x_fops, | 340 | .fops = &tea575x_fops, |
291 | .ioctl_ops = &tea575x_ioctl_ops, | 341 | .ioctl_ops = &tea575x_ioctl_ops, |
292 | .release = video_device_release_empty, | 342 | .release = video_device_release_empty, |
293 | }; | 343 | }; |
294 | 344 | ||
295 | static const struct v4l2_ctrl_ops tea575x_ctrl_ops = { | 345 | static const struct v4l2_ctrl_ops tea575x_ctrl_ops = { |
@@ -303,27 +353,34 @@ int snd_tea575x_init(struct snd_tea575x *tea) | |||
303 | { | 353 | { |
304 | int retval; | 354 | int retval; |
305 | 355 | ||
306 | tea->mute = 1; | 356 | tea->mute = true; |
307 | 357 | ||
308 | snd_tea575x_write(tea, 0x55AA); | 358 | /* Not all devices can or know how to read the data back. |
309 | if (snd_tea575x_read(tea) != 0x55AA) | 359 | Such devices can set cannot_read_data to true. */ |
310 | return -ENODEV; | 360 | if (!tea->cannot_read_data) { |
361 | snd_tea575x_write(tea, 0x55AA); | ||
362 | if (snd_tea575x_read(tea) != 0x55AA) | ||
363 | return -ENODEV; | ||
364 | } | ||
311 | 365 | ||
312 | tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40; | 366 | tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_5_28; |
313 | tea->freq = 90500 * 16; /* 90.5Mhz default */ | 367 | tea->freq = 90500 * 16; /* 90.5Mhz default */ |
314 | snd_tea575x_set_freq(tea); | 368 | snd_tea575x_set_freq(tea); |
315 | 369 | ||
316 | tea->vd = tea575x_radio; | 370 | tea->vd = tea575x_radio; |
317 | video_set_drvdata(&tea->vd, tea); | 371 | video_set_drvdata(&tea->vd, tea); |
318 | mutex_init(&tea->mutex); | 372 | mutex_init(&tea->mutex); |
373 | strlcpy(tea->vd.name, tea->v4l2_dev->name, sizeof(tea->vd.name)); | ||
319 | tea->vd.lock = &tea->mutex; | 374 | tea->vd.lock = &tea->mutex; |
375 | tea->vd.v4l2_dev = tea->v4l2_dev; | ||
376 | tea->vd.ctrl_handler = &tea->ctrl_handler; | ||
377 | set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags); | ||
320 | 378 | ||
321 | v4l2_ctrl_handler_init(&tea->ctrl_handler, 1); | 379 | v4l2_ctrl_handler_init(&tea->ctrl_handler, 1); |
322 | tea->vd.ctrl_handler = &tea->ctrl_handler; | ||
323 | v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); | 380 | v4l2_ctrl_new_std(&tea->ctrl_handler, &tea575x_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); |
324 | retval = tea->ctrl_handler.error; | 381 | retval = tea->ctrl_handler.error; |
325 | if (retval) { | 382 | if (retval) { |
326 | printk(KERN_ERR "tea575x-tuner: can't initialize controls\n"); | 383 | v4l2_err(tea->v4l2_dev, "can't initialize controls\n"); |
327 | v4l2_ctrl_handler_free(&tea->ctrl_handler); | 384 | v4l2_ctrl_handler_free(&tea->ctrl_handler); |
328 | return retval; | 385 | return retval; |
329 | } | 386 | } |
@@ -338,9 +395,9 @@ int snd_tea575x_init(struct snd_tea575x *tea) | |||
338 | 395 | ||
339 | v4l2_ctrl_handler_setup(&tea->ctrl_handler); | 396 | v4l2_ctrl_handler_setup(&tea->ctrl_handler); |
340 | 397 | ||
341 | retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, radio_nr); | 398 | retval = video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->radio_nr); |
342 | if (retval) { | 399 | if (retval) { |
343 | printk(KERN_ERR "tea575x-tuner: can't register video device!\n"); | 400 | v4l2_err(tea->v4l2_dev, "can't register video device!\n"); |
344 | v4l2_ctrl_handler_free(&tea->ctrl_handler); | 401 | v4l2_ctrl_handler_free(&tea->ctrl_handler); |
345 | return retval; | 402 | return retval; |
346 | } | 403 | } |
diff --git a/sound/isa/sb/emu8000_patch.c b/sound/isa/sb/emu8000_patch.c index e09f144177f5..c99c6078be33 100644 --- a/sound/isa/sb/emu8000_patch.c +++ b/sound/isa/sb/emu8000_patch.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include "emu8000_local.h" | 22 | #include "emu8000_local.h" |
23 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
24 | #include <linux/moduleparam.h> | 24 | #include <linux/moduleparam.h> |
25 | #include <linux/moduleparam.h> | ||
26 | 25 | ||
27 | static int emu8000_reset_addr; | 26 | static int emu8000_reset_addr; |
28 | module_param(emu8000_reset_addr, int, 0444); | 27 | module_param(emu8000_reset_addr, int, 0444); |
diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h index bb938153a964..466a5c8e8354 100644 --- a/sound/pci/au88x0/au88x0.h +++ b/sound/pci/au88x0/au88x0.h | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <sound/mpu401.h> | 26 | #include <sound/mpu401.h> |
27 | #include <sound/hwdep.h> | 27 | #include <sound/hwdep.h> |
28 | #include <sound/ac97_codec.h> | 28 | #include <sound/ac97_codec.h> |
29 | 29 | #include <sound/tlv.h> | |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | #ifndef CHIP_AU8820 | 32 | #ifndef CHIP_AU8820 |
@@ -107,6 +107,14 @@ | |||
107 | #define NR_WTPB 0x20 /* WT channels per each bank. */ | 107 | #define NR_WTPB 0x20 /* WT channels per each bank. */ |
108 | #define NR_PCM 0x10 | 108 | #define NR_PCM 0x10 |
109 | 109 | ||
110 | struct pcm_vol { | ||
111 | struct snd_kcontrol *kctl; | ||
112 | int active; | ||
113 | int dma; | ||
114 | int mixin[4]; | ||
115 | int vol[4]; | ||
116 | }; | ||
117 | |||
110 | /* Structs */ | 118 | /* Structs */ |
111 | typedef struct { | 119 | typedef struct { |
112 | //int this_08; /* Still unknown */ | 120 | //int this_08; /* Still unknown */ |
@@ -168,6 +176,7 @@ struct snd_vortex { | |||
168 | /* Xtalk canceler */ | 176 | /* Xtalk canceler */ |
169 | int xt_mode; /* 1: speakers, 0:headphones. */ | 177 | int xt_mode; /* 1: speakers, 0:headphones. */ |
170 | #endif | 178 | #endif |
179 | struct pcm_vol pcm_vol[NR_PCM]; | ||
171 | 180 | ||
172 | int isquad; /* cache of extended ID codec flag. */ | 181 | int isquad; /* cache of extended ID codec flag. */ |
173 | 182 | ||
@@ -239,7 +248,7 @@ static int vortex_alsafmt_aspfmt(int alsafmt); | |||
239 | /* Connection stuff. */ | 248 | /* Connection stuff. */ |
240 | static void vortex_connect_default(vortex_t * vortex, int en); | 249 | static void vortex_connect_default(vortex_t * vortex, int en); |
241 | static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, | 250 | static int vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, |
242 | int dir, int type); | 251 | int dir, int type, int subdev); |
243 | static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, | 252 | static char vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, |
244 | int restype); | 253 | int restype); |
245 | #ifndef CHIP_AU8810 | 254 | #ifndef CHIP_AU8810 |
diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index 6933a27a5d76..525f881f0409 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c | |||
@@ -2050,8 +2050,6 @@ vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype) | |||
2050 | } | 2050 | } |
2051 | 2051 | ||
2052 | /* Default Connections */ | 2052 | /* Default Connections */ |
2053 | static int | ||
2054 | vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type); | ||
2055 | 2053 | ||
2056 | static void vortex_connect_default(vortex_t * vortex, int en) | 2054 | static void vortex_connect_default(vortex_t * vortex, int en) |
2057 | { | 2055 | { |
@@ -2111,15 +2109,13 @@ static void vortex_connect_default(vortex_t * vortex, int en) | |||
2111 | Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0. | 2109 | Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0. |
2112 | */ | 2110 | */ |
2113 | static int | 2111 | static int |
2114 | vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type) | 2112 | vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir, |
2113 | int type, int subdev) | ||
2115 | { | 2114 | { |
2116 | stream_t *stream; | 2115 | stream_t *stream; |
2117 | int i, en; | 2116 | int i, en; |
2117 | struct pcm_vol *p; | ||
2118 | 2118 | ||
2119 | if ((nr_ch == 3) | ||
2120 | || ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2))) | ||
2121 | return -EBUSY; | ||
2122 | |||
2123 | if (dma >= 0) { | 2119 | if (dma >= 0) { |
2124 | en = 0; | 2120 | en = 0; |
2125 | vortex_adb_checkinout(vortex, | 2121 | vortex_adb_checkinout(vortex, |
@@ -2250,6 +2246,14 @@ vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type) | |||
2250 | MIX_DEFIGAIN); | 2246 | MIX_DEFIGAIN); |
2251 | #endif | 2247 | #endif |
2252 | } | 2248 | } |
2249 | if (stream->type == VORTEX_PCM_ADB && en) { | ||
2250 | p = &vortex->pcm_vol[subdev]; | ||
2251 | p->dma = dma; | ||
2252 | for (i = 0; i < nr_ch; i++) | ||
2253 | p->mixin[i] = mix[i]; | ||
2254 | for (i = 0; i < ch_top; i++) | ||
2255 | p->vol[i] = 0; | ||
2256 | } | ||
2253 | } | 2257 | } |
2254 | #ifndef CHIP_AU8820 | 2258 | #ifndef CHIP_AU8820 |
2255 | else { | 2259 | else { |
@@ -2473,7 +2477,7 @@ static irqreturn_t vortex_interrupt(int irq, void *dev_id) | |||
2473 | hwread(vortex->mmio, VORTEX_IRQ_STAT); | 2477 | hwread(vortex->mmio, VORTEX_IRQ_STAT); |
2474 | handled = 1; | 2478 | handled = 1; |
2475 | } | 2479 | } |
2476 | if (source & IRQ_MIDI) { | 2480 | if ((source & IRQ_MIDI) && vortex->rmidi) { |
2477 | snd_mpu401_uart_interrupt(vortex->irq, | 2481 | snd_mpu401_uart_interrupt(vortex->irq, |
2478 | vortex->rmidi->private_data); | 2482 | vortex->rmidi->private_data); |
2479 | handled = 1; | 2483 | handled = 1; |
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index 0ef2f9712208..e59f120742a4 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c | |||
@@ -122,6 +122,18 @@ static struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = { | |||
122 | .mask = 0, | 122 | .mask = 0, |
123 | }; | 123 | }; |
124 | #endif | 124 | #endif |
125 | |||
126 | static void vortex_notify_pcm_vol_change(struct snd_card *card, | ||
127 | struct snd_kcontrol *kctl, int activate) | ||
128 | { | ||
129 | if (activate) | ||
130 | kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
131 | else | ||
132 | kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
133 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE | | ||
134 | SNDRV_CTL_EVENT_MASK_INFO, &(kctl->id)); | ||
135 | } | ||
136 | |||
125 | /* open callback */ | 137 | /* open callback */ |
126 | static int snd_vortex_pcm_open(struct snd_pcm_substream *substream) | 138 | static int snd_vortex_pcm_open(struct snd_pcm_substream *substream) |
127 | { | 139 | { |
@@ -230,12 +242,14 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream, | |||
230 | if (stream != NULL) | 242 | if (stream != NULL) |
231 | vortex_adb_allocroute(chip, stream->dma, | 243 | vortex_adb_allocroute(chip, stream->dma, |
232 | stream->nr_ch, stream->dir, | 244 | stream->nr_ch, stream->dir, |
233 | stream->type); | 245 | stream->type, |
246 | substream->number); | ||
234 | /* Alloc routes. */ | 247 | /* Alloc routes. */ |
235 | dma = | 248 | dma = |
236 | vortex_adb_allocroute(chip, -1, | 249 | vortex_adb_allocroute(chip, -1, |
237 | params_channels(hw_params), | 250 | params_channels(hw_params), |
238 | substream->stream, type); | 251 | substream->stream, type, |
252 | substream->number); | ||
239 | if (dma < 0) { | 253 | if (dma < 0) { |
240 | spin_unlock_irq(&chip->lock); | 254 | spin_unlock_irq(&chip->lock); |
241 | return dma; | 255 | return dma; |
@@ -246,6 +260,11 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream, | |||
246 | vortex_adbdma_setbuffers(chip, dma, | 260 | vortex_adbdma_setbuffers(chip, dma, |
247 | params_period_bytes(hw_params), | 261 | params_period_bytes(hw_params), |
248 | params_periods(hw_params)); | 262 | params_periods(hw_params)); |
263 | if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) { | ||
264 | chip->pcm_vol[substream->number].active = 1; | ||
265 | vortex_notify_pcm_vol_change(chip->card, | ||
266 | chip->pcm_vol[substream->number].kctl, 1); | ||
267 | } | ||
249 | } | 268 | } |
250 | #ifndef CHIP_AU8810 | 269 | #ifndef CHIP_AU8810 |
251 | else { | 270 | else { |
@@ -275,10 +294,18 @@ static int snd_vortex_pcm_hw_free(struct snd_pcm_substream *substream) | |||
275 | spin_lock_irq(&chip->lock); | 294 | spin_lock_irq(&chip->lock); |
276 | // Delete audio routes. | 295 | // Delete audio routes. |
277 | if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { | 296 | if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { |
278 | if (stream != NULL) | 297 | if (stream != NULL) { |
298 | if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) { | ||
299 | chip->pcm_vol[substream->number].active = 0; | ||
300 | vortex_notify_pcm_vol_change(chip->card, | ||
301 | chip->pcm_vol[substream->number].kctl, | ||
302 | 0); | ||
303 | } | ||
279 | vortex_adb_allocroute(chip, stream->dma, | 304 | vortex_adb_allocroute(chip, stream->dma, |
280 | stream->nr_ch, stream->dir, | 305 | stream->nr_ch, stream->dir, |
281 | stream->type); | 306 | stream->type, |
307 | substream->number); | ||
308 | } | ||
282 | } | 309 | } |
283 | #ifndef CHIP_AU8810 | 310 | #ifndef CHIP_AU8810 |
284 | else { | 311 | else { |
@@ -506,6 +533,83 @@ static struct snd_kcontrol_new snd_vortex_mixer_spdif[] __devinitdata = { | |||
506 | }, | 533 | }, |
507 | }; | 534 | }; |
508 | 535 | ||
536 | /* subdevice PCM Volume control */ | ||
537 | |||
538 | static int snd_vortex_pcm_vol_info(struct snd_kcontrol *kcontrol, | ||
539 | struct snd_ctl_elem_info *uinfo) | ||
540 | { | ||
541 | vortex_t *vortex = snd_kcontrol_chip(kcontrol); | ||
542 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
543 | uinfo->count = (VORTEX_IS_QUAD(vortex) ? 4 : 2); | ||
544 | uinfo->value.integer.min = -128; | ||
545 | uinfo->value.integer.max = 32; | ||
546 | return 0; | ||
547 | } | ||
548 | |||
549 | static int snd_vortex_pcm_vol_get(struct snd_kcontrol *kcontrol, | ||
550 | struct snd_ctl_elem_value *ucontrol) | ||
551 | { | ||
552 | int i; | ||
553 | vortex_t *vortex = snd_kcontrol_chip(kcontrol); | ||
554 | int subdev = kcontrol->id.subdevice; | ||
555 | struct pcm_vol *p = &vortex->pcm_vol[subdev]; | ||
556 | int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2); | ||
557 | for (i = 0; i < max_chn; i++) | ||
558 | ucontrol->value.integer.value[i] = p->vol[i]; | ||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol, | ||
563 | struct snd_ctl_elem_value *ucontrol) | ||
564 | { | ||
565 | int i; | ||
566 | int changed = 0; | ||
567 | int mixin; | ||
568 | unsigned char vol; | ||
569 | vortex_t *vortex = snd_kcontrol_chip(kcontrol); | ||
570 | int subdev = kcontrol->id.subdevice; | ||
571 | struct pcm_vol *p = &vortex->pcm_vol[subdev]; | ||
572 | int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2); | ||
573 | for (i = 0; i < max_chn; i++) { | ||
574 | if (p->vol[i] != ucontrol->value.integer.value[i]) { | ||
575 | p->vol[i] = ucontrol->value.integer.value[i]; | ||
576 | if (p->active) { | ||
577 | switch (vortex->dma_adb[p->dma].nr_ch) { | ||
578 | case 1: | ||
579 | mixin = p->mixin[0]; | ||
580 | break; | ||
581 | case 2: | ||
582 | default: | ||
583 | mixin = p->mixin[(i < 2) ? i : (i - 2)]; | ||
584 | break; | ||
585 | case 4: | ||
586 | mixin = p->mixin[i]; | ||
587 | break; | ||
588 | }; | ||
589 | vol = p->vol[i]; | ||
590 | vortex_mix_setinputvolumebyte(vortex, | ||
591 | vortex->mixplayb[i], mixin, vol); | ||
592 | } | ||
593 | changed = 1; | ||
594 | } | ||
595 | } | ||
596 | return changed; | ||
597 | } | ||
598 | |||
599 | static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400); | ||
600 | |||
601 | static struct snd_kcontrol_new snd_vortex_pcm_vol __devinitdata = { | ||
602 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
603 | .name = "PCM Playback Volume", | ||
604 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
605 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | | ||
606 | SNDRV_CTL_ELEM_ACCESS_INACTIVE, | ||
607 | .info = snd_vortex_pcm_vol_info, | ||
608 | .get = snd_vortex_pcm_vol_get, | ||
609 | .put = snd_vortex_pcm_vol_put, | ||
610 | .tlv = { .p = vortex_pcm_vol_db_scale }, | ||
611 | }; | ||
612 | |||
509 | /* create a pcm device */ | 613 | /* create a pcm device */ |
510 | static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr) | 614 | static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr) |
511 | { | 615 | { |
@@ -555,5 +659,20 @@ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr) | |||
555 | return err; | 659 | return err; |
556 | } | 660 | } |
557 | } | 661 | } |
662 | if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_ADB) { | ||
663 | for (i = 0; i < NR_PCM; i++) { | ||
664 | chip->pcm_vol[i].active = 0; | ||
665 | chip->pcm_vol[i].dma = -1; | ||
666 | kctl = snd_ctl_new1(&snd_vortex_pcm_vol, chip); | ||
667 | if (!kctl) | ||
668 | return -ENOMEM; | ||
669 | chip->pcm_vol[i].kctl = kctl; | ||
670 | kctl->id.device = 0; | ||
671 | kctl->id.subdevice = i; | ||
672 | err = snd_ctl_add(chip->card, kctl); | ||
673 | if (err < 0) | ||
674 | return err; | ||
675 | } | ||
676 | } | ||
558 | return 0; | 677 | return 0; |
559 | } | 678 | } |
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 95ffa6a9db6e..496f14c1a731 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c | |||
@@ -2684,10 +2684,9 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | |||
2684 | err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); | 2684 | err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); |
2685 | if (err < 0) | 2685 | if (err < 0) |
2686 | goto out_err; | 2686 | goto out_err; |
2687 | opl3->private_data = chip; | ||
2687 | } | 2688 | } |
2688 | 2689 | ||
2689 | opl3->private_data = chip; | ||
2690 | |||
2691 | sprintf(card->longname, "%s at 0x%lx, irq %i", | 2690 | sprintf(card->longname, "%s at 0x%lx, irq %i", |
2692 | card->shortname, chip->ctrl_io, chip->irq); | 2691 | card->shortname, chip->ctrl_io, chip->irq); |
2693 | 2692 | ||
diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c index b78f3fc3c33c..6109490b83e8 100644 --- a/sound/pci/ctxfi/ctvmem.c +++ b/sound/pci/ctxfi/ctvmem.c | |||
@@ -36,7 +36,7 @@ get_vm_block(struct ct_vm *vm, unsigned int size) | |||
36 | 36 | ||
37 | size = CT_PAGE_ALIGN(size); | 37 | size = CT_PAGE_ALIGN(size); |
38 | if (size > vm->size) { | 38 | if (size > vm->size) { |
39 | printk(KERN_ERR "ctxfi: Fail! No sufficient device virtural " | 39 | printk(KERN_ERR "ctxfi: Fail! No sufficient device virtual " |
40 | "memory space available!\n"); | 40 | "memory space available!\n"); |
41 | return NULL; | 41 | return NULL; |
42 | } | 42 | } |
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index cb557c603a80..a8faae1c85e4 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
@@ -142,6 +142,7 @@ static int enable_mpu[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; | |||
142 | #ifdef SUPPORT_JOYSTICK | 142 | #ifdef SUPPORT_JOYSTICK |
143 | static bool joystick[SNDRV_CARDS]; | 143 | static bool joystick[SNDRV_CARDS]; |
144 | #endif | 144 | #endif |
145 | static int radio_nr[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; | ||
145 | 146 | ||
146 | module_param_array(index, int, NULL, 0444); | 147 | module_param_array(index, int, NULL, 0444); |
147 | MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); | 148 | MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); |
@@ -165,6 +166,9 @@ MODULE_PARM_DESC(enable_mpu, "Enable MPU401. (0 = off, 1 = on, 2 = auto)"); | |||
165 | module_param_array(joystick, bool, NULL, 0444); | 166 | module_param_array(joystick, bool, NULL, 0444); |
166 | MODULE_PARM_DESC(joystick, "Enable joystick."); | 167 | MODULE_PARM_DESC(joystick, "Enable joystick."); |
167 | #endif | 168 | #endif |
169 | module_param_array(radio_nr, int, NULL, 0444); | ||
170 | MODULE_PARM_DESC(radio_nr, "Radio device numbers"); | ||
171 | |||
168 | 172 | ||
169 | 173 | ||
170 | #define NR_APUS 64 | 174 | #define NR_APUS 64 |
@@ -558,6 +562,7 @@ struct es1968 { | |||
558 | struct work_struct hwvol_work; | 562 | struct work_struct hwvol_work; |
559 | 563 | ||
560 | #ifdef CONFIG_SND_ES1968_RADIO | 564 | #ifdef CONFIG_SND_ES1968_RADIO |
565 | struct v4l2_device v4l2_dev; | ||
561 | struct snd_tea575x tea; | 566 | struct snd_tea575x tea; |
562 | #endif | 567 | #endif |
563 | }; | 568 | }; |
@@ -2613,6 +2618,7 @@ static int snd_es1968_free(struct es1968 *chip) | |||
2613 | 2618 | ||
2614 | #ifdef CONFIG_SND_ES1968_RADIO | 2619 | #ifdef CONFIG_SND_ES1968_RADIO |
2615 | snd_tea575x_exit(&chip->tea); | 2620 | snd_tea575x_exit(&chip->tea); |
2621 | v4l2_device_unregister(&chip->v4l2_dev); | ||
2616 | #endif | 2622 | #endif |
2617 | 2623 | ||
2618 | if (chip->irq >= 0) | 2624 | if (chip->irq >= 0) |
@@ -2655,6 +2661,7 @@ static int __devinit snd_es1968_create(struct snd_card *card, | |||
2655 | int capt_streams, | 2661 | int capt_streams, |
2656 | int chip_type, | 2662 | int chip_type, |
2657 | int do_pm, | 2663 | int do_pm, |
2664 | int radio_nr, | ||
2658 | struct es1968 **chip_ret) | 2665 | struct es1968 **chip_ret) |
2659 | { | 2666 | { |
2660 | static struct snd_device_ops ops = { | 2667 | static struct snd_device_ops ops = { |
@@ -2751,7 +2758,14 @@ static int __devinit snd_es1968_create(struct snd_card *card, | |||
2751 | snd_card_set_dev(card, &pci->dev); | 2758 | snd_card_set_dev(card, &pci->dev); |
2752 | 2759 | ||
2753 | #ifdef CONFIG_SND_ES1968_RADIO | 2760 | #ifdef CONFIG_SND_ES1968_RADIO |
2761 | err = v4l2_device_register(&pci->dev, &chip->v4l2_dev); | ||
2762 | if (err < 0) { | ||
2763 | snd_es1968_free(chip); | ||
2764 | return err; | ||
2765 | } | ||
2766 | chip->tea.v4l2_dev = &chip->v4l2_dev; | ||
2754 | chip->tea.private_data = chip; | 2767 | chip->tea.private_data = chip; |
2768 | chip->tea.radio_nr = radio_nr; | ||
2755 | chip->tea.ops = &snd_es1968_tea_ops; | 2769 | chip->tea.ops = &snd_es1968_tea_ops; |
2756 | strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card)); | 2770 | strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card)); |
2757 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); | 2771 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); |
@@ -2797,6 +2811,7 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci, | |||
2797 | pcm_substreams_c[dev], | 2811 | pcm_substreams_c[dev], |
2798 | pci_id->driver_data, | 2812 | pci_id->driver_data, |
2799 | use_pm[dev], | 2813 | use_pm[dev], |
2814 | radio_nr[dev], | ||
2800 | &chip)) < 0) { | 2815 | &chip)) < 0) { |
2801 | snd_card_free(card); | 2816 | snd_card_free(card); |
2802 | return err; | 2817 | return err; |
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index 9597ef1eccca..a416ea8af3e9 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
@@ -58,6 +58,7 @@ static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card | |||
58 | * High 16-bits are video (radio) device number + 1 | 58 | * High 16-bits are video (radio) device number + 1 |
59 | */ | 59 | */ |
60 | static int tea575x_tuner[SNDRV_CARDS]; | 60 | static int tea575x_tuner[SNDRV_CARDS]; |
61 | static int radio_nr[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; | ||
61 | 62 | ||
62 | module_param_array(index, int, NULL, 0444); | 63 | module_param_array(index, int, NULL, 0444); |
63 | MODULE_PARM_DESC(index, "Index value for the FM801 soundcard."); | 64 | MODULE_PARM_DESC(index, "Index value for the FM801 soundcard."); |
@@ -67,6 +68,9 @@ module_param_array(enable, bool, NULL, 0444); | |||
67 | MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); | 68 | MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); |
68 | module_param_array(tea575x_tuner, int, NULL, 0444); | 69 | module_param_array(tea575x_tuner, int, NULL, 0444); |
69 | MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only)."); | 70 | MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only)."); |
71 | module_param_array(radio_nr, int, NULL, 0444); | ||
72 | MODULE_PARM_DESC(radio_nr, "Radio device numbers"); | ||
73 | |||
70 | 74 | ||
71 | #define TUNER_DISABLED (1<<3) | 75 | #define TUNER_DISABLED (1<<3) |
72 | #define TUNER_ONLY (1<<4) | 76 | #define TUNER_ONLY (1<<4) |
@@ -197,6 +201,7 @@ struct fm801 { | |||
197 | struct snd_info_entry *proc_entry; | 201 | struct snd_info_entry *proc_entry; |
198 | 202 | ||
199 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL | 203 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL |
204 | struct v4l2_device v4l2_dev; | ||
200 | struct snd_tea575x tea; | 205 | struct snd_tea575x tea; |
201 | #endif | 206 | #endif |
202 | 207 | ||
@@ -1154,8 +1159,10 @@ static int snd_fm801_free(struct fm801 *chip) | |||
1154 | 1159 | ||
1155 | __end_hw: | 1160 | __end_hw: |
1156 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL | 1161 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL |
1157 | if (!(chip->tea575x_tuner & TUNER_DISABLED)) | 1162 | if (!(chip->tea575x_tuner & TUNER_DISABLED)) { |
1158 | snd_tea575x_exit(&chip->tea); | 1163 | snd_tea575x_exit(&chip->tea); |
1164 | v4l2_device_unregister(&chip->v4l2_dev); | ||
1165 | } | ||
1159 | #endif | 1166 | #endif |
1160 | if (chip->irq >= 0) | 1167 | if (chip->irq >= 0) |
1161 | free_irq(chip->irq, chip); | 1168 | free_irq(chip->irq, chip); |
@@ -1175,6 +1182,7 @@ static int snd_fm801_dev_free(struct snd_device *device) | |||
1175 | static int __devinit snd_fm801_create(struct snd_card *card, | 1182 | static int __devinit snd_fm801_create(struct snd_card *card, |
1176 | struct pci_dev * pci, | 1183 | struct pci_dev * pci, |
1177 | int tea575x_tuner, | 1184 | int tea575x_tuner, |
1185 | int radio_nr, | ||
1178 | struct fm801 ** rchip) | 1186 | struct fm801 ** rchip) |
1179 | { | 1187 | { |
1180 | struct fm801 *chip; | 1188 | struct fm801 *chip; |
@@ -1234,6 +1242,13 @@ static int __devinit snd_fm801_create(struct snd_card *card, | |||
1234 | snd_card_set_dev(card, &pci->dev); | 1242 | snd_card_set_dev(card, &pci->dev); |
1235 | 1243 | ||
1236 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL | 1244 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL |
1245 | err = v4l2_device_register(&pci->dev, &chip->v4l2_dev); | ||
1246 | if (err < 0) { | ||
1247 | snd_fm801_free(chip); | ||
1248 | return err; | ||
1249 | } | ||
1250 | chip->tea.v4l2_dev = &chip->v4l2_dev; | ||
1251 | chip->tea.radio_nr = radio_nr; | ||
1237 | chip->tea.private_data = chip; | 1252 | chip->tea.private_data = chip; |
1238 | chip->tea.ops = &snd_fm801_tea_ops; | 1253 | chip->tea.ops = &snd_fm801_tea_ops; |
1239 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); | 1254 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); |
@@ -1241,6 +1256,7 @@ static int __devinit snd_fm801_create(struct snd_card *card, | |||
1241 | (tea575x_tuner & TUNER_TYPE_MASK) < 4) { | 1256 | (tea575x_tuner & TUNER_TYPE_MASK) < 4) { |
1242 | if (snd_tea575x_init(&chip->tea)) { | 1257 | if (snd_tea575x_init(&chip->tea)) { |
1243 | snd_printk(KERN_ERR "TEA575x radio not found\n"); | 1258 | snd_printk(KERN_ERR "TEA575x radio not found\n"); |
1259 | snd_fm801_free(chip); | ||
1244 | return -ENODEV; | 1260 | return -ENODEV; |
1245 | } | 1261 | } |
1246 | } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) { | 1262 | } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) { |
@@ -1287,7 +1303,7 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci, | |||
1287 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); | 1303 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); |
1288 | if (err < 0) | 1304 | if (err < 0) |
1289 | return err; | 1305 | return err; |
1290 | if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], &chip)) < 0) { | 1306 | if ((err = snd_fm801_create(card, pci, tea575x_tuner[dev], radio_nr[dev], &chip)) < 0) { |
1291 | snd_card_free(card); | 1307 | snd_card_free(card); |
1292 | return err; | 1308 | return err; |
1293 | } | 1309 | } |
diff --git a/sound/pci/hda/alc260_quirks.c b/sound/pci/hda/alc260_quirks.c deleted file mode 100644 index 3b5170b9700f..000000000000 --- a/sound/pci/hda/alc260_quirks.c +++ /dev/null | |||
@@ -1,968 +0,0 @@ | |||
1 | /* | ||
2 | * ALC260 quirk models | ||
3 | * included by patch_realtek.c | ||
4 | */ | ||
5 | |||
6 | /* ALC260 models */ | ||
7 | enum { | ||
8 | ALC260_AUTO, | ||
9 | ALC260_BASIC, | ||
10 | ALC260_FUJITSU_S702X, | ||
11 | ALC260_ACER, | ||
12 | ALC260_WILL, | ||
13 | ALC260_REPLACER_672V, | ||
14 | ALC260_FAVORIT100, | ||
15 | #ifdef CONFIG_SND_DEBUG | ||
16 | ALC260_TEST, | ||
17 | #endif | ||
18 | ALC260_MODEL_LAST /* last tag */ | ||
19 | }; | ||
20 | |||
21 | static const hda_nid_t alc260_dac_nids[1] = { | ||
22 | /* front */ | ||
23 | 0x02, | ||
24 | }; | ||
25 | |||
26 | static const hda_nid_t alc260_adc_nids[1] = { | ||
27 | /* ADC0 */ | ||
28 | 0x04, | ||
29 | }; | ||
30 | |||
31 | static const hda_nid_t alc260_adc_nids_alt[1] = { | ||
32 | /* ADC1 */ | ||
33 | 0x05, | ||
34 | }; | ||
35 | |||
36 | /* NIDs used when simultaneous access to both ADCs makes sense. Note that | ||
37 | * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. | ||
38 | */ | ||
39 | static const hda_nid_t alc260_dual_adc_nids[2] = { | ||
40 | /* ADC0, ADC1 */ | ||
41 | 0x04, 0x05 | ||
42 | }; | ||
43 | |||
44 | #define ALC260_DIGOUT_NID 0x03 | ||
45 | #define ALC260_DIGIN_NID 0x06 | ||
46 | |||
47 | static const struct hda_input_mux alc260_capture_source = { | ||
48 | .num_items = 4, | ||
49 | .items = { | ||
50 | { "Mic", 0x0 }, | ||
51 | { "Front Mic", 0x1 }, | ||
52 | { "Line", 0x2 }, | ||
53 | { "CD", 0x4 }, | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack, | ||
58 | * headphone jack and the internal CD lines since these are the only pins at | ||
59 | * which audio can appear. For flexibility, also allow the option of | ||
60 | * recording the mixer output on the second ADC (ADC0 doesn't have a | ||
61 | * connection to the mixer output). | ||
62 | */ | ||
63 | static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = { | ||
64 | { | ||
65 | .num_items = 3, | ||
66 | .items = { | ||
67 | { "Mic/Line", 0x0 }, | ||
68 | { "CD", 0x4 }, | ||
69 | { "Headphone", 0x2 }, | ||
70 | }, | ||
71 | }, | ||
72 | { | ||
73 | .num_items = 4, | ||
74 | .items = { | ||
75 | { "Mic/Line", 0x0 }, | ||
76 | { "CD", 0x4 }, | ||
77 | { "Headphone", 0x2 }, | ||
78 | { "Mixer", 0x5 }, | ||
79 | }, | ||
80 | }, | ||
81 | |||
82 | }; | ||
83 | |||
84 | /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to | ||
85 | * the Fujitsu S702x, but jacks are marked differently. | ||
86 | */ | ||
87 | static const struct hda_input_mux alc260_acer_capture_sources[2] = { | ||
88 | { | ||
89 | .num_items = 4, | ||
90 | .items = { | ||
91 | { "Mic", 0x0 }, | ||
92 | { "Line", 0x2 }, | ||
93 | { "CD", 0x4 }, | ||
94 | { "Headphone", 0x5 }, | ||
95 | }, | ||
96 | }, | ||
97 | { | ||
98 | .num_items = 5, | ||
99 | .items = { | ||
100 | { "Mic", 0x0 }, | ||
101 | { "Line", 0x2 }, | ||
102 | { "CD", 0x4 }, | ||
103 | { "Headphone", 0x6 }, | ||
104 | { "Mixer", 0x5 }, | ||
105 | }, | ||
106 | }, | ||
107 | }; | ||
108 | |||
109 | /* Maxdata Favorit 100XS */ | ||
110 | static const struct hda_input_mux alc260_favorit100_capture_sources[2] = { | ||
111 | { | ||
112 | .num_items = 2, | ||
113 | .items = { | ||
114 | { "Line/Mic", 0x0 }, | ||
115 | { "CD", 0x4 }, | ||
116 | }, | ||
117 | }, | ||
118 | { | ||
119 | .num_items = 3, | ||
120 | .items = { | ||
121 | { "Line/Mic", 0x0 }, | ||
122 | { "CD", 0x4 }, | ||
123 | { "Mixer", 0x5 }, | ||
124 | }, | ||
125 | }, | ||
126 | }; | ||
127 | |||
128 | /* | ||
129 | * This is just place-holder, so there's something for alc_build_pcms to look | ||
130 | * at when it calculates the maximum number of channels. ALC260 has no mixer | ||
131 | * element which allows changing the channel mode, so the verb list is | ||
132 | * never used. | ||
133 | */ | ||
134 | static const struct hda_channel_mode alc260_modes[1] = { | ||
135 | { 2, NULL }, | ||
136 | }; | ||
137 | |||
138 | |||
139 | /* Mixer combinations | ||
140 | * | ||
141 | * basic: base_output + input + pc_beep + capture | ||
142 | * fujitsu: fujitsu + capture | ||
143 | * acer: acer + capture | ||
144 | */ | ||
145 | |||
146 | static const struct snd_kcontrol_new alc260_base_output_mixer[] = { | ||
147 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
148 | HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), | ||
149 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), | ||
150 | HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), | ||
151 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | ||
152 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), | ||
153 | { } /* end */ | ||
154 | }; | ||
155 | |||
156 | static const struct snd_kcontrol_new alc260_input_mixer[] = { | ||
157 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
158 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
159 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
160 | HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
161 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
162 | HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
163 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT), | ||
164 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT), | ||
165 | { } /* end */ | ||
166 | }; | ||
167 | |||
168 | /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, | ||
169 | * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. | ||
170 | */ | ||
171 | static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = { | ||
172 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
173 | HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), | ||
174 | ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | ||
175 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
176 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
177 | HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
178 | HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
179 | ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
180 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT), | ||
181 | HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT), | ||
182 | { } /* end */ | ||
183 | }; | ||
184 | |||
185 | /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current | ||
186 | * versions of the ALC260 don't act on requests to enable mic bias from NID | ||
187 | * 0x0f (used to drive the headphone jack in these laptops). The ALC260 | ||
188 | * datasheet doesn't mention this restriction. At this stage it's not clear | ||
189 | * whether this behaviour is intentional or is a hardware bug in chip | ||
190 | * revisions available in early 2006. Therefore for now allow the | ||
191 | * "Headphone Jack Mode" control to span all choices, but if it turns out | ||
192 | * that the lack of mic bias for this NID is intentional we could change the | ||
193 | * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. | ||
194 | * | ||
195 | * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006 | ||
196 | * don't appear to make the mic bias available from the "line" jack, even | ||
197 | * though the NID used for this jack (0x14) can supply it. The theory is | ||
198 | * that perhaps Acer have included blocking capacitors between the ALC260 | ||
199 | * and the output jack. If this turns out to be the case for all such | ||
200 | * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT | ||
201 | * to ALC_PIN_DIR_INOUT_NOMICBIAS. | ||
202 | * | ||
203 | * The C20x Tablet series have a mono internal speaker which is controlled | ||
204 | * via the chip's Mono sum widget and pin complex, so include the necessary | ||
205 | * controls for such models. On models without a "mono speaker" the control | ||
206 | * won't do anything. | ||
207 | */ | ||
208 | static const struct snd_kcontrol_new alc260_acer_mixer[] = { | ||
209 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
210 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), | ||
211 | ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), | ||
212 | HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, | ||
213 | HDA_OUTPUT), | ||
214 | HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, | ||
215 | HDA_INPUT), | ||
216 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
217 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
218 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
219 | HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
220 | ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
221 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
222 | HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
223 | ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | ||
224 | { } /* end */ | ||
225 | }; | ||
226 | |||
227 | /* Maxdata Favorit 100XS: one output and one input (0x12) jack | ||
228 | */ | ||
229 | static const struct snd_kcontrol_new alc260_favorit100_mixer[] = { | ||
230 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
231 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), | ||
232 | ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), | ||
233 | HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
234 | HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
235 | ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
236 | { } /* end */ | ||
237 | }; | ||
238 | |||
239 | /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, | ||
240 | * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. | ||
241 | */ | ||
242 | static const struct snd_kcontrol_new alc260_will_mixer[] = { | ||
243 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
244 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), | ||
245 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
246 | HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
247 | ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
248 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
249 | HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
250 | ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | ||
251 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
252 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
253 | { } /* end */ | ||
254 | }; | ||
255 | |||
256 | /* Replacer 672V ALC260 pin usage: Mic jack = 0x12, | ||
257 | * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. | ||
258 | */ | ||
259 | static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { | ||
260 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
261 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), | ||
262 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | ||
263 | HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), | ||
264 | ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), | ||
265 | HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), | ||
266 | HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), | ||
267 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
268 | HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
269 | ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | ||
270 | { } /* end */ | ||
271 | }; | ||
272 | |||
273 | /* | ||
274 | * initialization verbs | ||
275 | */ | ||
276 | static const struct hda_verb alc260_init_verbs[] = { | ||
277 | /* Line In pin widget for input */ | ||
278 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
279 | /* CD pin widget for input */ | ||
280 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
281 | /* Mic1 (rear panel) pin widget for input and vref at 80% */ | ||
282 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
283 | /* Mic2 (front panel) pin widget for input and vref at 80% */ | ||
284 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
285 | /* LINE-2 is used for line-out in rear */ | ||
286 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
287 | /* select line-out */ | ||
288 | {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
289 | /* LINE-OUT pin */ | ||
290 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
291 | /* enable HP */ | ||
292 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
293 | /* enable Mono */ | ||
294 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
295 | /* mute capture amp left and right */ | ||
296 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
297 | /* set connection select to line in (default select for this ADC) */ | ||
298 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
299 | /* mute capture amp left and right */ | ||
300 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
301 | /* set connection select to line in (default select for this ADC) */ | ||
302 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
303 | /* set vol=0 Line-Out mixer amp left and right */ | ||
304 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
305 | /* unmute pin widget amp left and right (no gain on this amp) */ | ||
306 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
307 | /* set vol=0 HP mixer amp left and right */ | ||
308 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
309 | /* unmute pin widget amp left and right (no gain on this amp) */ | ||
310 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
311 | /* set vol=0 Mono mixer amp left and right */ | ||
312 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
313 | /* unmute pin widget amp left and right (no gain on this amp) */ | ||
314 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
315 | /* unmute LINE-2 out pin */ | ||
316 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
317 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & | ||
318 | * Line In 2 = 0x03 | ||
319 | */ | ||
320 | /* mute analog inputs */ | ||
321 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
322 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
323 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
324 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
325 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
326 | /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ | ||
327 | /* mute Front out path */ | ||
328 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
329 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
330 | /* mute Headphone out path */ | ||
331 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
332 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
333 | /* mute Mono out path */ | ||
334 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
335 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
336 | { } | ||
337 | }; | ||
338 | |||
339 | /* Initialisation sequence for ALC260 as configured in Fujitsu S702x | ||
340 | * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD | ||
341 | * audio = 0x16, internal speaker = 0x10. | ||
342 | */ | ||
343 | static const struct hda_verb alc260_fujitsu_init_verbs[] = { | ||
344 | /* Disable all GPIOs */ | ||
345 | {0x01, AC_VERB_SET_GPIO_MASK, 0}, | ||
346 | /* Internal speaker is connected to headphone pin */ | ||
347 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
348 | /* Headphone/Line-out jack connects to Line1 pin; make it an output */ | ||
349 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
350 | /* Mic/Line-in jack is connected to mic1 pin, so make it an input */ | ||
351 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
352 | /* Ensure all other unused pins are disabled and muted. */ | ||
353 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
354 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
355 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
356 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
357 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
358 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
359 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
360 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
361 | |||
362 | /* Disable digital (SPDIF) pins */ | ||
363 | {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
364 | {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
365 | |||
366 | /* Ensure Line1 pin widget takes its input from the OUT1 sum bus | ||
367 | * when acting as an output. | ||
368 | */ | ||
369 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, | ||
370 | |||
371 | /* Start with output sum widgets muted and their output gains at min */ | ||
372 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
373 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
374 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
375 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
376 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
377 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
378 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
379 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
380 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
381 | |||
382 | /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */ | ||
383 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
384 | /* Unmute Line1 pin widget output buffer since it starts as an output. | ||
385 | * If the pin mode is changed by the user the pin mode control will | ||
386 | * take care of enabling the pin's input/output buffers as needed. | ||
387 | * Therefore there's no need to enable the input buffer at this | ||
388 | * stage. | ||
389 | */ | ||
390 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
391 | /* Unmute input buffer of pin widget used for Line-in (no equiv | ||
392 | * mixer ctrl) | ||
393 | */ | ||
394 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
395 | |||
396 | /* Mute capture amp left and right */ | ||
397 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
398 | /* Set ADC connection select to match default mixer setting - line | ||
399 | * in (on mic1 pin) | ||
400 | */ | ||
401 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
402 | |||
403 | /* Do the same for the second ADC: mute capture input amp and | ||
404 | * set ADC connection to line in (on mic1 pin) | ||
405 | */ | ||
406 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
407 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
408 | |||
409 | /* Mute all inputs to mixer widget (even unconnected ones) */ | ||
410 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ | ||
411 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ | ||
412 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ | ||
413 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ | ||
414 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ | ||
415 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ | ||
416 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ | ||
417 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ | ||
418 | |||
419 | { } | ||
420 | }; | ||
421 | |||
422 | /* Initialisation sequence for ALC260 as configured in Acer TravelMate and | ||
423 | * similar laptops (adapted from Fujitsu init verbs). | ||
424 | */ | ||
425 | static const struct hda_verb alc260_acer_init_verbs[] = { | ||
426 | /* On TravelMate laptops, GPIO 0 enables the internal speaker and | ||
427 | * the headphone jack. Turn this on and rely on the standard mute | ||
428 | * methods whenever the user wants to turn these outputs off. | ||
429 | */ | ||
430 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | ||
431 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
432 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | ||
433 | /* Internal speaker/Headphone jack is connected to Line-out pin */ | ||
434 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
435 | /* Internal microphone/Mic jack is connected to Mic1 pin */ | ||
436 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, | ||
437 | /* Line In jack is connected to Line1 pin */ | ||
438 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
439 | /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */ | ||
440 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
441 | /* Ensure all other unused pins are disabled and muted. */ | ||
442 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
443 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
444 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
445 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
446 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
447 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
448 | /* Disable digital (SPDIF) pins */ | ||
449 | {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
450 | {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
451 | |||
452 | /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum | ||
453 | * bus when acting as outputs. | ||
454 | */ | ||
455 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, | ||
456 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, | ||
457 | |||
458 | /* Start with output sum widgets muted and their output gains at min */ | ||
459 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
460 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
461 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
462 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
463 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
464 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
465 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
466 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
467 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
468 | |||
469 | /* Unmute Line-out pin widget amp left and right | ||
470 | * (no equiv mixer ctrl) | ||
471 | */ | ||
472 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
473 | /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ | ||
474 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
475 | /* Unmute Mic1 and Line1 pin widget input buffers since they start as | ||
476 | * inputs. If the pin mode is changed by the user the pin mode control | ||
477 | * will take care of enabling the pin's input/output buffers as needed. | ||
478 | * Therefore there's no need to enable the input buffer at this | ||
479 | * stage. | ||
480 | */ | ||
481 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
482 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
483 | |||
484 | /* Mute capture amp left and right */ | ||
485 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
486 | /* Set ADC connection select to match default mixer setting - mic | ||
487 | * (on mic1 pin) | ||
488 | */ | ||
489 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
490 | |||
491 | /* Do similar with the second ADC: mute capture input amp and | ||
492 | * set ADC connection to mic to match ALSA's default state. | ||
493 | */ | ||
494 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
495 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
496 | |||
497 | /* Mute all inputs to mixer widget (even unconnected ones) */ | ||
498 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ | ||
499 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ | ||
500 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ | ||
501 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ | ||
502 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ | ||
503 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ | ||
504 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ | ||
505 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ | ||
506 | |||
507 | { } | ||
508 | }; | ||
509 | |||
510 | /* Initialisation sequence for Maxdata Favorit 100XS | ||
511 | * (adapted from Acer init verbs). | ||
512 | */ | ||
513 | static const struct hda_verb alc260_favorit100_init_verbs[] = { | ||
514 | /* GPIO 0 enables the output jack. | ||
515 | * Turn this on and rely on the standard mute | ||
516 | * methods whenever the user wants to turn these outputs off. | ||
517 | */ | ||
518 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | ||
519 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
520 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | ||
521 | /* Line/Mic input jack is connected to Mic1 pin */ | ||
522 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, | ||
523 | /* Ensure all other unused pins are disabled and muted. */ | ||
524 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
525 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
526 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
527 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
528 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
529 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
530 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
531 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
532 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | ||
533 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
534 | /* Disable digital (SPDIF) pins */ | ||
535 | {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
536 | {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
537 | |||
538 | /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum | ||
539 | * bus when acting as outputs. | ||
540 | */ | ||
541 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, | ||
542 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, | ||
543 | |||
544 | /* Start with output sum widgets muted and their output gains at min */ | ||
545 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
546 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
547 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
548 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
549 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
550 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
551 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
552 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
553 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
554 | |||
555 | /* Unmute Line-out pin widget amp left and right | ||
556 | * (no equiv mixer ctrl) | ||
557 | */ | ||
558 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
559 | /* Unmute Mic1 and Line1 pin widget input buffers since they start as | ||
560 | * inputs. If the pin mode is changed by the user the pin mode control | ||
561 | * will take care of enabling the pin's input/output buffers as needed. | ||
562 | * Therefore there's no need to enable the input buffer at this | ||
563 | * stage. | ||
564 | */ | ||
565 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
566 | |||
567 | /* Mute capture amp left and right */ | ||
568 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
569 | /* Set ADC connection select to match default mixer setting - mic | ||
570 | * (on mic1 pin) | ||
571 | */ | ||
572 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
573 | |||
574 | /* Do similar with the second ADC: mute capture input amp and | ||
575 | * set ADC connection to mic to match ALSA's default state. | ||
576 | */ | ||
577 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
578 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
579 | |||
580 | /* Mute all inputs to mixer widget (even unconnected ones) */ | ||
581 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ | ||
582 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ | ||
583 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ | ||
584 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ | ||
585 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ | ||
586 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ | ||
587 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ | ||
588 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ | ||
589 | |||
590 | { } | ||
591 | }; | ||
592 | |||
593 | static const struct hda_verb alc260_will_verbs[] = { | ||
594 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
595 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
596 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
597 | {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | ||
598 | {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, | ||
599 | {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, | ||
600 | {} | ||
601 | }; | ||
602 | |||
603 | static const struct hda_verb alc260_replacer_672v_verbs[] = { | ||
604 | {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | ||
605 | {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, | ||
606 | {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, | ||
607 | |||
608 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | ||
609 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | ||
610 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, | ||
611 | |||
612 | {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
613 | {} | ||
614 | }; | ||
615 | |||
616 | /* toggle speaker-output according to the hp-jack state */ | ||
617 | static void alc260_replacer_672v_automute(struct hda_codec *codec) | ||
618 | { | ||
619 | unsigned int present; | ||
620 | |||
621 | /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ | ||
622 | present = snd_hda_jack_detect(codec, 0x0f); | ||
623 | if (present) { | ||
624 | snd_hda_codec_write_cache(codec, 0x01, 0, | ||
625 | AC_VERB_SET_GPIO_DATA, 1); | ||
626 | snd_hda_codec_write_cache(codec, 0x0f, 0, | ||
627 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
628 | PIN_HP); | ||
629 | } else { | ||
630 | snd_hda_codec_write_cache(codec, 0x01, 0, | ||
631 | AC_VERB_SET_GPIO_DATA, 0); | ||
632 | snd_hda_codec_write_cache(codec, 0x0f, 0, | ||
633 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
634 | PIN_OUT); | ||
635 | } | ||
636 | } | ||
637 | |||
638 | static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, | ||
639 | unsigned int res) | ||
640 | { | ||
641 | if ((res >> 26) == ALC_HP_EVENT) | ||
642 | alc260_replacer_672v_automute(codec); | ||
643 | } | ||
644 | |||
645 | static const struct hda_verb alc260_hp_dc7600_verbs[] = { | ||
646 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
647 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
648 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
649 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
650 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
651 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
652 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
653 | {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
654 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
655 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
656 | {} | ||
657 | }; | ||
658 | |||
659 | /* Test configuration for debugging, modelled after the ALC880 test | ||
660 | * configuration. | ||
661 | */ | ||
662 | #ifdef CONFIG_SND_DEBUG | ||
663 | static const hda_nid_t alc260_test_dac_nids[1] = { | ||
664 | 0x02, | ||
665 | }; | ||
666 | static const hda_nid_t alc260_test_adc_nids[2] = { | ||
667 | 0x04, 0x05, | ||
668 | }; | ||
669 | /* For testing the ALC260, each input MUX needs its own definition since | ||
670 | * the signal assignments are different. This assumes that the first ADC | ||
671 | * is NID 0x04. | ||
672 | */ | ||
673 | static const struct hda_input_mux alc260_test_capture_sources[2] = { | ||
674 | { | ||
675 | .num_items = 7, | ||
676 | .items = { | ||
677 | { "MIC1 pin", 0x0 }, | ||
678 | { "MIC2 pin", 0x1 }, | ||
679 | { "LINE1 pin", 0x2 }, | ||
680 | { "LINE2 pin", 0x3 }, | ||
681 | { "CD pin", 0x4 }, | ||
682 | { "LINE-OUT pin", 0x5 }, | ||
683 | { "HP-OUT pin", 0x6 }, | ||
684 | }, | ||
685 | }, | ||
686 | { | ||
687 | .num_items = 8, | ||
688 | .items = { | ||
689 | { "MIC1 pin", 0x0 }, | ||
690 | { "MIC2 pin", 0x1 }, | ||
691 | { "LINE1 pin", 0x2 }, | ||
692 | { "LINE2 pin", 0x3 }, | ||
693 | { "CD pin", 0x4 }, | ||
694 | { "Mixer", 0x5 }, | ||
695 | { "LINE-OUT pin", 0x6 }, | ||
696 | { "HP-OUT pin", 0x7 }, | ||
697 | }, | ||
698 | }, | ||
699 | }; | ||
700 | static const struct snd_kcontrol_new alc260_test_mixer[] = { | ||
701 | /* Output driver widgets */ | ||
702 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | ||
703 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), | ||
704 | HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT), | ||
705 | HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT), | ||
706 | HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
707 | HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT), | ||
708 | |||
709 | /* Modes for retasking pin widgets | ||
710 | * Note: the ALC260 doesn't seem to act on requests to enable mic | ||
711 | * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't | ||
712 | * mention this restriction. At this stage it's not clear whether | ||
713 | * this behaviour is intentional or is a hardware bug in chip | ||
714 | * revisions available at least up until early 2006. Therefore for | ||
715 | * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all | ||
716 | * choices, but if it turns out that the lack of mic bias for these | ||
717 | * NIDs is intentional we could change their modes from | ||
718 | * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS. | ||
719 | */ | ||
720 | ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT), | ||
721 | ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT), | ||
722 | ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT), | ||
723 | ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT), | ||
724 | ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT), | ||
725 | ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT), | ||
726 | |||
727 | /* Loopback mixer controls */ | ||
728 | HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT), | ||
729 | HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT), | ||
730 | HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT), | ||
731 | HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT), | ||
732 | HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT), | ||
733 | HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT), | ||
734 | HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT), | ||
735 | HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT), | ||
736 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | ||
737 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | ||
738 | HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT), | ||
739 | HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT), | ||
740 | HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT), | ||
741 | HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT), | ||
742 | |||
743 | /* Controls for GPIO pins, assuming they are configured as outputs */ | ||
744 | ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), | ||
745 | ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), | ||
746 | ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), | ||
747 | ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), | ||
748 | |||
749 | /* Switches to allow the digital IO pins to be enabled. The datasheet | ||
750 | * is ambigious as to which NID is which; testing on laptops which | ||
751 | * make this output available should provide clarification. | ||
752 | */ | ||
753 | ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), | ||
754 | ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), | ||
755 | |||
756 | /* A switch allowing EAPD to be enabled. Some laptops seem to use | ||
757 | * this output to turn on an external amplifier. | ||
758 | */ | ||
759 | ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), | ||
760 | ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), | ||
761 | |||
762 | { } /* end */ | ||
763 | }; | ||
764 | static const struct hda_verb alc260_test_init_verbs[] = { | ||
765 | /* Enable all GPIOs as outputs with an initial value of 0 */ | ||
766 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, | ||
767 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, | ||
768 | {0x01, AC_VERB_SET_GPIO_MASK, 0x0f}, | ||
769 | |||
770 | /* Enable retasking pins as output, initially without power amp */ | ||
771 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
772 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
773 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
774 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
775 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
776 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
777 | |||
778 | /* Disable digital (SPDIF) pins initially, but users can enable | ||
779 | * them via a mixer switch. In the case of SPDIF-out, this initverb | ||
780 | * payload also sets the generation to 0, output to be in "consumer" | ||
781 | * PCM format, copyright asserted, no pre-emphasis and no validity | ||
782 | * control. | ||
783 | */ | ||
784 | {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
785 | {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, | ||
786 | |||
787 | /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the | ||
788 | * OUT1 sum bus when acting as an output. | ||
789 | */ | ||
790 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, | ||
791 | {0x0c, AC_VERB_SET_CONNECT_SEL, 0}, | ||
792 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, | ||
793 | {0x0e, AC_VERB_SET_CONNECT_SEL, 0}, | ||
794 | |||
795 | /* Start with output sum widgets muted and their output gains at min */ | ||
796 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
797 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
798 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
799 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
800 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
801 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
802 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
803 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
804 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
805 | |||
806 | /* Unmute retasking pin widget output buffers since the default | ||
807 | * state appears to be output. As the pin mode is changed by the | ||
808 | * user the pin mode control will take care of enabling the pin's | ||
809 | * input/output buffers as needed. | ||
810 | */ | ||
811 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
812 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
813 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
814 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
815 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
816 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
817 | /* Also unmute the mono-out pin widget */ | ||
818 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
819 | |||
820 | /* Mute capture amp left and right */ | ||
821 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
822 | /* Set ADC connection select to match default mixer setting (mic1 | ||
823 | * pin) | ||
824 | */ | ||
825 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
826 | |||
827 | /* Do the same for the second ADC: mute capture input amp and | ||
828 | * set ADC connection to mic1 pin | ||
829 | */ | ||
830 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
831 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
832 | |||
833 | /* Mute all inputs to mixer widget (even unconnected ones) */ | ||
834 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */ | ||
835 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */ | ||
836 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */ | ||
837 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */ | ||
838 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */ | ||
839 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */ | ||
840 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */ | ||
841 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */ | ||
842 | |||
843 | { } | ||
844 | }; | ||
845 | #endif | ||
846 | |||
847 | /* | ||
848 | * ALC260 configurations | ||
849 | */ | ||
850 | static const char * const alc260_models[ALC260_MODEL_LAST] = { | ||
851 | [ALC260_BASIC] = "basic", | ||
852 | [ALC260_FUJITSU_S702X] = "fujitsu", | ||
853 | [ALC260_ACER] = "acer", | ||
854 | [ALC260_WILL] = "will", | ||
855 | [ALC260_REPLACER_672V] = "replacer", | ||
856 | [ALC260_FAVORIT100] = "favorit100", | ||
857 | #ifdef CONFIG_SND_DEBUG | ||
858 | [ALC260_TEST] = "test", | ||
859 | #endif | ||
860 | [ALC260_AUTO] = "auto", | ||
861 | }; | ||
862 | |||
863 | static const struct snd_pci_quirk alc260_cfg_tbl[] = { | ||
864 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), | ||
865 | SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), | ||
866 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), | ||
867 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), | ||
868 | SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), | ||
869 | SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), | ||
870 | SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), | ||
871 | SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), | ||
872 | SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), | ||
873 | SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), | ||
874 | SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), | ||
875 | {} | ||
876 | }; | ||
877 | |||
878 | static const struct alc_config_preset alc260_presets[] = { | ||
879 | [ALC260_BASIC] = { | ||
880 | .mixers = { alc260_base_output_mixer, | ||
881 | alc260_input_mixer }, | ||
882 | .init_verbs = { alc260_init_verbs }, | ||
883 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
884 | .dac_nids = alc260_dac_nids, | ||
885 | .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), | ||
886 | .adc_nids = alc260_dual_adc_nids, | ||
887 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
888 | .channel_mode = alc260_modes, | ||
889 | .input_mux = &alc260_capture_source, | ||
890 | }, | ||
891 | [ALC260_FUJITSU_S702X] = { | ||
892 | .mixers = { alc260_fujitsu_mixer }, | ||
893 | .init_verbs = { alc260_fujitsu_init_verbs }, | ||
894 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
895 | .dac_nids = alc260_dac_nids, | ||
896 | .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), | ||
897 | .adc_nids = alc260_dual_adc_nids, | ||
898 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
899 | .channel_mode = alc260_modes, | ||
900 | .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources), | ||
901 | .input_mux = alc260_fujitsu_capture_sources, | ||
902 | }, | ||
903 | [ALC260_ACER] = { | ||
904 | .mixers = { alc260_acer_mixer }, | ||
905 | .init_verbs = { alc260_acer_init_verbs }, | ||
906 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
907 | .dac_nids = alc260_dac_nids, | ||
908 | .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), | ||
909 | .adc_nids = alc260_dual_adc_nids, | ||
910 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
911 | .channel_mode = alc260_modes, | ||
912 | .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), | ||
913 | .input_mux = alc260_acer_capture_sources, | ||
914 | }, | ||
915 | [ALC260_FAVORIT100] = { | ||
916 | .mixers = { alc260_favorit100_mixer }, | ||
917 | .init_verbs = { alc260_favorit100_init_verbs }, | ||
918 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
919 | .dac_nids = alc260_dac_nids, | ||
920 | .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids), | ||
921 | .adc_nids = alc260_dual_adc_nids, | ||
922 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
923 | .channel_mode = alc260_modes, | ||
924 | .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources), | ||
925 | .input_mux = alc260_favorit100_capture_sources, | ||
926 | }, | ||
927 | [ALC260_WILL] = { | ||
928 | .mixers = { alc260_will_mixer }, | ||
929 | .init_verbs = { alc260_init_verbs, alc260_will_verbs }, | ||
930 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
931 | .dac_nids = alc260_dac_nids, | ||
932 | .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), | ||
933 | .adc_nids = alc260_adc_nids, | ||
934 | .dig_out_nid = ALC260_DIGOUT_NID, | ||
935 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
936 | .channel_mode = alc260_modes, | ||
937 | .input_mux = &alc260_capture_source, | ||
938 | }, | ||
939 | [ALC260_REPLACER_672V] = { | ||
940 | .mixers = { alc260_replacer_672v_mixer }, | ||
941 | .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, | ||
942 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
943 | .dac_nids = alc260_dac_nids, | ||
944 | .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), | ||
945 | .adc_nids = alc260_adc_nids, | ||
946 | .dig_out_nid = ALC260_DIGOUT_NID, | ||
947 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
948 | .channel_mode = alc260_modes, | ||
949 | .input_mux = &alc260_capture_source, | ||
950 | .unsol_event = alc260_replacer_672v_unsol_event, | ||
951 | .init_hook = alc260_replacer_672v_automute, | ||
952 | }, | ||
953 | #ifdef CONFIG_SND_DEBUG | ||
954 | [ALC260_TEST] = { | ||
955 | .mixers = { alc260_test_mixer }, | ||
956 | .init_verbs = { alc260_test_init_verbs }, | ||
957 | .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), | ||
958 | .dac_nids = alc260_test_dac_nids, | ||
959 | .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids), | ||
960 | .adc_nids = alc260_test_adc_nids, | ||
961 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
962 | .channel_mode = alc260_modes, | ||
963 | .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources), | ||
964 | .input_mux = alc260_test_capture_sources, | ||
965 | }, | ||
966 | #endif | ||
967 | }; | ||
968 | |||
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c deleted file mode 100644 index 5b68435d195b..000000000000 --- a/sound/pci/hda/alc880_quirks.c +++ /dev/null | |||
@@ -1,1700 +0,0 @@ | |||
1 | /* | ||
2 | * ALC880 quirk models | ||
3 | * included by patch_realtek.c | ||
4 | */ | ||
5 | |||
6 | /* ALC880 board config type */ | ||
7 | enum { | ||
8 | ALC880_AUTO, | ||
9 | ALC880_3ST, | ||
10 | ALC880_3ST_DIG, | ||
11 | ALC880_5ST, | ||
12 | ALC880_5ST_DIG, | ||
13 | ALC880_W810, | ||
14 | ALC880_Z71V, | ||
15 | ALC880_6ST, | ||
16 | ALC880_6ST_DIG, | ||
17 | ALC880_F1734, | ||
18 | ALC880_ASUS, | ||
19 | ALC880_ASUS_DIG, | ||
20 | ALC880_ASUS_W1V, | ||
21 | ALC880_ASUS_DIG2, | ||
22 | ALC880_FUJITSU, | ||
23 | ALC880_UNIWILL_DIG, | ||
24 | ALC880_UNIWILL, | ||
25 | ALC880_UNIWILL_P53, | ||
26 | ALC880_CLEVO, | ||
27 | ALC880_TCL_S700, | ||
28 | ALC880_LG, | ||
29 | #ifdef CONFIG_SND_DEBUG | ||
30 | ALC880_TEST, | ||
31 | #endif | ||
32 | ALC880_MODEL_LAST /* last tag */ | ||
33 | }; | ||
34 | |||
35 | /* | ||
36 | * ALC880 3-stack model | ||
37 | * | ||
38 | * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) | ||
39 | * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18, | ||
40 | * F-Mic = 0x1b, HP = 0x19 | ||
41 | */ | ||
42 | |||
43 | static const hda_nid_t alc880_dac_nids[4] = { | ||
44 | /* front, rear, clfe, rear_surr */ | ||
45 | 0x02, 0x05, 0x04, 0x03 | ||
46 | }; | ||
47 | |||
48 | static const hda_nid_t alc880_adc_nids[3] = { | ||
49 | /* ADC0-2 */ | ||
50 | 0x07, 0x08, 0x09, | ||
51 | }; | ||
52 | |||
53 | /* The datasheet says the node 0x07 is connected from inputs, | ||
54 | * but it shows zero connection in the real implementation on some devices. | ||
55 | * Note: this is a 915GAV bug, fixed on 915GLV | ||
56 | */ | ||
57 | static const hda_nid_t alc880_adc_nids_alt[2] = { | ||
58 | /* ADC1-2 */ | ||
59 | 0x08, 0x09, | ||
60 | }; | ||
61 | |||
62 | #define ALC880_DIGOUT_NID 0x06 | ||
63 | #define ALC880_DIGIN_NID 0x0a | ||
64 | #define ALC880_PIN_CD_NID 0x1c | ||
65 | |||
66 | static const struct hda_input_mux alc880_capture_source = { | ||
67 | .num_items = 4, | ||
68 | .items = { | ||
69 | { "Mic", 0x0 }, | ||
70 | { "Front Mic", 0x3 }, | ||
71 | { "Line", 0x2 }, | ||
72 | { "CD", 0x4 }, | ||
73 | }, | ||
74 | }; | ||
75 | |||
76 | /* channel source setting (2/6 channel selection for 3-stack) */ | ||
77 | /* 2ch mode */ | ||
78 | static const struct hda_verb alc880_threestack_ch2_init[] = { | ||
79 | /* set line-in to input, mute it */ | ||
80 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
81 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
82 | /* set mic-in to input vref 80%, mute it */ | ||
83 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
84 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
85 | { } /* end */ | ||
86 | }; | ||
87 | |||
88 | /* 6ch mode */ | ||
89 | static const struct hda_verb alc880_threestack_ch6_init[] = { | ||
90 | /* set line-in to output, unmute it */ | ||
91 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
92 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
93 | /* set mic-in to output, unmute it */ | ||
94 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
95 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
96 | { } /* end */ | ||
97 | }; | ||
98 | |||
99 | static const struct hda_channel_mode alc880_threestack_modes[2] = { | ||
100 | { 2, alc880_threestack_ch2_init }, | ||
101 | { 6, alc880_threestack_ch6_init }, | ||
102 | }; | ||
103 | |||
104 | static const struct snd_kcontrol_new alc880_three_stack_mixer[] = { | ||
105 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
106 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
107 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | ||
108 | HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT), | ||
109 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
110 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
111 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
112 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
113 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
114 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
115 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
116 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
117 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
118 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
119 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), | ||
120 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), | ||
121 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT), | ||
122 | { | ||
123 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
124 | .name = "Channel Mode", | ||
125 | .info = alc_ch_mode_info, | ||
126 | .get = alc_ch_mode_get, | ||
127 | .put = alc_ch_mode_put, | ||
128 | }, | ||
129 | { } /* end */ | ||
130 | }; | ||
131 | |||
132 | /* | ||
133 | * ALC880 5-stack model | ||
134 | * | ||
135 | * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d), | ||
136 | * Side = 0x02 (0xd) | ||
137 | * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16 | ||
138 | * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19 | ||
139 | */ | ||
140 | |||
141 | /* additional mixers to alc880_three_stack_mixer */ | ||
142 | static const struct snd_kcontrol_new alc880_five_stack_mixer[] = { | ||
143 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
144 | HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), | ||
145 | { } /* end */ | ||
146 | }; | ||
147 | |||
148 | /* channel source setting (6/8 channel selection for 5-stack) */ | ||
149 | /* 6ch mode */ | ||
150 | static const struct hda_verb alc880_fivestack_ch6_init[] = { | ||
151 | /* set line-in to input, mute it */ | ||
152 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
153 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
154 | { } /* end */ | ||
155 | }; | ||
156 | |||
157 | /* 8ch mode */ | ||
158 | static const struct hda_verb alc880_fivestack_ch8_init[] = { | ||
159 | /* set line-in to output, unmute it */ | ||
160 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
161 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
162 | { } /* end */ | ||
163 | }; | ||
164 | |||
165 | static const struct hda_channel_mode alc880_fivestack_modes[2] = { | ||
166 | { 6, alc880_fivestack_ch6_init }, | ||
167 | { 8, alc880_fivestack_ch8_init }, | ||
168 | }; | ||
169 | |||
170 | |||
171 | /* | ||
172 | * ALC880 6-stack model | ||
173 | * | ||
174 | * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e), | ||
175 | * Side = 0x05 (0x0f) | ||
176 | * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17, | ||
177 | * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b | ||
178 | */ | ||
179 | |||
180 | static const hda_nid_t alc880_6st_dac_nids[4] = { | ||
181 | /* front, rear, clfe, rear_surr */ | ||
182 | 0x02, 0x03, 0x04, 0x05 | ||
183 | }; | ||
184 | |||
185 | static const struct hda_input_mux alc880_6stack_capture_source = { | ||
186 | .num_items = 4, | ||
187 | .items = { | ||
188 | { "Mic", 0x0 }, | ||
189 | { "Front Mic", 0x1 }, | ||
190 | { "Line", 0x2 }, | ||
191 | { "CD", 0x4 }, | ||
192 | }, | ||
193 | }; | ||
194 | |||
195 | /* fixed 8-channels */ | ||
196 | static const struct hda_channel_mode alc880_sixstack_modes[1] = { | ||
197 | { 8, NULL }, | ||
198 | }; | ||
199 | |||
200 | static const struct snd_kcontrol_new alc880_six_stack_mixer[] = { | ||
201 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
202 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
203 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
204 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
205 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
206 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
207 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
208 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
209 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | ||
210 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | ||
211 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
212 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
213 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
214 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
215 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
216 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
217 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
218 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
219 | { | ||
220 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
221 | .name = "Channel Mode", | ||
222 | .info = alc_ch_mode_info, | ||
223 | .get = alc_ch_mode_get, | ||
224 | .put = alc_ch_mode_put, | ||
225 | }, | ||
226 | { } /* end */ | ||
227 | }; | ||
228 | |||
229 | |||
230 | /* | ||
231 | * ALC880 W810 model | ||
232 | * | ||
233 | * W810 has rear IO for: | ||
234 | * Front (DAC 02) | ||
235 | * Surround (DAC 03) | ||
236 | * Center/LFE (DAC 04) | ||
237 | * Digital out (06) | ||
238 | * | ||
239 | * The system also has a pair of internal speakers, and a headphone jack. | ||
240 | * These are both connected to Line2 on the codec, hence to DAC 02. | ||
241 | * | ||
242 | * There is a variable resistor to control the speaker or headphone | ||
243 | * volume. This is a hardware-only device without a software API. | ||
244 | * | ||
245 | * Plugging headphones in will disable the internal speakers. This is | ||
246 | * implemented in hardware, not via the driver using jack sense. In | ||
247 | * a similar fashion, plugging into the rear socket marked "front" will | ||
248 | * disable both the speakers and headphones. | ||
249 | * | ||
250 | * For input, there's a microphone jack, and an "audio in" jack. | ||
251 | * These may not do anything useful with this driver yet, because I | ||
252 | * haven't setup any initialization verbs for these yet... | ||
253 | */ | ||
254 | |||
255 | static const hda_nid_t alc880_w810_dac_nids[3] = { | ||
256 | /* front, rear/surround, clfe */ | ||
257 | 0x02, 0x03, 0x04 | ||
258 | }; | ||
259 | |||
260 | /* fixed 6 channels */ | ||
261 | static const struct hda_channel_mode alc880_w810_modes[1] = { | ||
262 | { 6, NULL } | ||
263 | }; | ||
264 | |||
265 | /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ | ||
266 | static const struct snd_kcontrol_new alc880_w810_base_mixer[] = { | ||
267 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
268 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
269 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
270 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
271 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
272 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
273 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
274 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
275 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
276 | { } /* end */ | ||
277 | }; | ||
278 | |||
279 | |||
280 | /* | ||
281 | * Z710V model | ||
282 | * | ||
283 | * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d) | ||
284 | * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?), | ||
285 | * Line = 0x1a | ||
286 | */ | ||
287 | |||
288 | static const hda_nid_t alc880_z71v_dac_nids[1] = { | ||
289 | 0x02 | ||
290 | }; | ||
291 | #define ALC880_Z71V_HP_DAC 0x03 | ||
292 | |||
293 | /* fixed 2 channels */ | ||
294 | static const struct hda_channel_mode alc880_2_jack_modes[1] = { | ||
295 | { 2, NULL } | ||
296 | }; | ||
297 | |||
298 | static const struct snd_kcontrol_new alc880_z71v_mixer[] = { | ||
299 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
300 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
301 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
302 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), | ||
303 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
304 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
305 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
306 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
307 | { } /* end */ | ||
308 | }; | ||
309 | |||
310 | |||
311 | /* | ||
312 | * ALC880 F1734 model | ||
313 | * | ||
314 | * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d) | ||
315 | * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 | ||
316 | */ | ||
317 | |||
318 | static const hda_nid_t alc880_f1734_dac_nids[1] = { | ||
319 | 0x03 | ||
320 | }; | ||
321 | #define ALC880_F1734_HP_DAC 0x02 | ||
322 | |||
323 | static const struct snd_kcontrol_new alc880_f1734_mixer[] = { | ||
324 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
325 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | ||
326 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
327 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), | ||
328 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
329 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
330 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
331 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
332 | { } /* end */ | ||
333 | }; | ||
334 | |||
335 | static const struct hda_input_mux alc880_f1734_capture_source = { | ||
336 | .num_items = 2, | ||
337 | .items = { | ||
338 | { "Mic", 0x1 }, | ||
339 | { "CD", 0x4 }, | ||
340 | }, | ||
341 | }; | ||
342 | |||
343 | |||
344 | /* | ||
345 | * ALC880 ASUS model | ||
346 | * | ||
347 | * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) | ||
348 | * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, | ||
349 | * Mic = 0x18, Line = 0x1a | ||
350 | */ | ||
351 | |||
352 | #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ | ||
353 | #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ | ||
354 | |||
355 | static const struct snd_kcontrol_new alc880_asus_mixer[] = { | ||
356 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
357 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
358 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
359 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
360 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
361 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
362 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
363 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
364 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
365 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
366 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
367 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
368 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
369 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
370 | { | ||
371 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
372 | .name = "Channel Mode", | ||
373 | .info = alc_ch_mode_info, | ||
374 | .get = alc_ch_mode_get, | ||
375 | .put = alc_ch_mode_put, | ||
376 | }, | ||
377 | { } /* end */ | ||
378 | }; | ||
379 | |||
380 | /* | ||
381 | * ALC880 ASUS W1V model | ||
382 | * | ||
383 | * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e) | ||
384 | * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16, | ||
385 | * Mic = 0x18, Line = 0x1a, Line2 = 0x1b | ||
386 | */ | ||
387 | |||
388 | /* additional mixers to alc880_asus_mixer */ | ||
389 | static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { | ||
390 | HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), | ||
391 | HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), | ||
392 | { } /* end */ | ||
393 | }; | ||
394 | |||
395 | /* TCL S700 */ | ||
396 | static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { | ||
397 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
398 | HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
399 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
400 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT), | ||
401 | HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT), | ||
402 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT), | ||
403 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), | ||
404 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
405 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
406 | { } /* end */ | ||
407 | }; | ||
408 | |||
409 | /* Uniwill */ | ||
410 | static const struct snd_kcontrol_new alc880_uniwill_mixer[] = { | ||
411 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
412 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | ||
413 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
414 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), | ||
415 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
416 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
417 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
418 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
419 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
420 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
421 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
422 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
423 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
424 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
425 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
426 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
427 | { | ||
428 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
429 | .name = "Channel Mode", | ||
430 | .info = alc_ch_mode_info, | ||
431 | .get = alc_ch_mode_get, | ||
432 | .put = alc_ch_mode_put, | ||
433 | }, | ||
434 | { } /* end */ | ||
435 | }; | ||
436 | |||
437 | static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = { | ||
438 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
439 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | ||
440 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
441 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), | ||
442 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
443 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
444 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
445 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
446 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
447 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
448 | { } /* end */ | ||
449 | }; | ||
450 | |||
451 | static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { | ||
452 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
453 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | ||
454 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
455 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), | ||
456 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
457 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
458 | { } /* end */ | ||
459 | }; | ||
460 | |||
461 | /* | ||
462 | * initialize the codec volumes, etc | ||
463 | */ | ||
464 | |||
465 | /* | ||
466 | * generic initialization of ADC, input mixers and output mixers | ||
467 | */ | ||
468 | static const struct hda_verb alc880_volume_init_verbs[] = { | ||
469 | /* | ||
470 | * Unmute ADC0-2 and set the default input to mic-in | ||
471 | */ | ||
472 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
473 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
474 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
475 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
476 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
477 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
478 | |||
479 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | ||
480 | * mixer widget | ||
481 | * Note: PASD motherboards uses the Line In 2 as the input for front | ||
482 | * panel mic (mic 2) | ||
483 | */ | ||
484 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | ||
485 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
486 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
487 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
488 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
489 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
490 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, | ||
491 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, | ||
492 | |||
493 | /* | ||
494 | * Set up output mixers (0x0c - 0x0f) | ||
495 | */ | ||
496 | /* set vol=0 to output mixers */ | ||
497 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
498 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
499 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
500 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
501 | /* set up input amps for analog loopback */ | ||
502 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
503 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
504 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
505 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
506 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
507 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
508 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
509 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
510 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
511 | |||
512 | { } | ||
513 | }; | ||
514 | |||
515 | /* | ||
516 | * 3-stack pin configuration: | ||
517 | * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b | ||
518 | */ | ||
519 | static const struct hda_verb alc880_pin_3stack_init_verbs[] = { | ||
520 | /* | ||
521 | * preset connection lists of input pins | ||
522 | * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround | ||
523 | */ | ||
524 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ | ||
525 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | ||
526 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ | ||
527 | |||
528 | /* | ||
529 | * Set pin mode and muting | ||
530 | */ | ||
531 | /* set front pin widgets 0x14 for output */ | ||
532 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
533 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
534 | /* Mic1 (rear panel) pin widget for input and vref at 80% */ | ||
535 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
536 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
537 | /* Mic2 (as headphone out) for HP output */ | ||
538 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
539 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
540 | /* Line In pin widget for input */ | ||
541 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
542 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
543 | /* Line2 (as front mic) pin widget for input and vref at 80% */ | ||
544 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
545 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
546 | /* CD pin widget for input */ | ||
547 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
548 | |||
549 | { } | ||
550 | }; | ||
551 | |||
552 | /* | ||
553 | * 5-stack pin configuration: | ||
554 | * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, | ||
555 | * line-in/side = 0x1a, f-mic = 0x1b | ||
556 | */ | ||
557 | static const struct hda_verb alc880_pin_5stack_init_verbs[] = { | ||
558 | /* | ||
559 | * preset connection lists of input pins | ||
560 | * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround | ||
561 | */ | ||
562 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | ||
563 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */ | ||
564 | |||
565 | /* | ||
566 | * Set pin mode and muting | ||
567 | */ | ||
568 | /* set pin widgets 0x14-0x17 for output */ | ||
569 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
570 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
571 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
572 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
573 | /* unmute pins for output (no gain on this amp) */ | ||
574 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
575 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
576 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
577 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
578 | |||
579 | /* Mic1 (rear panel) pin widget for input and vref at 80% */ | ||
580 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
581 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
582 | /* Mic2 (as headphone out) for HP output */ | ||
583 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
584 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
585 | /* Line In pin widget for input */ | ||
586 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
587 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
588 | /* Line2 (as front mic) pin widget for input and vref at 80% */ | ||
589 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
590 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
591 | /* CD pin widget for input */ | ||
592 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
593 | |||
594 | { } | ||
595 | }; | ||
596 | |||
597 | /* | ||
598 | * W810 pin configuration: | ||
599 | * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b | ||
600 | */ | ||
601 | static const struct hda_verb alc880_pin_w810_init_verbs[] = { | ||
602 | /* hphone/speaker input selector: front DAC */ | ||
603 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
604 | |||
605 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
606 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
607 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
608 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
609 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
610 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
611 | |||
612 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
613 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
614 | |||
615 | { } | ||
616 | }; | ||
617 | |||
618 | /* | ||
619 | * Z71V pin configuration: | ||
620 | * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) | ||
621 | */ | ||
622 | static const struct hda_verb alc880_pin_z71v_init_verbs[] = { | ||
623 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
624 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
625 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
626 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
627 | |||
628 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
629 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
630 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
631 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
632 | |||
633 | { } | ||
634 | }; | ||
635 | |||
636 | /* | ||
637 | * 6-stack pin configuration: | ||
638 | * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, | ||
639 | * f-mic = 0x19, line = 0x1a, HP = 0x1b | ||
640 | */ | ||
641 | static const struct hda_verb alc880_pin_6stack_init_verbs[] = { | ||
642 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | ||
643 | |||
644 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
645 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
646 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
647 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
648 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
649 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
650 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
651 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
652 | |||
653 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
654 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
655 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
656 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
657 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
658 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
659 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
660 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
661 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
662 | |||
663 | { } | ||
664 | }; | ||
665 | |||
666 | /* | ||
667 | * Uniwill pin configuration: | ||
668 | * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, | ||
669 | * line = 0x1a | ||
670 | */ | ||
671 | static const struct hda_verb alc880_uniwill_init_verbs[] = { | ||
672 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | ||
673 | |||
674 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
675 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
676 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
677 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
678 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
679 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
680 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
681 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
682 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
683 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
684 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
685 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
686 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
687 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
688 | |||
689 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
690 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
691 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
692 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
693 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
694 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
695 | /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */ | ||
696 | /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ | ||
697 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
698 | |||
699 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
700 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
701 | |||
702 | { } | ||
703 | }; | ||
704 | |||
705 | /* | ||
706 | * Uniwill P53 | ||
707 | * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, | ||
708 | */ | ||
709 | static const struct hda_verb alc880_uniwill_p53_init_verbs[] = { | ||
710 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | ||
711 | |||
712 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
713 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
714 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
715 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
716 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
717 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
718 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
719 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
720 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
721 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
722 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
723 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
724 | |||
725 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
726 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
727 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
728 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
729 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
730 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
731 | |||
732 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
733 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_DCVOL_EVENT}, | ||
734 | |||
735 | { } | ||
736 | }; | ||
737 | |||
738 | static const struct hda_verb alc880_beep_init_verbs[] = { | ||
739 | { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, | ||
740 | { } | ||
741 | }; | ||
742 | |||
743 | static void alc880_uniwill_setup(struct hda_codec *codec) | ||
744 | { | ||
745 | struct alc_spec *spec = codec->spec; | ||
746 | |||
747 | spec->autocfg.hp_pins[0] = 0x14; | ||
748 | spec->autocfg.speaker_pins[0] = 0x15; | ||
749 | spec->autocfg.speaker_pins[0] = 0x16; | ||
750 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); | ||
751 | } | ||
752 | |||
753 | static void alc880_uniwill_init_hook(struct hda_codec *codec) | ||
754 | { | ||
755 | alc_hp_automute(codec); | ||
756 | alc88x_simple_mic_automute(codec); | ||
757 | } | ||
758 | |||
759 | static void alc880_uniwill_unsol_event(struct hda_codec *codec, | ||
760 | unsigned int res) | ||
761 | { | ||
762 | /* Looks like the unsol event is incompatible with the standard | ||
763 | * definition. 4bit tag is placed at 28 bit! | ||
764 | */ | ||
765 | switch (res >> 28) { | ||
766 | case ALC_MIC_EVENT: | ||
767 | alc88x_simple_mic_automute(codec); | ||
768 | break; | ||
769 | default: | ||
770 | alc_sku_unsol_event(codec, res); | ||
771 | break; | ||
772 | } | ||
773 | } | ||
774 | |||
775 | static void alc880_uniwill_p53_setup(struct hda_codec *codec) | ||
776 | { | ||
777 | struct alc_spec *spec = codec->spec; | ||
778 | |||
779 | spec->autocfg.hp_pins[0] = 0x14; | ||
780 | spec->autocfg.speaker_pins[0] = 0x15; | ||
781 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); | ||
782 | } | ||
783 | |||
784 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) | ||
785 | { | ||
786 | unsigned int present; | ||
787 | |||
788 | present = snd_hda_codec_read(codec, 0x21, 0, | ||
789 | AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); | ||
790 | present &= HDA_AMP_VOLMASK; | ||
791 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, | ||
792 | HDA_AMP_VOLMASK, present); | ||
793 | snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0, | ||
794 | HDA_AMP_VOLMASK, present); | ||
795 | } | ||
796 | |||
797 | static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, | ||
798 | unsigned int res) | ||
799 | { | ||
800 | /* Looks like the unsol event is incompatible with the standard | ||
801 | * definition. 4bit tag is placed at 28 bit! | ||
802 | */ | ||
803 | if ((res >> 28) == ALC_DCVOL_EVENT) | ||
804 | alc880_uniwill_p53_dcvol_automute(codec); | ||
805 | else | ||
806 | alc_sku_unsol_event(codec, res); | ||
807 | } | ||
808 | |||
809 | /* | ||
810 | * F1734 pin configuration: | ||
811 | * HP = 0x14, speaker-out = 0x15, mic = 0x18 | ||
812 | */ | ||
813 | static const struct hda_verb alc880_pin_f1734_init_verbs[] = { | ||
814 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
815 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
816 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
817 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
818 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
819 | |||
820 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
821 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
822 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
823 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
824 | |||
825 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
826 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
827 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, | ||
828 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
829 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
830 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
831 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
832 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
833 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
834 | |||
835 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT}, | ||
836 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_DCVOL_EVENT}, | ||
837 | |||
838 | { } | ||
839 | }; | ||
840 | |||
841 | /* | ||
842 | * ASUS pin configuration: | ||
843 | * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a | ||
844 | */ | ||
845 | static const struct hda_verb alc880_pin_asus_init_verbs[] = { | ||
846 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
847 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
848 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
849 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
850 | |||
851 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
852 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
853 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
854 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
855 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
856 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
857 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
858 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
859 | |||
860 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
861 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
862 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
863 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
864 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
865 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
866 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
867 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
868 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
869 | |||
870 | { } | ||
871 | }; | ||
872 | |||
873 | /* Enable GPIO mask and set output */ | ||
874 | #define alc880_gpio1_init_verbs alc_gpio1_init_verbs | ||
875 | #define alc880_gpio2_init_verbs alc_gpio2_init_verbs | ||
876 | #define alc880_gpio3_init_verbs alc_gpio3_init_verbs | ||
877 | |||
878 | /* Clevo m520g init */ | ||
879 | static const struct hda_verb alc880_pin_clevo_init_verbs[] = { | ||
880 | /* headphone output */ | ||
881 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
882 | /* line-out */ | ||
883 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
884 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
885 | /* Line-in */ | ||
886 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
887 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
888 | /* CD */ | ||
889 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
890 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
891 | /* Mic1 (rear panel) */ | ||
892 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
893 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
894 | /* Mic2 (front panel) */ | ||
895 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
896 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
897 | /* headphone */ | ||
898 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
899 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
900 | /* change to EAPD mode */ | ||
901 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | ||
902 | {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, | ||
903 | |||
904 | { } | ||
905 | }; | ||
906 | |||
907 | static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { | ||
908 | /* change to EAPD mode */ | ||
909 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | ||
910 | {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, | ||
911 | |||
912 | /* Headphone output */ | ||
913 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
914 | /* Front output*/ | ||
915 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
916 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
917 | |||
918 | /* Line In pin widget for input */ | ||
919 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
920 | /* CD pin widget for input */ | ||
921 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
922 | /* Mic1 (rear panel) pin widget for input and vref at 80% */ | ||
923 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
924 | |||
925 | /* change to EAPD mode */ | ||
926 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | ||
927 | {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, | ||
928 | |||
929 | { } | ||
930 | }; | ||
931 | |||
932 | /* | ||
933 | * LG m1 express dual | ||
934 | * | ||
935 | * Pin assignment: | ||
936 | * Rear Line-In/Out (blue): 0x14 | ||
937 | * Build-in Mic-In: 0x15 | ||
938 | * Speaker-out: 0x17 | ||
939 | * HP-Out (green): 0x1b | ||
940 | * Mic-In/Out (red): 0x19 | ||
941 | * SPDIF-Out: 0x1e | ||
942 | */ | ||
943 | |||
944 | /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ | ||
945 | static const hda_nid_t alc880_lg_dac_nids[3] = { | ||
946 | 0x05, 0x02, 0x03 | ||
947 | }; | ||
948 | |||
949 | /* seems analog CD is not working */ | ||
950 | static const struct hda_input_mux alc880_lg_capture_source = { | ||
951 | .num_items = 3, | ||
952 | .items = { | ||
953 | { "Mic", 0x1 }, | ||
954 | { "Line", 0x5 }, | ||
955 | { "Internal Mic", 0x6 }, | ||
956 | }, | ||
957 | }; | ||
958 | |||
959 | /* 2,4,6 channel modes */ | ||
960 | static const struct hda_verb alc880_lg_ch2_init[] = { | ||
961 | /* set line-in and mic-in to input */ | ||
962 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
963 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
964 | { } | ||
965 | }; | ||
966 | |||
967 | static const struct hda_verb alc880_lg_ch4_init[] = { | ||
968 | /* set line-in to out and mic-in to input */ | ||
969 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
970 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
971 | { } | ||
972 | }; | ||
973 | |||
974 | static const struct hda_verb alc880_lg_ch6_init[] = { | ||
975 | /* set line-in and mic-in to output */ | ||
976 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
977 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | ||
978 | { } | ||
979 | }; | ||
980 | |||
981 | static const struct hda_channel_mode alc880_lg_ch_modes[3] = { | ||
982 | { 2, alc880_lg_ch2_init }, | ||
983 | { 4, alc880_lg_ch4_init }, | ||
984 | { 6, alc880_lg_ch6_init }, | ||
985 | }; | ||
986 | |||
987 | static const struct snd_kcontrol_new alc880_lg_mixer[] = { | ||
988 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | ||
989 | HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT), | ||
990 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
991 | HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT), | ||
992 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT), | ||
993 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), | ||
994 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), | ||
995 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), | ||
996 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
997 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
998 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT), | ||
999 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT), | ||
1000 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT), | ||
1001 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT), | ||
1002 | { | ||
1003 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1004 | .name = "Channel Mode", | ||
1005 | .info = alc_ch_mode_info, | ||
1006 | .get = alc_ch_mode_get, | ||
1007 | .put = alc_ch_mode_put, | ||
1008 | }, | ||
1009 | { } /* end */ | ||
1010 | }; | ||
1011 | |||
1012 | static const struct hda_verb alc880_lg_init_verbs[] = { | ||
1013 | /* set capture source to mic-in */ | ||
1014 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1015 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1016 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1017 | /* mute all amp mixer inputs */ | ||
1018 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, | ||
1019 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, | ||
1020 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, | ||
1021 | /* line-in to input */ | ||
1022 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
1023 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1024 | /* built-in mic */ | ||
1025 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
1026 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1027 | /* speaker-out */ | ||
1028 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
1029 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1030 | /* mic-in to input */ | ||
1031 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
1032 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
1033 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1034 | /* HP-out */ | ||
1035 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
1036 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
1037 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1038 | /* jack sense */ | ||
1039 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
1040 | { } | ||
1041 | }; | ||
1042 | |||
1043 | /* toggle speaker-output according to the hp-jack state */ | ||
1044 | static void alc880_lg_setup(struct hda_codec *codec) | ||
1045 | { | ||
1046 | struct alc_spec *spec = codec->spec; | ||
1047 | |||
1048 | spec->autocfg.hp_pins[0] = 0x1b; | ||
1049 | spec->autocfg.speaker_pins[0] = 0x17; | ||
1050 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); | ||
1051 | } | ||
1052 | |||
1053 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
1054 | static const struct hda_amp_list alc880_lg_loopbacks[] = { | ||
1055 | { 0x0b, HDA_INPUT, 1 }, | ||
1056 | { 0x0b, HDA_INPUT, 6 }, | ||
1057 | { 0x0b, HDA_INPUT, 7 }, | ||
1058 | { } /* end */ | ||
1059 | }; | ||
1060 | #endif | ||
1061 | |||
1062 | /* | ||
1063 | * Test configuration for debugging | ||
1064 | * | ||
1065 | * Almost all inputs/outputs are enabled. I/O pins can be configured via | ||
1066 | * enum controls. | ||
1067 | */ | ||
1068 | #ifdef CONFIG_SND_DEBUG | ||
1069 | static const hda_nid_t alc880_test_dac_nids[4] = { | ||
1070 | 0x02, 0x03, 0x04, 0x05 | ||
1071 | }; | ||
1072 | |||
1073 | static const struct hda_input_mux alc880_test_capture_source = { | ||
1074 | .num_items = 7, | ||
1075 | .items = { | ||
1076 | { "In-1", 0x0 }, | ||
1077 | { "In-2", 0x1 }, | ||
1078 | { "In-3", 0x2 }, | ||
1079 | { "In-4", 0x3 }, | ||
1080 | { "CD", 0x4 }, | ||
1081 | { "Front", 0x5 }, | ||
1082 | { "Surround", 0x6 }, | ||
1083 | }, | ||
1084 | }; | ||
1085 | |||
1086 | static const struct hda_channel_mode alc880_test_modes[4] = { | ||
1087 | { 2, NULL }, | ||
1088 | { 4, NULL }, | ||
1089 | { 6, NULL }, | ||
1090 | { 8, NULL }, | ||
1091 | }; | ||
1092 | |||
1093 | static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, | ||
1094 | struct snd_ctl_elem_info *uinfo) | ||
1095 | { | ||
1096 | static const char * const texts[] = { | ||
1097 | "N/A", "Line Out", "HP Out", | ||
1098 | "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" | ||
1099 | }; | ||
1100 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1101 | uinfo->count = 1; | ||
1102 | uinfo->value.enumerated.items = 8; | ||
1103 | if (uinfo->value.enumerated.item >= 8) | ||
1104 | uinfo->value.enumerated.item = 7; | ||
1105 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1106 | return 0; | ||
1107 | } | ||
1108 | |||
1109 | static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol, | ||
1110 | struct snd_ctl_elem_value *ucontrol) | ||
1111 | { | ||
1112 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1113 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; | ||
1114 | unsigned int pin_ctl, item = 0; | ||
1115 | |||
1116 | pin_ctl = snd_hda_codec_read(codec, nid, 0, | ||
1117 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
1118 | if (pin_ctl & AC_PINCTL_OUT_EN) { | ||
1119 | if (pin_ctl & AC_PINCTL_HP_EN) | ||
1120 | item = 2; | ||
1121 | else | ||
1122 | item = 1; | ||
1123 | } else if (pin_ctl & AC_PINCTL_IN_EN) { | ||
1124 | switch (pin_ctl & AC_PINCTL_VREFEN) { | ||
1125 | case AC_PINCTL_VREF_HIZ: item = 3; break; | ||
1126 | case AC_PINCTL_VREF_50: item = 4; break; | ||
1127 | case AC_PINCTL_VREF_GRD: item = 5; break; | ||
1128 | case AC_PINCTL_VREF_80: item = 6; break; | ||
1129 | case AC_PINCTL_VREF_100: item = 7; break; | ||
1130 | } | ||
1131 | } | ||
1132 | ucontrol->value.enumerated.item[0] = item; | ||
1133 | return 0; | ||
1134 | } | ||
1135 | |||
1136 | static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, | ||
1137 | struct snd_ctl_elem_value *ucontrol) | ||
1138 | { | ||
1139 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1140 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; | ||
1141 | static const unsigned int ctls[] = { | ||
1142 | 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, | ||
1143 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, | ||
1144 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, | ||
1145 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD, | ||
1146 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_80, | ||
1147 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_100, | ||
1148 | }; | ||
1149 | unsigned int old_ctl, new_ctl; | ||
1150 | |||
1151 | old_ctl = snd_hda_codec_read(codec, nid, 0, | ||
1152 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
1153 | new_ctl = ctls[ucontrol->value.enumerated.item[0]]; | ||
1154 | if (old_ctl != new_ctl) { | ||
1155 | int val; | ||
1156 | snd_hda_codec_write_cache(codec, nid, 0, | ||
1157 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1158 | new_ctl); | ||
1159 | val = ucontrol->value.enumerated.item[0] >= 3 ? | ||
1160 | HDA_AMP_MUTE : 0; | ||
1161 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | ||
1162 | HDA_AMP_MUTE, val); | ||
1163 | return 1; | ||
1164 | } | ||
1165 | return 0; | ||
1166 | } | ||
1167 | |||
1168 | static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, | ||
1169 | struct snd_ctl_elem_info *uinfo) | ||
1170 | { | ||
1171 | static const char * const texts[] = { | ||
1172 | "Front", "Surround", "CLFE", "Side" | ||
1173 | }; | ||
1174 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1175 | uinfo->count = 1; | ||
1176 | uinfo->value.enumerated.items = 4; | ||
1177 | if (uinfo->value.enumerated.item >= 4) | ||
1178 | uinfo->value.enumerated.item = 3; | ||
1179 | strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); | ||
1180 | return 0; | ||
1181 | } | ||
1182 | |||
1183 | static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol, | ||
1184 | struct snd_ctl_elem_value *ucontrol) | ||
1185 | { | ||
1186 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1187 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; | ||
1188 | unsigned int sel; | ||
1189 | |||
1190 | sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0); | ||
1191 | ucontrol->value.enumerated.item[0] = sel & 3; | ||
1192 | return 0; | ||
1193 | } | ||
1194 | |||
1195 | static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, | ||
1196 | struct snd_ctl_elem_value *ucontrol) | ||
1197 | { | ||
1198 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1199 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; | ||
1200 | unsigned int sel; | ||
1201 | |||
1202 | sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3; | ||
1203 | if (ucontrol->value.enumerated.item[0] != sel) { | ||
1204 | sel = ucontrol->value.enumerated.item[0] & 3; | ||
1205 | snd_hda_codec_write_cache(codec, nid, 0, | ||
1206 | AC_VERB_SET_CONNECT_SEL, sel); | ||
1207 | return 1; | ||
1208 | } | ||
1209 | return 0; | ||
1210 | } | ||
1211 | |||
1212 | #define PIN_CTL_TEST(xname,nid) { \ | ||
1213 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
1214 | .name = xname, \ | ||
1215 | .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ | ||
1216 | .info = alc_test_pin_ctl_info, \ | ||
1217 | .get = alc_test_pin_ctl_get, \ | ||
1218 | .put = alc_test_pin_ctl_put, \ | ||
1219 | .private_value = nid \ | ||
1220 | } | ||
1221 | |||
1222 | #define PIN_SRC_TEST(xname,nid) { \ | ||
1223 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
1224 | .name = xname, \ | ||
1225 | .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ | ||
1226 | .info = alc_test_pin_src_info, \ | ||
1227 | .get = alc_test_pin_src_get, \ | ||
1228 | .put = alc_test_pin_src_put, \ | ||
1229 | .private_value = nid \ | ||
1230 | } | ||
1231 | |||
1232 | static const struct snd_kcontrol_new alc880_test_mixer[] = { | ||
1233 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
1234 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
1235 | HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), | ||
1236 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | ||
1237 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
1238 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
1239 | HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT), | ||
1240 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | ||
1241 | PIN_CTL_TEST("Front Pin Mode", 0x14), | ||
1242 | PIN_CTL_TEST("Surround Pin Mode", 0x15), | ||
1243 | PIN_CTL_TEST("CLFE Pin Mode", 0x16), | ||
1244 | PIN_CTL_TEST("Side Pin Mode", 0x17), | ||
1245 | PIN_CTL_TEST("In-1 Pin Mode", 0x18), | ||
1246 | PIN_CTL_TEST("In-2 Pin Mode", 0x19), | ||
1247 | PIN_CTL_TEST("In-3 Pin Mode", 0x1a), | ||
1248 | PIN_CTL_TEST("In-4 Pin Mode", 0x1b), | ||
1249 | PIN_SRC_TEST("In-1 Pin Source", 0x18), | ||
1250 | PIN_SRC_TEST("In-2 Pin Source", 0x19), | ||
1251 | PIN_SRC_TEST("In-3 Pin Source", 0x1a), | ||
1252 | PIN_SRC_TEST("In-4 Pin Source", 0x1b), | ||
1253 | HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
1254 | HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
1255 | HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
1256 | HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
1257 | HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT), | ||
1258 | HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT), | ||
1259 | HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT), | ||
1260 | HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT), | ||
1261 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT), | ||
1262 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT), | ||
1263 | { | ||
1264 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1265 | .name = "Channel Mode", | ||
1266 | .info = alc_ch_mode_info, | ||
1267 | .get = alc_ch_mode_get, | ||
1268 | .put = alc_ch_mode_put, | ||
1269 | }, | ||
1270 | { } /* end */ | ||
1271 | }; | ||
1272 | |||
1273 | static const struct hda_verb alc880_test_init_verbs[] = { | ||
1274 | /* Unmute inputs of 0x0c - 0x0f */ | ||
1275 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1276 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1277 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1278 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1279 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1280 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1281 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1282 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1283 | /* Vol output for 0x0c-0x0f */ | ||
1284 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1285 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1286 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1287 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
1288 | /* Set output pins 0x14-0x17 */ | ||
1289 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1290 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1291 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1292 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
1293 | /* Unmute output pins 0x14-0x17 */ | ||
1294 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1295 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1296 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1297 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
1298 | /* Set input pins 0x18-0x1c */ | ||
1299 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
1300 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
1301 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
1302 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
1303 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
1304 | /* Mute input pins 0x18-0x1b */ | ||
1305 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1306 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1307 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1308 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
1309 | /* ADC set up */ | ||
1310 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1311 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1312 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1313 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1314 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1315 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
1316 | /* Analog input/passthru */ | ||
1317 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
1318 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
1319 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
1320 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
1321 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
1322 | { } | ||
1323 | }; | ||
1324 | #endif | ||
1325 | |||
1326 | /* | ||
1327 | */ | ||
1328 | |||
1329 | static const char * const alc880_models[ALC880_MODEL_LAST] = { | ||
1330 | [ALC880_3ST] = "3stack", | ||
1331 | [ALC880_TCL_S700] = "tcl", | ||
1332 | [ALC880_3ST_DIG] = "3stack-digout", | ||
1333 | [ALC880_CLEVO] = "clevo", | ||
1334 | [ALC880_5ST] = "5stack", | ||
1335 | [ALC880_5ST_DIG] = "5stack-digout", | ||
1336 | [ALC880_W810] = "w810", | ||
1337 | [ALC880_Z71V] = "z71v", | ||
1338 | [ALC880_6ST] = "6stack", | ||
1339 | [ALC880_6ST_DIG] = "6stack-digout", | ||
1340 | [ALC880_ASUS] = "asus", | ||
1341 | [ALC880_ASUS_W1V] = "asus-w1v", | ||
1342 | [ALC880_ASUS_DIG] = "asus-dig", | ||
1343 | [ALC880_ASUS_DIG2] = "asus-dig2", | ||
1344 | [ALC880_UNIWILL_DIG] = "uniwill", | ||
1345 | [ALC880_UNIWILL_P53] = "uniwill-p53", | ||
1346 | [ALC880_FUJITSU] = "fujitsu", | ||
1347 | [ALC880_F1734] = "F1734", | ||
1348 | [ALC880_LG] = "lg", | ||
1349 | #ifdef CONFIG_SND_DEBUG | ||
1350 | [ALC880_TEST] = "test", | ||
1351 | #endif | ||
1352 | [ALC880_AUTO] = "auto", | ||
1353 | }; | ||
1354 | |||
1355 | static const struct snd_pci_quirk alc880_cfg_tbl[] = { | ||
1356 | SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), | ||
1357 | SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), | ||
1358 | SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), | ||
1359 | SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG), | ||
1360 | SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG), | ||
1361 | SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG), | ||
1362 | SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG), | ||
1363 | SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG), | ||
1364 | SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST), | ||
1365 | SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG), | ||
1366 | SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V), | ||
1367 | SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG), | ||
1368 | SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG), | ||
1369 | SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG), | ||
1370 | SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG), | ||
1371 | SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG), | ||
1372 | SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V), | ||
1373 | /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */ | ||
1374 | SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG), | ||
1375 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG), | ||
1376 | SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG), | ||
1377 | SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG), | ||
1378 | SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST), | ||
1379 | SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST), | ||
1380 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */ | ||
1381 | SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST), | ||
1382 | SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST), | ||
1383 | SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST), | ||
1384 | SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST), | ||
1385 | SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST), | ||
1386 | SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG), | ||
1387 | SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG), | ||
1388 | SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG), | ||
1389 | SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG), | ||
1390 | SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO), | ||
1391 | SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO), | ||
1392 | SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2), | ||
1393 | SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG), | ||
1394 | SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG), | ||
1395 | SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734), | ||
1396 | SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL), | ||
1397 | SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53), | ||
1398 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810), | ||
1399 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG), | ||
1400 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), | ||
1401 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), | ||
1402 | SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), | ||
1403 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734), | ||
1404 | SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), | ||
1405 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), | ||
1406 | SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG), | ||
1407 | SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), | ||
1408 | SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), | ||
1409 | SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */ | ||
1410 | SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG), | ||
1411 | SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG), | ||
1412 | SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG), | ||
1413 | SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG), | ||
1414 | SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG), | ||
1415 | SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG), | ||
1416 | SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG), | ||
1417 | SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG), | ||
1418 | SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG), | ||
1419 | SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG), | ||
1420 | SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG), | ||
1421 | /* default Intel */ | ||
1422 | SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST), | ||
1423 | SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG), | ||
1424 | SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG), | ||
1425 | {} | ||
1426 | }; | ||
1427 | |||
1428 | /* | ||
1429 | * ALC880 codec presets | ||
1430 | */ | ||
1431 | static const struct alc_config_preset alc880_presets[] = { | ||
1432 | [ALC880_3ST] = { | ||
1433 | .mixers = { alc880_three_stack_mixer }, | ||
1434 | .init_verbs = { alc880_volume_init_verbs, | ||
1435 | alc880_pin_3stack_init_verbs }, | ||
1436 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | ||
1437 | .dac_nids = alc880_dac_nids, | ||
1438 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | ||
1439 | .channel_mode = alc880_threestack_modes, | ||
1440 | .need_dac_fix = 1, | ||
1441 | .input_mux = &alc880_capture_source, | ||
1442 | }, | ||
1443 | [ALC880_3ST_DIG] = { | ||
1444 | .mixers = { alc880_three_stack_mixer }, | ||
1445 | .init_verbs = { alc880_volume_init_verbs, | ||
1446 | alc880_pin_3stack_init_verbs }, | ||
1447 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | ||
1448 | .dac_nids = alc880_dac_nids, | ||
1449 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
1450 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | ||
1451 | .channel_mode = alc880_threestack_modes, | ||
1452 | .need_dac_fix = 1, | ||
1453 | .input_mux = &alc880_capture_source, | ||
1454 | }, | ||
1455 | [ALC880_TCL_S700] = { | ||
1456 | .mixers = { alc880_tcl_s700_mixer }, | ||
1457 | .init_verbs = { alc880_volume_init_verbs, | ||
1458 | alc880_pin_tcl_S700_init_verbs, | ||
1459 | alc880_gpio2_init_verbs }, | ||
1460 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | ||
1461 | .dac_nids = alc880_dac_nids, | ||
1462 | .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */ | ||
1463 | .num_adc_nids = 1, /* single ADC */ | ||
1464 | .hp_nid = 0x03, | ||
1465 | .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), | ||
1466 | .channel_mode = alc880_2_jack_modes, | ||
1467 | .input_mux = &alc880_capture_source, | ||
1468 | }, | ||
1469 | [ALC880_5ST] = { | ||
1470 | .mixers = { alc880_three_stack_mixer, | ||
1471 | alc880_five_stack_mixer}, | ||
1472 | .init_verbs = { alc880_volume_init_verbs, | ||
1473 | alc880_pin_5stack_init_verbs }, | ||
1474 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | ||
1475 | .dac_nids = alc880_dac_nids, | ||
1476 | .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), | ||
1477 | .channel_mode = alc880_fivestack_modes, | ||
1478 | .input_mux = &alc880_capture_source, | ||
1479 | }, | ||
1480 | [ALC880_5ST_DIG] = { | ||
1481 | .mixers = { alc880_three_stack_mixer, | ||
1482 | alc880_five_stack_mixer }, | ||
1483 | .init_verbs = { alc880_volume_init_verbs, | ||
1484 | alc880_pin_5stack_init_verbs }, | ||
1485 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | ||
1486 | .dac_nids = alc880_dac_nids, | ||
1487 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
1488 | .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), | ||
1489 | .channel_mode = alc880_fivestack_modes, | ||
1490 | .input_mux = &alc880_capture_source, | ||
1491 | }, | ||
1492 | [ALC880_6ST] = { | ||
1493 | .mixers = { alc880_six_stack_mixer }, | ||
1494 | .init_verbs = { alc880_volume_init_verbs, | ||
1495 | alc880_pin_6stack_init_verbs }, | ||
1496 | .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), | ||
1497 | .dac_nids = alc880_6st_dac_nids, | ||
1498 | .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), | ||
1499 | .channel_mode = alc880_sixstack_modes, | ||
1500 | .input_mux = &alc880_6stack_capture_source, | ||
1501 | }, | ||
1502 | [ALC880_6ST_DIG] = { | ||
1503 | .mixers = { alc880_six_stack_mixer }, | ||
1504 | .init_verbs = { alc880_volume_init_verbs, | ||
1505 | alc880_pin_6stack_init_verbs }, | ||
1506 | .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), | ||
1507 | .dac_nids = alc880_6st_dac_nids, | ||
1508 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
1509 | .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), | ||
1510 | .channel_mode = alc880_sixstack_modes, | ||
1511 | .input_mux = &alc880_6stack_capture_source, | ||
1512 | }, | ||
1513 | [ALC880_W810] = { | ||
1514 | .mixers = { alc880_w810_base_mixer }, | ||
1515 | .init_verbs = { alc880_volume_init_verbs, | ||
1516 | alc880_pin_w810_init_verbs, | ||
1517 | alc880_gpio2_init_verbs }, | ||
1518 | .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), | ||
1519 | .dac_nids = alc880_w810_dac_nids, | ||
1520 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
1521 | .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), | ||
1522 | .channel_mode = alc880_w810_modes, | ||
1523 | .input_mux = &alc880_capture_source, | ||
1524 | }, | ||
1525 | [ALC880_Z71V] = { | ||
1526 | .mixers = { alc880_z71v_mixer }, | ||
1527 | .init_verbs = { alc880_volume_init_verbs, | ||
1528 | alc880_pin_z71v_init_verbs }, | ||
1529 | .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), | ||
1530 | .dac_nids = alc880_z71v_dac_nids, | ||
1531 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
1532 | .hp_nid = 0x03, | ||
1533 | .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), | ||
1534 | .channel_mode = alc880_2_jack_modes, | ||
1535 | .input_mux = &alc880_capture_source, | ||
1536 | }, | ||
1537 | [ALC880_F1734] = { | ||
1538 | .mixers = { alc880_f1734_mixer }, | ||
1539 | .init_verbs = { alc880_volume_init_verbs, | ||
1540 | alc880_pin_f1734_init_verbs }, | ||
1541 | .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), | ||
1542 | .dac_nids = alc880_f1734_dac_nids, | ||
1543 | .hp_nid = 0x02, | ||
1544 | .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), | ||
1545 | .channel_mode = alc880_2_jack_modes, | ||
1546 | .input_mux = &alc880_f1734_capture_source, | ||
1547 | .unsol_event = alc880_uniwill_p53_unsol_event, | ||
1548 | .setup = alc880_uniwill_p53_setup, | ||
1549 | .init_hook = alc_hp_automute, | ||
1550 | }, | ||
1551 | [ALC880_ASUS] = { | ||
1552 | .mixers = { alc880_asus_mixer }, | ||
1553 | .init_verbs = { alc880_volume_init_verbs, | ||
1554 | alc880_pin_asus_init_verbs, | ||
1555 | alc880_gpio1_init_verbs }, | ||
1556 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | ||
1557 | .dac_nids = alc880_asus_dac_nids, | ||
1558 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), | ||
1559 | .channel_mode = alc880_asus_modes, | ||
1560 | .need_dac_fix = 1, | ||
1561 | .input_mux = &alc880_capture_source, | ||
1562 | }, | ||
1563 | [ALC880_ASUS_DIG] = { | ||
1564 | .mixers = { alc880_asus_mixer }, | ||
1565 | .init_verbs = { alc880_volume_init_verbs, | ||
1566 | alc880_pin_asus_init_verbs, | ||
1567 | alc880_gpio1_init_verbs }, | ||
1568 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | ||
1569 | .dac_nids = alc880_asus_dac_nids, | ||
1570 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
1571 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), | ||
1572 | .channel_mode = alc880_asus_modes, | ||
1573 | .need_dac_fix = 1, | ||
1574 | .input_mux = &alc880_capture_source, | ||
1575 | }, | ||
1576 | [ALC880_ASUS_DIG2] = { | ||
1577 | .mixers = { alc880_asus_mixer }, | ||
1578 | .init_verbs = { alc880_volume_init_verbs, | ||
1579 | alc880_pin_asus_init_verbs, | ||
1580 | alc880_gpio2_init_verbs }, /* use GPIO2 */ | ||
1581 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | ||
1582 | .dac_nids = alc880_asus_dac_nids, | ||
1583 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
1584 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), | ||
1585 | .channel_mode = alc880_asus_modes, | ||
1586 | .need_dac_fix = 1, | ||
1587 | .input_mux = &alc880_capture_source, | ||
1588 | }, | ||
1589 | [ALC880_ASUS_W1V] = { | ||
1590 | .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, | ||
1591 | .init_verbs = { alc880_volume_init_verbs, | ||
1592 | alc880_pin_asus_init_verbs, | ||
1593 | alc880_gpio1_init_verbs }, | ||
1594 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | ||
1595 | .dac_nids = alc880_asus_dac_nids, | ||
1596 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
1597 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), | ||
1598 | .channel_mode = alc880_asus_modes, | ||
1599 | .need_dac_fix = 1, | ||
1600 | .input_mux = &alc880_capture_source, | ||
1601 | }, | ||
1602 | [ALC880_UNIWILL_DIG] = { | ||
1603 | .mixers = { alc880_asus_mixer }, | ||
1604 | .init_verbs = { alc880_volume_init_verbs, | ||
1605 | alc880_pin_asus_init_verbs }, | ||
1606 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | ||
1607 | .dac_nids = alc880_asus_dac_nids, | ||
1608 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
1609 | .num_channel_mode = ARRAY_SIZE(alc880_asus_modes), | ||
1610 | .channel_mode = alc880_asus_modes, | ||
1611 | .need_dac_fix = 1, | ||
1612 | .input_mux = &alc880_capture_source, | ||
1613 | }, | ||
1614 | [ALC880_UNIWILL] = { | ||
1615 | .mixers = { alc880_uniwill_mixer }, | ||
1616 | .init_verbs = { alc880_volume_init_verbs, | ||
1617 | alc880_uniwill_init_verbs }, | ||
1618 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | ||
1619 | .dac_nids = alc880_asus_dac_nids, | ||
1620 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
1621 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | ||
1622 | .channel_mode = alc880_threestack_modes, | ||
1623 | .need_dac_fix = 1, | ||
1624 | .input_mux = &alc880_capture_source, | ||
1625 | .unsol_event = alc880_uniwill_unsol_event, | ||
1626 | .setup = alc880_uniwill_setup, | ||
1627 | .init_hook = alc880_uniwill_init_hook, | ||
1628 | }, | ||
1629 | [ALC880_UNIWILL_P53] = { | ||
1630 | .mixers = { alc880_uniwill_p53_mixer }, | ||
1631 | .init_verbs = { alc880_volume_init_verbs, | ||
1632 | alc880_uniwill_p53_init_verbs }, | ||
1633 | .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), | ||
1634 | .dac_nids = alc880_asus_dac_nids, | ||
1635 | .num_channel_mode = ARRAY_SIZE(alc880_w810_modes), | ||
1636 | .channel_mode = alc880_threestack_modes, | ||
1637 | .input_mux = &alc880_capture_source, | ||
1638 | .unsol_event = alc880_uniwill_p53_unsol_event, | ||
1639 | .setup = alc880_uniwill_p53_setup, | ||
1640 | .init_hook = alc_hp_automute, | ||
1641 | }, | ||
1642 | [ALC880_FUJITSU] = { | ||
1643 | .mixers = { alc880_fujitsu_mixer }, | ||
1644 | .init_verbs = { alc880_volume_init_verbs, | ||
1645 | alc880_uniwill_p53_init_verbs, | ||
1646 | alc880_beep_init_verbs }, | ||
1647 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | ||
1648 | .dac_nids = alc880_dac_nids, | ||
1649 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
1650 | .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), | ||
1651 | .channel_mode = alc880_2_jack_modes, | ||
1652 | .input_mux = &alc880_capture_source, | ||
1653 | .unsol_event = alc880_uniwill_p53_unsol_event, | ||
1654 | .setup = alc880_uniwill_p53_setup, | ||
1655 | .init_hook = alc_hp_automute, | ||
1656 | }, | ||
1657 | [ALC880_CLEVO] = { | ||
1658 | .mixers = { alc880_three_stack_mixer }, | ||
1659 | .init_verbs = { alc880_volume_init_verbs, | ||
1660 | alc880_pin_clevo_init_verbs }, | ||
1661 | .num_dacs = ARRAY_SIZE(alc880_dac_nids), | ||
1662 | .dac_nids = alc880_dac_nids, | ||
1663 | .hp_nid = 0x03, | ||
1664 | .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), | ||
1665 | .channel_mode = alc880_threestack_modes, | ||
1666 | .need_dac_fix = 1, | ||
1667 | .input_mux = &alc880_capture_source, | ||
1668 | }, | ||
1669 | [ALC880_LG] = { | ||
1670 | .mixers = { alc880_lg_mixer }, | ||
1671 | .init_verbs = { alc880_volume_init_verbs, | ||
1672 | alc880_lg_init_verbs }, | ||
1673 | .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids), | ||
1674 | .dac_nids = alc880_lg_dac_nids, | ||
1675 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
1676 | .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes), | ||
1677 | .channel_mode = alc880_lg_ch_modes, | ||
1678 | .need_dac_fix = 1, | ||
1679 | .input_mux = &alc880_lg_capture_source, | ||
1680 | .unsol_event = alc_sku_unsol_event, | ||
1681 | .setup = alc880_lg_setup, | ||
1682 | .init_hook = alc_hp_automute, | ||
1683 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
1684 | .loopbacks = alc880_lg_loopbacks, | ||
1685 | #endif | ||
1686 | }, | ||
1687 | #ifdef CONFIG_SND_DEBUG | ||
1688 | [ALC880_TEST] = { | ||
1689 | .mixers = { alc880_test_mixer }, | ||
1690 | .init_verbs = { alc880_test_init_verbs }, | ||
1691 | .num_dacs = ARRAY_SIZE(alc880_test_dac_nids), | ||
1692 | .dac_nids = alc880_test_dac_nids, | ||
1693 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
1694 | .num_channel_mode = ARRAY_SIZE(alc880_test_modes), | ||
1695 | .channel_mode = alc880_test_modes, | ||
1696 | .input_mux = &alc880_test_capture_source, | ||
1697 | }, | ||
1698 | #endif | ||
1699 | }; | ||
1700 | |||
diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c deleted file mode 100644 index bdf0ed4ab3e2..000000000000 --- a/sound/pci/hda/alc882_quirks.c +++ /dev/null | |||
@@ -1,861 +0,0 @@ | |||
1 | /* | ||
2 | * ALC882/ALC883/ALC888/ALC889 quirk models | ||
3 | * included by patch_realtek.c | ||
4 | */ | ||
5 | |||
6 | /* ALC882 models */ | ||
7 | enum { | ||
8 | ALC882_AUTO, | ||
9 | ALC885_MBA21, | ||
10 | ALC885_MBP3, | ||
11 | ALC885_MB5, | ||
12 | ALC885_MACMINI3, | ||
13 | ALC885_IMAC91, | ||
14 | ALC889A_MB31, | ||
15 | ALC882_MODEL_LAST, | ||
16 | }; | ||
17 | |||
18 | #define ALC882_DIGOUT_NID 0x06 | ||
19 | #define ALC882_DIGIN_NID 0x0a | ||
20 | #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID | ||
21 | #define ALC883_DIGIN_NID ALC882_DIGIN_NID | ||
22 | #define ALC1200_DIGOUT_NID 0x10 | ||
23 | |||
24 | |||
25 | static const struct hda_channel_mode alc882_ch_modes[1] = { | ||
26 | { 8, NULL } | ||
27 | }; | ||
28 | |||
29 | /* DACs */ | ||
30 | static const hda_nid_t alc882_dac_nids[4] = { | ||
31 | /* front, rear, clfe, rear_surr */ | ||
32 | 0x02, 0x03, 0x04, 0x05 | ||
33 | }; | ||
34 | #define alc883_dac_nids alc882_dac_nids | ||
35 | |||
36 | /* ADCs */ | ||
37 | #define alc882_adc_nids alc880_adc_nids | ||
38 | #define alc882_adc_nids_alt alc880_adc_nids_alt | ||
39 | #define alc883_adc_nids alc882_adc_nids_alt | ||
40 | |||
41 | static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; | ||
42 | #define alc883_capsrc_nids alc882_capsrc_nids_alt | ||
43 | |||
44 | /* input MUX */ | ||
45 | /* FIXME: should be a matrix-type input source selection */ | ||
46 | |||
47 | static const struct hda_input_mux alc882_capture_source = { | ||
48 | .num_items = 4, | ||
49 | .items = { | ||
50 | { "Mic", 0x0 }, | ||
51 | { "Front Mic", 0x1 }, | ||
52 | { "Line", 0x2 }, | ||
53 | { "CD", 0x4 }, | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | #define alc883_capture_source alc882_capture_source | ||
58 | |||
59 | static const struct hda_input_mux mb5_capture_source = { | ||
60 | .num_items = 3, | ||
61 | .items = { | ||
62 | { "Mic", 0x1 }, | ||
63 | { "Line", 0x7 }, | ||
64 | { "CD", 0x4 }, | ||
65 | }, | ||
66 | }; | ||
67 | |||
68 | static const struct hda_input_mux macmini3_capture_source = { | ||
69 | .num_items = 2, | ||
70 | .items = { | ||
71 | { "Line", 0x2 }, | ||
72 | { "CD", 0x4 }, | ||
73 | }, | ||
74 | }; | ||
75 | |||
76 | static const struct hda_input_mux alc883_3stack_6ch_intel = { | ||
77 | .num_items = 4, | ||
78 | .items = { | ||
79 | { "Mic", 0x1 }, | ||
80 | { "Front Mic", 0x0 }, | ||
81 | { "Line", 0x2 }, | ||
82 | { "CD", 0x4 }, | ||
83 | }, | ||
84 | }; | ||
85 | |||
86 | static const struct hda_input_mux alc889A_mb31_capture_source = { | ||
87 | .num_items = 2, | ||
88 | .items = { | ||
89 | { "Mic", 0x0 }, | ||
90 | /* Front Mic (0x01) unused */ | ||
91 | { "Line", 0x2 }, | ||
92 | /* Line 2 (0x03) unused */ | ||
93 | /* CD (0x04) unused? */ | ||
94 | }, | ||
95 | }; | ||
96 | |||
97 | static const struct hda_input_mux alc889A_imac91_capture_source = { | ||
98 | .num_items = 2, | ||
99 | .items = { | ||
100 | { "Mic", 0x01 }, | ||
101 | { "Line", 0x2 }, /* Not sure! */ | ||
102 | }, | ||
103 | }; | ||
104 | |||
105 | /* Macbook Air 2,1 */ | ||
106 | |||
107 | static const struct hda_channel_mode alc885_mba21_ch_modes[1] = { | ||
108 | { 2, NULL }, | ||
109 | }; | ||
110 | |||
111 | /* | ||
112 | * macbook pro ALC885 can switch LineIn to LineOut without losing Mic | ||
113 | */ | ||
114 | |||
115 | /* | ||
116 | * 2ch mode | ||
117 | */ | ||
118 | static const struct hda_verb alc885_mbp_ch2_init[] = { | ||
119 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
120 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
121 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
122 | { } /* end */ | ||
123 | }; | ||
124 | |||
125 | /* | ||
126 | * 4ch mode | ||
127 | */ | ||
128 | static const struct hda_verb alc885_mbp_ch4_init[] = { | ||
129 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
130 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
131 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
132 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
133 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
134 | { } /* end */ | ||
135 | }; | ||
136 | |||
137 | static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = { | ||
138 | { 2, alc885_mbp_ch2_init }, | ||
139 | { 4, alc885_mbp_ch4_init }, | ||
140 | }; | ||
141 | |||
142 | /* | ||
143 | * 2ch | ||
144 | * Speakers/Woofer/HP = Front | ||
145 | * LineIn = Input | ||
146 | */ | ||
147 | static const struct hda_verb alc885_mb5_ch2_init[] = { | ||
148 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
149 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
150 | { } /* end */ | ||
151 | }; | ||
152 | |||
153 | /* | ||
154 | * 6ch mode | ||
155 | * Speakers/HP = Front | ||
156 | * Woofer = LFE | ||
157 | * LineIn = Surround | ||
158 | */ | ||
159 | static const struct hda_verb alc885_mb5_ch6_init[] = { | ||
160 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
161 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
162 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
163 | { } /* end */ | ||
164 | }; | ||
165 | |||
166 | static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = { | ||
167 | { 2, alc885_mb5_ch2_init }, | ||
168 | { 6, alc885_mb5_ch6_init }, | ||
169 | }; | ||
170 | |||
171 | #define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes | ||
172 | |||
173 | /* Macbook Air 2,1 same control for HP and internal Speaker */ | ||
174 | |||
175 | static const struct snd_kcontrol_new alc885_mba21_mixer[] = { | ||
176 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | ||
177 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT), | ||
178 | { } | ||
179 | }; | ||
180 | |||
181 | |||
182 | static const struct snd_kcontrol_new alc885_mbp3_mixer[] = { | ||
183 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | ||
184 | HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), | ||
185 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), | ||
186 | HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT), | ||
187 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), | ||
188 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
189 | HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
190 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), | ||
191 | HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), | ||
192 | HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT), | ||
193 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT), | ||
194 | { } /* end */ | ||
195 | }; | ||
196 | |||
197 | static const struct snd_kcontrol_new alc885_mb5_mixer[] = { | ||
198 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | ||
199 | HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), | ||
200 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), | ||
201 | HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), | ||
202 | HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), | ||
203 | HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), | ||
204 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), | ||
205 | HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), | ||
206 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), | ||
207 | HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), | ||
208 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
209 | HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
210 | HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT), | ||
211 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT), | ||
212 | { } /* end */ | ||
213 | }; | ||
214 | |||
215 | static const struct snd_kcontrol_new alc885_macmini3_mixer[] = { | ||
216 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | ||
217 | HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), | ||
218 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), | ||
219 | HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), | ||
220 | HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT), | ||
221 | HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), | ||
222 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), | ||
223 | HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), | ||
224 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), | ||
225 | HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), | ||
226 | HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT), | ||
227 | { } /* end */ | ||
228 | }; | ||
229 | |||
230 | static const struct snd_kcontrol_new alc885_imac91_mixer[] = { | ||
231 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | ||
232 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), | ||
233 | { } /* end */ | ||
234 | }; | ||
235 | |||
236 | |||
237 | static const struct snd_kcontrol_new alc882_chmode_mixer[] = { | ||
238 | { | ||
239 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
240 | .name = "Channel Mode", | ||
241 | .info = alc_ch_mode_info, | ||
242 | .get = alc_ch_mode_get, | ||
243 | .put = alc_ch_mode_put, | ||
244 | }, | ||
245 | { } /* end */ | ||
246 | }; | ||
247 | |||
248 | static const struct hda_verb alc882_base_init_verbs[] = { | ||
249 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | ||
250 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
251 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
252 | /* Rear mixer */ | ||
253 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
254 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
255 | /* CLFE mixer */ | ||
256 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
257 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
258 | /* Side mixer */ | ||
259 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
260 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
261 | |||
262 | /* Front Pin: output 0 (0x0c) */ | ||
263 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
264 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
265 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
266 | /* Rear Pin: output 1 (0x0d) */ | ||
267 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
268 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
269 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
270 | /* CLFE Pin: output 2 (0x0e) */ | ||
271 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
272 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
273 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
274 | /* Side Pin: output 3 (0x0f) */ | ||
275 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
276 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
277 | {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
278 | /* Mic (rear) pin: input vref at 80% */ | ||
279 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
280 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
281 | /* Front Mic pin: input vref at 80% */ | ||
282 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
283 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
284 | /* Line In pin: input */ | ||
285 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
286 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
287 | /* Line-2 In: Headphone output (output 0 - 0x0c) */ | ||
288 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
289 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
290 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
291 | /* CD pin widget for input */ | ||
292 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
293 | |||
294 | /* FIXME: use matrix-type input source selection */ | ||
295 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
296 | /* Input mixer2 */ | ||
297 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
298 | /* Input mixer3 */ | ||
299 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
300 | /* ADC2: mute amp left and right */ | ||
301 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
302 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
303 | /* ADC3: mute amp left and right */ | ||
304 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
305 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
306 | |||
307 | { } | ||
308 | }; | ||
309 | |||
310 | #define alc883_init_verbs alc882_base_init_verbs | ||
311 | |||
312 | /* Macbook 5,1 */ | ||
313 | static const struct hda_verb alc885_mb5_init_verbs[] = { | ||
314 | /* DACs */ | ||
315 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
316 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
317 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
318 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
319 | /* Front mixer */ | ||
320 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
321 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
322 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
323 | /* Surround mixer */ | ||
324 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
325 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
326 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
327 | /* LFE mixer */ | ||
328 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
329 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
330 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
331 | /* HP mixer */ | ||
332 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
333 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
334 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
335 | /* Front Pin (0x0c) */ | ||
336 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, | ||
337 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
338 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
339 | /* LFE Pin (0x0e) */ | ||
340 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, | ||
341 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
342 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
343 | /* HP Pin (0x0f) */ | ||
344 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
345 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
346 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
347 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
348 | /* Front Mic pin: input vref at 80% */ | ||
349 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
350 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
351 | /* Line In pin */ | ||
352 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
353 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
354 | |||
355 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)}, | ||
356 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)}, | ||
357 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)}, | ||
358 | { } | ||
359 | }; | ||
360 | |||
361 | /* Macmini 3,1 */ | ||
362 | static const struct hda_verb alc885_macmini3_init_verbs[] = { | ||
363 | /* DACs */ | ||
364 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
365 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
366 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
367 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
368 | /* Front mixer */ | ||
369 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
370 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
371 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
372 | /* Surround mixer */ | ||
373 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
374 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
375 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
376 | /* LFE mixer */ | ||
377 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
378 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
379 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
380 | /* HP mixer */ | ||
381 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
382 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
383 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
384 | /* Front Pin (0x0c) */ | ||
385 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, | ||
386 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
387 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
388 | /* LFE Pin (0x0e) */ | ||
389 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01}, | ||
390 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
391 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
392 | /* HP Pin (0x0f) */ | ||
393 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
394 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
395 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
396 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
397 | /* Line In pin */ | ||
398 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
399 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
400 | |||
401 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
402 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
403 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
404 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
405 | { } | ||
406 | }; | ||
407 | |||
408 | |||
409 | static const struct hda_verb alc885_mba21_init_verbs[] = { | ||
410 | /*Internal and HP Speaker Mixer*/ | ||
411 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
412 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
413 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
414 | /*Internal Speaker Pin (0x0c)*/ | ||
415 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, | ||
416 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
417 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
418 | /* HP Pin: output 0 (0x0e) */ | ||
419 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, | ||
420 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
421 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
422 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)}, | ||
423 | /* Line in (is hp when jack connected)*/ | ||
424 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, | ||
425 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
426 | |||
427 | { } | ||
428 | }; | ||
429 | |||
430 | |||
431 | /* Macbook Pro rev3 */ | ||
432 | static const struct hda_verb alc885_mbp3_init_verbs[] = { | ||
433 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | ||
434 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
435 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
436 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
437 | /* Rear mixer */ | ||
438 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
439 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
440 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
441 | /* HP mixer */ | ||
442 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
443 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
444 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
445 | /* Front Pin: output 0 (0x0c) */ | ||
446 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
447 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
448 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
449 | /* HP Pin: output 0 (0x0e) */ | ||
450 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, | ||
451 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
452 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
453 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
454 | /* Mic (rear) pin: input vref at 80% */ | ||
455 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
456 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
457 | /* Front Mic pin: input vref at 80% */ | ||
458 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
459 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
460 | /* Line In pin: use output 1 when in LineOut mode */ | ||
461 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
462 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
463 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
464 | |||
465 | /* FIXME: use matrix-type input source selection */ | ||
466 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
467 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | ||
468 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
469 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
470 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
471 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
472 | /* Input mixer2 */ | ||
473 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
474 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
475 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
476 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
477 | /* Input mixer3 */ | ||
478 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
479 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
480 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
481 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
482 | /* ADC1: mute amp left and right */ | ||
483 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
484 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
485 | /* ADC2: mute amp left and right */ | ||
486 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
487 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
488 | /* ADC3: mute amp left and right */ | ||
489 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
490 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
491 | |||
492 | { } | ||
493 | }; | ||
494 | |||
495 | /* iMac 9,1 */ | ||
496 | static const struct hda_verb alc885_imac91_init_verbs[] = { | ||
497 | /* Internal Speaker Pin (0x0c) */ | ||
498 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, | ||
499 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
500 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
501 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, | ||
502 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
503 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
504 | /* HP Pin: Rear */ | ||
505 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
506 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
507 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
508 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)}, | ||
509 | /* Line in Rear */ | ||
510 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50}, | ||
511 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
512 | /* Front Mic pin: input vref at 80% */ | ||
513 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
514 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
515 | /* Rear mixer */ | ||
516 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
517 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
518 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
519 | /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */ | ||
520 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
521 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
522 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
523 | /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ | ||
524 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
525 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
526 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
527 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
528 | /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ | ||
529 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
530 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
531 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
532 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
533 | /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */ | ||
534 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
535 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
536 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
537 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
538 | /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ | ||
539 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
540 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
541 | /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ | ||
542 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
543 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
544 | /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */ | ||
545 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
546 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
547 | { } | ||
548 | }; | ||
549 | |||
550 | /* Toggle speaker-output according to the hp-jack state */ | ||
551 | static void alc885_imac24_setup(struct hda_codec *codec) | ||
552 | { | ||
553 | struct alc_spec *spec = codec->spec; | ||
554 | |||
555 | spec->autocfg.hp_pins[0] = 0x14; | ||
556 | spec->autocfg.speaker_pins[0] = 0x18; | ||
557 | spec->autocfg.speaker_pins[1] = 0x1a; | ||
558 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); | ||
559 | } | ||
560 | |||
561 | #define alc885_mb5_setup alc885_imac24_setup | ||
562 | #define alc885_macmini3_setup alc885_imac24_setup | ||
563 | |||
564 | /* Macbook Air 2,1 */ | ||
565 | static void alc885_mba21_setup(struct hda_codec *codec) | ||
566 | { | ||
567 | struct alc_spec *spec = codec->spec; | ||
568 | |||
569 | spec->autocfg.hp_pins[0] = 0x14; | ||
570 | spec->autocfg.speaker_pins[0] = 0x18; | ||
571 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); | ||
572 | } | ||
573 | |||
574 | |||
575 | |||
576 | static void alc885_mbp3_setup(struct hda_codec *codec) | ||
577 | { | ||
578 | struct alc_spec *spec = codec->spec; | ||
579 | |||
580 | spec->autocfg.hp_pins[0] = 0x15; | ||
581 | spec->autocfg.speaker_pins[0] = 0x14; | ||
582 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); | ||
583 | } | ||
584 | |||
585 | static void alc885_imac91_setup(struct hda_codec *codec) | ||
586 | { | ||
587 | struct alc_spec *spec = codec->spec; | ||
588 | |||
589 | spec->autocfg.hp_pins[0] = 0x14; | ||
590 | spec->autocfg.speaker_pins[0] = 0x18; | ||
591 | spec->autocfg.speaker_pins[1] = 0x1a; | ||
592 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); | ||
593 | } | ||
594 | |||
595 | /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ | ||
596 | static const struct hda_verb alc889A_mb31_ch2_init[] = { | ||
597 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ | ||
598 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ | ||
599 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ | ||
600 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ | ||
601 | { } /* end */ | ||
602 | }; | ||
603 | |||
604 | /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ | ||
605 | static const struct hda_verb alc889A_mb31_ch4_init[] = { | ||
606 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ | ||
607 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ | ||
608 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ | ||
609 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ | ||
610 | { } /* end */ | ||
611 | }; | ||
612 | |||
613 | /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ | ||
614 | static const struct hda_verb alc889A_mb31_ch5_init[] = { | ||
615 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ | ||
616 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ | ||
617 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ | ||
618 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */ | ||
619 | { } /* end */ | ||
620 | }; | ||
621 | |||
622 | /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ | ||
623 | static const struct hda_verb alc889A_mb31_ch6_init[] = { | ||
624 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ | ||
625 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ | ||
626 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ | ||
627 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */ | ||
628 | { } /* end */ | ||
629 | }; | ||
630 | |||
631 | static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { | ||
632 | { 2, alc889A_mb31_ch2_init }, | ||
633 | { 4, alc889A_mb31_ch4_init }, | ||
634 | { 5, alc889A_mb31_ch5_init }, | ||
635 | { 6, alc889A_mb31_ch6_init }, | ||
636 | }; | ||
637 | |||
638 | static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { | ||
639 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
640 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
641 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
642 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
643 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | ||
644 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), | ||
645 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
646 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
647 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
648 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
649 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
650 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
651 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
652 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
653 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
654 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
655 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
656 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
657 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
658 | { } /* end */ | ||
659 | }; | ||
660 | |||
661 | static const struct snd_kcontrol_new alc889A_mb31_mixer[] = { | ||
662 | /* Output mixers */ | ||
663 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | ||
664 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), | ||
665 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), | ||
666 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT), | ||
667 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00, | ||
668 | HDA_OUTPUT), | ||
669 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT), | ||
670 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT), | ||
671 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT), | ||
672 | /* Output switches */ | ||
673 | HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT), | ||
674 | HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT), | ||
675 | HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT), | ||
676 | /* Boost mixers */ | ||
677 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT), | ||
678 | HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT), | ||
679 | /* Input mixers */ | ||
680 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), | ||
681 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), | ||
682 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
683 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
684 | { } /* end */ | ||
685 | }; | ||
686 | |||
687 | static const struct snd_kcontrol_new alc883_chmode_mixer[] = { | ||
688 | { | ||
689 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
690 | .name = "Channel Mode", | ||
691 | .info = alc_ch_mode_info, | ||
692 | .get = alc_ch_mode_get, | ||
693 | .put = alc_ch_mode_put, | ||
694 | }, | ||
695 | { } /* end */ | ||
696 | }; | ||
697 | |||
698 | static const struct hda_verb alc889A_mb31_verbs[] = { | ||
699 | /* Init rear pin (used as headphone output) */ | ||
700 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ | ||
701 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ | ||
702 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
703 | /* Init line pin (used as output in 4ch and 6ch mode) */ | ||
704 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */ | ||
705 | /* Init line 2 pin (used as headphone out by default) */ | ||
706 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */ | ||
707 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */ | ||
708 | { } /* end */ | ||
709 | }; | ||
710 | |||
711 | /* Mute speakers according to the headphone jack state */ | ||
712 | static void alc889A_mb31_automute(struct hda_codec *codec) | ||
713 | { | ||
714 | unsigned int present; | ||
715 | |||
716 | /* Mute only in 2ch or 4ch mode */ | ||
717 | if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0) | ||
718 | == 0x00) { | ||
719 | present = snd_hda_jack_detect(codec, 0x15); | ||
720 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
721 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
722 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | ||
723 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
724 | } | ||
725 | } | ||
726 | |||
727 | static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) | ||
728 | { | ||
729 | if ((res >> 26) == ALC_HP_EVENT) | ||
730 | alc889A_mb31_automute(codec); | ||
731 | } | ||
732 | |||
733 | /* | ||
734 | * configuration and preset | ||
735 | */ | ||
736 | static const char * const alc882_models[ALC882_MODEL_LAST] = { | ||
737 | [ALC885_MB5] = "mb5", | ||
738 | [ALC885_MACMINI3] = "macmini3", | ||
739 | [ALC885_MBA21] = "mba21", | ||
740 | [ALC885_MBP3] = "mbp3", | ||
741 | [ALC885_IMAC91] = "imac91", | ||
742 | [ALC889A_MB31] = "mb31", | ||
743 | [ALC882_AUTO] = "auto", | ||
744 | }; | ||
745 | |||
746 | /* codec SSID table for Intel Mac */ | ||
747 | static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { | ||
748 | SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3), | ||
749 | SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3), | ||
750 | SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), | ||
751 | SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3), | ||
752 | SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31), | ||
753 | SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3), | ||
754 | SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21), | ||
755 | SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31), | ||
756 | SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3), | ||
757 | SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91), | ||
758 | SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5), | ||
759 | SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5), | ||
760 | /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2, | ||
761 | * so apparently no perfect solution yet | ||
762 | */ | ||
763 | SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), | ||
764 | SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5), | ||
765 | SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3), | ||
766 | {} /* terminator */ | ||
767 | }; | ||
768 | |||
769 | static const struct alc_config_preset alc882_presets[] = { | ||
770 | [ALC885_MBA21] = { | ||
771 | .mixers = { alc885_mba21_mixer }, | ||
772 | .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs }, | ||
773 | .num_dacs = 2, | ||
774 | .dac_nids = alc882_dac_nids, | ||
775 | .channel_mode = alc885_mba21_ch_modes, | ||
776 | .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), | ||
777 | .input_mux = &alc882_capture_source, | ||
778 | .unsol_event = alc_sku_unsol_event, | ||
779 | .setup = alc885_mba21_setup, | ||
780 | .init_hook = alc_hp_automute, | ||
781 | }, | ||
782 | [ALC885_MBP3] = { | ||
783 | .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, | ||
784 | .init_verbs = { alc885_mbp3_init_verbs, | ||
785 | alc880_gpio1_init_verbs }, | ||
786 | .num_dacs = 2, | ||
787 | .dac_nids = alc882_dac_nids, | ||
788 | .hp_nid = 0x04, | ||
789 | .channel_mode = alc885_mbp_4ch_modes, | ||
790 | .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes), | ||
791 | .input_mux = &alc882_capture_source, | ||
792 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
793 | .dig_in_nid = ALC882_DIGIN_NID, | ||
794 | .unsol_event = alc_sku_unsol_event, | ||
795 | .setup = alc885_mbp3_setup, | ||
796 | .init_hook = alc_hp_automute, | ||
797 | }, | ||
798 | [ALC885_MB5] = { | ||
799 | .mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, | ||
800 | .init_verbs = { alc885_mb5_init_verbs, | ||
801 | alc880_gpio1_init_verbs }, | ||
802 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
803 | .dac_nids = alc882_dac_nids, | ||
804 | .channel_mode = alc885_mb5_6ch_modes, | ||
805 | .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes), | ||
806 | .input_mux = &mb5_capture_source, | ||
807 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
808 | .dig_in_nid = ALC882_DIGIN_NID, | ||
809 | .unsol_event = alc_sku_unsol_event, | ||
810 | .setup = alc885_mb5_setup, | ||
811 | .init_hook = alc_hp_automute, | ||
812 | }, | ||
813 | [ALC885_MACMINI3] = { | ||
814 | .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer }, | ||
815 | .init_verbs = { alc885_macmini3_init_verbs, | ||
816 | alc880_gpio1_init_verbs }, | ||
817 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
818 | .dac_nids = alc882_dac_nids, | ||
819 | .channel_mode = alc885_macmini3_6ch_modes, | ||
820 | .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes), | ||
821 | .input_mux = &macmini3_capture_source, | ||
822 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
823 | .dig_in_nid = ALC882_DIGIN_NID, | ||
824 | .unsol_event = alc_sku_unsol_event, | ||
825 | .setup = alc885_macmini3_setup, | ||
826 | .init_hook = alc_hp_automute, | ||
827 | }, | ||
828 | [ALC885_IMAC91] = { | ||
829 | .mixers = {alc885_imac91_mixer}, | ||
830 | .init_verbs = { alc885_imac91_init_verbs, | ||
831 | alc880_gpio1_init_verbs }, | ||
832 | .num_dacs = ARRAY_SIZE(alc882_dac_nids), | ||
833 | .dac_nids = alc882_dac_nids, | ||
834 | .channel_mode = alc885_mba21_ch_modes, | ||
835 | .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), | ||
836 | .input_mux = &alc889A_imac91_capture_source, | ||
837 | .dig_out_nid = ALC882_DIGOUT_NID, | ||
838 | .dig_in_nid = ALC882_DIGIN_NID, | ||
839 | .unsol_event = alc_sku_unsol_event, | ||
840 | .setup = alc885_imac91_setup, | ||
841 | .init_hook = alc_hp_automute, | ||
842 | }, | ||
843 | [ALC889A_MB31] = { | ||
844 | .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer}, | ||
845 | .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs, | ||
846 | alc880_gpio1_init_verbs }, | ||
847 | .adc_nids = alc883_adc_nids, | ||
848 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
849 | .capsrc_nids = alc883_capsrc_nids, | ||
850 | .dac_nids = alc883_dac_nids, | ||
851 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
852 | .channel_mode = alc889A_mb31_6ch_modes, | ||
853 | .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes), | ||
854 | .input_mux = &alc889A_mb31_capture_source, | ||
855 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
856 | .unsol_event = alc889A_mb31_unsol_event, | ||
857 | .init_hook = alc889A_mb31_automute, | ||
858 | }, | ||
859 | }; | ||
860 | |||
861 | |||
diff --git a/sound/pci/hda/alc_quirks.c b/sound/pci/hda/alc_quirks.c deleted file mode 100644 index a18952ed4311..000000000000 --- a/sound/pci/hda/alc_quirks.c +++ /dev/null | |||
@@ -1,480 +0,0 @@ | |||
1 | /* | ||
2 | * Common codes for Realtek codec quirks | ||
3 | * included by patch_realtek.c | ||
4 | */ | ||
5 | |||
6 | /* | ||
7 | * configuration template - to be copied to the spec instance | ||
8 | */ | ||
9 | struct alc_config_preset { | ||
10 | const struct snd_kcontrol_new *mixers[5]; /* should be identical size | ||
11 | * with spec | ||
12 | */ | ||
13 | const struct snd_kcontrol_new *cap_mixer; /* capture mixer */ | ||
14 | const struct hda_verb *init_verbs[5]; | ||
15 | unsigned int num_dacs; | ||
16 | const hda_nid_t *dac_nids; | ||
17 | hda_nid_t dig_out_nid; /* optional */ | ||
18 | hda_nid_t hp_nid; /* optional */ | ||
19 | const hda_nid_t *slave_dig_outs; | ||
20 | unsigned int num_adc_nids; | ||
21 | const hda_nid_t *adc_nids; | ||
22 | const hda_nid_t *capsrc_nids; | ||
23 | hda_nid_t dig_in_nid; | ||
24 | unsigned int num_channel_mode; | ||
25 | const struct hda_channel_mode *channel_mode; | ||
26 | int need_dac_fix; | ||
27 | int const_channel_count; | ||
28 | unsigned int num_mux_defs; | ||
29 | const struct hda_input_mux *input_mux; | ||
30 | void (*unsol_event)(struct hda_codec *, unsigned int); | ||
31 | void (*setup)(struct hda_codec *); | ||
32 | void (*init_hook)(struct hda_codec *); | ||
33 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
34 | const struct hda_amp_list *loopbacks; | ||
35 | void (*power_hook)(struct hda_codec *codec); | ||
36 | #endif | ||
37 | }; | ||
38 | |||
39 | /* | ||
40 | * channel mode setting | ||
41 | */ | ||
42 | static int alc_ch_mode_info(struct snd_kcontrol *kcontrol, | ||
43 | struct snd_ctl_elem_info *uinfo) | ||
44 | { | ||
45 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
46 | struct alc_spec *spec = codec->spec; | ||
47 | return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, | ||
48 | spec->num_channel_mode); | ||
49 | } | ||
50 | |||
51 | static int alc_ch_mode_get(struct snd_kcontrol *kcontrol, | ||
52 | struct snd_ctl_elem_value *ucontrol) | ||
53 | { | ||
54 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
55 | struct alc_spec *spec = codec->spec; | ||
56 | return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, | ||
57 | spec->num_channel_mode, | ||
58 | spec->ext_channel_count); | ||
59 | } | ||
60 | |||
61 | static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, | ||
62 | struct snd_ctl_elem_value *ucontrol) | ||
63 | { | ||
64 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
65 | struct alc_spec *spec = codec->spec; | ||
66 | int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, | ||
67 | spec->num_channel_mode, | ||
68 | &spec->ext_channel_count); | ||
69 | if (err >= 0 && !spec->const_channel_count) { | ||
70 | spec->multiout.max_channels = spec->ext_channel_count; | ||
71 | if (spec->need_dac_fix) | ||
72 | spec->multiout.num_dacs = spec->multiout.max_channels / 2; | ||
73 | } | ||
74 | return err; | ||
75 | } | ||
76 | |||
77 | /* | ||
78 | * Control the mode of pin widget settings via the mixer. "pc" is used | ||
79 | * instead of "%" to avoid consequences of accidentally treating the % as | ||
80 | * being part of a format specifier. Maximum allowed length of a value is | ||
81 | * 63 characters plus NULL terminator. | ||
82 | * | ||
83 | * Note: some retasking pin complexes seem to ignore requests for input | ||
84 | * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these | ||
85 | * are requested. Therefore order this list so that this behaviour will not | ||
86 | * cause problems when mixer clients move through the enum sequentially. | ||
87 | * NIDs 0x0f and 0x10 have been observed to have this behaviour as of | ||
88 | * March 2006. | ||
89 | */ | ||
90 | static const char * const alc_pin_mode_names[] = { | ||
91 | "Mic 50pc bias", "Mic 80pc bias", | ||
92 | "Line in", "Line out", "Headphone out", | ||
93 | }; | ||
94 | static const unsigned char alc_pin_mode_values[] = { | ||
95 | PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, | ||
96 | }; | ||
97 | /* The control can present all 5 options, or it can limit the options based | ||
98 | * in the pin being assumed to be exclusively an input or an output pin. In | ||
99 | * addition, "input" pins may or may not process the mic bias option | ||
100 | * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to | ||
101 | * accept requests for bias as of chip versions up to March 2006) and/or | ||
102 | * wiring in the computer. | ||
103 | */ | ||
104 | #define ALC_PIN_DIR_IN 0x00 | ||
105 | #define ALC_PIN_DIR_OUT 0x01 | ||
106 | #define ALC_PIN_DIR_INOUT 0x02 | ||
107 | #define ALC_PIN_DIR_IN_NOMICBIAS 0x03 | ||
108 | #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 | ||
109 | |||
110 | /* Info about the pin modes supported by the different pin direction modes. | ||
111 | * For each direction the minimum and maximum values are given. | ||
112 | */ | ||
113 | static const signed char alc_pin_mode_dir_info[5][2] = { | ||
114 | { 0, 2 }, /* ALC_PIN_DIR_IN */ | ||
115 | { 3, 4 }, /* ALC_PIN_DIR_OUT */ | ||
116 | { 0, 4 }, /* ALC_PIN_DIR_INOUT */ | ||
117 | { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */ | ||
118 | { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */ | ||
119 | }; | ||
120 | #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0]) | ||
121 | #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1]) | ||
122 | #define alc_pin_mode_n_items(_dir) \ | ||
123 | (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1) | ||
124 | |||
125 | static int alc_pin_mode_info(struct snd_kcontrol *kcontrol, | ||
126 | struct snd_ctl_elem_info *uinfo) | ||
127 | { | ||
128 | unsigned int item_num = uinfo->value.enumerated.item; | ||
129 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; | ||
130 | |||
131 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
132 | uinfo->count = 1; | ||
133 | uinfo->value.enumerated.items = alc_pin_mode_n_items(dir); | ||
134 | |||
135 | if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir)) | ||
136 | item_num = alc_pin_mode_min(dir); | ||
137 | strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]); | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static int alc_pin_mode_get(struct snd_kcontrol *kcontrol, | ||
142 | struct snd_ctl_elem_value *ucontrol) | ||
143 | { | ||
144 | unsigned int i; | ||
145 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
146 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
147 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; | ||
148 | long *valp = ucontrol->value.integer.value; | ||
149 | unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, | ||
150 | AC_VERB_GET_PIN_WIDGET_CONTROL, | ||
151 | 0x00); | ||
152 | |||
153 | /* Find enumerated value for current pinctl setting */ | ||
154 | i = alc_pin_mode_min(dir); | ||
155 | while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl) | ||
156 | i++; | ||
157 | *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir); | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, | ||
162 | struct snd_ctl_elem_value *ucontrol) | ||
163 | { | ||
164 | signed int change; | ||
165 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
166 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
167 | unsigned char dir = (kcontrol->private_value >> 16) & 0xff; | ||
168 | long val = *ucontrol->value.integer.value; | ||
169 | unsigned int pinctl = snd_hda_codec_read(codec, nid, 0, | ||
170 | AC_VERB_GET_PIN_WIDGET_CONTROL, | ||
171 | 0x00); | ||
172 | |||
173 | if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) | ||
174 | val = alc_pin_mode_min(dir); | ||
175 | |||
176 | change = pinctl != alc_pin_mode_values[val]; | ||
177 | if (change) { | ||
178 | /* Set pin mode to that requested */ | ||
179 | snd_hda_codec_write_cache(codec, nid, 0, | ||
180 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
181 | alc_pin_mode_values[val]); | ||
182 | |||
183 | /* Also enable the retasking pin's input/output as required | ||
184 | * for the requested pin mode. Enum values of 2 or less are | ||
185 | * input modes. | ||
186 | * | ||
187 | * Dynamically switching the input/output buffers probably | ||
188 | * reduces noise slightly (particularly on input) so we'll | ||
189 | * do it. However, having both input and output buffers | ||
190 | * enabled simultaneously doesn't seem to be problematic if | ||
191 | * this turns out to be necessary in the future. | ||
192 | */ | ||
193 | if (val <= 2) { | ||
194 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | ||
195 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
196 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, | ||
197 | HDA_AMP_MUTE, 0); | ||
198 | } else { | ||
199 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, | ||
200 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
201 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | ||
202 | HDA_AMP_MUTE, 0); | ||
203 | } | ||
204 | } | ||
205 | return change; | ||
206 | } | ||
207 | |||
208 | #define ALC_PIN_MODE(xname, nid, dir) \ | ||
209 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | ||
210 | .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ | ||
211 | .info = alc_pin_mode_info, \ | ||
212 | .get = alc_pin_mode_get, \ | ||
213 | .put = alc_pin_mode_put, \ | ||
214 | .private_value = nid | (dir<<16) } | ||
215 | |||
216 | /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged | ||
217 | * together using a mask with more than one bit set. This control is | ||
218 | * currently used only by the ALC260 test model. At this stage they are not | ||
219 | * needed for any "production" models. | ||
220 | */ | ||
221 | #ifdef CONFIG_SND_DEBUG | ||
222 | #define alc_gpio_data_info snd_ctl_boolean_mono_info | ||
223 | |||
224 | static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, | ||
225 | struct snd_ctl_elem_value *ucontrol) | ||
226 | { | ||
227 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
228 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
229 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | ||
230 | long *valp = ucontrol->value.integer.value; | ||
231 | unsigned int val = snd_hda_codec_read(codec, nid, 0, | ||
232 | AC_VERB_GET_GPIO_DATA, 0x00); | ||
233 | |||
234 | *valp = (val & mask) != 0; | ||
235 | return 0; | ||
236 | } | ||
237 | static int alc_gpio_data_put(struct snd_kcontrol *kcontrol, | ||
238 | struct snd_ctl_elem_value *ucontrol) | ||
239 | { | ||
240 | signed int change; | ||
241 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
242 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
243 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | ||
244 | long val = *ucontrol->value.integer.value; | ||
245 | unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, | ||
246 | AC_VERB_GET_GPIO_DATA, | ||
247 | 0x00); | ||
248 | |||
249 | /* Set/unset the masked GPIO bit(s) as needed */ | ||
250 | change = (val == 0 ? 0 : mask) != (gpio_data & mask); | ||
251 | if (val == 0) | ||
252 | gpio_data &= ~mask; | ||
253 | else | ||
254 | gpio_data |= mask; | ||
255 | snd_hda_codec_write_cache(codec, nid, 0, | ||
256 | AC_VERB_SET_GPIO_DATA, gpio_data); | ||
257 | |||
258 | return change; | ||
259 | } | ||
260 | #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \ | ||
261 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | ||
262 | .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ | ||
263 | .info = alc_gpio_data_info, \ | ||
264 | .get = alc_gpio_data_get, \ | ||
265 | .put = alc_gpio_data_put, \ | ||
266 | .private_value = nid | (mask<<16) } | ||
267 | #endif /* CONFIG_SND_DEBUG */ | ||
268 | |||
269 | /* A switch control to allow the enabling of the digital IO pins on the | ||
270 | * ALC260. This is incredibly simplistic; the intention of this control is | ||
271 | * to provide something in the test model allowing digital outputs to be | ||
272 | * identified if present. If models are found which can utilise these | ||
273 | * outputs a more complete mixer control can be devised for those models if | ||
274 | * necessary. | ||
275 | */ | ||
276 | #ifdef CONFIG_SND_DEBUG | ||
277 | #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info | ||
278 | |||
279 | static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, | ||
280 | struct snd_ctl_elem_value *ucontrol) | ||
281 | { | ||
282 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
283 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
284 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | ||
285 | long *valp = ucontrol->value.integer.value; | ||
286 | unsigned int val = snd_hda_codec_read(codec, nid, 0, | ||
287 | AC_VERB_GET_DIGI_CONVERT_1, 0x00); | ||
288 | |||
289 | *valp = (val & mask) != 0; | ||
290 | return 0; | ||
291 | } | ||
292 | static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol, | ||
293 | struct snd_ctl_elem_value *ucontrol) | ||
294 | { | ||
295 | signed int change; | ||
296 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
297 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
298 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | ||
299 | long val = *ucontrol->value.integer.value; | ||
300 | unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, | ||
301 | AC_VERB_GET_DIGI_CONVERT_1, | ||
302 | 0x00); | ||
303 | |||
304 | /* Set/unset the masked control bit(s) as needed */ | ||
305 | change = (val == 0 ? 0 : mask) != (ctrl_data & mask); | ||
306 | if (val==0) | ||
307 | ctrl_data &= ~mask; | ||
308 | else | ||
309 | ctrl_data |= mask; | ||
310 | snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, | ||
311 | ctrl_data); | ||
312 | |||
313 | return change; | ||
314 | } | ||
315 | #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \ | ||
316 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | ||
317 | .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ | ||
318 | .info = alc_spdif_ctrl_info, \ | ||
319 | .get = alc_spdif_ctrl_get, \ | ||
320 | .put = alc_spdif_ctrl_put, \ | ||
321 | .private_value = nid | (mask<<16) } | ||
322 | #endif /* CONFIG_SND_DEBUG */ | ||
323 | |||
324 | /* A switch control to allow the enabling EAPD digital outputs on the ALC26x. | ||
325 | * Again, this is only used in the ALC26x test models to help identify when | ||
326 | * the EAPD line must be asserted for features to work. | ||
327 | */ | ||
328 | #ifdef CONFIG_SND_DEBUG | ||
329 | #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info | ||
330 | |||
331 | static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol, | ||
332 | struct snd_ctl_elem_value *ucontrol) | ||
333 | { | ||
334 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
335 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
336 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | ||
337 | long *valp = ucontrol->value.integer.value; | ||
338 | unsigned int val = snd_hda_codec_read(codec, nid, 0, | ||
339 | AC_VERB_GET_EAPD_BTLENABLE, 0x00); | ||
340 | |||
341 | *valp = (val & mask) != 0; | ||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, | ||
346 | struct snd_ctl_elem_value *ucontrol) | ||
347 | { | ||
348 | int change; | ||
349 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
350 | hda_nid_t nid = kcontrol->private_value & 0xffff; | ||
351 | unsigned char mask = (kcontrol->private_value >> 16) & 0xff; | ||
352 | long val = *ucontrol->value.integer.value; | ||
353 | unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, | ||
354 | AC_VERB_GET_EAPD_BTLENABLE, | ||
355 | 0x00); | ||
356 | |||
357 | /* Set/unset the masked control bit(s) as needed */ | ||
358 | change = (!val ? 0 : mask) != (ctrl_data & mask); | ||
359 | if (!val) | ||
360 | ctrl_data &= ~mask; | ||
361 | else | ||
362 | ctrl_data |= mask; | ||
363 | snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, | ||
364 | ctrl_data); | ||
365 | |||
366 | return change; | ||
367 | } | ||
368 | |||
369 | #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \ | ||
370 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | ||
371 | .subdevice = HDA_SUBDEV_NID_FLAG | nid, \ | ||
372 | .info = alc_eapd_ctrl_info, \ | ||
373 | .get = alc_eapd_ctrl_get, \ | ||
374 | .put = alc_eapd_ctrl_put, \ | ||
375 | .private_value = nid | (mask<<16) } | ||
376 | #endif /* CONFIG_SND_DEBUG */ | ||
377 | |||
378 | static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec) | ||
379 | { | ||
380 | struct alc_spec *spec = codec->spec; | ||
381 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
382 | |||
383 | if (!cfg->line_outs) { | ||
384 | while (cfg->line_outs < AUTO_CFG_MAX_OUTS && | ||
385 | cfg->line_out_pins[cfg->line_outs]) | ||
386 | cfg->line_outs++; | ||
387 | } | ||
388 | if (!cfg->speaker_outs) { | ||
389 | while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS && | ||
390 | cfg->speaker_pins[cfg->speaker_outs]) | ||
391 | cfg->speaker_outs++; | ||
392 | } | ||
393 | if (!cfg->hp_outs) { | ||
394 | while (cfg->hp_outs < AUTO_CFG_MAX_OUTS && | ||
395 | cfg->hp_pins[cfg->hp_outs]) | ||
396 | cfg->hp_outs++; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | /* | ||
401 | * set up from the preset table | ||
402 | */ | ||
403 | static void setup_preset(struct hda_codec *codec, | ||
404 | const struct alc_config_preset *preset) | ||
405 | { | ||
406 | struct alc_spec *spec = codec->spec; | ||
407 | int i; | ||
408 | |||
409 | for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) | ||
410 | add_mixer(spec, preset->mixers[i]); | ||
411 | spec->cap_mixer = preset->cap_mixer; | ||
412 | for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; | ||
413 | i++) | ||
414 | add_verb(spec, preset->init_verbs[i]); | ||
415 | |||
416 | spec->channel_mode = preset->channel_mode; | ||
417 | spec->num_channel_mode = preset->num_channel_mode; | ||
418 | spec->need_dac_fix = preset->need_dac_fix; | ||
419 | spec->const_channel_count = preset->const_channel_count; | ||
420 | |||
421 | if (preset->const_channel_count) | ||
422 | spec->multiout.max_channels = preset->const_channel_count; | ||
423 | else | ||
424 | spec->multiout.max_channels = spec->channel_mode[0].channels; | ||
425 | spec->ext_channel_count = spec->channel_mode[0].channels; | ||
426 | |||
427 | spec->multiout.num_dacs = preset->num_dacs; | ||
428 | spec->multiout.dac_nids = preset->dac_nids; | ||
429 | spec->multiout.dig_out_nid = preset->dig_out_nid; | ||
430 | spec->multiout.slave_dig_outs = preset->slave_dig_outs; | ||
431 | spec->multiout.hp_nid = preset->hp_nid; | ||
432 | |||
433 | spec->num_mux_defs = preset->num_mux_defs; | ||
434 | if (!spec->num_mux_defs) | ||
435 | spec->num_mux_defs = 1; | ||
436 | spec->input_mux = preset->input_mux; | ||
437 | |||
438 | spec->num_adc_nids = preset->num_adc_nids; | ||
439 | spec->adc_nids = preset->adc_nids; | ||
440 | spec->capsrc_nids = preset->capsrc_nids; | ||
441 | spec->dig_in_nid = preset->dig_in_nid; | ||
442 | |||
443 | spec->unsol_event = preset->unsol_event; | ||
444 | spec->init_hook = preset->init_hook; | ||
445 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
446 | spec->power_hook = preset->power_hook; | ||
447 | spec->loopback.amplist = preset->loopbacks; | ||
448 | #endif | ||
449 | |||
450 | if (preset->setup) | ||
451 | preset->setup(codec); | ||
452 | |||
453 | alc_fixup_autocfg_pin_nums(codec); | ||
454 | } | ||
455 | |||
456 | static void alc_simple_setup_automute(struct alc_spec *spec, int mode) | ||
457 | { | ||
458 | int lo_pin = spec->autocfg.line_out_pins[0]; | ||
459 | |||
460 | if (lo_pin == spec->autocfg.speaker_pins[0] || | ||
461 | lo_pin == spec->autocfg.hp_pins[0]) | ||
462 | lo_pin = 0; | ||
463 | spec->automute_mode = mode; | ||
464 | spec->detect_hp = !!spec->autocfg.hp_pins[0]; | ||
465 | spec->detect_lo = !!lo_pin; | ||
466 | spec->automute_lo = spec->automute_lo_possible = !!lo_pin; | ||
467 | spec->automute_speaker = spec->automute_speaker_possible = !!spec->autocfg.speaker_pins[0]; | ||
468 | } | ||
469 | |||
470 | /* auto-toggle front mic */ | ||
471 | static void alc88x_simple_mic_automute(struct hda_codec *codec) | ||
472 | { | ||
473 | unsigned int present; | ||
474 | unsigned char bits; | ||
475 | |||
476 | present = snd_hda_jack_detect(codec, 0x18); | ||
477 | bits = present ? HDA_AMP_MUTE : 0; | ||
478 | snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); | ||
479 | } | ||
480 | |||
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 4df72c0e8c37..7a8fcc4c15f8 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -19,6 +19,7 @@ | |||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/mm.h> | ||
22 | #include <linux/init.h> | 23 | #include <linux/init.h> |
23 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
@@ -1447,7 +1448,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1447 | for (i = 0; i < c->cvt_setups.used; i++) { | 1448 | for (i = 0; i < c->cvt_setups.used; i++) { |
1448 | p = snd_array_elem(&c->cvt_setups, i); | 1449 | p = snd_array_elem(&c->cvt_setups, i); |
1449 | if (!p->active && p->stream_tag == stream_tag && | 1450 | if (!p->active && p->stream_tag == stream_tag && |
1450 | get_wcaps_type(get_wcaps(codec, p->nid)) == type) | 1451 | get_wcaps_type(get_wcaps(c, p->nid)) == type) |
1451 | p->dirty = 1; | 1452 | p->dirty = 1; |
1452 | } | 1453 | } |
1453 | } | 1454 | } |
@@ -1759,7 +1760,11 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, | |||
1759 | parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT; | 1760 | parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT; |
1760 | parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT; | 1761 | parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT; |
1761 | parm |= index << AC_AMP_SET_INDEX_SHIFT; | 1762 | parm |= index << AC_AMP_SET_INDEX_SHIFT; |
1762 | parm |= val; | 1763 | if ((val & HDA_AMP_MUTE) && !(info->amp_caps & AC_AMPCAP_MUTE) && |
1764 | (info->amp_caps & AC_AMPCAP_MIN_MUTE)) | ||
1765 | ; /* set the zero value as a fake mute */ | ||
1766 | else | ||
1767 | parm |= val; | ||
1763 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm); | 1768 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm); |
1764 | info->vol[ch] = val; | 1769 | info->vol[ch] = val; |
1765 | } | 1770 | } |
@@ -2026,7 +2031,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, | |||
2026 | val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); | 2031 | val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); |
2027 | val1 += ofs; | 2032 | val1 += ofs; |
2028 | val1 = ((int)val1) * ((int)val2); | 2033 | val1 = ((int)val1) * ((int)val2); |
2029 | if (min_mute) | 2034 | if (min_mute || (caps & AC_AMPCAP_MIN_MUTE)) |
2030 | val2 |= TLV_DB_SCALE_MUTE; | 2035 | val2 |= TLV_DB_SCALE_MUTE; |
2031 | if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) | 2036 | if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) |
2032 | return -EFAULT; | 2037 | return -EFAULT; |
@@ -2300,7 +2305,7 @@ typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *); | |||
2300 | 2305 | ||
2301 | /* apply the function to all matching slave ctls in the mixer list */ | 2306 | /* apply the function to all matching slave ctls in the mixer list */ |
2302 | static int map_slaves(struct hda_codec *codec, const char * const *slaves, | 2307 | static int map_slaves(struct hda_codec *codec, const char * const *slaves, |
2303 | map_slave_func_t func, void *data) | 2308 | const char *suffix, map_slave_func_t func, void *data) |
2304 | { | 2309 | { |
2305 | struct hda_nid_item *items; | 2310 | struct hda_nid_item *items; |
2306 | const char * const *s; | 2311 | const char * const *s; |
@@ -2313,7 +2318,14 @@ static int map_slaves(struct hda_codec *codec, const char * const *slaves, | |||
2313 | sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) | 2318 | sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) |
2314 | continue; | 2319 | continue; |
2315 | for (s = slaves; *s; s++) { | 2320 | for (s = slaves; *s; s++) { |
2316 | if (!strcmp(sctl->id.name, *s)) { | 2321 | char tmpname[sizeof(sctl->id.name)]; |
2322 | const char *name = *s; | ||
2323 | if (suffix) { | ||
2324 | snprintf(tmpname, sizeof(tmpname), "%s %s", | ||
2325 | name, suffix); | ||
2326 | name = tmpname; | ||
2327 | } | ||
2328 | if (!strcmp(sctl->id.name, name)) { | ||
2317 | err = func(data, sctl); | 2329 | err = func(data, sctl); |
2318 | if (err) | 2330 | if (err) |
2319 | return err; | 2331 | return err; |
@@ -2329,12 +2341,65 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl) | |||
2329 | return 1; | 2341 | return 1; |
2330 | } | 2342 | } |
2331 | 2343 | ||
2344 | /* guess the value corresponding to 0dB */ | ||
2345 | static int get_kctl_0dB_offset(struct snd_kcontrol *kctl) | ||
2346 | { | ||
2347 | int _tlv[4]; | ||
2348 | const int *tlv = NULL; | ||
2349 | int val = -1; | ||
2350 | |||
2351 | if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { | ||
2352 | /* FIXME: set_fs() hack for obtaining user-space TLV data */ | ||
2353 | mm_segment_t fs = get_fs(); | ||
2354 | set_fs(get_ds()); | ||
2355 | if (!kctl->tlv.c(kctl, 0, sizeof(_tlv), _tlv)) | ||
2356 | tlv = _tlv; | ||
2357 | set_fs(fs); | ||
2358 | } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) | ||
2359 | tlv = kctl->tlv.p; | ||
2360 | if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE) | ||
2361 | val = -tlv[2] / tlv[3]; | ||
2362 | return val; | ||
2363 | } | ||
2364 | |||
2365 | /* call kctl->put with the given value(s) */ | ||
2366 | static int put_kctl_with_value(struct snd_kcontrol *kctl, int val) | ||
2367 | { | ||
2368 | struct snd_ctl_elem_value *ucontrol; | ||
2369 | ucontrol = kzalloc(sizeof(*ucontrol), GFP_KERNEL); | ||
2370 | if (!ucontrol) | ||
2371 | return -ENOMEM; | ||
2372 | ucontrol->value.integer.value[0] = val; | ||
2373 | ucontrol->value.integer.value[1] = val; | ||
2374 | kctl->put(kctl, ucontrol); | ||
2375 | kfree(ucontrol); | ||
2376 | return 0; | ||
2377 | } | ||
2378 | |||
2379 | /* initialize the slave volume with 0dB */ | ||
2380 | static int init_slave_0dB(void *data, struct snd_kcontrol *slave) | ||
2381 | { | ||
2382 | int offset = get_kctl_0dB_offset(slave); | ||
2383 | if (offset > 0) | ||
2384 | put_kctl_with_value(slave, offset); | ||
2385 | return 0; | ||
2386 | } | ||
2387 | |||
2388 | /* unmute the slave */ | ||
2389 | static int init_slave_unmute(void *data, struct snd_kcontrol *slave) | ||
2390 | { | ||
2391 | return put_kctl_with_value(slave, 1); | ||
2392 | } | ||
2393 | |||
2332 | /** | 2394 | /** |
2333 | * snd_hda_add_vmaster - create a virtual master control and add slaves | 2395 | * snd_hda_add_vmaster - create a virtual master control and add slaves |
2334 | * @codec: HD-audio codec | 2396 | * @codec: HD-audio codec |
2335 | * @name: vmaster control name | 2397 | * @name: vmaster control name |
2336 | * @tlv: TLV data (optional) | 2398 | * @tlv: TLV data (optional) |
2337 | * @slaves: slave control names (optional) | 2399 | * @slaves: slave control names (optional) |
2400 | * @suffix: suffix string to each slave name (optional) | ||
2401 | * @init_slave_vol: initialize slaves to unmute/0dB | ||
2402 | * @ctl_ret: store the vmaster kcontrol in return | ||
2338 | * | 2403 | * |
2339 | * Create a virtual master control with the given name. The TLV data | 2404 | * Create a virtual master control with the given name. The TLV data |
2340 | * must be either NULL or a valid data. | 2405 | * must be either NULL or a valid data. |
@@ -2345,13 +2410,18 @@ static int check_slave_present(void *data, struct snd_kcontrol *sctl) | |||
2345 | * | 2410 | * |
2346 | * This function returns zero if successful or a negative error code. | 2411 | * This function returns zero if successful or a negative error code. |
2347 | */ | 2412 | */ |
2348 | int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | 2413 | int __snd_hda_add_vmaster(struct hda_codec *codec, char *name, |
2349 | unsigned int *tlv, const char * const *slaves) | 2414 | unsigned int *tlv, const char * const *slaves, |
2415 | const char *suffix, bool init_slave_vol, | ||
2416 | struct snd_kcontrol **ctl_ret) | ||
2350 | { | 2417 | { |
2351 | struct snd_kcontrol *kctl; | 2418 | struct snd_kcontrol *kctl; |
2352 | int err; | 2419 | int err; |
2353 | 2420 | ||
2354 | err = map_slaves(codec, slaves, check_slave_present, NULL); | 2421 | if (ctl_ret) |
2422 | *ctl_ret = NULL; | ||
2423 | |||
2424 | err = map_slaves(codec, slaves, suffix, check_slave_present, NULL); | ||
2355 | if (err != 1) { | 2425 | if (err != 1) { |
2356 | snd_printdd("No slave found for %s\n", name); | 2426 | snd_printdd("No slave found for %s\n", name); |
2357 | return 0; | 2427 | return 0; |
@@ -2363,13 +2433,119 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | |||
2363 | if (err < 0) | 2433 | if (err < 0) |
2364 | return err; | 2434 | return err; |
2365 | 2435 | ||
2366 | err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave, | 2436 | err = map_slaves(codec, slaves, suffix, |
2367 | kctl); | 2437 | (map_slave_func_t)snd_ctl_add_slave, kctl); |
2368 | if (err < 0) | 2438 | if (err < 0) |
2369 | return err; | 2439 | return err; |
2440 | |||
2441 | /* init with master mute & zero volume */ | ||
2442 | put_kctl_with_value(kctl, 0); | ||
2443 | if (init_slave_vol) | ||
2444 | map_slaves(codec, slaves, suffix, | ||
2445 | tlv ? init_slave_0dB : init_slave_unmute, kctl); | ||
2446 | |||
2447 | if (ctl_ret) | ||
2448 | *ctl_ret = kctl; | ||
2449 | return 0; | ||
2450 | } | ||
2451 | EXPORT_SYMBOL_HDA(__snd_hda_add_vmaster); | ||
2452 | |||
2453 | /* | ||
2454 | * mute-LED control using vmaster | ||
2455 | */ | ||
2456 | static int vmaster_mute_mode_info(struct snd_kcontrol *kcontrol, | ||
2457 | struct snd_ctl_elem_info *uinfo) | ||
2458 | { | ||
2459 | static const char * const texts[] = { | ||
2460 | "Off", "On", "Follow Master" | ||
2461 | }; | ||
2462 | unsigned int index; | ||
2463 | |||
2464 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
2465 | uinfo->count = 1; | ||
2466 | uinfo->value.enumerated.items = 3; | ||
2467 | index = uinfo->value.enumerated.item; | ||
2468 | if (index >= 3) | ||
2469 | index = 2; | ||
2470 | strcpy(uinfo->value.enumerated.name, texts[index]); | ||
2471 | return 0; | ||
2472 | } | ||
2473 | |||
2474 | static int vmaster_mute_mode_get(struct snd_kcontrol *kcontrol, | ||
2475 | struct snd_ctl_elem_value *ucontrol) | ||
2476 | { | ||
2477 | struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol); | ||
2478 | ucontrol->value.enumerated.item[0] = hook->mute_mode; | ||
2370 | return 0; | 2479 | return 0; |
2371 | } | 2480 | } |
2372 | EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); | 2481 | |
2482 | static int vmaster_mute_mode_put(struct snd_kcontrol *kcontrol, | ||
2483 | struct snd_ctl_elem_value *ucontrol) | ||
2484 | { | ||
2485 | struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol); | ||
2486 | unsigned int old_mode = hook->mute_mode; | ||
2487 | |||
2488 | hook->mute_mode = ucontrol->value.enumerated.item[0]; | ||
2489 | if (hook->mute_mode > HDA_VMUTE_FOLLOW_MASTER) | ||
2490 | hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER; | ||
2491 | if (old_mode == hook->mute_mode) | ||
2492 | return 0; | ||
2493 | snd_hda_sync_vmaster_hook(hook); | ||
2494 | return 1; | ||
2495 | } | ||
2496 | |||
2497 | static struct snd_kcontrol_new vmaster_mute_mode = { | ||
2498 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2499 | .name = "Mute-LED Mode", | ||
2500 | .info = vmaster_mute_mode_info, | ||
2501 | .get = vmaster_mute_mode_get, | ||
2502 | .put = vmaster_mute_mode_put, | ||
2503 | }; | ||
2504 | |||
2505 | /* | ||
2506 | * Add a mute-LED hook with the given vmaster switch kctl | ||
2507 | * "Mute-LED Mode" control is automatically created and associated with | ||
2508 | * the given hook. | ||
2509 | */ | ||
2510 | int snd_hda_add_vmaster_hook(struct hda_codec *codec, | ||
2511 | struct hda_vmaster_mute_hook *hook, | ||
2512 | bool expose_enum_ctl) | ||
2513 | { | ||
2514 | struct snd_kcontrol *kctl; | ||
2515 | |||
2516 | if (!hook->hook || !hook->sw_kctl) | ||
2517 | return 0; | ||
2518 | snd_ctl_add_vmaster_hook(hook->sw_kctl, hook->hook, codec); | ||
2519 | hook->codec = codec; | ||
2520 | hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER; | ||
2521 | if (!expose_enum_ctl) | ||
2522 | return 0; | ||
2523 | kctl = snd_ctl_new1(&vmaster_mute_mode, hook); | ||
2524 | if (!kctl) | ||
2525 | return -ENOMEM; | ||
2526 | return snd_hda_ctl_add(codec, 0, kctl); | ||
2527 | } | ||
2528 | EXPORT_SYMBOL_HDA(snd_hda_add_vmaster_hook); | ||
2529 | |||
2530 | /* | ||
2531 | * Call the hook with the current value for synchronization | ||
2532 | * Should be called in init callback | ||
2533 | */ | ||
2534 | void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook) | ||
2535 | { | ||
2536 | if (!hook->hook || !hook->codec) | ||
2537 | return; | ||
2538 | switch (hook->mute_mode) { | ||
2539 | case HDA_VMUTE_FOLLOW_MASTER: | ||
2540 | snd_ctl_sync_vmaster_hook(hook->sw_kctl); | ||
2541 | break; | ||
2542 | default: | ||
2543 | hook->hook(hook->codec, hook->mute_mode); | ||
2544 | break; | ||
2545 | } | ||
2546 | } | ||
2547 | EXPORT_SYMBOL_HDA(snd_hda_sync_vmaster_hook); | ||
2548 | |||
2373 | 2549 | ||
2374 | /** | 2550 | /** |
2375 | * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch | 2551 | * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch |
@@ -5114,7 +5290,7 @@ static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid, | |||
5114 | const char *pfx = "", *sfx = ""; | 5290 | const char *pfx = "", *sfx = ""; |
5115 | 5291 | ||
5116 | /* handle as a speaker if it's a fixed line-out */ | 5292 | /* handle as a speaker if it's a fixed line-out */ |
5117 | if (!strcmp(name, "Line-Out") && attr == INPUT_PIN_ATTR_INT) | 5293 | if (!strcmp(name, "Line Out") && attr == INPUT_PIN_ATTR_INT) |
5118 | name = "Speaker"; | 5294 | name = "Speaker"; |
5119 | /* check the location */ | 5295 | /* check the location */ |
5120 | switch (attr) { | 5296 | switch (attr) { |
@@ -5173,7 +5349,7 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, | |||
5173 | 5349 | ||
5174 | switch (get_defcfg_device(def_conf)) { | 5350 | switch (get_defcfg_device(def_conf)) { |
5175 | case AC_JACK_LINE_OUT: | 5351 | case AC_JACK_LINE_OUT: |
5176 | return fill_audio_out_name(codec, nid, cfg, "Line-Out", | 5352 | return fill_audio_out_name(codec, nid, cfg, "Line Out", |
5177 | label, maxlen, indexp); | 5353 | label, maxlen, indexp); |
5178 | case AC_JACK_SPEAKER: | 5354 | case AC_JACK_SPEAKER: |
5179 | return fill_audio_out_name(codec, nid, cfg, "Speaker", | 5355 | return fill_audio_out_name(codec, nid, cfg, "Speaker", |
@@ -5268,6 +5444,10 @@ int snd_hda_suspend(struct hda_bus *bus) | |||
5268 | list_for_each_entry(codec, &bus->codec_list, list) { | 5444 | list_for_each_entry(codec, &bus->codec_list, list) { |
5269 | if (hda_codec_is_power_on(codec)) | 5445 | if (hda_codec_is_power_on(codec)) |
5270 | hda_call_codec_suspend(codec); | 5446 | hda_call_codec_suspend(codec); |
5447 | else /* forcibly change the power to D3 even if not used */ | ||
5448 | hda_set_power_state(codec, | ||
5449 | codec->afg ? codec->afg : codec->mfg, | ||
5450 | AC_PWRST_D3); | ||
5271 | if (codec->patch_ops.post_suspend) | 5451 | if (codec->patch_ops.post_suspend) |
5272 | codec->patch_ops.post_suspend(codec); | 5452 | codec->patch_ops.post_suspend(codec); |
5273 | } | 5453 | } |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index e9f71dc0d464..9a9f372e1be4 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -298,6 +298,9 @@ enum { | |||
298 | #define AC_AMPCAP_MUTE (1<<31) /* mute capable */ | 298 | #define AC_AMPCAP_MUTE (1<<31) /* mute capable */ |
299 | #define AC_AMPCAP_MUTE_SHIFT 31 | 299 | #define AC_AMPCAP_MUTE_SHIFT 31 |
300 | 300 | ||
301 | /* driver-specific amp-caps: using bits 24-30 */ | ||
302 | #define AC_AMPCAP_MIN_MUTE (1 << 30) /* min-volume = mute */ | ||
303 | |||
301 | /* Connection list */ | 304 | /* Connection list */ |
302 | #define AC_CLIST_LENGTH (0x7f<<0) | 305 | #define AC_CLIST_LENGTH (0x7f<<0) |
303 | #define AC_CLIST_LONG (1<<7) | 306 | #define AC_CLIST_LONG (1<<7) |
@@ -852,6 +855,7 @@ struct hda_codec { | |||
852 | unsigned int pins_shutup:1; /* pins are shut up */ | 855 | unsigned int pins_shutup:1; /* pins are shut up */ |
853 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ | 856 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ |
854 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ | 857 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ |
858 | unsigned int no_jack_detect:1; /* Machine has no jack-detection */ | ||
855 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 859 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
856 | unsigned int power_on :1; /* current (global) power-state */ | 860 | unsigned int power_on :1; /* current (global) power-state */ |
857 | unsigned int power_transition :1; /* power-state in transition */ | 861 | unsigned int power_transition :1; /* power-state in transition */ |
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index c1da422e085a..b58b4b1687fa 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c | |||
@@ -385,8 +385,8 @@ error: | |||
385 | static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen) | 385 | static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen) |
386 | { | 386 | { |
387 | static unsigned int alsa_rates[] = { | 387 | static unsigned int alsa_rates[] = { |
388 | 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200, | 388 | 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, |
389 | 96000, 176400, 192000, 384000 | 389 | 88200, 96000, 176400, 192000, 384000 |
390 | }; | 390 | }; |
391 | int i, j; | 391 | int i, j; |
392 | 392 | ||
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index fb35474c1203..c19e71a94e1b 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -84,7 +84,7 @@ module_param_array(model, charp, NULL, 0444); | |||
84 | MODULE_PARM_DESC(model, "Use the given board model."); | 84 | MODULE_PARM_DESC(model, "Use the given board model."); |
85 | module_param_array(position_fix, int, NULL, 0444); | 85 | module_param_array(position_fix, int, NULL, 0444); |
86 | MODULE_PARM_DESC(position_fix, "DMA pointer read method." | 86 | MODULE_PARM_DESC(position_fix, "DMA pointer read method." |
87 | "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO)."); | 87 | "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO)."); |
88 | module_param_array(bdl_pos_adj, int, NULL, 0644); | 88 | module_param_array(bdl_pos_adj, int, NULL, 0644); |
89 | MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); | 89 | MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); |
90 | module_param_array(probe_mask, int, NULL, 0444); | 90 | module_param_array(probe_mask, int, NULL, 0444); |
@@ -94,7 +94,7 @@ MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization."); | |||
94 | module_param(single_cmd, bool, 0444); | 94 | module_param(single_cmd, bool, 0444); |
95 | MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " | 95 | MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " |
96 | "(for debugging only)."); | 96 | "(for debugging only)."); |
97 | module_param(enable_msi, int, 0444); | 97 | module_param(enable_msi, bint, 0444); |
98 | MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); | 98 | MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); |
99 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | 99 | #ifdef CONFIG_SND_HDA_PATCH_LOADER |
100 | module_param_array(patch, charp, NULL, 0444); | 100 | module_param_array(patch, charp, NULL, 0444); |
@@ -121,8 +121,8 @@ module_param(power_save_controller, bool, 0644); | |||
121 | MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); | 121 | MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); |
122 | #endif | 122 | #endif |
123 | 123 | ||
124 | static bool align_buffer_size = 1; | 124 | static int align_buffer_size = -1; |
125 | module_param(align_buffer_size, bool, 0644); | 125 | module_param(align_buffer_size, bint, 0644); |
126 | MODULE_PARM_DESC(align_buffer_size, | 126 | MODULE_PARM_DESC(align_buffer_size, |
127 | "Force buffer and period sizes to be multiple of 128 bytes."); | 127 | "Force buffer and period sizes to be multiple of 128 bytes."); |
128 | 128 | ||
@@ -148,6 +148,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | |||
148 | "{Intel, PCH}," | 148 | "{Intel, PCH}," |
149 | "{Intel, CPT}," | 149 | "{Intel, CPT}," |
150 | "{Intel, PPT}," | 150 | "{Intel, PPT}," |
151 | "{Intel, LPT}," | ||
151 | "{Intel, PBG}," | 152 | "{Intel, PBG}," |
152 | "{Intel, SCH}," | 153 | "{Intel, SCH}," |
153 | "{ATI, SB450}," | 154 | "{ATI, SB450}," |
@@ -329,6 +330,7 @@ enum { | |||
329 | POS_FIX_LPIB, | 330 | POS_FIX_LPIB, |
330 | POS_FIX_POSBUF, | 331 | POS_FIX_POSBUF, |
331 | POS_FIX_VIACOMBO, | 332 | POS_FIX_VIACOMBO, |
333 | POS_FIX_COMBO, | ||
332 | }; | 334 | }; |
333 | 335 | ||
334 | /* Defines for ATI HD Audio support in SB450 south bridge */ | 336 | /* Defines for ATI HD Audio support in SB450 south bridge */ |
@@ -469,6 +471,7 @@ struct azx { | |||
469 | unsigned int irq_pending_warned :1; | 471 | unsigned int irq_pending_warned :1; |
470 | unsigned int probing :1; /* codec probing phase */ | 472 | unsigned int probing :1; /* codec probing phase */ |
471 | unsigned int snoop:1; | 473 | unsigned int snoop:1; |
474 | unsigned int align_buffer_size:1; | ||
472 | 475 | ||
473 | /* for debugging */ | 476 | /* for debugging */ |
474 | unsigned int last_cmd[AZX_MAX_CODECS]; | 477 | unsigned int last_cmd[AZX_MAX_CODECS]; |
@@ -514,6 +517,7 @@ enum { | |||
514 | #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ | 517 | #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ |
515 | #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ | 518 | #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ |
516 | #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ | 519 | #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ |
520 | #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ | ||
517 | 521 | ||
518 | /* quirks for ATI SB / AMD Hudson */ | 522 | /* quirks for ATI SB / AMD Hudson */ |
519 | #define AZX_DCAPS_PRESET_ATI_SB \ | 523 | #define AZX_DCAPS_PRESET_ATI_SB \ |
@@ -526,7 +530,8 @@ enum { | |||
526 | 530 | ||
527 | /* quirks for Nvidia */ | 531 | /* quirks for Nvidia */ |
528 | #define AZX_DCAPS_PRESET_NVIDIA \ | 532 | #define AZX_DCAPS_PRESET_NVIDIA \ |
529 | (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI) | 533 | (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\ |
534 | AZX_DCAPS_ALIGN_BUFSIZE) | ||
530 | 535 | ||
531 | static char *driver_short_names[] __devinitdata = { | 536 | static char *driver_short_names[] __devinitdata = { |
532 | [AZX_DRIVER_ICH] = "HDA Intel", | 537 | [AZX_DRIVER_ICH] = "HDA Intel", |
@@ -1690,7 +1695,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
1690 | runtime->hw.rates = hinfo->rates; | 1695 | runtime->hw.rates = hinfo->rates; |
1691 | snd_pcm_limit_hw_rates(runtime); | 1696 | snd_pcm_limit_hw_rates(runtime); |
1692 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | 1697 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); |
1693 | if (align_buffer_size) | 1698 | if (chip->align_buffer_size) |
1694 | /* constrain buffer sizes to be multiple of 128 | 1699 | /* constrain buffer sizes to be multiple of 128 |
1695 | bytes. This is more efficient in terms of memory | 1700 | bytes. This is more efficient in terms of memory |
1696 | access but isn't required by the HDA spec and | 1701 | access but isn't required by the HDA spec and |
@@ -2346,17 +2351,6 @@ static void azx_power_notify(struct hda_bus *bus) | |||
2346 | * power management | 2351 | * power management |
2347 | */ | 2352 | */ |
2348 | 2353 | ||
2349 | static int snd_hda_codecs_inuse(struct hda_bus *bus) | ||
2350 | { | ||
2351 | struct hda_codec *codec; | ||
2352 | |||
2353 | list_for_each_entry(codec, &bus->codec_list, list) { | ||
2354 | if (snd_hda_codec_needs_resume(codec)) | ||
2355 | return 1; | ||
2356 | } | ||
2357 | return 0; | ||
2358 | } | ||
2359 | |||
2360 | static int azx_suspend(struct pci_dev *pci, pm_message_t state) | 2354 | static int azx_suspend(struct pci_dev *pci, pm_message_t state) |
2361 | { | 2355 | { |
2362 | struct snd_card *card = pci_get_drvdata(pci); | 2356 | struct snd_card *card = pci_get_drvdata(pci); |
@@ -2403,8 +2397,7 @@ static int azx_resume(struct pci_dev *pci) | |||
2403 | return -EIO; | 2397 | return -EIO; |
2404 | azx_init_pci(chip); | 2398 | azx_init_pci(chip); |
2405 | 2399 | ||
2406 | if (snd_hda_codecs_inuse(chip->bus)) | 2400 | azx_init_chip(chip, 1); |
2407 | azx_init_chip(chip, 1); | ||
2408 | 2401 | ||
2409 | snd_hda_resume(chip->bus); | 2402 | snd_hda_resume(chip->bus); |
2410 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 2403 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
@@ -2516,6 +2509,7 @@ static int __devinit check_position_fix(struct azx *chip, int fix) | |||
2516 | case POS_FIX_LPIB: | 2509 | case POS_FIX_LPIB: |
2517 | case POS_FIX_POSBUF: | 2510 | case POS_FIX_POSBUF: |
2518 | case POS_FIX_VIACOMBO: | 2511 | case POS_FIX_VIACOMBO: |
2512 | case POS_FIX_COMBO: | ||
2519 | return fix; | 2513 | return fix; |
2520 | } | 2514 | } |
2521 | 2515 | ||
@@ -2695,6 +2689,12 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2695 | 2689 | ||
2696 | chip->position_fix[0] = chip->position_fix[1] = | 2690 | chip->position_fix[0] = chip->position_fix[1] = |
2697 | check_position_fix(chip, position_fix[dev]); | 2691 | check_position_fix(chip, position_fix[dev]); |
2692 | /* combo mode uses LPIB for playback */ | ||
2693 | if (chip->position_fix[0] == POS_FIX_COMBO) { | ||
2694 | chip->position_fix[0] = POS_FIX_LPIB; | ||
2695 | chip->position_fix[1] = POS_FIX_AUTO; | ||
2696 | } | ||
2697 | |||
2698 | check_probe_mask(chip, dev); | 2698 | check_probe_mask(chip, dev); |
2699 | 2699 | ||
2700 | chip->single_cmd = single_cmd; | 2700 | chip->single_cmd = single_cmd; |
@@ -2773,8 +2773,16 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2773 | } | 2773 | } |
2774 | 2774 | ||
2775 | /* disable buffer size rounding to 128-byte multiples if supported */ | 2775 | /* disable buffer size rounding to 128-byte multiples if supported */ |
2776 | if (chip->driver_caps & AZX_DCAPS_BUFSIZE) | 2776 | if (align_buffer_size >= 0) |
2777 | align_buffer_size = 0; | 2777 | chip->align_buffer_size = !!align_buffer_size; |
2778 | else { | ||
2779 | if (chip->driver_caps & AZX_DCAPS_BUFSIZE) | ||
2780 | chip->align_buffer_size = 0; | ||
2781 | else if (chip->driver_caps & AZX_DCAPS_ALIGN_BUFSIZE) | ||
2782 | chip->align_buffer_size = 1; | ||
2783 | else | ||
2784 | chip->align_buffer_size = 1; | ||
2785 | } | ||
2778 | 2786 | ||
2779 | /* allow 64bit DMA address if supported by H/W */ | 2787 | /* allow 64bit DMA address if supported by H/W */ |
2780 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) | 2788 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) |
@@ -2990,6 +2998,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
2990 | { PCI_DEVICE(0x8086, 0x1e20), | 2998 | { PCI_DEVICE(0x8086, 0x1e20), |
2991 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 2999 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
2992 | AZX_DCAPS_BUFSIZE}, | 3000 | AZX_DCAPS_BUFSIZE}, |
3001 | /* Lynx Point */ | ||
3002 | { PCI_DEVICE(0x8086, 0x8c20), | ||
3003 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | ||
3004 | AZX_DCAPS_BUFSIZE}, | ||
2993 | /* SCH */ | 3005 | /* SCH */ |
2994 | { PCI_DEVICE(0x8086, 0x811b), | 3006 | { PCI_DEVICE(0x8086, 0x811b), |
2995 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | | 3007 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index d8a35da0803f..d68948499fbc 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c | |||
@@ -19,6 +19,22 @@ | |||
19 | #include "hda_local.h" | 19 | #include "hda_local.h" |
20 | #include "hda_jack.h" | 20 | #include "hda_jack.h" |
21 | 21 | ||
22 | bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) | ||
23 | { | ||
24 | if (codec->no_jack_detect) | ||
25 | return false; | ||
26 | if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT)) | ||
27 | return false; | ||
28 | if (!codec->ignore_misc_bit && | ||
29 | (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & | ||
30 | AC_DEFCFG_MISC_NO_PRESENCE)) | ||
31 | return false; | ||
32 | if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) | ||
33 | return false; | ||
34 | return true; | ||
35 | } | ||
36 | EXPORT_SYMBOL_HDA(is_jack_detectable); | ||
37 | |||
22 | /* execute pin sense measurement */ | 38 | /* execute pin sense measurement */ |
23 | static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) | 39 | static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid) |
24 | { | 40 | { |
@@ -282,7 +298,8 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, | |||
282 | EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); | 298 | EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); |
283 | 299 | ||
284 | static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, | 300 | static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, |
285 | const struct auto_pin_cfg *cfg) | 301 | const struct auto_pin_cfg *cfg, |
302 | char *lastname, int *lastidx) | ||
286 | { | 303 | { |
287 | unsigned int def_conf, conn; | 304 | unsigned int def_conf, conn; |
288 | char name[44]; | 305 | char name[44]; |
@@ -298,6 +315,10 @@ static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, | |||
298 | return 0; | 315 | return 0; |
299 | 316 | ||
300 | snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); | 317 | snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); |
318 | if (!strcmp(name, lastname) && idx == *lastidx) | ||
319 | idx++; | ||
320 | strncpy(lastname, name, 44); | ||
321 | *lastidx = idx; | ||
301 | err = snd_hda_jack_add_kctl(codec, nid, name, idx); | 322 | err = snd_hda_jack_add_kctl(codec, nid, name, idx); |
302 | if (err < 0) | 323 | if (err < 0) |
303 | return err; | 324 | return err; |
@@ -311,41 +332,42 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, | |||
311 | const struct auto_pin_cfg *cfg) | 332 | const struct auto_pin_cfg *cfg) |
312 | { | 333 | { |
313 | const hda_nid_t *p; | 334 | const hda_nid_t *p; |
314 | int i, err; | 335 | int i, err, lastidx = 0; |
336 | char lastname[44] = ""; | ||
315 | 337 | ||
316 | for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { | 338 | for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { |
317 | err = add_jack_kctl(codec, *p, cfg); | 339 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); |
318 | if (err < 0) | 340 | if (err < 0) |
319 | return err; | 341 | return err; |
320 | } | 342 | } |
321 | for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { | 343 | for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { |
322 | if (*p == *cfg->line_out_pins) /* might be duplicated */ | 344 | if (*p == *cfg->line_out_pins) /* might be duplicated */ |
323 | break; | 345 | break; |
324 | err = add_jack_kctl(codec, *p, cfg); | 346 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); |
325 | if (err < 0) | 347 | if (err < 0) |
326 | return err; | 348 | return err; |
327 | } | 349 | } |
328 | for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { | 350 | for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { |
329 | if (*p == *cfg->line_out_pins) /* might be duplicated */ | 351 | if (*p == *cfg->line_out_pins) /* might be duplicated */ |
330 | break; | 352 | break; |
331 | err = add_jack_kctl(codec, *p, cfg); | 353 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); |
332 | if (err < 0) | 354 | if (err < 0) |
333 | return err; | 355 | return err; |
334 | } | 356 | } |
335 | for (i = 0; i < cfg->num_inputs; i++) { | 357 | for (i = 0; i < cfg->num_inputs; i++) { |
336 | err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg); | 358 | err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, lastname, &lastidx); |
337 | if (err < 0) | 359 | if (err < 0) |
338 | return err; | 360 | return err; |
339 | } | 361 | } |
340 | for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { | 362 | for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { |
341 | err = add_jack_kctl(codec, *p, cfg); | 363 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); |
342 | if (err < 0) | 364 | if (err < 0) |
343 | return err; | 365 | return err; |
344 | } | 366 | } |
345 | err = add_jack_kctl(codec, cfg->dig_in_pin, cfg); | 367 | err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, lastname, &lastidx); |
346 | if (err < 0) | 368 | if (err < 0) |
347 | return err; | 369 | return err; |
348 | err = add_jack_kctl(codec, cfg->mono_out_pin, cfg); | 370 | err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, lastname, &lastidx); |
349 | if (err < 0) | 371 | if (err < 0) |
350 | return err; | 372 | return err; |
351 | return 0; | 373 | return 0; |
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h index f8f97c71c9c1..c66655cf413a 100644 --- a/sound/pci/hda/hda_jack.h +++ b/sound/pci/hda/hda_jack.h | |||
@@ -62,18 +62,7 @@ int snd_hda_jack_detect_enable(struct hda_codec *codec, hda_nid_t nid, | |||
62 | u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); | 62 | u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); |
63 | int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); | 63 | int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); |
64 | 64 | ||
65 | static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) | 65 | bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid); |
66 | { | ||
67 | if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT)) | ||
68 | return false; | ||
69 | if (!codec->ignore_misc_bit && | ||
70 | (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & | ||
71 | AC_DEFCFG_MISC_NO_PRESENCE)) | ||
72 | return false; | ||
73 | if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) | ||
74 | return false; | ||
75 | return true; | ||
76 | } | ||
77 | 66 | ||
78 | int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, | 67 | int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, |
79 | const char *name, int idx); | 68 | const char *name, int idx); |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index aca8d3193b95..0ec9248165bc 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -139,10 +139,36 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir, | |||
139 | unsigned int *tlv); | 139 | unsigned int *tlv); |
140 | struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, | 140 | struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, |
141 | const char *name); | 141 | const char *name); |
142 | int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | 142 | int __snd_hda_add_vmaster(struct hda_codec *codec, char *name, |
143 | unsigned int *tlv, const char * const *slaves); | 143 | unsigned int *tlv, const char * const *slaves, |
144 | const char *suffix, bool init_slave_vol, | ||
145 | struct snd_kcontrol **ctl_ret); | ||
146 | #define snd_hda_add_vmaster(codec, name, tlv, slaves, suffix) \ | ||
147 | __snd_hda_add_vmaster(codec, name, tlv, slaves, suffix, true, NULL) | ||
144 | int snd_hda_codec_reset(struct hda_codec *codec); | 148 | int snd_hda_codec_reset(struct hda_codec *codec); |
145 | 149 | ||
150 | enum { | ||
151 | HDA_VMUTE_OFF, | ||
152 | HDA_VMUTE_ON, | ||
153 | HDA_VMUTE_FOLLOW_MASTER, | ||
154 | }; | ||
155 | |||
156 | struct hda_vmaster_mute_hook { | ||
157 | /* below two fields must be filled by the caller of | ||
158 | * snd_hda_add_vmaster_hook() beforehand | ||
159 | */ | ||
160 | struct snd_kcontrol *sw_kctl; | ||
161 | void (*hook)(void *, int); | ||
162 | /* below are initialized automatically */ | ||
163 | unsigned int mute_mode; /* HDA_VMUTE_XXX */ | ||
164 | struct hda_codec *codec; | ||
165 | }; | ||
166 | |||
167 | int snd_hda_add_vmaster_hook(struct hda_codec *codec, | ||
168 | struct hda_vmaster_mute_hook *hook, | ||
169 | bool expose_enum_ctl); | ||
170 | void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook); | ||
171 | |||
146 | /* amp value bits */ | 172 | /* amp value bits */ |
147 | #define HDA_AMP_MUTE 0x80 | 173 | #define HDA_AMP_MUTE 0x80 |
148 | #define HDA_AMP_UNMUTE 0x00 | 174 | #define HDA_AMP_UNMUTE 0x00 |
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 9cb14b42dfff..7143393927da 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -82,6 +82,7 @@ struct ad198x_spec { | |||
82 | unsigned int inv_jack_detect: 1;/* inverted jack-detection */ | 82 | unsigned int inv_jack_detect: 1;/* inverted jack-detection */ |
83 | unsigned int inv_eapd: 1; /* inverted EAPD implementation */ | 83 | unsigned int inv_eapd: 1; /* inverted EAPD implementation */ |
84 | unsigned int analog_beep: 1; /* analog beep input present */ | 84 | unsigned int analog_beep: 1; /* analog beep input present */ |
85 | unsigned int avoid_init_slave_vol:1; | ||
85 | 86 | ||
86 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 87 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
87 | struct hda_loopback_check loopback; | 88 | struct hda_loopback_check loopback; |
@@ -137,51 +138,17 @@ static int ad198x_init(struct hda_codec *codec) | |||
137 | return 0; | 138 | return 0; |
138 | } | 139 | } |
139 | 140 | ||
140 | static const char * const ad_slave_vols[] = { | 141 | static const char * const ad_slave_pfxs[] = { |
141 | "Front Playback Volume", | 142 | "Front", "Surround", "Center", "LFE", "Side", |
142 | "Surround Playback Volume", | 143 | "Headphone", "Mono", "Speaker", "IEC958", |
143 | "Center Playback Volume", | ||
144 | "LFE Playback Volume", | ||
145 | "Side Playback Volume", | ||
146 | "Headphone Playback Volume", | ||
147 | "Mono Playback Volume", | ||
148 | "Speaker Playback Volume", | ||
149 | "IEC958 Playback Volume", | ||
150 | NULL | 144 | NULL |
151 | }; | 145 | }; |
152 | 146 | ||
153 | static const char * const ad_slave_sws[] = { | 147 | static const char * const ad1988_6stack_fp_slave_pfxs[] = { |
154 | "Front Playback Switch", | 148 | "Front", "Surround", "Center", "LFE", "Side", "IEC958", |
155 | "Surround Playback Switch", | ||
156 | "Center Playback Switch", | ||
157 | "LFE Playback Switch", | ||
158 | "Side Playback Switch", | ||
159 | "Headphone Playback Switch", | ||
160 | "Mono Playback Switch", | ||
161 | "Speaker Playback Switch", | ||
162 | "IEC958 Playback Switch", | ||
163 | NULL | 149 | NULL |
164 | }; | 150 | }; |
165 | 151 | ||
166 | static const char * const ad1988_6stack_fp_slave_vols[] = { | ||
167 | "Front Playback Volume", | ||
168 | "Surround Playback Volume", | ||
169 | "Center Playback Volume", | ||
170 | "LFE Playback Volume", | ||
171 | "Side Playback Volume", | ||
172 | "IEC958 Playback Volume", | ||
173 | NULL | ||
174 | }; | ||
175 | |||
176 | static const char * const ad1988_6stack_fp_slave_sws[] = { | ||
177 | "Front Playback Switch", | ||
178 | "Surround Playback Switch", | ||
179 | "Center Playback Switch", | ||
180 | "LFE Playback Switch", | ||
181 | "Side Playback Switch", | ||
182 | "IEC958 Playback Switch", | ||
183 | NULL | ||
184 | }; | ||
185 | static void ad198x_free_kctls(struct hda_codec *codec); | 152 | static void ad198x_free_kctls(struct hda_codec *codec); |
186 | 153 | ||
187 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 154 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
@@ -257,10 +224,12 @@ static int ad198x_build_controls(struct hda_codec *codec) | |||
257 | unsigned int vmaster_tlv[4]; | 224 | unsigned int vmaster_tlv[4]; |
258 | snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, | 225 | snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, |
259 | HDA_OUTPUT, vmaster_tlv); | 226 | HDA_OUTPUT, vmaster_tlv); |
260 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | 227 | err = __snd_hda_add_vmaster(codec, "Master Playback Volume", |
261 | vmaster_tlv, | 228 | vmaster_tlv, |
262 | (spec->slave_vols ? | 229 | (spec->slave_vols ? |
263 | spec->slave_vols : ad_slave_vols)); | 230 | spec->slave_vols : ad_slave_pfxs), |
231 | "Playback Volume", | ||
232 | !spec->avoid_init_slave_vol, NULL); | ||
264 | if (err < 0) | 233 | if (err < 0) |
265 | return err; | 234 | return err; |
266 | } | 235 | } |
@@ -268,7 +237,8 @@ static int ad198x_build_controls(struct hda_codec *codec) | |||
268 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", | 237 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", |
269 | NULL, | 238 | NULL, |
270 | (spec->slave_sws ? | 239 | (spec->slave_sws ? |
271 | spec->slave_sws : ad_slave_sws)); | 240 | spec->slave_sws : ad_slave_pfxs), |
241 | "Playback Switch"); | ||
272 | if (err < 0) | 242 | if (err < 0) |
273 | return err; | 243 | return err; |
274 | } | 244 | } |
@@ -3385,8 +3355,8 @@ static int patch_ad1988(struct hda_codec *codec) | |||
3385 | 3355 | ||
3386 | if (spec->autocfg.hp_pins[0]) { | 3356 | if (spec->autocfg.hp_pins[0]) { |
3387 | spec->mixers[spec->num_mixers++] = ad1988_hp_mixers; | 3357 | spec->mixers[spec->num_mixers++] = ad1988_hp_mixers; |
3388 | spec->slave_vols = ad1988_6stack_fp_slave_vols; | 3358 | spec->slave_vols = ad1988_6stack_fp_slave_pfxs; |
3389 | spec->slave_sws = ad1988_6stack_fp_slave_sws; | 3359 | spec->slave_sws = ad1988_6stack_fp_slave_pfxs; |
3390 | spec->alt_dac_nid = ad1988_alt_dac_nid; | 3360 | spec->alt_dac_nid = ad1988_alt_dac_nid; |
3391 | spec->stream_analog_alt_playback = | 3361 | spec->stream_analog_alt_playback = |
3392 | &ad198x_pcm_analog_alt_playback; | 3362 | &ad198x_pcm_analog_alt_playback; |
@@ -3594,16 +3564,8 @@ static const struct hda_amp_list ad1884_loopbacks[] = { | |||
3594 | #endif | 3564 | #endif |
3595 | 3565 | ||
3596 | static const char * const ad1884_slave_vols[] = { | 3566 | static const char * const ad1884_slave_vols[] = { |
3597 | "PCM Playback Volume", | 3567 | "PCM", "Mic", "Mono", "Front Mic", "Mic", "CD", |
3598 | "Mic Playback Volume", | 3568 | "Internal Mic", "Docking Mic", /* "Beep", */ "IEC958", |
3599 | "Mono Playback Volume", | ||
3600 | "Front Mic Playback Volume", | ||
3601 | "Mic Playback Volume", | ||
3602 | "CD Playback Volume", | ||
3603 | "Internal Mic Playback Volume", | ||
3604 | "Docking Mic Playback Volume", | ||
3605 | /* "Beep Playback Volume", */ | ||
3606 | "IEC958 Playback Volume", | ||
3607 | NULL | 3569 | NULL |
3608 | }; | 3570 | }; |
3609 | 3571 | ||
@@ -3644,6 +3606,8 @@ static int patch_ad1884(struct hda_codec *codec) | |||
3644 | spec->vmaster_nid = 0x04; | 3606 | spec->vmaster_nid = 0x04; |
3645 | /* we need to cover all playback volumes */ | 3607 | /* we need to cover all playback volumes */ |
3646 | spec->slave_vols = ad1884_slave_vols; | 3608 | spec->slave_vols = ad1884_slave_vols; |
3609 | /* slaves may contain input volumes, so we can't raise to 0dB blindly */ | ||
3610 | spec->avoid_init_slave_vol = 1; | ||
3647 | 3611 | ||
3648 | codec->patch_ops = ad198x_patch_ops; | 3612 | codec->patch_ops = ad198x_patch_ops; |
3649 | 3613 | ||
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 35abe3c62908..21d91d580da8 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
@@ -728,18 +728,19 @@ static int ca0132_hp_switch_put(struct snd_kcontrol *kcontrol, | |||
728 | 728 | ||
729 | err = chipio_read(codec, REG_CODEC_MUTE, &data); | 729 | err = chipio_read(codec, REG_CODEC_MUTE, &data); |
730 | if (err < 0) | 730 | if (err < 0) |
731 | return err; | 731 | goto exit; |
732 | 732 | ||
733 | /* *valp 0 is mute, 1 is unmute */ | 733 | /* *valp 0 is mute, 1 is unmute */ |
734 | data = (data & 0x7f) | (*valp ? 0 : 0x80); | 734 | data = (data & 0x7f) | (*valp ? 0 : 0x80); |
735 | chipio_write(codec, REG_CODEC_MUTE, data); | 735 | err = chipio_write(codec, REG_CODEC_MUTE, data); |
736 | if (err < 0) | 736 | if (err < 0) |
737 | return err; | 737 | goto exit; |
738 | 738 | ||
739 | spec->curr_hp_switch = *valp; | 739 | spec->curr_hp_switch = *valp; |
740 | 740 | ||
741 | exit: | ||
741 | snd_hda_power_down(codec); | 742 | snd_hda_power_down(codec); |
742 | return 1; | 743 | return err < 0 ? err : 1; |
743 | } | 744 | } |
744 | 745 | ||
745 | static int ca0132_speaker_switch_get(struct snd_kcontrol *kcontrol, | 746 | static int ca0132_speaker_switch_get(struct snd_kcontrol *kcontrol, |
@@ -770,18 +771,19 @@ static int ca0132_speaker_switch_put(struct snd_kcontrol *kcontrol, | |||
770 | 771 | ||
771 | err = chipio_read(codec, REG_CODEC_MUTE, &data); | 772 | err = chipio_read(codec, REG_CODEC_MUTE, &data); |
772 | if (err < 0) | 773 | if (err < 0) |
773 | return err; | 774 | goto exit; |
774 | 775 | ||
775 | /* *valp 0 is mute, 1 is unmute */ | 776 | /* *valp 0 is mute, 1 is unmute */ |
776 | data = (data & 0xef) | (*valp ? 0 : 0x10); | 777 | data = (data & 0xef) | (*valp ? 0 : 0x10); |
777 | chipio_write(codec, REG_CODEC_MUTE, data); | 778 | err = chipio_write(codec, REG_CODEC_MUTE, data); |
778 | if (err < 0) | 779 | if (err < 0) |
779 | return err; | 780 | goto exit; |
780 | 781 | ||
781 | spec->curr_speaker_switch = *valp; | 782 | spec->curr_speaker_switch = *valp; |
782 | 783 | ||
784 | exit: | ||
783 | snd_hda_power_down(codec); | 785 | snd_hda_power_down(codec); |
784 | return 1; | 786 | return err < 0 ? err : 1; |
785 | } | 787 | } |
786 | 788 | ||
787 | static int ca0132_hp_volume_get(struct snd_kcontrol *kcontrol, | 789 | static int ca0132_hp_volume_get(struct snd_kcontrol *kcontrol, |
@@ -819,25 +821,26 @@ static int ca0132_hp_volume_put(struct snd_kcontrol *kcontrol, | |||
819 | 821 | ||
820 | err = chipio_read(codec, REG_CODEC_HP_VOL_L, &data); | 822 | err = chipio_read(codec, REG_CODEC_HP_VOL_L, &data); |
821 | if (err < 0) | 823 | if (err < 0) |
822 | return err; | 824 | goto exit; |
823 | 825 | ||
824 | val = 31 - left_vol; | 826 | val = 31 - left_vol; |
825 | data = (data & 0xe0) | val; | 827 | data = (data & 0xe0) | val; |
826 | chipio_write(codec, REG_CODEC_HP_VOL_L, data); | 828 | err = chipio_write(codec, REG_CODEC_HP_VOL_L, data); |
827 | if (err < 0) | 829 | if (err < 0) |
828 | return err; | 830 | goto exit; |
829 | 831 | ||
830 | val = 31 - right_vol; | 832 | val = 31 - right_vol; |
831 | data = (data & 0xe0) | val; | 833 | data = (data & 0xe0) | val; |
832 | chipio_write(codec, REG_CODEC_HP_VOL_R, data); | 834 | err = chipio_write(codec, REG_CODEC_HP_VOL_R, data); |
833 | if (err < 0) | 835 | if (err < 0) |
834 | return err; | 836 | goto exit; |
835 | 837 | ||
836 | spec->curr_hp_volume[0] = left_vol; | 838 | spec->curr_hp_volume[0] = left_vol; |
837 | spec->curr_hp_volume[1] = right_vol; | 839 | spec->curr_hp_volume[1] = right_vol; |
838 | 840 | ||
841 | exit: | ||
839 | snd_hda_power_down(codec); | 842 | snd_hda_power_down(codec); |
840 | return 1; | 843 | return err < 0 ? err : 1; |
841 | } | 844 | } |
842 | 845 | ||
843 | static int add_hp_switch(struct hda_codec *codec, hda_nid_t nid) | 846 | static int add_hp_switch(struct hda_codec *codec, hda_nid_t nid) |
@@ -936,6 +939,8 @@ static int ca0132_build_controls(struct hda_codec *codec) | |||
936 | if (err < 0) | 939 | if (err < 0) |
937 | return err; | 940 | return err; |
938 | err = add_in_volume(codec, spec->dig_in, "IEC958"); | 941 | err = add_in_volume(codec, spec->dig_in, "IEC958"); |
942 | if (err < 0) | ||
943 | return err; | ||
939 | } | 944 | } |
940 | return 0; | 945 | return 0; |
941 | } | 946 | } |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 0e99357e822c..c83ccdba1e5a 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -609,7 +609,7 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx, | |||
609 | "Front Speaker", "Surround Speaker", "Bass Speaker" | 609 | "Front Speaker", "Surround Speaker", "Bass Speaker" |
610 | }; | 610 | }; |
611 | static const char * const line_outs[] = { | 611 | static const char * const line_outs[] = { |
612 | "Front Line-Out", "Surround Line-Out", "Bass Line-Out" | 612 | "Front Line Out", "Surround Line Out", "Bass Line Out" |
613 | }; | 613 | }; |
614 | 614 | ||
615 | fix_volume_caps(codec, dac); | 615 | fix_volume_caps(codec, dac); |
@@ -635,7 +635,7 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx, | |||
635 | if (num_ctls > 1) | 635 | if (num_ctls > 1) |
636 | name = line_outs[idx]; | 636 | name = line_outs[idx]; |
637 | else | 637 | else |
638 | name = "Line-Out"; | 638 | name = "Line Out"; |
639 | break; | 639 | break; |
640 | } | 640 | } |
641 | 641 | ||
@@ -988,8 +988,10 @@ static void cs_automic(struct hda_codec *codec) | |||
988 | change_cur_input(codec, !spec->automic_idx, 0); | 988 | change_cur_input(codec, !spec->automic_idx, 0); |
989 | } else { | 989 | } else { |
990 | if (present) { | 990 | if (present) { |
991 | spec->last_input = spec->cur_input; | 991 | if (spec->cur_input != spec->automic_idx) { |
992 | spec->cur_input = spec->automic_idx; | 992 | spec->last_input = spec->cur_input; |
993 | spec->cur_input = spec->automic_idx; | ||
994 | } | ||
993 | } else { | 995 | } else { |
994 | spec->cur_input = spec->last_input; | 996 | spec->cur_input = spec->last_input; |
995 | } | 997 | } |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 8a32a69c83c3..8c6523bbc797 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -70,6 +70,8 @@ struct conexant_spec { | |||
70 | const struct snd_kcontrol_new *mixers[5]; | 70 | const struct snd_kcontrol_new *mixers[5]; |
71 | int num_mixers; | 71 | int num_mixers; |
72 | hda_nid_t vmaster_nid; | 72 | hda_nid_t vmaster_nid; |
73 | struct hda_vmaster_mute_hook vmaster_mute; | ||
74 | bool vmaster_mute_led; | ||
73 | 75 | ||
74 | const struct hda_verb *init_verbs[5]; /* initialization verbs | 76 | const struct hda_verb *init_verbs[5]; /* initialization verbs |
75 | * don't forget NULL | 77 | * don't forget NULL |
@@ -465,21 +467,8 @@ static const struct snd_kcontrol_new cxt_beep_mixer[] = { | |||
465 | }; | 467 | }; |
466 | #endif | 468 | #endif |
467 | 469 | ||
468 | static const char * const slave_vols[] = { | 470 | static const char * const slave_pfxs[] = { |
469 | "Headphone Playback Volume", | 471 | "Headphone", "Speaker", "Front", "Surround", "CLFE", |
470 | "Speaker Playback Volume", | ||
471 | "Front Playback Volume", | ||
472 | "Surround Playback Volume", | ||
473 | "CLFE Playback Volume", | ||
474 | NULL | ||
475 | }; | ||
476 | |||
477 | static const char * const slave_sws[] = { | ||
478 | "Headphone Playback Switch", | ||
479 | "Speaker Playback Switch", | ||
480 | "Front Playback Switch", | ||
481 | "Surround Playback Switch", | ||
482 | "CLFE Playback Switch", | ||
483 | NULL | 472 | NULL |
484 | }; | 473 | }; |
485 | 474 | ||
@@ -519,14 +508,17 @@ static int conexant_build_controls(struct hda_codec *codec) | |||
519 | snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, | 508 | snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, |
520 | HDA_OUTPUT, vmaster_tlv); | 509 | HDA_OUTPUT, vmaster_tlv); |
521 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | 510 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", |
522 | vmaster_tlv, slave_vols); | 511 | vmaster_tlv, slave_pfxs, |
512 | "Playback Volume"); | ||
523 | if (err < 0) | 513 | if (err < 0) |
524 | return err; | 514 | return err; |
525 | } | 515 | } |
526 | if (spec->vmaster_nid && | 516 | if (spec->vmaster_nid && |
527 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | 517 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { |
528 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", | 518 | err = __snd_hda_add_vmaster(codec, "Master Playback Switch", |
529 | NULL, slave_sws); | 519 | NULL, slave_pfxs, |
520 | "Playback Switch", true, | ||
521 | &spec->vmaster_mute.sw_kctl); | ||
530 | if (err < 0) | 522 | if (err < 0) |
531 | return err; | 523 | return err; |
532 | } | 524 | } |
@@ -1643,7 +1635,7 @@ static void cxt5051_update_speaker(struct hda_codec *codec) | |||
1643 | pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; | 1635 | pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; |
1644 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 1636 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
1645 | pinctl); | 1637 | pinctl); |
1646 | /* on ideapad there is an aditional speaker (subwoofer) to mute */ | 1638 | /* on ideapad there is an additional speaker (subwoofer) to mute */ |
1647 | if (spec->ideapad) | 1639 | if (spec->ideapad) |
1648 | snd_hda_codec_write(codec, 0x1b, 0, | 1640 | snd_hda_codec_write(codec, 0x1b, 0, |
1649 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 1641 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
@@ -3027,14 +3019,13 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
3027 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), | 3019 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), |
3028 | SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), | 3020 | SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), |
3029 | SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), | 3021 | SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), |
3030 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), | 3022 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T510", CXT5066_AUTO), |
3031 | SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO), | 3023 | SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO), |
3032 | SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), | 3024 | SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), |
3033 | SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), | 3025 | SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), |
3034 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), | 3026 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), |
3035 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), | 3027 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), |
3036 | SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO), | 3028 | SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO), |
3037 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */ | ||
3038 | SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO), | 3029 | SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO), |
3039 | {} | 3030 | {} |
3040 | }; | 3031 | }; |
@@ -3482,7 +3473,7 @@ static int cx_automute_mode_info(struct snd_kcontrol *kcontrol, | |||
3482 | "Disabled", "Enabled" | 3473 | "Disabled", "Enabled" |
3483 | }; | 3474 | }; |
3484 | static const char * const texts3[] = { | 3475 | static const char * const texts3[] = { |
3485 | "Disabled", "Speaker Only", "Line-Out+Speaker" | 3476 | "Disabled", "Speaker Only", "Line Out+Speaker" |
3486 | }; | 3477 | }; |
3487 | const char * const *texts; | 3478 | const char * const *texts; |
3488 | 3479 | ||
@@ -3943,6 +3934,63 @@ static void enable_unsol_pins(struct hda_codec *codec, int num_pins, | |||
3943 | snd_hda_jack_detect_enable(codec, pins[i], action); | 3934 | snd_hda_jack_detect_enable(codec, pins[i], action); |
3944 | } | 3935 | } |
3945 | 3936 | ||
3937 | static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | ||
3938 | { | ||
3939 | int i; | ||
3940 | for (i = 0; i < nums; i++) | ||
3941 | if (list[i] == nid) | ||
3942 | return true; | ||
3943 | return false; | ||
3944 | } | ||
3945 | |||
3946 | /* is the given NID found in any of autocfg items? */ | ||
3947 | static bool found_in_autocfg(struct auto_pin_cfg *cfg, hda_nid_t nid) | ||
3948 | { | ||
3949 | int i; | ||
3950 | |||
3951 | if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) || | ||
3952 | found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) || | ||
3953 | found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs) || | ||
3954 | found_in_nid_list(nid, cfg->dig_out_pins, cfg->dig_outs)) | ||
3955 | return true; | ||
3956 | for (i = 0; i < cfg->num_inputs; i++) | ||
3957 | if (cfg->inputs[i].pin == nid) | ||
3958 | return true; | ||
3959 | if (cfg->dig_in_pin == nid) | ||
3960 | return true; | ||
3961 | return false; | ||
3962 | } | ||
3963 | |||
3964 | /* clear unsol-event tags on unused pins; Conexant codecs seem to leave | ||
3965 | * invalid unsol tags by some reason | ||
3966 | */ | ||
3967 | static void clear_unsol_on_unused_pins(struct hda_codec *codec) | ||
3968 | { | ||
3969 | struct conexant_spec *spec = codec->spec; | ||
3970 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3971 | int i; | ||
3972 | |||
3973 | for (i = 0; i < codec->init_pins.used; i++) { | ||
3974 | struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i); | ||
3975 | if (!found_in_autocfg(cfg, pin->nid)) | ||
3976 | snd_hda_codec_write(codec, pin->nid, 0, | ||
3977 | AC_VERB_SET_UNSOLICITED_ENABLE, 0); | ||
3978 | } | ||
3979 | } | ||
3980 | |||
3981 | /* turn on/off EAPD according to Master switch */ | ||
3982 | static void cx_auto_vmaster_hook(void *private_data, int enabled) | ||
3983 | { | ||
3984 | struct hda_codec *codec = private_data; | ||
3985 | struct conexant_spec *spec = codec->spec; | ||
3986 | |||
3987 | if (enabled && spec->pin_eapd_ctrls) { | ||
3988 | cx_auto_update_speakers(codec); | ||
3989 | return; | ||
3990 | } | ||
3991 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, enabled); | ||
3992 | } | ||
3993 | |||
3946 | static void cx_auto_init_output(struct hda_codec *codec) | 3994 | static void cx_auto_init_output(struct hda_codec *codec) |
3947 | { | 3995 | { |
3948 | struct conexant_spec *spec = codec->spec; | 3996 | struct conexant_spec *spec = codec->spec; |
@@ -3983,6 +4031,7 @@ static void cx_auto_init_output(struct hda_codec *codec) | |||
3983 | /* turn on all EAPDs if no individual EAPD control is available */ | 4031 | /* turn on all EAPDs if no individual EAPD control is available */ |
3984 | if (!spec->pin_eapd_ctrls) | 4032 | if (!spec->pin_eapd_ctrls) |
3985 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); | 4033 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); |
4034 | clear_unsol_on_unused_pins(codec); | ||
3986 | } | 4035 | } |
3987 | 4036 | ||
3988 | static void cx_auto_init_input(struct hda_codec *codec) | 4037 | static void cx_auto_init_input(struct hda_codec *codec) |
@@ -4046,11 +4095,13 @@ static void cx_auto_init_digital(struct hda_codec *codec) | |||
4046 | 4095 | ||
4047 | static int cx_auto_init(struct hda_codec *codec) | 4096 | static int cx_auto_init(struct hda_codec *codec) |
4048 | { | 4097 | { |
4098 | struct conexant_spec *spec = codec->spec; | ||
4049 | /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/ | 4099 | /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/ |
4050 | cx_auto_init_output(codec); | 4100 | cx_auto_init_output(codec); |
4051 | cx_auto_init_input(codec); | 4101 | cx_auto_init_input(codec); |
4052 | cx_auto_init_digital(codec); | 4102 | cx_auto_init_digital(codec); |
4053 | snd_hda_jack_report_sync(codec); | 4103 | snd_hda_jack_report_sync(codec); |
4104 | snd_hda_sync_vmaster_hook(&spec->vmaster_mute); | ||
4054 | return 0; | 4105 | return 0; |
4055 | } | 4106 | } |
4056 | 4107 | ||
@@ -4079,7 +4130,8 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename, | |||
4079 | err = snd_hda_ctl_add(codec, nid, kctl); | 4130 | err = snd_hda_ctl_add(codec, nid, kctl); |
4080 | if (err < 0) | 4131 | if (err < 0) |
4081 | return err; | 4132 | return err; |
4082 | if (!(query_amp_caps(codec, nid, hda_dir) & AC_AMPCAP_MUTE)) | 4133 | if (!(query_amp_caps(codec, nid, hda_dir) & |
4134 | (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE))) | ||
4083 | break; | 4135 | break; |
4084 | } | 4136 | } |
4085 | return 0; | 4137 | return 0; |
@@ -4295,6 +4347,13 @@ static int cx_auto_build_controls(struct hda_codec *codec) | |||
4295 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | 4347 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); |
4296 | if (err < 0) | 4348 | if (err < 0) |
4297 | return err; | 4349 | return err; |
4350 | if (spec->vmaster_mute.sw_kctl) { | ||
4351 | spec->vmaster_mute.hook = cx_auto_vmaster_hook; | ||
4352 | err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, | ||
4353 | spec->vmaster_mute_led); | ||
4354 | if (err < 0) | ||
4355 | return err; | ||
4356 | } | ||
4298 | return 0; | 4357 | return 0; |
4299 | } | 4358 | } |
4300 | 4359 | ||
@@ -4319,7 +4378,6 @@ static int cx_auto_search_adcs(struct hda_codec *codec) | |||
4319 | return 0; | 4378 | return 0; |
4320 | } | 4379 | } |
4321 | 4380 | ||
4322 | |||
4323 | static const struct hda_codec_ops cx_auto_patch_ops = { | 4381 | static const struct hda_codec_ops cx_auto_patch_ops = { |
4324 | .build_controls = cx_auto_build_controls, | 4382 | .build_controls = cx_auto_build_controls, |
4325 | .build_pcms = conexant_build_pcms, | 4383 | .build_pcms = conexant_build_pcms, |
@@ -4367,6 +4425,7 @@ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = { | |||
4367 | { 0x16, 0x042140ff }, /* HP (seq# overridden) */ | 4425 | { 0x16, 0x042140ff }, /* HP (seq# overridden) */ |
4368 | { 0x17, 0x21a11000 }, /* dock-mic */ | 4426 | { 0x17, 0x21a11000 }, /* dock-mic */ |
4369 | { 0x19, 0x2121103f }, /* dock-HP */ | 4427 | { 0x19, 0x2121103f }, /* dock-HP */ |
4428 | { 0x1c, 0x21440100 }, /* dock SPDIF out */ | ||
4370 | {} | 4429 | {} |
4371 | }; | 4430 | }; |
4372 | 4431 | ||
@@ -4379,6 +4438,22 @@ static const struct snd_pci_quirk cxt_fixups[] = { | |||
4379 | {} | 4438 | {} |
4380 | }; | 4439 | }; |
4381 | 4440 | ||
4441 | /* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches | ||
4442 | * can be created (bko#42825) | ||
4443 | */ | ||
4444 | static void add_cx5051_fake_mutes(struct hda_codec *codec) | ||
4445 | { | ||
4446 | static hda_nid_t out_nids[] = { | ||
4447 | 0x10, 0x11, 0 | ||
4448 | }; | ||
4449 | hda_nid_t *p; | ||
4450 | |||
4451 | for (p = out_nids; *p; p++) | ||
4452 | snd_hda_override_amp_caps(codec, *p, HDA_OUTPUT, | ||
4453 | AC_AMPCAP_MIN_MUTE | | ||
4454 | query_amp_caps(codec, *p, HDA_OUTPUT)); | ||
4455 | } | ||
4456 | |||
4382 | static int patch_conexant_auto(struct hda_codec *codec) | 4457 | static int patch_conexant_auto(struct hda_codec *codec) |
4383 | { | 4458 | { |
4384 | struct conexant_spec *spec; | 4459 | struct conexant_spec *spec; |
@@ -4397,10 +4472,25 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
4397 | case 0x14f15045: | 4472 | case 0x14f15045: |
4398 | spec->single_adc_amp = 1; | 4473 | spec->single_adc_amp = 1; |
4399 | break; | 4474 | break; |
4475 | case 0x14f15051: | ||
4476 | add_cx5051_fake_mutes(codec); | ||
4477 | break; | ||
4400 | } | 4478 | } |
4401 | 4479 | ||
4402 | apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); | 4480 | apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); |
4403 | 4481 | ||
4482 | /* Show mute-led control only on HP laptops | ||
4483 | * This is a sort of white-list: on HP laptops, EAPD corresponds | ||
4484 | * only to the mute-LED without actualy amp function. Meanwhile, | ||
4485 | * others may use EAPD really as an amp switch, so it might be | ||
4486 | * not good to expose it blindly. | ||
4487 | */ | ||
4488 | switch (codec->subsystem_id >> 16) { | ||
4489 | case 0x103c: | ||
4490 | spec->vmaster_mute_led = 1; | ||
4491 | break; | ||
4492 | } | ||
4493 | |||
4404 | err = cx_auto_search_adcs(codec); | 4494 | err = cx_auto_search_adcs(codec); |
4405 | if (err < 0) | 4495 | if (err < 0) |
4406 | return err; | 4496 | return err; |
@@ -4414,6 +4504,18 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
4414 | codec->patch_ops = cx_auto_patch_ops; | 4504 | codec->patch_ops = cx_auto_patch_ops; |
4415 | if (spec->beep_amp) | 4505 | if (spec->beep_amp) |
4416 | snd_hda_attach_beep_device(codec, spec->beep_amp); | 4506 | snd_hda_attach_beep_device(codec, spec->beep_amp); |
4507 | |||
4508 | /* Some laptops with Conexant chips show stalls in S3 resume, | ||
4509 | * which falls into the single-cmd mode. | ||
4510 | * Better to make reset, then. | ||
4511 | */ | ||
4512 | if (!codec->bus->sync_write) { | ||
4513 | snd_printd("hda_codec: " | ||
4514 | "Enable sync_write for stable communication\n"); | ||
4515 | codec->bus->sync_write = 1; | ||
4516 | codec->bus->allow_bus_reset = 1; | ||
4517 | } | ||
4518 | |||
4417 | return 0; | 4519 | return 0; |
4418 | } | 4520 | } |
4419 | 4521 | ||
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 1168ebd3fb5c..540cd13f7f15 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -1912,6 +1912,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { | |||
1912 | { .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, | 1912 | { .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, |
1913 | { .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, | 1913 | { .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, |
1914 | { .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi }, | 1914 | { .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi }, |
1915 | { .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi }, | ||
1915 | { .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, | 1916 | { .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, |
1916 | {} /* terminator */ | 1917 | {} /* terminator */ |
1917 | }; | 1918 | }; |
@@ -1958,6 +1959,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862803"); | |||
1958 | MODULE_ALIAS("snd-hda-codec-id:80862804"); | 1959 | MODULE_ALIAS("snd-hda-codec-id:80862804"); |
1959 | MODULE_ALIAS("snd-hda-codec-id:80862805"); | 1960 | MODULE_ALIAS("snd-hda-codec-id:80862805"); |
1960 | MODULE_ALIAS("snd-hda-codec-id:80862806"); | 1961 | MODULE_ALIAS("snd-hda-codec-id:80862806"); |
1962 | MODULE_ALIAS("snd-hda-codec-id:80862880"); | ||
1961 | MODULE_ALIAS("snd-hda-codec-id:808629fb"); | 1963 | MODULE_ALIAS("snd-hda-codec-id:808629fb"); |
1962 | 1964 | ||
1963 | MODULE_LICENSE("GPL"); | 1965 | MODULE_LICENSE("GPL"); |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5e82acf77c5a..8ea2fd654327 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -80,6 +80,8 @@ enum { | |||
80 | ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */ | 80 | ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */ |
81 | }; | 81 | }; |
82 | 82 | ||
83 | #define MAX_VOL_NIDS 0x40 | ||
84 | |||
83 | struct alc_spec { | 85 | struct alc_spec { |
84 | /* codec parameterization */ | 86 | /* codec parameterization */ |
85 | const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ | 87 | const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ |
@@ -118,8 +120,8 @@ struct alc_spec { | |||
118 | const hda_nid_t *capsrc_nids; | 120 | const hda_nid_t *capsrc_nids; |
119 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ | 121 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ |
120 | hda_nid_t mixer_nid; /* analog-mixer NID */ | 122 | hda_nid_t mixer_nid; /* analog-mixer NID */ |
121 | DECLARE_BITMAP(vol_ctls, 0x20 << 1); | 123 | DECLARE_BITMAP(vol_ctls, MAX_VOL_NIDS << 1); |
122 | DECLARE_BITMAP(sw_ctls, 0x20 << 1); | 124 | DECLARE_BITMAP(sw_ctls, MAX_VOL_NIDS << 1); |
123 | 125 | ||
124 | /* capture setup for dynamic dual-adc switch */ | 126 | /* capture setup for dynamic dual-adc switch */ |
125 | hda_nid_t cur_adc; | 127 | hda_nid_t cur_adc; |
@@ -177,6 +179,7 @@ struct alc_spec { | |||
177 | unsigned int detect_lo:1; /* Line-out detection enabled */ | 179 | unsigned int detect_lo:1; /* Line-out detection enabled */ |
178 | unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */ | 180 | unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */ |
179 | unsigned int automute_lo_possible:1; /* there are line outs and HP */ | 181 | unsigned int automute_lo_possible:1; /* there are line outs and HP */ |
182 | unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */ | ||
180 | 183 | ||
181 | /* other flags */ | 184 | /* other flags */ |
182 | unsigned int no_analog :1; /* digital I/O only */ | 185 | unsigned int no_analog :1; /* digital I/O only */ |
@@ -185,7 +188,6 @@ struct alc_spec { | |||
185 | unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ | 188 | unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ |
186 | unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ | 189 | unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ |
187 | unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ | 190 | unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ |
188 | unsigned int use_jack_tbl:1; /* 1 for model=auto */ | ||
189 | 191 | ||
190 | /* auto-mute control */ | 192 | /* auto-mute control */ |
191 | int automute_mode; | 193 | int automute_mode; |
@@ -196,8 +198,11 @@ struct alc_spec { | |||
196 | 198 | ||
197 | /* for virtual master */ | 199 | /* for virtual master */ |
198 | hda_nid_t vmaster_nid; | 200 | hda_nid_t vmaster_nid; |
201 | struct hda_vmaster_mute_hook vmaster_mute; | ||
199 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 202 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
200 | struct hda_loopback_check loopback; | 203 | struct hda_loopback_check loopback; |
204 | int num_loopbacks; | ||
205 | struct hda_amp_list loopback_list[8]; | ||
201 | #endif | 206 | #endif |
202 | 207 | ||
203 | /* for PLL fix */ | 208 | /* for PLL fix */ |
@@ -218,8 +223,6 @@ struct alc_spec { | |||
218 | struct snd_array bind_ctls; | 223 | struct snd_array bind_ctls; |
219 | }; | 224 | }; |
220 | 225 | ||
221 | #define ALC_MODEL_AUTO 0 /* common for all chips */ | ||
222 | |||
223 | static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, | 226 | static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, |
224 | int dir, unsigned int bits) | 227 | int dir, unsigned int bits) |
225 | { | 228 | { |
@@ -298,6 +301,9 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
298 | int i, type, num_conns; | 301 | int i, type, num_conns; |
299 | hda_nid_t nid; | 302 | hda_nid_t nid; |
300 | 303 | ||
304 | if (!spec->input_mux) | ||
305 | return 0; | ||
306 | |||
301 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; | 307 | mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; |
302 | imux = &spec->input_mux[mux_idx]; | 308 | imux = &spec->input_mux[mux_idx]; |
303 | if (!imux->num_items && mux_idx > 0) | 309 | if (!imux->num_items && mux_idx > 0) |
@@ -496,13 +502,24 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, | |||
496 | 502 | ||
497 | for (i = 0; i < num_pins; i++) { | 503 | for (i = 0; i < num_pins; i++) { |
498 | hda_nid_t nid = pins[i]; | 504 | hda_nid_t nid = pins[i]; |
505 | unsigned int val; | ||
499 | if (!nid) | 506 | if (!nid) |
500 | break; | 507 | break; |
501 | switch (spec->automute_mode) { | 508 | switch (spec->automute_mode) { |
502 | case ALC_AUTOMUTE_PIN: | 509 | case ALC_AUTOMUTE_PIN: |
510 | /* don't reset VREF value in case it's controlling | ||
511 | * the amp (see alc861_fixup_asus_amp_vref_0f()) | ||
512 | */ | ||
513 | if (spec->keep_vref_in_automute) { | ||
514 | val = snd_hda_codec_read(codec, nid, 0, | ||
515 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
516 | val &= ~PIN_HP; | ||
517 | } else | ||
518 | val = 0; | ||
519 | val |= pin_bits; | ||
503 | snd_hda_codec_write(codec, nid, 0, | 520 | snd_hda_codec_write(codec, nid, 0, |
504 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 521 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
505 | pin_bits); | 522 | val); |
506 | break; | 523 | break; |
507 | case ALC_AUTOMUTE_AMP: | 524 | case ALC_AUTOMUTE_AMP: |
508 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | 525 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, |
@@ -621,17 +638,10 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
621 | alc_mux_select(codec, 0, spec->int_mic_idx, false); | 638 | alc_mux_select(codec, 0, spec->int_mic_idx, false); |
622 | } | 639 | } |
623 | 640 | ||
624 | /* unsolicited event for HP jack sensing */ | 641 | /* handle the specified unsol action (ALC_XXX_EVENT) */ |
625 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | 642 | static void alc_exec_unsol_event(struct hda_codec *codec, int action) |
626 | { | 643 | { |
627 | struct alc_spec *spec = codec->spec; | 644 | switch (action) { |
628 | if (codec->vendor_id == 0x10ec0880) | ||
629 | res >>= 28; | ||
630 | else | ||
631 | res >>= 26; | ||
632 | if (spec->use_jack_tbl) | ||
633 | res = snd_hda_jack_get_action(codec, res); | ||
634 | switch (res) { | ||
635 | case ALC_HP_EVENT: | 645 | case ALC_HP_EVENT: |
636 | alc_hp_automute(codec); | 646 | alc_hp_automute(codec); |
637 | break; | 647 | break; |
@@ -645,6 +655,53 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | |||
645 | snd_hda_jack_report_sync(codec); | 655 | snd_hda_jack_report_sync(codec); |
646 | } | 656 | } |
647 | 657 | ||
658 | /* update the master volume per volume-knob's unsol event */ | ||
659 | static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid) | ||
660 | { | ||
661 | unsigned int val; | ||
662 | struct snd_kcontrol *kctl; | ||
663 | struct snd_ctl_elem_value *uctl; | ||
664 | |||
665 | kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume"); | ||
666 | if (!kctl) | ||
667 | return; | ||
668 | uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); | ||
669 | if (!uctl) | ||
670 | return; | ||
671 | val = snd_hda_codec_read(codec, nid, 0, | ||
672 | AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); | ||
673 | val &= HDA_AMP_VOLMASK; | ||
674 | uctl->value.integer.value[0] = val; | ||
675 | uctl->value.integer.value[1] = val; | ||
676 | kctl->put(kctl, uctl); | ||
677 | kfree(uctl); | ||
678 | } | ||
679 | |||
680 | /* unsolicited event for HP jack sensing */ | ||
681 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | ||
682 | { | ||
683 | int action; | ||
684 | |||
685 | if (codec->vendor_id == 0x10ec0880) | ||
686 | res >>= 28; | ||
687 | else | ||
688 | res >>= 26; | ||
689 | action = snd_hda_jack_get_action(codec, res); | ||
690 | if (action == ALC_DCVOL_EVENT) { | ||
691 | /* Execute the dc-vol event here as it requires the NID | ||
692 | * but we don't pass NID to alc_exec_unsol_event(). | ||
693 | * Once when we convert all static quirks to the auto-parser, | ||
694 | * this can be integerated into there. | ||
695 | */ | ||
696 | struct hda_jack_tbl *jack; | ||
697 | jack = snd_hda_jack_tbl_get_from_tag(codec, res); | ||
698 | if (jack) | ||
699 | alc_update_knob_master(codec, jack->nid); | ||
700 | return; | ||
701 | } | ||
702 | alc_exec_unsol_event(codec, action); | ||
703 | } | ||
704 | |||
648 | /* call init functions of standard auto-mute helpers */ | 705 | /* call init functions of standard auto-mute helpers */ |
649 | static void alc_inithook(struct hda_codec *codec) | 706 | static void alc_inithook(struct hda_codec *codec) |
650 | { | 707 | { |
@@ -785,7 +842,7 @@ static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, | |||
785 | "Disabled", "Enabled" | 842 | "Disabled", "Enabled" |
786 | }; | 843 | }; |
787 | static const char * const texts3[] = { | 844 | static const char * const texts3[] = { |
788 | "Disabled", "Speaker Only", "Line-Out+Speaker" | 845 | "Disabled", "Speaker Only", "Line Out+Speaker" |
789 | }; | 846 | }; |
790 | const char * const *texts; | 847 | const char * const *texts; |
791 | 848 | ||
@@ -1016,45 +1073,6 @@ static bool alc_check_dyn_adc_switch(struct hda_codec *codec) | |||
1016 | return true; | 1073 | return true; |
1017 | } | 1074 | } |
1018 | 1075 | ||
1019 | /* rebuild imux for matching with the given auto-mic pins (if not yet) */ | ||
1020 | static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec) | ||
1021 | { | ||
1022 | struct alc_spec *spec = codec->spec; | ||
1023 | struct hda_input_mux *imux; | ||
1024 | static char * const texts[3] = { | ||
1025 | "Mic", "Internal Mic", "Dock Mic" | ||
1026 | }; | ||
1027 | int i; | ||
1028 | |||
1029 | if (!spec->auto_mic) | ||
1030 | return false; | ||
1031 | imux = &spec->private_imux[0]; | ||
1032 | if (spec->input_mux == imux) | ||
1033 | return true; | ||
1034 | spec->imux_pins[0] = spec->ext_mic_pin; | ||
1035 | spec->imux_pins[1] = spec->int_mic_pin; | ||
1036 | spec->imux_pins[2] = spec->dock_mic_pin; | ||
1037 | for (i = 0; i < 3; i++) { | ||
1038 | strcpy(imux->items[i].label, texts[i]); | ||
1039 | if (spec->imux_pins[i]) { | ||
1040 | hda_nid_t pin = spec->imux_pins[i]; | ||
1041 | int c; | ||
1042 | for (c = 0; c < spec->num_adc_nids; c++) { | ||
1043 | hda_nid_t cap = get_capsrc(spec, c); | ||
1044 | int idx = get_connection_index(codec, cap, pin); | ||
1045 | if (idx >= 0) { | ||
1046 | imux->items[i].index = idx; | ||
1047 | break; | ||
1048 | } | ||
1049 | } | ||
1050 | imux->num_items = i + 1; | ||
1051 | } | ||
1052 | } | ||
1053 | spec->num_mux_defs = 1; | ||
1054 | spec->input_mux = imux; | ||
1055 | return true; | ||
1056 | } | ||
1057 | |||
1058 | /* check whether all auto-mic pins are valid; setup indices if OK */ | 1076 | /* check whether all auto-mic pins are valid; setup indices if OK */ |
1059 | static bool alc_auto_mic_check_imux(struct hda_codec *codec) | 1077 | static bool alc_auto_mic_check_imux(struct hda_codec *codec) |
1060 | { | 1078 | { |
@@ -1424,6 +1442,7 @@ enum { | |||
1424 | ALC_FIXUP_ACT_PRE_PROBE, | 1442 | ALC_FIXUP_ACT_PRE_PROBE, |
1425 | ALC_FIXUP_ACT_PROBE, | 1443 | ALC_FIXUP_ACT_PROBE, |
1426 | ALC_FIXUP_ACT_INIT, | 1444 | ALC_FIXUP_ACT_INIT, |
1445 | ALC_FIXUP_ACT_BUILD, | ||
1427 | }; | 1446 | }; |
1428 | 1447 | ||
1429 | static void alc_apply_fixup(struct hda_codec *codec, int action) | 1448 | static void alc_apply_fixup(struct hda_codec *codec, int action) |
@@ -1503,6 +1522,13 @@ static void alc_pick_fixup(struct hda_codec *codec, | |||
1503 | int id = -1; | 1522 | int id = -1; |
1504 | const char *name = NULL; | 1523 | const char *name = NULL; |
1505 | 1524 | ||
1525 | /* when model=nofixup is given, don't pick up any fixups */ | ||
1526 | if (codec->modelname && !strcmp(codec->modelname, "nofixup")) { | ||
1527 | spec->fixup_list = NULL; | ||
1528 | spec->fixup_id = -1; | ||
1529 | return; | ||
1530 | } | ||
1531 | |||
1506 | if (codec->modelname && models) { | 1532 | if (codec->modelname && models) { |
1507 | while (models->name) { | 1533 | while (models->name) { |
1508 | if (!strcmp(codec->modelname, models->name)) { | 1534 | if (!strcmp(codec->modelname, models->name)) { |
@@ -1830,32 +1856,10 @@ DEFINE_CAPMIX_NOSRC(3); | |||
1830 | /* | 1856 | /* |
1831 | * slave controls for virtual master | 1857 | * slave controls for virtual master |
1832 | */ | 1858 | */ |
1833 | static const char * const alc_slave_vols[] = { | 1859 | static const char * const alc_slave_pfxs[] = { |
1834 | "Front Playback Volume", | 1860 | "Front", "Surround", "Center", "LFE", "Side", |
1835 | "Surround Playback Volume", | 1861 | "Headphone", "Speaker", "Mono", "Line Out", |
1836 | "Center Playback Volume", | 1862 | "CLFE", "Bass Speaker", "PCM", |
1837 | "LFE Playback Volume", | ||
1838 | "Side Playback Volume", | ||
1839 | "Headphone Playback Volume", | ||
1840 | "Speaker Playback Volume", | ||
1841 | "Mono Playback Volume", | ||
1842 | "Line-Out Playback Volume", | ||
1843 | "PCM Playback Volume", | ||
1844 | NULL, | ||
1845 | }; | ||
1846 | |||
1847 | static const char * const alc_slave_sws[] = { | ||
1848 | "Front Playback Switch", | ||
1849 | "Surround Playback Switch", | ||
1850 | "Center Playback Switch", | ||
1851 | "LFE Playback Switch", | ||
1852 | "Side Playback Switch", | ||
1853 | "Headphone Playback Switch", | ||
1854 | "Speaker Playback Switch", | ||
1855 | "Mono Playback Switch", | ||
1856 | "IEC958 Playback Switch", | ||
1857 | "Line-Out Playback Switch", | ||
1858 | "PCM Playback Switch", | ||
1859 | NULL, | 1863 | NULL, |
1860 | }; | 1864 | }; |
1861 | 1865 | ||
@@ -1883,7 +1887,7 @@ static const struct snd_kcontrol_new alc_beep_mixer[] = { | |||
1883 | }; | 1887 | }; |
1884 | #endif | 1888 | #endif |
1885 | 1889 | ||
1886 | static int alc_build_controls(struct hda_codec *codec) | 1890 | static int __alc_build_controls(struct hda_codec *codec) |
1887 | { | 1891 | { |
1888 | struct alc_spec *spec = codec->spec; | 1892 | struct alc_spec *spec = codec->spec; |
1889 | struct snd_kcontrol *kctl = NULL; | 1893 | struct snd_kcontrol *kctl = NULL; |
@@ -1946,14 +1950,17 @@ static int alc_build_controls(struct hda_codec *codec) | |||
1946 | snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, | 1950 | snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, |
1947 | HDA_OUTPUT, vmaster_tlv); | 1951 | HDA_OUTPUT, vmaster_tlv); |
1948 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | 1952 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", |
1949 | vmaster_tlv, alc_slave_vols); | 1953 | vmaster_tlv, alc_slave_pfxs, |
1954 | "Playback Volume"); | ||
1950 | if (err < 0) | 1955 | if (err < 0) |
1951 | return err; | 1956 | return err; |
1952 | } | 1957 | } |
1953 | if (!spec->no_analog && | 1958 | if (!spec->no_analog && |
1954 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | 1959 | !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { |
1955 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", | 1960 | err = __snd_hda_add_vmaster(codec, "Master Playback Switch", |
1956 | NULL, alc_slave_sws); | 1961 | NULL, alc_slave_pfxs, |
1962 | "Playback Switch", | ||
1963 | true, &spec->vmaster_mute.sw_kctl); | ||
1957 | if (err < 0) | 1964 | if (err < 0) |
1958 | return err; | 1965 | return err; |
1959 | } | 1966 | } |
@@ -2029,10 +2036,19 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2029 | 2036 | ||
2030 | alc_free_kctls(codec); /* no longer needed */ | 2037 | alc_free_kctls(codec); /* no longer needed */ |
2031 | 2038 | ||
2039 | return 0; | ||
2040 | } | ||
2041 | |||
2042 | static int alc_build_controls(struct hda_codec *codec) | ||
2043 | { | ||
2044 | struct alc_spec *spec = codec->spec; | ||
2045 | int err = __alc_build_controls(codec); | ||
2046 | if (err < 0) | ||
2047 | return err; | ||
2032 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | 2048 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); |
2033 | if (err < 0) | 2049 | if (err < 0) |
2034 | return err; | 2050 | return err; |
2035 | 2051 | alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD); | |
2036 | return 0; | 2052 | return 0; |
2037 | } | 2053 | } |
2038 | 2054 | ||
@@ -2042,21 +2058,23 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2042 | */ | 2058 | */ |
2043 | 2059 | ||
2044 | static void alc_init_special_input_src(struct hda_codec *codec); | 2060 | static void alc_init_special_input_src(struct hda_codec *codec); |
2061 | static void alc_auto_init_std(struct hda_codec *codec); | ||
2045 | 2062 | ||
2046 | static int alc_init(struct hda_codec *codec) | 2063 | static int alc_init(struct hda_codec *codec) |
2047 | { | 2064 | { |
2048 | struct alc_spec *spec = codec->spec; | 2065 | struct alc_spec *spec = codec->spec; |
2049 | unsigned int i; | 2066 | unsigned int i; |
2050 | 2067 | ||
2068 | if (spec->init_hook) | ||
2069 | spec->init_hook(codec); | ||
2070 | |||
2051 | alc_fix_pll(codec); | 2071 | alc_fix_pll(codec); |
2052 | alc_auto_init_amp(codec, spec->init_amp); | 2072 | alc_auto_init_amp(codec, spec->init_amp); |
2053 | 2073 | ||
2054 | for (i = 0; i < spec->num_init_verbs; i++) | 2074 | for (i = 0; i < spec->num_init_verbs; i++) |
2055 | snd_hda_sequence_write(codec, spec->init_verbs[i]); | 2075 | snd_hda_sequence_write(codec, spec->init_verbs[i]); |
2056 | alc_init_special_input_src(codec); | 2076 | alc_init_special_input_src(codec); |
2057 | 2077 | alc_auto_init_std(codec); | |
2058 | if (spec->init_hook) | ||
2059 | spec->init_hook(codec); | ||
2060 | 2078 | ||
2061 | alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); | 2079 | alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT); |
2062 | 2080 | ||
@@ -2298,7 +2316,7 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
2298 | "%s Analog", codec->chip_name); | 2316 | "%s Analog", codec->chip_name); |
2299 | info->name = spec->stream_name_analog; | 2317 | info->name = spec->stream_name_analog; |
2300 | 2318 | ||
2301 | if (spec->multiout.dac_nids > 0) { | 2319 | if (spec->multiout.num_dacs > 0) { |
2302 | p = spec->stream_analog_playback; | 2320 | p = spec->stream_analog_playback; |
2303 | if (!p) | 2321 | if (!p) |
2304 | p = &alc_pcm_analog_playback; | 2322 | p = &alc_pcm_analog_playback; |
@@ -2645,6 +2663,25 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, | |||
2645 | return channel_name[ch]; | 2663 | return channel_name[ch]; |
2646 | } | 2664 | } |
2647 | 2665 | ||
2666 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
2667 | /* add the powersave loopback-list entry */ | ||
2668 | static void add_loopback_list(struct alc_spec *spec, hda_nid_t mix, int idx) | ||
2669 | { | ||
2670 | struct hda_amp_list *list; | ||
2671 | |||
2672 | if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1) | ||
2673 | return; | ||
2674 | list = spec->loopback_list + spec->num_loopbacks; | ||
2675 | list->nid = mix; | ||
2676 | list->dir = HDA_INPUT; | ||
2677 | list->idx = idx; | ||
2678 | spec->num_loopbacks++; | ||
2679 | spec->loopback.amplist = spec->loopback_list; | ||
2680 | } | ||
2681 | #else | ||
2682 | #define add_loopback_list(spec, mix, idx) /* NOP */ | ||
2683 | #endif | ||
2684 | |||
2648 | /* create input playback/capture controls for the given pin */ | 2685 | /* create input playback/capture controls for the given pin */ |
2649 | static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, | 2686 | static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, |
2650 | const char *ctlname, int ctlidx, | 2687 | const char *ctlname, int ctlidx, |
@@ -2660,6 +2697,7 @@ static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, | |||
2660 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); | 2697 | HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); |
2661 | if (err < 0) | 2698 | if (err < 0) |
2662 | return err; | 2699 | return err; |
2700 | add_loopback_list(spec, mix_nid, idx); | ||
2663 | return 0; | 2701 | return 0; |
2664 | } | 2702 | } |
2665 | 2703 | ||
@@ -2924,10 +2962,27 @@ static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin, | |||
2924 | return 0; | 2962 | return 0; |
2925 | } | 2963 | } |
2926 | 2964 | ||
2965 | static bool alc_is_dac_already_used(struct hda_codec *codec, hda_nid_t nid) | ||
2966 | { | ||
2967 | struct alc_spec *spec = codec->spec; | ||
2968 | int i; | ||
2969 | if (found_in_nid_list(nid, spec->multiout.dac_nids, | ||
2970 | ARRAY_SIZE(spec->private_dac_nids)) || | ||
2971 | found_in_nid_list(nid, spec->multiout.hp_out_nid, | ||
2972 | ARRAY_SIZE(spec->multiout.hp_out_nid)) || | ||
2973 | found_in_nid_list(nid, spec->multiout.extra_out_nid, | ||
2974 | ARRAY_SIZE(spec->multiout.extra_out_nid))) | ||
2975 | return true; | ||
2976 | for (i = 0; i < spec->multi_ios; i++) { | ||
2977 | if (spec->multi_io[i].dac == nid) | ||
2978 | return true; | ||
2979 | } | ||
2980 | return false; | ||
2981 | } | ||
2982 | |||
2927 | /* look for an empty DAC slot */ | 2983 | /* look for an empty DAC slot */ |
2928 | static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) | 2984 | static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) |
2929 | { | 2985 | { |
2930 | struct alc_spec *spec = codec->spec; | ||
2931 | hda_nid_t srcs[5]; | 2986 | hda_nid_t srcs[5]; |
2932 | int i, num; | 2987 | int i, num; |
2933 | 2988 | ||
@@ -2937,16 +2992,8 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) | |||
2937 | hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]); | 2992 | hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]); |
2938 | if (!nid) | 2993 | if (!nid) |
2939 | continue; | 2994 | continue; |
2940 | if (found_in_nid_list(nid, spec->multiout.dac_nids, | 2995 | if (!alc_is_dac_already_used(codec, nid)) |
2941 | ARRAY_SIZE(spec->private_dac_nids))) | 2996 | return nid; |
2942 | continue; | ||
2943 | if (found_in_nid_list(nid, spec->multiout.hp_out_nid, | ||
2944 | ARRAY_SIZE(spec->multiout.hp_out_nid))) | ||
2945 | continue; | ||
2946 | if (found_in_nid_list(nid, spec->multiout.extra_out_nid, | ||
2947 | ARRAY_SIZE(spec->multiout.extra_out_nid))) | ||
2948 | continue; | ||
2949 | return nid; | ||
2950 | } | 2997 | } |
2951 | return 0; | 2998 | return 0; |
2952 | } | 2999 | } |
@@ -2958,6 +3005,8 @@ static bool alc_auto_is_dac_reachable(struct hda_codec *codec, | |||
2958 | hda_nid_t srcs[5]; | 3005 | hda_nid_t srcs[5]; |
2959 | int i, num; | 3006 | int i, num; |
2960 | 3007 | ||
3008 | if (!pin || !dac) | ||
3009 | return false; | ||
2961 | pin = alc_go_down_to_selector(codec, pin); | 3010 | pin = alc_go_down_to_selector(codec, pin); |
2962 | num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); | 3011 | num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); |
2963 | for (i = 0; i < num; i++) { | 3012 | for (i = 0; i < num; i++) { |
@@ -2970,83 +3019,260 @@ static bool alc_auto_is_dac_reachable(struct hda_codec *codec, | |||
2970 | 3019 | ||
2971 | static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) | 3020 | static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) |
2972 | { | 3021 | { |
3022 | struct alc_spec *spec = codec->spec; | ||
2973 | hda_nid_t sel = alc_go_down_to_selector(codec, pin); | 3023 | hda_nid_t sel = alc_go_down_to_selector(codec, pin); |
2974 | if (snd_hda_get_conn_list(codec, sel, NULL) == 1) | 3024 | hda_nid_t nid, nid_found, srcs[5]; |
3025 | int i, num = snd_hda_get_connections(codec, sel, srcs, | ||
3026 | ARRAY_SIZE(srcs)); | ||
3027 | if (num == 1) | ||
2975 | return alc_auto_look_for_dac(codec, pin); | 3028 | return alc_auto_look_for_dac(codec, pin); |
2976 | return 0; | 3029 | nid_found = 0; |
3030 | for (i = 0; i < num; i++) { | ||
3031 | if (srcs[i] == spec->mixer_nid) | ||
3032 | continue; | ||
3033 | nid = alc_auto_mix_to_dac(codec, srcs[i]); | ||
3034 | if (nid && !alc_is_dac_already_used(codec, nid)) { | ||
3035 | if (nid_found) | ||
3036 | return 0; | ||
3037 | nid_found = nid; | ||
3038 | } | ||
3039 | } | ||
3040 | return nid_found; | ||
2977 | } | 3041 | } |
2978 | 3042 | ||
2979 | /* return 0 if no possible DAC is found, 1 if one or more found */ | 3043 | /* mark up volume and mute control NIDs: used during badness parsing and |
2980 | static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, | 3044 | * at creating actual controls |
2981 | const hda_nid_t *pins, hda_nid_t *dacs) | 3045 | */ |
3046 | static inline unsigned int get_ctl_pos(unsigned int data) | ||
2982 | { | 3047 | { |
2983 | int i; | 3048 | hda_nid_t nid = get_amp_nid_(data); |
3049 | unsigned int dir; | ||
3050 | if (snd_BUG_ON(nid >= MAX_VOL_NIDS)) | ||
3051 | return 0; | ||
3052 | dir = get_amp_direction_(data); | ||
3053 | return (nid << 1) | dir; | ||
3054 | } | ||
2984 | 3055 | ||
2985 | if (num_outs && !dacs[0]) { | 3056 | #define is_ctl_used(bits, data) \ |
2986 | dacs[0] = alc_auto_look_for_dac(codec, pins[0]); | 3057 | test_bit(get_ctl_pos(data), bits) |
2987 | if (!dacs[0]) | 3058 | #define mark_ctl_usage(bits, data) \ |
2988 | return 0; | 3059 | set_bit(get_ctl_pos(data), bits) |
2989 | } | ||
2990 | 3060 | ||
2991 | for (i = 1; i < num_outs; i++) | 3061 | static void clear_vol_marks(struct hda_codec *codec) |
2992 | dacs[i] = get_dac_if_single(codec, pins[i]); | 3062 | { |
2993 | for (i = 1; i < num_outs; i++) { | 3063 | struct alc_spec *spec = codec->spec; |
3064 | memset(spec->vol_ctls, 0, sizeof(spec->vol_ctls)); | ||
3065 | memset(spec->sw_ctls, 0, sizeof(spec->sw_ctls)); | ||
3066 | } | ||
3067 | |||
3068 | /* badness definition */ | ||
3069 | enum { | ||
3070 | /* No primary DAC is found for the main output */ | ||
3071 | BAD_NO_PRIMARY_DAC = 0x10000, | ||
3072 | /* No DAC is found for the extra output */ | ||
3073 | BAD_NO_DAC = 0x4000, | ||
3074 | /* No possible multi-ios */ | ||
3075 | BAD_MULTI_IO = 0x103, | ||
3076 | /* No individual DAC for extra output */ | ||
3077 | BAD_NO_EXTRA_DAC = 0x102, | ||
3078 | /* No individual DAC for extra surrounds */ | ||
3079 | BAD_NO_EXTRA_SURR_DAC = 0x101, | ||
3080 | /* Primary DAC shared with main surrounds */ | ||
3081 | BAD_SHARED_SURROUND = 0x100, | ||
3082 | /* Primary DAC shared with main CLFE */ | ||
3083 | BAD_SHARED_CLFE = 0x10, | ||
3084 | /* Primary DAC shared with extra surrounds */ | ||
3085 | BAD_SHARED_EXTRA_SURROUND = 0x10, | ||
3086 | /* Volume widget is shared */ | ||
3087 | BAD_SHARED_VOL = 0x10, | ||
3088 | }; | ||
3089 | |||
3090 | static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec, | ||
3091 | hda_nid_t pin, hda_nid_t dac); | ||
3092 | static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec, | ||
3093 | hda_nid_t pin, hda_nid_t dac); | ||
3094 | |||
3095 | static int eval_shared_vol_badness(struct hda_codec *codec, hda_nid_t pin, | ||
3096 | hda_nid_t dac) | ||
3097 | { | ||
3098 | struct alc_spec *spec = codec->spec; | ||
3099 | hda_nid_t nid; | ||
3100 | unsigned int val; | ||
3101 | int badness = 0; | ||
3102 | |||
3103 | nid = alc_look_for_out_vol_nid(codec, pin, dac); | ||
3104 | if (nid) { | ||
3105 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | ||
3106 | if (is_ctl_used(spec->vol_ctls, nid)) | ||
3107 | badness += BAD_SHARED_VOL; | ||
3108 | else | ||
3109 | mark_ctl_usage(spec->vol_ctls, val); | ||
3110 | } else | ||
3111 | badness += BAD_SHARED_VOL; | ||
3112 | nid = alc_look_for_out_mute_nid(codec, pin, dac); | ||
3113 | if (nid) { | ||
3114 | unsigned int wid_type = get_wcaps_type(get_wcaps(codec, nid)); | ||
3115 | if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT) | ||
3116 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); | ||
3117 | else | ||
3118 | val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT); | ||
3119 | if (is_ctl_used(spec->sw_ctls, val)) | ||
3120 | badness += BAD_SHARED_VOL; | ||
3121 | else | ||
3122 | mark_ctl_usage(spec->sw_ctls, val); | ||
3123 | } else | ||
3124 | badness += BAD_SHARED_VOL; | ||
3125 | return badness; | ||
3126 | } | ||
3127 | |||
3128 | struct badness_table { | ||
3129 | int no_primary_dac; /* no primary DAC */ | ||
3130 | int no_dac; /* no secondary DACs */ | ||
3131 | int shared_primary; /* primary DAC is shared with main output */ | ||
3132 | int shared_surr; /* secondary DAC shared with main or primary */ | ||
3133 | int shared_clfe; /* third DAC shared with main or primary */ | ||
3134 | int shared_surr_main; /* secondary DAC sahred with main/DAC0 */ | ||
3135 | }; | ||
3136 | |||
3137 | static struct badness_table main_out_badness = { | ||
3138 | .no_primary_dac = BAD_NO_PRIMARY_DAC, | ||
3139 | .no_dac = BAD_NO_DAC, | ||
3140 | .shared_primary = BAD_NO_PRIMARY_DAC, | ||
3141 | .shared_surr = BAD_SHARED_SURROUND, | ||
3142 | .shared_clfe = BAD_SHARED_CLFE, | ||
3143 | .shared_surr_main = BAD_SHARED_SURROUND, | ||
3144 | }; | ||
3145 | |||
3146 | static struct badness_table extra_out_badness = { | ||
3147 | .no_primary_dac = BAD_NO_DAC, | ||
3148 | .no_dac = BAD_NO_DAC, | ||
3149 | .shared_primary = BAD_NO_EXTRA_DAC, | ||
3150 | .shared_surr = BAD_SHARED_EXTRA_SURROUND, | ||
3151 | .shared_clfe = BAD_SHARED_EXTRA_SURROUND, | ||
3152 | .shared_surr_main = BAD_NO_EXTRA_SURR_DAC, | ||
3153 | }; | ||
3154 | |||
3155 | /* try to assign DACs to pins and return the resultant badness */ | ||
3156 | static int alc_auto_fill_dacs(struct hda_codec *codec, int num_outs, | ||
3157 | const hda_nid_t *pins, hda_nid_t *dacs, | ||
3158 | const struct badness_table *bad) | ||
3159 | { | ||
3160 | struct alc_spec *spec = codec->spec; | ||
3161 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3162 | int i, j; | ||
3163 | int badness = 0; | ||
3164 | hda_nid_t dac; | ||
3165 | |||
3166 | if (!num_outs) | ||
3167 | return 0; | ||
3168 | |||
3169 | for (i = 0; i < num_outs; i++) { | ||
3170 | hda_nid_t pin = pins[i]; | ||
2994 | if (!dacs[i]) | 3171 | if (!dacs[i]) |
2995 | dacs[i] = alc_auto_look_for_dac(codec, pins[i]); | 3172 | dacs[i] = alc_auto_look_for_dac(codec, pin); |
3173 | if (!dacs[i] && !i) { | ||
3174 | for (j = 1; j < num_outs; j++) { | ||
3175 | if (alc_auto_is_dac_reachable(codec, pin, dacs[j])) { | ||
3176 | dacs[0] = dacs[j]; | ||
3177 | dacs[j] = 0; | ||
3178 | break; | ||
3179 | } | ||
3180 | } | ||
3181 | } | ||
3182 | dac = dacs[i]; | ||
3183 | if (!dac) { | ||
3184 | if (alc_auto_is_dac_reachable(codec, pin, dacs[0])) | ||
3185 | dac = dacs[0]; | ||
3186 | else if (cfg->line_outs > i && | ||
3187 | alc_auto_is_dac_reachable(codec, pin, | ||
3188 | spec->private_dac_nids[i])) | ||
3189 | dac = spec->private_dac_nids[i]; | ||
3190 | if (dac) { | ||
3191 | if (!i) | ||
3192 | badness += bad->shared_primary; | ||
3193 | else if (i == 1) | ||
3194 | badness += bad->shared_surr; | ||
3195 | else | ||
3196 | badness += bad->shared_clfe; | ||
3197 | } else if (alc_auto_is_dac_reachable(codec, pin, | ||
3198 | spec->private_dac_nids[0])) { | ||
3199 | dac = spec->private_dac_nids[0]; | ||
3200 | badness += bad->shared_surr_main; | ||
3201 | } else if (!i) | ||
3202 | badness += bad->no_primary_dac; | ||
3203 | else | ||
3204 | badness += bad->no_dac; | ||
3205 | } | ||
3206 | if (dac) | ||
3207 | badness += eval_shared_vol_badness(codec, pin, dac); | ||
2996 | } | 3208 | } |
2997 | return 1; | 3209 | |
3210 | return badness; | ||
2998 | } | 3211 | } |
2999 | 3212 | ||
3000 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, | 3213 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, |
3001 | unsigned int location, int offset); | 3214 | hda_nid_t reference_pin, |
3002 | static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec, | 3215 | bool hardwired, int offset); |
3003 | hda_nid_t pin, hda_nid_t dac); | 3216 | |
3217 | static bool alc_map_singles(struct hda_codec *codec, int outs, | ||
3218 | const hda_nid_t *pins, hda_nid_t *dacs) | ||
3219 | { | ||
3220 | int i; | ||
3221 | bool found = false; | ||
3222 | for (i = 0; i < outs; i++) { | ||
3223 | if (dacs[i]) | ||
3224 | continue; | ||
3225 | dacs[i] = get_dac_if_single(codec, pins[i]); | ||
3226 | if (dacs[i]) | ||
3227 | found = true; | ||
3228 | } | ||
3229 | return found; | ||
3230 | } | ||
3004 | 3231 | ||
3005 | /* fill in the dac_nids table from the parsed pin configuration */ | 3232 | /* fill in the dac_nids table from the parsed pin configuration */ |
3006 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) | 3233 | static int fill_and_eval_dacs(struct hda_codec *codec, |
3234 | bool fill_hardwired, | ||
3235 | bool fill_mio_first) | ||
3007 | { | 3236 | { |
3008 | struct alc_spec *spec = codec->spec; | 3237 | struct alc_spec *spec = codec->spec; |
3009 | struct auto_pin_cfg *cfg = &spec->autocfg; | 3238 | struct auto_pin_cfg *cfg = &spec->autocfg; |
3010 | unsigned int location, defcfg; | 3239 | int i, err, badness; |
3011 | int num_pins; | ||
3012 | bool redone = false; | ||
3013 | int i; | ||
3014 | 3240 | ||
3015 | again: | ||
3016 | /* set num_dacs once to full for alc_auto_look_for_dac() */ | 3241 | /* set num_dacs once to full for alc_auto_look_for_dac() */ |
3017 | spec->multiout.num_dacs = cfg->line_outs; | 3242 | spec->multiout.num_dacs = cfg->line_outs; |
3018 | spec->multiout.hp_out_nid[0] = 0; | ||
3019 | spec->multiout.extra_out_nid[0] = 0; | ||
3020 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); | ||
3021 | spec->multiout.dac_nids = spec->private_dac_nids; | 3243 | spec->multiout.dac_nids = spec->private_dac_nids; |
3244 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); | ||
3245 | memset(spec->multiout.hp_out_nid, 0, sizeof(spec->multiout.hp_out_nid)); | ||
3246 | memset(spec->multiout.extra_out_nid, 0, sizeof(spec->multiout.extra_out_nid)); | ||
3022 | spec->multi_ios = 0; | 3247 | spec->multi_ios = 0; |
3248 | clear_vol_marks(codec); | ||
3249 | badness = 0; | ||
3023 | 3250 | ||
3024 | /* fill hard-wired DACs first */ | 3251 | /* fill hard-wired DACs first */ |
3025 | if (!redone) { | 3252 | if (fill_hardwired) { |
3026 | for (i = 0; i < cfg->line_outs; i++) | 3253 | bool mapped; |
3027 | spec->private_dac_nids[i] = | 3254 | do { |
3028 | get_dac_if_single(codec, cfg->line_out_pins[i]); | 3255 | mapped = alc_map_singles(codec, cfg->line_outs, |
3029 | if (cfg->hp_outs) | 3256 | cfg->line_out_pins, |
3030 | spec->multiout.hp_out_nid[0] = | 3257 | spec->private_dac_nids); |
3031 | get_dac_if_single(codec, cfg->hp_pins[0]); | 3258 | mapped |= alc_map_singles(codec, cfg->hp_outs, |
3032 | if (cfg->speaker_outs) | 3259 | cfg->hp_pins, |
3033 | spec->multiout.extra_out_nid[0] = | 3260 | spec->multiout.hp_out_nid); |
3034 | get_dac_if_single(codec, cfg->speaker_pins[0]); | 3261 | mapped |= alc_map_singles(codec, cfg->speaker_outs, |
3262 | cfg->speaker_pins, | ||
3263 | spec->multiout.extra_out_nid); | ||
3264 | if (fill_mio_first && cfg->line_outs == 1 && | ||
3265 | cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | ||
3266 | err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], true, 0); | ||
3267 | if (!err) | ||
3268 | mapped = true; | ||
3269 | } | ||
3270 | } while (mapped); | ||
3035 | } | 3271 | } |
3036 | 3272 | ||
3037 | for (i = 0; i < cfg->line_outs; i++) { | 3273 | badness += alc_auto_fill_dacs(codec, cfg->line_outs, cfg->line_out_pins, |
3038 | hda_nid_t pin = cfg->line_out_pins[i]; | 3274 | spec->private_dac_nids, |
3039 | if (spec->private_dac_nids[i]) | 3275 | &main_out_badness); |
3040 | continue; | ||
3041 | spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin); | ||
3042 | if (!spec->private_dac_nids[i] && !redone) { | ||
3043 | /* if we can't find primary DACs, re-probe without | ||
3044 | * checking the hard-wired DACs | ||
3045 | */ | ||
3046 | redone = true; | ||
3047 | goto again; | ||
3048 | } | ||
3049 | } | ||
3050 | 3276 | ||
3051 | /* re-count num_dacs and squash invalid entries */ | 3277 | /* re-count num_dacs and squash invalid entries */ |
3052 | spec->multiout.num_dacs = 0; | 3278 | spec->multiout.num_dacs = 0; |
@@ -3061,30 +3287,144 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
3061 | } | 3287 | } |
3062 | } | 3288 | } |
3063 | 3289 | ||
3064 | if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | 3290 | if (fill_mio_first && |
3291 | cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | ||
3065 | /* try to fill multi-io first */ | 3292 | /* try to fill multi-io first */ |
3066 | defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]); | 3293 | err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0); |
3067 | location = get_defcfg_location(defcfg); | 3294 | if (err < 0) |
3068 | 3295 | return err; | |
3069 | num_pins = alc_auto_fill_multi_ios(codec, location, 0); | 3296 | /* we don't count badness at this stage yet */ |
3070 | if (num_pins > 0) { | ||
3071 | spec->multi_ios = num_pins; | ||
3072 | spec->ext_channel_count = 2; | ||
3073 | spec->multiout.num_dacs = num_pins + 1; | ||
3074 | } | ||
3075 | } | 3297 | } |
3076 | 3298 | ||
3077 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) | 3299 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) { |
3078 | alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, | 3300 | err = alc_auto_fill_dacs(codec, cfg->hp_outs, cfg->hp_pins, |
3079 | spec->multiout.hp_out_nid); | 3301 | spec->multiout.hp_out_nid, |
3302 | &extra_out_badness); | ||
3303 | if (err < 0) | ||
3304 | return err; | ||
3305 | badness += err; | ||
3306 | } | ||
3080 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | 3307 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
3081 | int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, | 3308 | err = alc_auto_fill_dacs(codec, cfg->speaker_outs, |
3082 | cfg->speaker_pins, | 3309 | cfg->speaker_pins, |
3083 | spec->multiout.extra_out_nid); | 3310 | spec->multiout.extra_out_nid, |
3084 | /* if no speaker volume is assigned, try again as the primary | 3311 | &extra_out_badness); |
3085 | * output | 3312 | if (err < 0) |
3086 | */ | 3313 | return err; |
3087 | if (!err && cfg->speaker_outs > 0 && | 3314 | badness += err; |
3315 | } | ||
3316 | if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | ||
3317 | err = alc_auto_fill_multi_ios(codec, cfg->line_out_pins[0], false, 0); | ||
3318 | if (err < 0) | ||
3319 | return err; | ||
3320 | badness += err; | ||
3321 | } | ||
3322 | if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { | ||
3323 | /* try multi-ios with HP + inputs */ | ||
3324 | int offset = 0; | ||
3325 | if (cfg->line_outs >= 3) | ||
3326 | offset = 1; | ||
3327 | err = alc_auto_fill_multi_ios(codec, cfg->hp_pins[0], false, | ||
3328 | offset); | ||
3329 | if (err < 0) | ||
3330 | return err; | ||
3331 | badness += err; | ||
3332 | } | ||
3333 | |||
3334 | if (spec->multi_ios == 2) { | ||
3335 | for (i = 0; i < 2; i++) | ||
3336 | spec->private_dac_nids[spec->multiout.num_dacs++] = | ||
3337 | spec->multi_io[i].dac; | ||
3338 | spec->ext_channel_count = 2; | ||
3339 | } else if (spec->multi_ios) { | ||
3340 | spec->multi_ios = 0; | ||
3341 | badness += BAD_MULTI_IO; | ||
3342 | } | ||
3343 | |||
3344 | return badness; | ||
3345 | } | ||
3346 | |||
3347 | #define DEBUG_BADNESS | ||
3348 | |||
3349 | #ifdef DEBUG_BADNESS | ||
3350 | #define debug_badness snd_printdd | ||
3351 | #else | ||
3352 | #define debug_badness(...) | ||
3353 | #endif | ||
3354 | |||
3355 | static void debug_show_configs(struct alc_spec *spec, struct auto_pin_cfg *cfg) | ||
3356 | { | ||
3357 | debug_badness("multi_outs = %x/%x/%x/%x : %x/%x/%x/%x\n", | ||
3358 | cfg->line_out_pins[0], cfg->line_out_pins[1], | ||
3359 | cfg->line_out_pins[2], cfg->line_out_pins[2], | ||
3360 | spec->multiout.dac_nids[0], | ||
3361 | spec->multiout.dac_nids[1], | ||
3362 | spec->multiout.dac_nids[2], | ||
3363 | spec->multiout.dac_nids[3]); | ||
3364 | if (spec->multi_ios > 0) | ||
3365 | debug_badness("multi_ios(%d) = %x/%x : %x/%x\n", | ||
3366 | spec->multi_ios, | ||
3367 | spec->multi_io[0].pin, spec->multi_io[1].pin, | ||
3368 | spec->multi_io[0].dac, spec->multi_io[1].dac); | ||
3369 | debug_badness("hp_outs = %x/%x/%x/%x : %x/%x/%x/%x\n", | ||
3370 | cfg->hp_pins[0], cfg->hp_pins[1], | ||
3371 | cfg->hp_pins[2], cfg->hp_pins[2], | ||
3372 | spec->multiout.hp_out_nid[0], | ||
3373 | spec->multiout.hp_out_nid[1], | ||
3374 | spec->multiout.hp_out_nid[2], | ||
3375 | spec->multiout.hp_out_nid[3]); | ||
3376 | debug_badness("spk_outs = %x/%x/%x/%x : %x/%x/%x/%x\n", | ||
3377 | cfg->speaker_pins[0], cfg->speaker_pins[1], | ||
3378 | cfg->speaker_pins[2], cfg->speaker_pins[3], | ||
3379 | spec->multiout.extra_out_nid[0], | ||
3380 | spec->multiout.extra_out_nid[1], | ||
3381 | spec->multiout.extra_out_nid[2], | ||
3382 | spec->multiout.extra_out_nid[3]); | ||
3383 | } | ||
3384 | |||
3385 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) | ||
3386 | { | ||
3387 | struct alc_spec *spec = codec->spec; | ||
3388 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3389 | struct auto_pin_cfg *best_cfg; | ||
3390 | int best_badness = INT_MAX; | ||
3391 | int badness; | ||
3392 | bool fill_hardwired = true, fill_mio_first = true; | ||
3393 | bool best_wired = true, best_mio = true; | ||
3394 | bool hp_spk_swapped = false; | ||
3395 | |||
3396 | best_cfg = kmalloc(sizeof(*best_cfg), GFP_KERNEL); | ||
3397 | if (!best_cfg) | ||
3398 | return -ENOMEM; | ||
3399 | *best_cfg = *cfg; | ||
3400 | |||
3401 | for (;;) { | ||
3402 | badness = fill_and_eval_dacs(codec, fill_hardwired, | ||
3403 | fill_mio_first); | ||
3404 | if (badness < 0) | ||
3405 | return badness; | ||
3406 | debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n", | ||
3407 | cfg->line_out_type, fill_hardwired, fill_mio_first, | ||
3408 | badness); | ||
3409 | debug_show_configs(spec, cfg); | ||
3410 | if (badness < best_badness) { | ||
3411 | best_badness = badness; | ||
3412 | *best_cfg = *cfg; | ||
3413 | best_wired = fill_hardwired; | ||
3414 | best_mio = fill_mio_first; | ||
3415 | } | ||
3416 | if (!badness) | ||
3417 | break; | ||
3418 | fill_mio_first = !fill_mio_first; | ||
3419 | if (!fill_mio_first) | ||
3420 | continue; | ||
3421 | fill_hardwired = !fill_hardwired; | ||
3422 | if (!fill_hardwired) | ||
3423 | continue; | ||
3424 | if (hp_spk_swapped) | ||
3425 | break; | ||
3426 | hp_spk_swapped = true; | ||
3427 | if (cfg->speaker_outs > 0 && | ||
3088 | cfg->line_out_type == AUTO_PIN_HP_OUT) { | 3428 | cfg->line_out_type == AUTO_PIN_HP_OUT) { |
3089 | cfg->hp_outs = cfg->line_outs; | 3429 | cfg->hp_outs = cfg->line_outs; |
3090 | memcpy(cfg->hp_pins, cfg->line_out_pins, | 3430 | memcpy(cfg->hp_pins, cfg->line_out_pins, |
@@ -3095,45 +3435,45 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
3095 | cfg->speaker_outs = 0; | 3435 | cfg->speaker_outs = 0; |
3096 | memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); | 3436 | memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); |
3097 | cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; | 3437 | cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; |
3098 | redone = false; | 3438 | fill_hardwired = true; |
3099 | goto again; | 3439 | continue; |
3100 | } | 3440 | } |
3441 | if (cfg->hp_outs > 0 && | ||
3442 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { | ||
3443 | cfg->speaker_outs = cfg->line_outs; | ||
3444 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | ||
3445 | sizeof(cfg->speaker_pins)); | ||
3446 | cfg->line_outs = cfg->hp_outs; | ||
3447 | memcpy(cfg->line_out_pins, cfg->hp_pins, | ||
3448 | sizeof(cfg->hp_pins)); | ||
3449 | cfg->hp_outs = 0; | ||
3450 | memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); | ||
3451 | cfg->line_out_type = AUTO_PIN_HP_OUT; | ||
3452 | fill_hardwired = true; | ||
3453 | continue; | ||
3454 | } | ||
3455 | break; | ||
3101 | } | 3456 | } |
3102 | 3457 | ||
3103 | if (!spec->multi_ios && | 3458 | if (badness) { |
3104 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && | 3459 | *cfg = *best_cfg; |
3105 | cfg->hp_outs) { | 3460 | fill_and_eval_dacs(codec, best_wired, best_mio); |
3106 | /* try multi-ios with HP + inputs */ | ||
3107 | defcfg = snd_hda_codec_get_pincfg(codec, cfg->hp_pins[0]); | ||
3108 | location = get_defcfg_location(defcfg); | ||
3109 | |||
3110 | num_pins = alc_auto_fill_multi_ios(codec, location, 1); | ||
3111 | if (num_pins > 0) { | ||
3112 | spec->multi_ios = num_pins; | ||
3113 | spec->ext_channel_count = 2; | ||
3114 | spec->multiout.num_dacs = num_pins + 1; | ||
3115 | } | ||
3116 | } | 3461 | } |
3462 | debug_badness("==> Best config: lo_type=%d, wired=%d, mio=%d\n", | ||
3463 | cfg->line_out_type, best_wired, best_mio); | ||
3464 | debug_show_configs(spec, cfg); | ||
3117 | 3465 | ||
3118 | if (cfg->line_out_pins[0]) | 3466 | if (cfg->line_out_pins[0]) |
3119 | spec->vmaster_nid = | 3467 | spec->vmaster_nid = |
3120 | alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0], | 3468 | alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0], |
3121 | spec->multiout.dac_nids[0]); | 3469 | spec->multiout.dac_nids[0]); |
3122 | return 0; | ||
3123 | } | ||
3124 | 3470 | ||
3125 | static inline unsigned int get_ctl_pos(unsigned int data) | 3471 | /* clear the bitmap flags for creating controls */ |
3126 | { | 3472 | clear_vol_marks(codec); |
3127 | hda_nid_t nid = get_amp_nid_(data); | 3473 | kfree(best_cfg); |
3128 | unsigned int dir = get_amp_direction_(data); | 3474 | return 0; |
3129 | return (nid << 1) | dir; | ||
3130 | } | 3475 | } |
3131 | 3476 | ||
3132 | #define is_ctl_used(bits, data) \ | ||
3133 | test_bit(get_ctl_pos(data), bits) | ||
3134 | #define mark_ctl_usage(bits, data) \ | ||
3135 | set_bit(get_ctl_pos(data), bits) | ||
3136 | |||
3137 | static int alc_auto_add_vol_ctl(struct hda_codec *codec, | 3477 | static int alc_auto_add_vol_ctl(struct hda_codec *codec, |
3138 | const char *pfx, int cidx, | 3478 | const char *pfx, int cidx, |
3139 | hda_nid_t nid, unsigned int chs) | 3479 | hda_nid_t nid, unsigned int chs) |
@@ -3233,7 +3573,7 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3233 | int i, err, noutputs; | 3573 | int i, err, noutputs; |
3234 | 3574 | ||
3235 | noutputs = cfg->line_outs; | 3575 | noutputs = cfg->line_outs; |
3236 | if (spec->multi_ios > 0) | 3576 | if (spec->multi_ios > 0 && cfg->line_outs < 3) |
3237 | noutputs += spec->multi_ios; | 3577 | noutputs += spec->multi_ios; |
3238 | 3578 | ||
3239 | for (i = 0; i < noutputs; i++) { | 3579 | for (i = 0; i < noutputs; i++) { |
@@ -3245,14 +3585,17 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3245 | dac = spec->multiout.dac_nids[i]; | 3585 | dac = spec->multiout.dac_nids[i]; |
3246 | if (!dac) | 3586 | if (!dac) |
3247 | continue; | 3587 | continue; |
3248 | if (i >= cfg->line_outs) | 3588 | if (i >= cfg->line_outs) { |
3249 | pin = spec->multi_io[i - 1].pin; | 3589 | pin = spec->multi_io[i - 1].pin; |
3250 | else | 3590 | index = 0; |
3591 | name = channel_name[i]; | ||
3592 | } else { | ||
3251 | pin = cfg->line_out_pins[i]; | 3593 | pin = cfg->line_out_pins[i]; |
3594 | name = alc_get_line_out_pfx(spec, i, true, &index); | ||
3595 | } | ||
3252 | 3596 | ||
3253 | sw = alc_look_for_out_mute_nid(codec, pin, dac); | 3597 | sw = alc_look_for_out_mute_nid(codec, pin, dac); |
3254 | vol = alc_look_for_out_vol_nid(codec, pin, dac); | 3598 | vol = alc_look_for_out_vol_nid(codec, pin, dac); |
3255 | name = alc_get_line_out_pfx(spec, i, true, &index); | ||
3256 | if (!name || !strcmp(name, "CLFE")) { | 3599 | if (!name || !strcmp(name, "CLFE")) { |
3257 | /* Center/LFE */ | 3600 | /* Center/LFE */ |
3258 | err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1); | 3601 | err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1); |
@@ -3349,41 +3692,31 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins, | |||
3349 | return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); | 3692 | return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); |
3350 | } | 3693 | } |
3351 | 3694 | ||
3352 | if (dacs[num_pins - 1]) { | ||
3353 | /* OK, we have a multi-output system with individual volumes */ | ||
3354 | for (i = 0; i < num_pins; i++) { | ||
3355 | if (num_pins >= 3) { | ||
3356 | snprintf(name, sizeof(name), "%s %s", | ||
3357 | pfx, channel_name[i]); | ||
3358 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], | ||
3359 | name, 0); | ||
3360 | } else { | ||
3361 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], | ||
3362 | pfx, i); | ||
3363 | } | ||
3364 | if (err < 0) | ||
3365 | return err; | ||
3366 | } | ||
3367 | return 0; | ||
3368 | } | ||
3369 | |||
3370 | /* Let's create a bind-controls */ | ||
3371 | ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_sw); | ||
3372 | if (!ctl) | ||
3373 | return -ENOMEM; | ||
3374 | n = 0; | ||
3375 | for (i = 0; i < num_pins; i++) { | 3695 | for (i = 0; i < num_pins; i++) { |
3376 | if (get_wcaps(codec, pins[i]) & AC_WCAP_OUT_AMP) | 3696 | hda_nid_t dac; |
3377 | ctl->values[n++] = | 3697 | if (dacs[num_pins - 1]) |
3378 | HDA_COMPOSE_AMP_VAL(pins[i], 3, 0, HDA_OUTPUT); | 3698 | dac = dacs[i]; /* with individual volumes */ |
3379 | } | 3699 | else |
3380 | if (n) { | 3700 | dac = 0; |
3381 | snprintf(name, sizeof(name), "%s Playback Switch", pfx); | 3701 | if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker")) { |
3382 | err = add_control(spec, ALC_CTL_BIND_SW, name, 0, (long)ctl); | 3702 | err = alc_auto_create_extra_out(codec, pins[i], dac, |
3703 | "Bass Speaker", 0); | ||
3704 | } else if (num_pins >= 3) { | ||
3705 | snprintf(name, sizeof(name), "%s %s", | ||
3706 | pfx, channel_name[i]); | ||
3707 | err = alc_auto_create_extra_out(codec, pins[i], dac, | ||
3708 | name, 0); | ||
3709 | } else { | ||
3710 | err = alc_auto_create_extra_out(codec, pins[i], dac, | ||
3711 | pfx, i); | ||
3712 | } | ||
3383 | if (err < 0) | 3713 | if (err < 0) |
3384 | return err; | 3714 | return err; |
3385 | } | 3715 | } |
3716 | if (dacs[num_pins - 1]) | ||
3717 | return 0; | ||
3386 | 3718 | ||
3719 | /* Let's create a bind-controls for volumes */ | ||
3387 | ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol); | 3720 | ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol); |
3388 | if (!ctl) | 3721 | if (!ctl) |
3389 | return -ENOMEM; | 3722 | return -ENOMEM; |
@@ -3519,58 +3852,111 @@ static void alc_auto_init_extra_out(struct hda_codec *codec) | |||
3519 | } | 3852 | } |
3520 | } | 3853 | } |
3521 | 3854 | ||
3855 | /* check whether the given pin can be a multi-io pin */ | ||
3856 | static bool can_be_multiio_pin(struct hda_codec *codec, | ||
3857 | unsigned int location, hda_nid_t nid) | ||
3858 | { | ||
3859 | unsigned int defcfg, caps; | ||
3860 | |||
3861 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | ||
3862 | if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX) | ||
3863 | return false; | ||
3864 | if (location && get_defcfg_location(defcfg) != location) | ||
3865 | return false; | ||
3866 | caps = snd_hda_query_pin_caps(codec, nid); | ||
3867 | if (!(caps & AC_PINCAP_OUT)) | ||
3868 | return false; | ||
3869 | return true; | ||
3870 | } | ||
3871 | |||
3522 | /* | 3872 | /* |
3523 | * multi-io helper | 3873 | * multi-io helper |
3874 | * | ||
3875 | * When hardwired is set, try to fill ony hardwired pins, and returns | ||
3876 | * zero if any pins are filled, non-zero if nothing found. | ||
3877 | * When hardwired is off, try to fill possible input pins, and returns | ||
3878 | * the badness value. | ||
3524 | */ | 3879 | */ |
3525 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, | 3880 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, |
3526 | unsigned int location, | 3881 | hda_nid_t reference_pin, |
3527 | int offset) | 3882 | bool hardwired, int offset) |
3528 | { | 3883 | { |
3529 | struct alc_spec *spec = codec->spec; | 3884 | struct alc_spec *spec = codec->spec; |
3530 | struct auto_pin_cfg *cfg = &spec->autocfg; | 3885 | struct auto_pin_cfg *cfg = &spec->autocfg; |
3531 | hda_nid_t prime_dac = spec->private_dac_nids[0]; | 3886 | int type, i, j, dacs, num_pins, old_pins; |
3532 | int type, i, dacs, num_pins = 0; | 3887 | unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin); |
3888 | unsigned int location = get_defcfg_location(defcfg); | ||
3889 | int badness = 0; | ||
3890 | |||
3891 | old_pins = spec->multi_ios; | ||
3892 | if (old_pins >= 2) | ||
3893 | goto end_fill; | ||
3894 | |||
3895 | num_pins = 0; | ||
3896 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { | ||
3897 | for (i = 0; i < cfg->num_inputs; i++) { | ||
3898 | if (cfg->inputs[i].type != type) | ||
3899 | continue; | ||
3900 | if (can_be_multiio_pin(codec, location, | ||
3901 | cfg->inputs[i].pin)) | ||
3902 | num_pins++; | ||
3903 | } | ||
3904 | } | ||
3905 | if (num_pins < 2) | ||
3906 | goto end_fill; | ||
3533 | 3907 | ||
3534 | dacs = spec->multiout.num_dacs; | 3908 | dacs = spec->multiout.num_dacs; |
3535 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { | 3909 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { |
3536 | for (i = 0; i < cfg->num_inputs; i++) { | 3910 | for (i = 0; i < cfg->num_inputs; i++) { |
3537 | hda_nid_t nid = cfg->inputs[i].pin; | 3911 | hda_nid_t nid = cfg->inputs[i].pin; |
3538 | hda_nid_t dac = 0; | 3912 | hda_nid_t dac = 0; |
3539 | unsigned int defcfg, caps; | 3913 | |
3540 | if (cfg->inputs[i].type != type) | 3914 | if (cfg->inputs[i].type != type) |
3541 | continue; | 3915 | continue; |
3542 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | 3916 | if (!can_be_multiio_pin(codec, location, nid)) |
3543 | if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX) | ||
3544 | continue; | ||
3545 | if (location && get_defcfg_location(defcfg) != location) | ||
3546 | continue; | 3917 | continue; |
3547 | caps = snd_hda_query_pin_caps(codec, nid); | 3918 | for (j = 0; j < spec->multi_ios; j++) { |
3548 | if (!(caps & AC_PINCAP_OUT)) | 3919 | if (nid == spec->multi_io[j].pin) |
3920 | break; | ||
3921 | } | ||
3922 | if (j < spec->multi_ios) | ||
3549 | continue; | 3923 | continue; |
3550 | if (offset && offset + num_pins < dacs) { | 3924 | |
3551 | dac = spec->private_dac_nids[offset + num_pins]; | 3925 | if (offset && offset + spec->multi_ios < dacs) { |
3926 | dac = spec->private_dac_nids[offset + spec->multi_ios]; | ||
3552 | if (!alc_auto_is_dac_reachable(codec, nid, dac)) | 3927 | if (!alc_auto_is_dac_reachable(codec, nid, dac)) |
3553 | dac = 0; | 3928 | dac = 0; |
3554 | } | 3929 | } |
3555 | if (!dac) | 3930 | if (hardwired) |
3931 | dac = get_dac_if_single(codec, nid); | ||
3932 | else if (!dac) | ||
3556 | dac = alc_auto_look_for_dac(codec, nid); | 3933 | dac = alc_auto_look_for_dac(codec, nid); |
3557 | if (!dac) | 3934 | if (!dac) { |
3935 | badness++; | ||
3558 | continue; | 3936 | continue; |
3559 | spec->multi_io[num_pins].pin = nid; | 3937 | } |
3560 | spec->multi_io[num_pins].dac = dac; | 3938 | spec->multi_io[spec->multi_ios].pin = nid; |
3561 | num_pins++; | 3939 | spec->multi_io[spec->multi_ios].dac = dac; |
3562 | spec->private_dac_nids[spec->multiout.num_dacs++] = dac; | 3940 | spec->multi_ios++; |
3941 | if (spec->multi_ios >= 2) | ||
3942 | break; | ||
3563 | } | 3943 | } |
3564 | } | 3944 | } |
3565 | spec->multiout.num_dacs = dacs; | 3945 | end_fill: |
3566 | if (num_pins < 2) { | 3946 | if (badness) |
3567 | /* clear up again */ | 3947 | badness = BAD_MULTI_IO; |
3568 | memset(spec->private_dac_nids + dacs, 0, | 3948 | if (old_pins == spec->multi_ios) { |
3569 | sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - dacs)); | 3949 | if (hardwired) |
3570 | spec->private_dac_nids[0] = prime_dac; | 3950 | return 1; /* nothing found */ |
3571 | return 0; | 3951 | else |
3952 | return badness; /* no badness if nothing found */ | ||
3572 | } | 3953 | } |
3573 | return num_pins; | 3954 | if (!hardwired && spec->multi_ios < 2) { |
3955 | spec->multi_ios = old_pins; | ||
3956 | return badness; | ||
3957 | } | ||
3958 | |||
3959 | return 0; | ||
3574 | } | 3960 | } |
3575 | 3961 | ||
3576 | static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol, | 3962 | static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol, |
@@ -3768,7 +4154,7 @@ static void alc_auto_init_input_src(struct hda_codec *codec) | |||
3768 | else | 4154 | else |
3769 | nums = spec->num_adc_nids; | 4155 | nums = spec->num_adc_nids; |
3770 | for (c = 0; c < nums; c++) | 4156 | for (c = 0; c < nums; c++) |
3771 | alc_mux_select(codec, 0, spec->cur_mux[c], true); | 4157 | alc_mux_select(codec, c, spec->cur_mux[c], true); |
3772 | } | 4158 | } |
3773 | 4159 | ||
3774 | /* add mic boosts if needed */ | 4160 | /* add mic boosts if needed */ |
@@ -3904,7 +4290,6 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
3904 | static void alc_auto_init_std(struct hda_codec *codec) | 4290 | static void alc_auto_init_std(struct hda_codec *codec) |
3905 | { | 4291 | { |
3906 | struct alc_spec *spec = codec->spec; | 4292 | struct alc_spec *spec = codec->spec; |
3907 | spec->use_jack_tbl = 1; | ||
3908 | alc_auto_init_multi_out(codec); | 4293 | alc_auto_init_multi_out(codec); |
3909 | alc_auto_init_extra_out(codec); | 4294 | alc_auto_init_extra_out(codec); |
3910 | alc_auto_init_analog_input(codec); | 4295 | alc_auto_init_analog_input(codec); |
@@ -3926,6 +4311,7 @@ static const struct snd_pci_quirk beep_white_list[] = { | |||
3926 | SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), | 4311 | SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), |
3927 | SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), | 4312 | SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), |
3928 | SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), | 4313 | SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), |
4314 | SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1), | ||
3929 | SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), | 4315 | SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), |
3930 | {} | 4316 | {} |
3931 | }; | 4317 | }; |
@@ -4025,6 +4411,9 @@ static int alc_parse_auto_config(struct hda_codec *codec, | |||
4025 | if (spec->kctls.list) | 4411 | if (spec->kctls.list) |
4026 | add_mixer(spec, spec->kctls.list); | 4412 | add_mixer(spec, spec->kctls.list); |
4027 | 4413 | ||
4414 | if (!spec->no_analog && !spec->cap_mixer) | ||
4415 | set_capture_mixer(codec); | ||
4416 | |||
4028 | return 1; | 4417 | return 1; |
4029 | } | 4418 | } |
4030 | 4419 | ||
@@ -4035,26 +4424,47 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
4035 | return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids); | 4424 | return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids); |
4036 | } | 4425 | } |
4037 | 4426 | ||
4038 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
4039 | static const struct hda_amp_list alc880_loopbacks[] = { | ||
4040 | { 0x0b, HDA_INPUT, 0 }, | ||
4041 | { 0x0b, HDA_INPUT, 1 }, | ||
4042 | { 0x0b, HDA_INPUT, 2 }, | ||
4043 | { 0x0b, HDA_INPUT, 3 }, | ||
4044 | { 0x0b, HDA_INPUT, 4 }, | ||
4045 | { } /* end */ | ||
4046 | }; | ||
4047 | #endif | ||
4048 | |||
4049 | /* | 4427 | /* |
4050 | * ALC880 fix-ups | 4428 | * ALC880 fix-ups |
4051 | */ | 4429 | */ |
4052 | enum { | 4430 | enum { |
4431 | ALC880_FIXUP_GPIO1, | ||
4053 | ALC880_FIXUP_GPIO2, | 4432 | ALC880_FIXUP_GPIO2, |
4054 | ALC880_FIXUP_MEDION_RIM, | 4433 | ALC880_FIXUP_MEDION_RIM, |
4434 | ALC880_FIXUP_LG, | ||
4435 | ALC880_FIXUP_W810, | ||
4436 | ALC880_FIXUP_EAPD_COEF, | ||
4437 | ALC880_FIXUP_TCL_S700, | ||
4438 | ALC880_FIXUP_VOL_KNOB, | ||
4439 | ALC880_FIXUP_FUJITSU, | ||
4440 | ALC880_FIXUP_F1734, | ||
4441 | ALC880_FIXUP_UNIWILL, | ||
4442 | ALC880_FIXUP_UNIWILL_DIG, | ||
4443 | ALC880_FIXUP_Z71V, | ||
4444 | ALC880_FIXUP_3ST_BASE, | ||
4445 | ALC880_FIXUP_3ST, | ||
4446 | ALC880_FIXUP_3ST_DIG, | ||
4447 | ALC880_FIXUP_5ST_BASE, | ||
4448 | ALC880_FIXUP_5ST, | ||
4449 | ALC880_FIXUP_5ST_DIG, | ||
4450 | ALC880_FIXUP_6ST_BASE, | ||
4451 | ALC880_FIXUP_6ST, | ||
4452 | ALC880_FIXUP_6ST_DIG, | ||
4055 | }; | 4453 | }; |
4056 | 4454 | ||
4455 | /* enable the volume-knob widget support on NID 0x21 */ | ||
4456 | static void alc880_fixup_vol_knob(struct hda_codec *codec, | ||
4457 | const struct alc_fixup *fix, int action) | ||
4458 | { | ||
4459 | if (action == ALC_FIXUP_ACT_PROBE) | ||
4460 | snd_hda_jack_detect_enable(codec, 0x21, ALC_DCVOL_EVENT); | ||
4461 | } | ||
4462 | |||
4057 | static const struct alc_fixup alc880_fixups[] = { | 4463 | static const struct alc_fixup alc880_fixups[] = { |
4464 | [ALC880_FIXUP_GPIO1] = { | ||
4465 | .type = ALC_FIXUP_VERBS, | ||
4466 | .v.verbs = alc_gpio1_init_verbs, | ||
4467 | }, | ||
4058 | [ALC880_FIXUP_GPIO2] = { | 4468 | [ALC880_FIXUP_GPIO2] = { |
4059 | .type = ALC_FIXUP_VERBS, | 4469 | .type = ALC_FIXUP_VERBS, |
4060 | .v.verbs = alc_gpio2_init_verbs, | 4470 | .v.verbs = alc_gpio2_init_verbs, |
@@ -4069,40 +4479,323 @@ static const struct alc_fixup alc880_fixups[] = { | |||
4069 | .chained = true, | 4479 | .chained = true, |
4070 | .chain_id = ALC880_FIXUP_GPIO2, | 4480 | .chain_id = ALC880_FIXUP_GPIO2, |
4071 | }, | 4481 | }, |
4482 | [ALC880_FIXUP_LG] = { | ||
4483 | .type = ALC_FIXUP_PINS, | ||
4484 | .v.pins = (const struct alc_pincfg[]) { | ||
4485 | /* disable bogus unused pins */ | ||
4486 | { 0x16, 0x411111f0 }, | ||
4487 | { 0x18, 0x411111f0 }, | ||
4488 | { 0x1a, 0x411111f0 }, | ||
4489 | { } | ||
4490 | } | ||
4491 | }, | ||
4492 | [ALC880_FIXUP_W810] = { | ||
4493 | .type = ALC_FIXUP_PINS, | ||
4494 | .v.pins = (const struct alc_pincfg[]) { | ||
4495 | /* disable bogus unused pins */ | ||
4496 | { 0x17, 0x411111f0 }, | ||
4497 | { } | ||
4498 | }, | ||
4499 | .chained = true, | ||
4500 | .chain_id = ALC880_FIXUP_GPIO2, | ||
4501 | }, | ||
4502 | [ALC880_FIXUP_EAPD_COEF] = { | ||
4503 | .type = ALC_FIXUP_VERBS, | ||
4504 | .v.verbs = (const struct hda_verb[]) { | ||
4505 | /* change to EAPD mode */ | ||
4506 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | ||
4507 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, | ||
4508 | {} | ||
4509 | }, | ||
4510 | }, | ||
4511 | [ALC880_FIXUP_TCL_S700] = { | ||
4512 | .type = ALC_FIXUP_VERBS, | ||
4513 | .v.verbs = (const struct hda_verb[]) { | ||
4514 | /* change to EAPD mode */ | ||
4515 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | ||
4516 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, | ||
4517 | {} | ||
4518 | }, | ||
4519 | .chained = true, | ||
4520 | .chain_id = ALC880_FIXUP_GPIO2, | ||
4521 | }, | ||
4522 | [ALC880_FIXUP_VOL_KNOB] = { | ||
4523 | .type = ALC_FIXUP_FUNC, | ||
4524 | .v.func = alc880_fixup_vol_knob, | ||
4525 | }, | ||
4526 | [ALC880_FIXUP_FUJITSU] = { | ||
4527 | /* override all pins as BIOS on old Amilo is broken */ | ||
4528 | .type = ALC_FIXUP_PINS, | ||
4529 | .v.pins = (const struct alc_pincfg[]) { | ||
4530 | { 0x14, 0x0121411f }, /* HP */ | ||
4531 | { 0x15, 0x99030120 }, /* speaker */ | ||
4532 | { 0x16, 0x99030130 }, /* bass speaker */ | ||
4533 | { 0x17, 0x411111f0 }, /* N/A */ | ||
4534 | { 0x18, 0x411111f0 }, /* N/A */ | ||
4535 | { 0x19, 0x01a19950 }, /* mic-in */ | ||
4536 | { 0x1a, 0x411111f0 }, /* N/A */ | ||
4537 | { 0x1b, 0x411111f0 }, /* N/A */ | ||
4538 | { 0x1c, 0x411111f0 }, /* N/A */ | ||
4539 | { 0x1d, 0x411111f0 }, /* N/A */ | ||
4540 | { 0x1e, 0x01454140 }, /* SPDIF out */ | ||
4541 | { } | ||
4542 | }, | ||
4543 | .chained = true, | ||
4544 | .chain_id = ALC880_FIXUP_VOL_KNOB, | ||
4545 | }, | ||
4546 | [ALC880_FIXUP_F1734] = { | ||
4547 | /* almost compatible with FUJITSU, but no bass and SPDIF */ | ||
4548 | .type = ALC_FIXUP_PINS, | ||
4549 | .v.pins = (const struct alc_pincfg[]) { | ||
4550 | { 0x14, 0x0121411f }, /* HP */ | ||
4551 | { 0x15, 0x99030120 }, /* speaker */ | ||
4552 | { 0x16, 0x411111f0 }, /* N/A */ | ||
4553 | { 0x17, 0x411111f0 }, /* N/A */ | ||
4554 | { 0x18, 0x411111f0 }, /* N/A */ | ||
4555 | { 0x19, 0x01a19950 }, /* mic-in */ | ||
4556 | { 0x1a, 0x411111f0 }, /* N/A */ | ||
4557 | { 0x1b, 0x411111f0 }, /* N/A */ | ||
4558 | { 0x1c, 0x411111f0 }, /* N/A */ | ||
4559 | { 0x1d, 0x411111f0 }, /* N/A */ | ||
4560 | { 0x1e, 0x411111f0 }, /* N/A */ | ||
4561 | { } | ||
4562 | }, | ||
4563 | .chained = true, | ||
4564 | .chain_id = ALC880_FIXUP_VOL_KNOB, | ||
4565 | }, | ||
4566 | [ALC880_FIXUP_UNIWILL] = { | ||
4567 | /* need to fix HP and speaker pins to be parsed correctly */ | ||
4568 | .type = ALC_FIXUP_PINS, | ||
4569 | .v.pins = (const struct alc_pincfg[]) { | ||
4570 | { 0x14, 0x0121411f }, /* HP */ | ||
4571 | { 0x15, 0x99030120 }, /* speaker */ | ||
4572 | { 0x16, 0x99030130 }, /* bass speaker */ | ||
4573 | { } | ||
4574 | }, | ||
4575 | }, | ||
4576 | [ALC880_FIXUP_UNIWILL_DIG] = { | ||
4577 | .type = ALC_FIXUP_PINS, | ||
4578 | .v.pins = (const struct alc_pincfg[]) { | ||
4579 | /* disable bogus unused pins */ | ||
4580 | { 0x17, 0x411111f0 }, | ||
4581 | { 0x19, 0x411111f0 }, | ||
4582 | { 0x1b, 0x411111f0 }, | ||
4583 | { 0x1f, 0x411111f0 }, | ||
4584 | { } | ||
4585 | } | ||
4586 | }, | ||
4587 | [ALC880_FIXUP_Z71V] = { | ||
4588 | .type = ALC_FIXUP_PINS, | ||
4589 | .v.pins = (const struct alc_pincfg[]) { | ||
4590 | /* set up the whole pins as BIOS is utterly broken */ | ||
4591 | { 0x14, 0x99030120 }, /* speaker */ | ||
4592 | { 0x15, 0x0121411f }, /* HP */ | ||
4593 | { 0x16, 0x411111f0 }, /* N/A */ | ||
4594 | { 0x17, 0x411111f0 }, /* N/A */ | ||
4595 | { 0x18, 0x01a19950 }, /* mic-in */ | ||
4596 | { 0x19, 0x411111f0 }, /* N/A */ | ||
4597 | { 0x1a, 0x01813031 }, /* line-in */ | ||
4598 | { 0x1b, 0x411111f0 }, /* N/A */ | ||
4599 | { 0x1c, 0x411111f0 }, /* N/A */ | ||
4600 | { 0x1d, 0x411111f0 }, /* N/A */ | ||
4601 | { 0x1e, 0x0144111e }, /* SPDIF */ | ||
4602 | { } | ||
4603 | } | ||
4604 | }, | ||
4605 | [ALC880_FIXUP_3ST_BASE] = { | ||
4606 | .type = ALC_FIXUP_PINS, | ||
4607 | .v.pins = (const struct alc_pincfg[]) { | ||
4608 | { 0x14, 0x01014010 }, /* line-out */ | ||
4609 | { 0x15, 0x411111f0 }, /* N/A */ | ||
4610 | { 0x16, 0x411111f0 }, /* N/A */ | ||
4611 | { 0x17, 0x411111f0 }, /* N/A */ | ||
4612 | { 0x18, 0x01a19c30 }, /* mic-in */ | ||
4613 | { 0x19, 0x0121411f }, /* HP */ | ||
4614 | { 0x1a, 0x01813031 }, /* line-in */ | ||
4615 | { 0x1b, 0x02a19c40 }, /* front-mic */ | ||
4616 | { 0x1c, 0x411111f0 }, /* N/A */ | ||
4617 | { 0x1d, 0x411111f0 }, /* N/A */ | ||
4618 | /* 0x1e is filled in below */ | ||
4619 | { 0x1f, 0x411111f0 }, /* N/A */ | ||
4620 | { } | ||
4621 | } | ||
4622 | }, | ||
4623 | [ALC880_FIXUP_3ST] = { | ||
4624 | .type = ALC_FIXUP_PINS, | ||
4625 | .v.pins = (const struct alc_pincfg[]) { | ||
4626 | { 0x1e, 0x411111f0 }, /* N/A */ | ||
4627 | { } | ||
4628 | }, | ||
4629 | .chained = true, | ||
4630 | .chain_id = ALC880_FIXUP_3ST_BASE, | ||
4631 | }, | ||
4632 | [ALC880_FIXUP_3ST_DIG] = { | ||
4633 | .type = ALC_FIXUP_PINS, | ||
4634 | .v.pins = (const struct alc_pincfg[]) { | ||
4635 | { 0x1e, 0x0144111e }, /* SPDIF */ | ||
4636 | { } | ||
4637 | }, | ||
4638 | .chained = true, | ||
4639 | .chain_id = ALC880_FIXUP_3ST_BASE, | ||
4640 | }, | ||
4641 | [ALC880_FIXUP_5ST_BASE] = { | ||
4642 | .type = ALC_FIXUP_PINS, | ||
4643 | .v.pins = (const struct alc_pincfg[]) { | ||
4644 | { 0x14, 0x01014010 }, /* front */ | ||
4645 | { 0x15, 0x411111f0 }, /* N/A */ | ||
4646 | { 0x16, 0x01011411 }, /* CLFE */ | ||
4647 | { 0x17, 0x01016412 }, /* surr */ | ||
4648 | { 0x18, 0x01a19c30 }, /* mic-in */ | ||
4649 | { 0x19, 0x0121411f }, /* HP */ | ||
4650 | { 0x1a, 0x01813031 }, /* line-in */ | ||
4651 | { 0x1b, 0x02a19c40 }, /* front-mic */ | ||
4652 | { 0x1c, 0x411111f0 }, /* N/A */ | ||
4653 | { 0x1d, 0x411111f0 }, /* N/A */ | ||
4654 | /* 0x1e is filled in below */ | ||
4655 | { 0x1f, 0x411111f0 }, /* N/A */ | ||
4656 | { } | ||
4657 | } | ||
4658 | }, | ||
4659 | [ALC880_FIXUP_5ST] = { | ||
4660 | .type = ALC_FIXUP_PINS, | ||
4661 | .v.pins = (const struct alc_pincfg[]) { | ||
4662 | { 0x1e, 0x411111f0 }, /* N/A */ | ||
4663 | { } | ||
4664 | }, | ||
4665 | .chained = true, | ||
4666 | .chain_id = ALC880_FIXUP_5ST_BASE, | ||
4667 | }, | ||
4668 | [ALC880_FIXUP_5ST_DIG] = { | ||
4669 | .type = ALC_FIXUP_PINS, | ||
4670 | .v.pins = (const struct alc_pincfg[]) { | ||
4671 | { 0x1e, 0x0144111e }, /* SPDIF */ | ||
4672 | { } | ||
4673 | }, | ||
4674 | .chained = true, | ||
4675 | .chain_id = ALC880_FIXUP_5ST_BASE, | ||
4676 | }, | ||
4677 | [ALC880_FIXUP_6ST_BASE] = { | ||
4678 | .type = ALC_FIXUP_PINS, | ||
4679 | .v.pins = (const struct alc_pincfg[]) { | ||
4680 | { 0x14, 0x01014010 }, /* front */ | ||
4681 | { 0x15, 0x01016412 }, /* surr */ | ||
4682 | { 0x16, 0x01011411 }, /* CLFE */ | ||
4683 | { 0x17, 0x01012414 }, /* side */ | ||
4684 | { 0x18, 0x01a19c30 }, /* mic-in */ | ||
4685 | { 0x19, 0x02a19c40 }, /* front-mic */ | ||
4686 | { 0x1a, 0x01813031 }, /* line-in */ | ||
4687 | { 0x1b, 0x0121411f }, /* HP */ | ||
4688 | { 0x1c, 0x411111f0 }, /* N/A */ | ||
4689 | { 0x1d, 0x411111f0 }, /* N/A */ | ||
4690 | /* 0x1e is filled in below */ | ||
4691 | { 0x1f, 0x411111f0 }, /* N/A */ | ||
4692 | { } | ||
4693 | } | ||
4694 | }, | ||
4695 | [ALC880_FIXUP_6ST] = { | ||
4696 | .type = ALC_FIXUP_PINS, | ||
4697 | .v.pins = (const struct alc_pincfg[]) { | ||
4698 | { 0x1e, 0x411111f0 }, /* N/A */ | ||
4699 | { } | ||
4700 | }, | ||
4701 | .chained = true, | ||
4702 | .chain_id = ALC880_FIXUP_6ST_BASE, | ||
4703 | }, | ||
4704 | [ALC880_FIXUP_6ST_DIG] = { | ||
4705 | .type = ALC_FIXUP_PINS, | ||
4706 | .v.pins = (const struct alc_pincfg[]) { | ||
4707 | { 0x1e, 0x0144111e }, /* SPDIF */ | ||
4708 | { } | ||
4709 | }, | ||
4710 | .chained = true, | ||
4711 | .chain_id = ALC880_FIXUP_6ST_BASE, | ||
4712 | }, | ||
4072 | }; | 4713 | }; |
4073 | 4714 | ||
4074 | static const struct snd_pci_quirk alc880_fixup_tbl[] = { | 4715 | static const struct snd_pci_quirk alc880_fixup_tbl[] = { |
4716 | SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810), | ||
4717 | SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V), | ||
4718 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1), | ||
4719 | SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2), | ||
4720 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF), | ||
4721 | SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG), | ||
4722 | SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734), | ||
4723 | SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL), | ||
4724 | SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB), | ||
4725 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810), | ||
4075 | SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), | 4726 | SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), |
4727 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734), | ||
4728 | SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU), | ||
4729 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734), | ||
4730 | SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU), | ||
4731 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG), | ||
4732 | SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG), | ||
4733 | SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG), | ||
4734 | SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700), | ||
4735 | |||
4736 | /* Below is the copied entries from alc880_quirks.c. | ||
4737 | * It's not quite sure whether BIOS sets the correct pin-config table | ||
4738 | * on these machines, thus they are kept to be compatible with | ||
4739 | * the old static quirks. Once when it's confirmed to work without | ||
4740 | * these overrides, it'd be better to remove. | ||
4741 | */ | ||
4742 | SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG), | ||
4743 | SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST), | ||
4744 | SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG), | ||
4745 | SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG), | ||
4746 | SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG), | ||
4747 | SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG), | ||
4748 | SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG), | ||
4749 | SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST), | ||
4750 | SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG), | ||
4751 | SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST), | ||
4752 | SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST), | ||
4753 | SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST), | ||
4754 | SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST), | ||
4755 | SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST), | ||
4756 | SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG), | ||
4757 | SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG), | ||
4758 | SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG), | ||
4759 | SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG), | ||
4760 | SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG), | ||
4761 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG), | ||
4762 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG), | ||
4763 | SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */ | ||
4764 | SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG), | ||
4765 | SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG), | ||
4766 | SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG), | ||
4767 | SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG), | ||
4768 | SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG), | ||
4769 | SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG), | ||
4770 | SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG), | ||
4771 | SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG), | ||
4772 | SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG), | ||
4773 | SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG), | ||
4774 | SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG), | ||
4775 | /* default Intel */ | ||
4776 | SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST), | ||
4777 | SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG), | ||
4778 | SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG), | ||
4076 | {} | 4779 | {} |
4077 | }; | 4780 | }; |
4078 | 4781 | ||
4782 | static const struct alc_model_fixup alc880_fixup_models[] = { | ||
4783 | {.id = ALC880_FIXUP_3ST, .name = "3stack"}, | ||
4784 | {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"}, | ||
4785 | {.id = ALC880_FIXUP_5ST, .name = "5stack"}, | ||
4786 | {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"}, | ||
4787 | {.id = ALC880_FIXUP_6ST, .name = "6stack"}, | ||
4788 | {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"}, | ||
4789 | {} | ||
4790 | }; | ||
4079 | 4791 | ||
4080 | /* | ||
4081 | * board setups | ||
4082 | */ | ||
4083 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
4084 | #define alc_board_config \ | ||
4085 | snd_hda_check_board_config | ||
4086 | #define alc_board_codec_sid_config \ | ||
4087 | snd_hda_check_board_codec_sid_config | ||
4088 | #include "alc_quirks.c" | ||
4089 | #else | ||
4090 | #define alc_board_config(codec, nums, models, tbl) -1 | ||
4091 | #define alc_board_codec_sid_config(codec, nums, models, tbl) -1 | ||
4092 | #define setup_preset(codec, x) /* NOP */ | ||
4093 | #endif | ||
4094 | 4792 | ||
4095 | /* | 4793 | /* |
4096 | * OK, here we have finally the patch for ALC880 | 4794 | * OK, here we have finally the patch for ALC880 |
4097 | */ | 4795 | */ |
4098 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
4099 | #include "alc880_quirks.c" | ||
4100 | #endif | ||
4101 | |||
4102 | static int patch_alc880(struct hda_codec *codec) | 4796 | static int patch_alc880(struct hda_codec *codec) |
4103 | { | 4797 | { |
4104 | struct alc_spec *spec; | 4798 | struct alc_spec *spec; |
4105 | int board_config; | ||
4106 | int err; | 4799 | int err; |
4107 | 4800 | ||
4108 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4801 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
@@ -4114,47 +4807,14 @@ static int patch_alc880(struct hda_codec *codec) | |||
4114 | spec->mixer_nid = 0x0b; | 4807 | spec->mixer_nid = 0x0b; |
4115 | spec->need_dac_fix = 1; | 4808 | spec->need_dac_fix = 1; |
4116 | 4809 | ||
4117 | board_config = alc_board_config(codec, ALC880_MODEL_LAST, | 4810 | alc_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl, |
4118 | alc880_models, alc880_cfg_tbl); | 4811 | alc880_fixups); |
4119 | if (board_config < 0) { | 4812 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); |
4120 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
4121 | codec->chip_name); | ||
4122 | board_config = ALC_MODEL_AUTO; | ||
4123 | } | ||
4124 | |||
4125 | if (board_config == ALC_MODEL_AUTO) { | ||
4126 | alc_pick_fixup(codec, NULL, alc880_fixup_tbl, alc880_fixups); | ||
4127 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | ||
4128 | } | ||
4129 | |||
4130 | if (board_config == ALC_MODEL_AUTO) { | ||
4131 | /* automatic parse from the BIOS config */ | ||
4132 | err = alc880_parse_auto_config(codec); | ||
4133 | if (err < 0) | ||
4134 | goto error; | ||
4135 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
4136 | else if (!err) { | ||
4137 | printk(KERN_INFO | ||
4138 | "hda_codec: Cannot set up configuration " | ||
4139 | "from BIOS. Using 3-stack mode...\n"); | ||
4140 | board_config = ALC880_3ST; | ||
4141 | } | ||
4142 | #endif | ||
4143 | } | ||
4144 | |||
4145 | if (board_config != ALC_MODEL_AUTO) { | ||
4146 | spec->vmaster_nid = 0x0c; | ||
4147 | setup_preset(codec, &alc880_presets[board_config]); | ||
4148 | } | ||
4149 | |||
4150 | if (!spec->no_analog && !spec->adc_nids) { | ||
4151 | alc_auto_fill_adc_caps(codec); | ||
4152 | alc_rebuild_imux_for_auto_mic(codec); | ||
4153 | alc_remove_invalid_adc_nids(codec); | ||
4154 | } | ||
4155 | 4813 | ||
4156 | if (!spec->no_analog && !spec->cap_mixer) | 4814 | /* automatic parse from the BIOS config */ |
4157 | set_capture_mixer(codec); | 4815 | err = alc880_parse_auto_config(codec); |
4816 | if (err < 0) | ||
4817 | goto error; | ||
4158 | 4818 | ||
4159 | if (!spec->no_analog) { | 4819 | if (!spec->no_analog) { |
4160 | err = snd_hda_attach_beep_device(codec, 0x1); | 4820 | err = snd_hda_attach_beep_device(codec, 0x1); |
@@ -4163,15 +4823,9 @@ static int patch_alc880(struct hda_codec *codec) | |||
4163 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 4823 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
4164 | } | 4824 | } |
4165 | 4825 | ||
4166 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | ||
4167 | |||
4168 | codec->patch_ops = alc_patch_ops; | 4826 | codec->patch_ops = alc_patch_ops; |
4169 | if (board_config == ALC_MODEL_AUTO) | 4827 | |
4170 | spec->init_hook = alc_auto_init_std; | 4828 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
4171 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
4172 | if (!spec->loopback.amplist) | ||
4173 | spec->loopback.amplist = alc880_loopbacks; | ||
4174 | #endif | ||
4175 | 4829 | ||
4176 | return 0; | 4830 | return 0; |
4177 | 4831 | ||
@@ -4191,49 +4845,115 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
4191 | return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids); | 4845 | return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids); |
4192 | } | 4846 | } |
4193 | 4847 | ||
4194 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
4195 | static const struct hda_amp_list alc260_loopbacks[] = { | ||
4196 | { 0x07, HDA_INPUT, 0 }, | ||
4197 | { 0x07, HDA_INPUT, 1 }, | ||
4198 | { 0x07, HDA_INPUT, 2 }, | ||
4199 | { 0x07, HDA_INPUT, 3 }, | ||
4200 | { 0x07, HDA_INPUT, 4 }, | ||
4201 | { } /* end */ | ||
4202 | }; | ||
4203 | #endif | ||
4204 | |||
4205 | /* | 4848 | /* |
4206 | * Pin config fixes | 4849 | * Pin config fixes |
4207 | */ | 4850 | */ |
4208 | enum { | 4851 | enum { |
4209 | PINFIX_HP_DC5750, | 4852 | ALC260_FIXUP_HP_DC5750, |
4853 | ALC260_FIXUP_HP_PIN_0F, | ||
4854 | ALC260_FIXUP_COEF, | ||
4855 | ALC260_FIXUP_GPIO1, | ||
4856 | ALC260_FIXUP_GPIO1_TOGGLE, | ||
4857 | ALC260_FIXUP_REPLACER, | ||
4858 | ALC260_FIXUP_HP_B1900, | ||
4210 | }; | 4859 | }; |
4211 | 4860 | ||
4861 | static void alc260_gpio1_automute(struct hda_codec *codec) | ||
4862 | { | ||
4863 | struct alc_spec *spec = codec->spec; | ||
4864 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | ||
4865 | spec->hp_jack_present); | ||
4866 | } | ||
4867 | |||
4868 | static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, | ||
4869 | const struct alc_fixup *fix, int action) | ||
4870 | { | ||
4871 | struct alc_spec *spec = codec->spec; | ||
4872 | if (action == ALC_FIXUP_ACT_PROBE) { | ||
4873 | /* although the machine has only one output pin, we need to | ||
4874 | * toggle GPIO1 according to the jack state | ||
4875 | */ | ||
4876 | spec->automute_hook = alc260_gpio1_automute; | ||
4877 | spec->detect_hp = 1; | ||
4878 | spec->automute_speaker = 1; | ||
4879 | spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ | ||
4880 | snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT); | ||
4881 | spec->unsol_event = alc_sku_unsol_event; | ||
4882 | add_verb(codec->spec, alc_gpio1_init_verbs); | ||
4883 | } | ||
4884 | } | ||
4885 | |||
4212 | static const struct alc_fixup alc260_fixups[] = { | 4886 | static const struct alc_fixup alc260_fixups[] = { |
4213 | [PINFIX_HP_DC5750] = { | 4887 | [ALC260_FIXUP_HP_DC5750] = { |
4214 | .type = ALC_FIXUP_PINS, | 4888 | .type = ALC_FIXUP_PINS, |
4215 | .v.pins = (const struct alc_pincfg[]) { | 4889 | .v.pins = (const struct alc_pincfg[]) { |
4216 | { 0x11, 0x90130110 }, /* speaker */ | 4890 | { 0x11, 0x90130110 }, /* speaker */ |
4217 | { } | 4891 | { } |
4218 | } | 4892 | } |
4219 | }, | 4893 | }, |
4894 | [ALC260_FIXUP_HP_PIN_0F] = { | ||
4895 | .type = ALC_FIXUP_PINS, | ||
4896 | .v.pins = (const struct alc_pincfg[]) { | ||
4897 | { 0x0f, 0x01214000 }, /* HP */ | ||
4898 | { } | ||
4899 | } | ||
4900 | }, | ||
4901 | [ALC260_FIXUP_COEF] = { | ||
4902 | .type = ALC_FIXUP_VERBS, | ||
4903 | .v.verbs = (const struct hda_verb[]) { | ||
4904 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | ||
4905 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3040 }, | ||
4906 | { } | ||
4907 | }, | ||
4908 | .chained = true, | ||
4909 | .chain_id = ALC260_FIXUP_HP_PIN_0F, | ||
4910 | }, | ||
4911 | [ALC260_FIXUP_GPIO1] = { | ||
4912 | .type = ALC_FIXUP_VERBS, | ||
4913 | .v.verbs = alc_gpio1_init_verbs, | ||
4914 | }, | ||
4915 | [ALC260_FIXUP_GPIO1_TOGGLE] = { | ||
4916 | .type = ALC_FIXUP_FUNC, | ||
4917 | .v.func = alc260_fixup_gpio1_toggle, | ||
4918 | .chained = true, | ||
4919 | .chain_id = ALC260_FIXUP_HP_PIN_0F, | ||
4920 | }, | ||
4921 | [ALC260_FIXUP_REPLACER] = { | ||
4922 | .type = ALC_FIXUP_VERBS, | ||
4923 | .v.verbs = (const struct hda_verb[]) { | ||
4924 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | ||
4925 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | ||
4926 | { } | ||
4927 | }, | ||
4928 | .chained = true, | ||
4929 | .chain_id = ALC260_FIXUP_GPIO1_TOGGLE, | ||
4930 | }, | ||
4931 | [ALC260_FIXUP_HP_B1900] = { | ||
4932 | .type = ALC_FIXUP_FUNC, | ||
4933 | .v.func = alc260_fixup_gpio1_toggle, | ||
4934 | .chained = true, | ||
4935 | .chain_id = ALC260_FIXUP_COEF, | ||
4936 | } | ||
4220 | }; | 4937 | }; |
4221 | 4938 | ||
4222 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { | 4939 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { |
4223 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), | 4940 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1), |
4941 | SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF), | ||
4942 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1), | ||
4943 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), | ||
4944 | SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), | ||
4945 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), | ||
4946 | SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), | ||
4947 | SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), | ||
4224 | {} | 4948 | {} |
4225 | }; | 4949 | }; |
4226 | 4950 | ||
4227 | /* | 4951 | /* |
4228 | */ | 4952 | */ |
4229 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
4230 | #include "alc260_quirks.c" | ||
4231 | #endif | ||
4232 | |||
4233 | static int patch_alc260(struct hda_codec *codec) | 4953 | static int patch_alc260(struct hda_codec *codec) |
4234 | { | 4954 | { |
4235 | struct alc_spec *spec; | 4955 | struct alc_spec *spec; |
4236 | int err, board_config; | 4956 | int err; |
4237 | 4957 | ||
4238 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4958 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
4239 | if (spec == NULL) | 4959 | if (spec == NULL) |
@@ -4243,47 +4963,13 @@ static int patch_alc260(struct hda_codec *codec) | |||
4243 | 4963 | ||
4244 | spec->mixer_nid = 0x07; | 4964 | spec->mixer_nid = 0x07; |
4245 | 4965 | ||
4246 | board_config = alc_board_config(codec, ALC260_MODEL_LAST, | 4966 | alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); |
4247 | alc260_models, alc260_cfg_tbl); | 4967 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); |
4248 | if (board_config < 0) { | ||
4249 | snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
4250 | codec->chip_name); | ||
4251 | board_config = ALC_MODEL_AUTO; | ||
4252 | } | ||
4253 | |||
4254 | if (board_config == ALC_MODEL_AUTO) { | ||
4255 | alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); | ||
4256 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | ||
4257 | } | ||
4258 | |||
4259 | if (board_config == ALC_MODEL_AUTO) { | ||
4260 | /* automatic parse from the BIOS config */ | ||
4261 | err = alc260_parse_auto_config(codec); | ||
4262 | if (err < 0) | ||
4263 | goto error; | ||
4264 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
4265 | else if (!err) { | ||
4266 | printk(KERN_INFO | ||
4267 | "hda_codec: Cannot set up configuration " | ||
4268 | "from BIOS. Using base mode...\n"); | ||
4269 | board_config = ALC260_BASIC; | ||
4270 | } | ||
4271 | #endif | ||
4272 | } | ||
4273 | |||
4274 | if (board_config != ALC_MODEL_AUTO) { | ||
4275 | setup_preset(codec, &alc260_presets[board_config]); | ||
4276 | spec->vmaster_nid = 0x08; | ||
4277 | } | ||
4278 | |||
4279 | if (!spec->no_analog && !spec->adc_nids) { | ||
4280 | alc_auto_fill_adc_caps(codec); | ||
4281 | alc_rebuild_imux_for_auto_mic(codec); | ||
4282 | alc_remove_invalid_adc_nids(codec); | ||
4283 | } | ||
4284 | 4968 | ||
4285 | if (!spec->no_analog && !spec->cap_mixer) | 4969 | /* automatic parse from the BIOS config */ |
4286 | set_capture_mixer(codec); | 4970 | err = alc260_parse_auto_config(codec); |
4971 | if (err < 0) | ||
4972 | goto error; | ||
4287 | 4973 | ||
4288 | if (!spec->no_analog) { | 4974 | if (!spec->no_analog) { |
4289 | err = snd_hda_attach_beep_device(codec, 0x1); | 4975 | err = snd_hda_attach_beep_device(codec, 0x1); |
@@ -4292,16 +4978,10 @@ static int patch_alc260(struct hda_codec *codec) | |||
4292 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); | 4978 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); |
4293 | } | 4979 | } |
4294 | 4980 | ||
4295 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | ||
4296 | |||
4297 | codec->patch_ops = alc_patch_ops; | 4981 | codec->patch_ops = alc_patch_ops; |
4298 | if (board_config == ALC_MODEL_AUTO) | ||
4299 | spec->init_hook = alc_auto_init_std; | ||
4300 | spec->shutup = alc_eapd_shutup; | 4982 | spec->shutup = alc_eapd_shutup; |
4301 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4983 | |
4302 | if (!spec->loopback.amplist) | 4984 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
4303 | spec->loopback.amplist = alc260_loopbacks; | ||
4304 | #endif | ||
4305 | 4985 | ||
4306 | return 0; | 4986 | return 0; |
4307 | 4987 | ||
@@ -4322,9 +5002,6 @@ static int patch_alc260(struct hda_codec *codec) | |||
4322 | * In addition, an independent DAC for the multi-playback (not used in this | 5002 | * In addition, an independent DAC for the multi-playback (not used in this |
4323 | * driver yet). | 5003 | * driver yet). |
4324 | */ | 5004 | */ |
4325 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
4326 | #define alc882_loopbacks alc880_loopbacks | ||
4327 | #endif | ||
4328 | 5005 | ||
4329 | /* | 5006 | /* |
4330 | * Pin config fixes | 5007 | * Pin config fixes |
@@ -4335,11 +5012,14 @@ enum { | |||
4335 | ALC882_FIXUP_PB_M5210, | 5012 | ALC882_FIXUP_PB_M5210, |
4336 | ALC882_FIXUP_ACER_ASPIRE_7736, | 5013 | ALC882_FIXUP_ACER_ASPIRE_7736, |
4337 | ALC882_FIXUP_ASUS_W90V, | 5014 | ALC882_FIXUP_ASUS_W90V, |
5015 | ALC889_FIXUP_CD, | ||
4338 | ALC889_FIXUP_VAIO_TT, | 5016 | ALC889_FIXUP_VAIO_TT, |
4339 | ALC888_FIXUP_EEE1601, | 5017 | ALC888_FIXUP_EEE1601, |
4340 | ALC882_FIXUP_EAPD, | 5018 | ALC882_FIXUP_EAPD, |
4341 | ALC883_FIXUP_EAPD, | 5019 | ALC883_FIXUP_EAPD, |
4342 | ALC883_FIXUP_ACER_EAPD, | 5020 | ALC883_FIXUP_ACER_EAPD, |
5021 | ALC882_FIXUP_GPIO1, | ||
5022 | ALC882_FIXUP_GPIO2, | ||
4343 | ALC882_FIXUP_GPIO3, | 5023 | ALC882_FIXUP_GPIO3, |
4344 | ALC889_FIXUP_COEF, | 5024 | ALC889_FIXUP_COEF, |
4345 | ALC882_FIXUP_ASUS_W2JC, | 5025 | ALC882_FIXUP_ASUS_W2JC, |
@@ -4347,6 +5027,9 @@ enum { | |||
4347 | ALC882_FIXUP_ACER_ASPIRE_8930G, | 5027 | ALC882_FIXUP_ACER_ASPIRE_8930G, |
4348 | ALC882_FIXUP_ASPIRE_8930G_VERBS, | 5028 | ALC882_FIXUP_ASPIRE_8930G_VERBS, |
4349 | ALC885_FIXUP_MACPRO_GPIO, | 5029 | ALC885_FIXUP_MACPRO_GPIO, |
5030 | ALC889_FIXUP_DAC_ROUTE, | ||
5031 | ALC889_FIXUP_MBP_VREF, | ||
5032 | ALC889_FIXUP_IMAC91_VREF, | ||
4350 | }; | 5033 | }; |
4351 | 5034 | ||
4352 | static void alc889_fixup_coef(struct hda_codec *codec, | 5035 | static void alc889_fixup_coef(struct hda_codec *codec, |
@@ -4400,6 +5083,76 @@ static void alc885_fixup_macpro_gpio(struct hda_codec *codec, | |||
4400 | alc882_gpio_mute(codec, 1, 0); | 5083 | alc882_gpio_mute(codec, 1, 0); |
4401 | } | 5084 | } |
4402 | 5085 | ||
5086 | /* Fix the connection of some pins for ALC889: | ||
5087 | * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't | ||
5088 | * work correctly (bko#42740) | ||
5089 | */ | ||
5090 | static void alc889_fixup_dac_route(struct hda_codec *codec, | ||
5091 | const struct alc_fixup *fix, int action) | ||
5092 | { | ||
5093 | if (action == ALC_FIXUP_ACT_PRE_PROBE) { | ||
5094 | /* fake the connections during parsing the tree */ | ||
5095 | hda_nid_t conn1[2] = { 0x0c, 0x0d }; | ||
5096 | hda_nid_t conn2[2] = { 0x0e, 0x0f }; | ||
5097 | snd_hda_override_conn_list(codec, 0x14, 2, conn1); | ||
5098 | snd_hda_override_conn_list(codec, 0x15, 2, conn1); | ||
5099 | snd_hda_override_conn_list(codec, 0x18, 2, conn2); | ||
5100 | snd_hda_override_conn_list(codec, 0x1a, 2, conn2); | ||
5101 | } else if (action == ALC_FIXUP_ACT_PROBE) { | ||
5102 | /* restore the connections */ | ||
5103 | hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 }; | ||
5104 | snd_hda_override_conn_list(codec, 0x14, 5, conn); | ||
5105 | snd_hda_override_conn_list(codec, 0x15, 5, conn); | ||
5106 | snd_hda_override_conn_list(codec, 0x18, 5, conn); | ||
5107 | snd_hda_override_conn_list(codec, 0x1a, 5, conn); | ||
5108 | } | ||
5109 | } | ||
5110 | |||
5111 | /* Set VREF on HP pin */ | ||
5112 | static void alc889_fixup_mbp_vref(struct hda_codec *codec, | ||
5113 | const struct alc_fixup *fix, int action) | ||
5114 | { | ||
5115 | struct alc_spec *spec = codec->spec; | ||
5116 | static hda_nid_t nids[2] = { 0x14, 0x15 }; | ||
5117 | int i; | ||
5118 | |||
5119 | if (action != ALC_FIXUP_ACT_INIT) | ||
5120 | return; | ||
5121 | for (i = 0; i < ARRAY_SIZE(nids); i++) { | ||
5122 | unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]); | ||
5123 | if (get_defcfg_device(val) != AC_JACK_HP_OUT) | ||
5124 | continue; | ||
5125 | val = snd_hda_codec_read(codec, nids[i], 0, | ||
5126 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
5127 | val |= AC_PINCTL_VREF_80; | ||
5128 | snd_hda_codec_write(codec, nids[i], 0, | ||
5129 | AC_VERB_SET_PIN_WIDGET_CONTROL, val); | ||
5130 | spec->keep_vref_in_automute = 1; | ||
5131 | break; | ||
5132 | } | ||
5133 | } | ||
5134 | |||
5135 | /* Set VREF on speaker pins on imac91 */ | ||
5136 | static void alc889_fixup_imac91_vref(struct hda_codec *codec, | ||
5137 | const struct alc_fixup *fix, int action) | ||
5138 | { | ||
5139 | struct alc_spec *spec = codec->spec; | ||
5140 | static hda_nid_t nids[2] = { 0x18, 0x1a }; | ||
5141 | int i; | ||
5142 | |||
5143 | if (action != ALC_FIXUP_ACT_INIT) | ||
5144 | return; | ||
5145 | for (i = 0; i < ARRAY_SIZE(nids); i++) { | ||
5146 | unsigned int val; | ||
5147 | val = snd_hda_codec_read(codec, nids[i], 0, | ||
5148 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
5149 | val |= AC_PINCTL_VREF_50; | ||
5150 | snd_hda_codec_write(codec, nids[i], 0, | ||
5151 | AC_VERB_SET_PIN_WIDGET_CONTROL, val); | ||
5152 | } | ||
5153 | spec->keep_vref_in_automute = 1; | ||
5154 | } | ||
5155 | |||
4403 | static const struct alc_fixup alc882_fixups[] = { | 5156 | static const struct alc_fixup alc882_fixups[] = { |
4404 | [ALC882_FIXUP_ABIT_AW9D_MAX] = { | 5157 | [ALC882_FIXUP_ABIT_AW9D_MAX] = { |
4405 | .type = ALC_FIXUP_PINS, | 5158 | .type = ALC_FIXUP_PINS, |
@@ -4436,6 +5189,13 @@ static const struct alc_fixup alc882_fixups[] = { | |||
4436 | { } | 5189 | { } |
4437 | } | 5190 | } |
4438 | }, | 5191 | }, |
5192 | [ALC889_FIXUP_CD] = { | ||
5193 | .type = ALC_FIXUP_PINS, | ||
5194 | .v.pins = (const struct alc_pincfg[]) { | ||
5195 | { 0x1c, 0x993301f0 }, /* CD */ | ||
5196 | { } | ||
5197 | } | ||
5198 | }, | ||
4439 | [ALC889_FIXUP_VAIO_TT] = { | 5199 | [ALC889_FIXUP_VAIO_TT] = { |
4440 | .type = ALC_FIXUP_PINS, | 5200 | .type = ALC_FIXUP_PINS, |
4441 | .v.pins = (const struct alc_pincfg[]) { | 5201 | .v.pins = (const struct alc_pincfg[]) { |
@@ -4478,6 +5238,14 @@ static const struct alc_fixup alc882_fixups[] = { | |||
4478 | { } | 5238 | { } |
4479 | } | 5239 | } |
4480 | }, | 5240 | }, |
5241 | [ALC882_FIXUP_GPIO1] = { | ||
5242 | .type = ALC_FIXUP_VERBS, | ||
5243 | .v.verbs = alc_gpio1_init_verbs, | ||
5244 | }, | ||
5245 | [ALC882_FIXUP_GPIO2] = { | ||
5246 | .type = ALC_FIXUP_VERBS, | ||
5247 | .v.verbs = alc_gpio2_init_verbs, | ||
5248 | }, | ||
4481 | [ALC882_FIXUP_GPIO3] = { | 5249 | [ALC882_FIXUP_GPIO3] = { |
4482 | .type = ALC_FIXUP_VERBS, | 5250 | .type = ALC_FIXUP_VERBS, |
4483 | .v.verbs = alc_gpio3_init_verbs, | 5251 | .v.verbs = alc_gpio3_init_verbs, |
@@ -4547,6 +5315,22 @@ static const struct alc_fixup alc882_fixups[] = { | |||
4547 | .type = ALC_FIXUP_FUNC, | 5315 | .type = ALC_FIXUP_FUNC, |
4548 | .v.func = alc885_fixup_macpro_gpio, | 5316 | .v.func = alc885_fixup_macpro_gpio, |
4549 | }, | 5317 | }, |
5318 | [ALC889_FIXUP_DAC_ROUTE] = { | ||
5319 | .type = ALC_FIXUP_FUNC, | ||
5320 | .v.func = alc889_fixup_dac_route, | ||
5321 | }, | ||
5322 | [ALC889_FIXUP_MBP_VREF] = { | ||
5323 | .type = ALC_FIXUP_FUNC, | ||
5324 | .v.func = alc889_fixup_mbp_vref, | ||
5325 | .chained = true, | ||
5326 | .chain_id = ALC882_FIXUP_GPIO1, | ||
5327 | }, | ||
5328 | [ALC889_FIXUP_IMAC91_VREF] = { | ||
5329 | .type = ALC_FIXUP_FUNC, | ||
5330 | .v.func = alc889_fixup_imac91_vref, | ||
5331 | .chained = true, | ||
5332 | .chain_id = ALC882_FIXUP_GPIO1, | ||
5333 | }, | ||
4550 | }; | 5334 | }; |
4551 | 5335 | ||
4552 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { | 5336 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { |
@@ -4571,6 +5355,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { | |||
4571 | SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", | 5355 | SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", |
4572 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 5356 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
4573 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), | 5357 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), |
5358 | SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), | ||
4574 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), | 5359 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), |
4575 | SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), | 5360 | SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), |
4576 | SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), | 5361 | SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), |
@@ -4579,14 +5364,30 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = { | |||
4579 | SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), | 5364 | SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), |
4580 | 5365 | ||
4581 | /* All Apple entries are in codec SSIDs */ | 5366 | /* All Apple entries are in codec SSIDs */ |
5367 | SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), | ||
5368 | SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF), | ||
5369 | SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), | ||
4582 | SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO), | 5370 | SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_FIXUP_MACPRO_GPIO), |
4583 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), | 5371 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), |
4584 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), | 5372 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), |
5373 | SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF), | ||
5374 | SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF), | ||
4585 | SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), | 5375 | SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), |
5376 | SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBP_VREF), | ||
5377 | SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBP_VREF), | ||
5378 | SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF), | ||
5379 | SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), | ||
4586 | SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), | 5380 | SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), |
5381 | SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF), | ||
5382 | SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), | ||
5383 | SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), | ||
5384 | SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), | ||
5385 | SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), | ||
5386 | SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), | ||
4587 | 5387 | ||
4588 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), | 5388 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), |
4589 | SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), | 5389 | SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), |
5390 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3", ALC889_FIXUP_CD), | ||
4590 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), | 5391 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), |
4591 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), | 5392 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), |
4592 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), | 5393 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), |
@@ -4608,14 +5409,10 @@ static int alc882_parse_auto_config(struct hda_codec *codec) | |||
4608 | 5409 | ||
4609 | /* | 5410 | /* |
4610 | */ | 5411 | */ |
4611 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
4612 | #include "alc882_quirks.c" | ||
4613 | #endif | ||
4614 | |||
4615 | static int patch_alc882(struct hda_codec *codec) | 5412 | static int patch_alc882(struct hda_codec *codec) |
4616 | { | 5413 | { |
4617 | struct alc_spec *spec; | 5414 | struct alc_spec *spec; |
4618 | int err, board_config; | 5415 | int err; |
4619 | 5416 | ||
4620 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5417 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
4621 | if (spec == NULL) | 5418 | if (spec == NULL) |
@@ -4639,45 +5436,15 @@ static int patch_alc882(struct hda_codec *codec) | |||
4639 | if (err < 0) | 5436 | if (err < 0) |
4640 | goto error; | 5437 | goto error; |
4641 | 5438 | ||
4642 | board_config = alc_board_config(codec, ALC882_MODEL_LAST, | 5439 | alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); |
4643 | alc882_models, NULL); | 5440 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); |
4644 | if (board_config < 0) | ||
4645 | board_config = alc_board_codec_sid_config(codec, | ||
4646 | ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); | ||
4647 | |||
4648 | if (board_config < 0) { | ||
4649 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
4650 | codec->chip_name); | ||
4651 | board_config = ALC_MODEL_AUTO; | ||
4652 | } | ||
4653 | |||
4654 | if (board_config == ALC_MODEL_AUTO) { | ||
4655 | alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); | ||
4656 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | ||
4657 | } | ||
4658 | 5441 | ||
4659 | alc_auto_parse_customize_define(codec); | 5442 | alc_auto_parse_customize_define(codec); |
4660 | 5443 | ||
4661 | if (board_config == ALC_MODEL_AUTO) { | 5444 | /* automatic parse from the BIOS config */ |
4662 | /* automatic parse from the BIOS config */ | 5445 | err = alc882_parse_auto_config(codec); |
4663 | err = alc882_parse_auto_config(codec); | 5446 | if (err < 0) |
4664 | if (err < 0) | 5447 | goto error; |
4665 | goto error; | ||
4666 | } | ||
4667 | |||
4668 | if (board_config != ALC_MODEL_AUTO) { | ||
4669 | setup_preset(codec, &alc882_presets[board_config]); | ||
4670 | spec->vmaster_nid = 0x0c; | ||
4671 | } | ||
4672 | |||
4673 | if (!spec->no_analog && !spec->adc_nids) { | ||
4674 | alc_auto_fill_adc_caps(codec); | ||
4675 | alc_rebuild_imux_for_auto_mic(codec); | ||
4676 | alc_remove_invalid_adc_nids(codec); | ||
4677 | } | ||
4678 | |||
4679 | if (!spec->no_analog && !spec->cap_mixer) | ||
4680 | set_capture_mixer(codec); | ||
4681 | 5448 | ||
4682 | if (!spec->no_analog && has_cdefine_beep(codec)) { | 5449 | if (!spec->no_analog && has_cdefine_beep(codec)) { |
4683 | err = snd_hda_attach_beep_device(codec, 0x1); | 5450 | err = snd_hda_attach_beep_device(codec, 0x1); |
@@ -4686,16 +5453,9 @@ static int patch_alc882(struct hda_codec *codec) | |||
4686 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 5453 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
4687 | } | 5454 | } |
4688 | 5455 | ||
4689 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | ||
4690 | |||
4691 | codec->patch_ops = alc_patch_ops; | 5456 | codec->patch_ops = alc_patch_ops; |
4692 | if (board_config == ALC_MODEL_AUTO) | ||
4693 | spec->init_hook = alc_auto_init_std; | ||
4694 | 5457 | ||
4695 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5458 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
4696 | if (!spec->loopback.amplist) | ||
4697 | spec->loopback.amplist = alc882_loopbacks; | ||
4698 | #endif | ||
4699 | 5459 | ||
4700 | return 0; | 5460 | return 0; |
4701 | 5461 | ||
@@ -4722,7 +5482,6 @@ enum { | |||
4722 | ALC262_FIXUP_FSC_H270, | 5482 | ALC262_FIXUP_FSC_H270, |
4723 | ALC262_FIXUP_HP_Z200, | 5483 | ALC262_FIXUP_HP_Z200, |
4724 | ALC262_FIXUP_TYAN, | 5484 | ALC262_FIXUP_TYAN, |
4725 | ALC262_FIXUP_TOSHIBA_RX1, | ||
4726 | ALC262_FIXUP_LENOVO_3000, | 5485 | ALC262_FIXUP_LENOVO_3000, |
4727 | ALC262_FIXUP_BENQ, | 5486 | ALC262_FIXUP_BENQ, |
4728 | ALC262_FIXUP_BENQ_T31, | 5487 | ALC262_FIXUP_BENQ_T31, |
@@ -4752,16 +5511,6 @@ static const struct alc_fixup alc262_fixups[] = { | |||
4752 | { } | 5511 | { } |
4753 | } | 5512 | } |
4754 | }, | 5513 | }, |
4755 | [ALC262_FIXUP_TOSHIBA_RX1] = { | ||
4756 | .type = ALC_FIXUP_PINS, | ||
4757 | .v.pins = (const struct alc_pincfg[]) { | ||
4758 | { 0x14, 0x90170110 }, /* speaker */ | ||
4759 | { 0x15, 0x0421101f }, /* HP */ | ||
4760 | { 0x1a, 0x40f000f0 }, /* N/A */ | ||
4761 | { 0x1b, 0x40f000f0 }, /* N/A */ | ||
4762 | { 0x1e, 0x40f000f0 }, /* N/A */ | ||
4763 | } | ||
4764 | }, | ||
4765 | [ALC262_FIXUP_LENOVO_3000] = { | 5514 | [ALC262_FIXUP_LENOVO_3000] = { |
4766 | .type = ALC_FIXUP_VERBS, | 5515 | .type = ALC_FIXUP_VERBS, |
4767 | .v.verbs = (const struct hda_verb[]) { | 5516 | .v.verbs = (const struct hda_verb[]) { |
@@ -4794,8 +5543,6 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = { | |||
4794 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ), | 5543 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FIXUP_BENQ), |
4795 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), | 5544 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), |
4796 | SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), | 5545 | SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), |
4797 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", | ||
4798 | ALC262_FIXUP_TOSHIBA_RX1), | ||
4799 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), | 5546 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), |
4800 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), | 5547 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), |
4801 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), | 5548 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), |
@@ -4804,10 +5551,6 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = { | |||
4804 | }; | 5551 | }; |
4805 | 5552 | ||
4806 | 5553 | ||
4807 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
4808 | #define alc262_loopbacks alc880_loopbacks | ||
4809 | #endif | ||
4810 | |||
4811 | /* | 5554 | /* |
4812 | */ | 5555 | */ |
4813 | static int patch_alc262(struct hda_codec *codec) | 5556 | static int patch_alc262(struct hda_codec *codec) |
@@ -4847,15 +5590,6 @@ static int patch_alc262(struct hda_codec *codec) | |||
4847 | if (err < 0) | 5590 | if (err < 0) |
4848 | goto error; | 5591 | goto error; |
4849 | 5592 | ||
4850 | if (!spec->no_analog && !spec->adc_nids) { | ||
4851 | alc_auto_fill_adc_caps(codec); | ||
4852 | alc_rebuild_imux_for_auto_mic(codec); | ||
4853 | alc_remove_invalid_adc_nids(codec); | ||
4854 | } | ||
4855 | |||
4856 | if (!spec->no_analog && !spec->cap_mixer) | ||
4857 | set_capture_mixer(codec); | ||
4858 | |||
4859 | if (!spec->no_analog && has_cdefine_beep(codec)) { | 5593 | if (!spec->no_analog && has_cdefine_beep(codec)) { |
4860 | err = snd_hda_attach_beep_device(codec, 0x1); | 5594 | err = snd_hda_attach_beep_device(codec, 0x1); |
4861 | if (err < 0) | 5595 | if (err < 0) |
@@ -4863,16 +5597,10 @@ static int patch_alc262(struct hda_codec *codec) | |||
4863 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 5597 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
4864 | } | 5598 | } |
4865 | 5599 | ||
4866 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | ||
4867 | |||
4868 | codec->patch_ops = alc_patch_ops; | 5600 | codec->patch_ops = alc_patch_ops; |
4869 | spec->init_hook = alc_auto_init_std; | ||
4870 | spec->shutup = alc_eapd_shutup; | 5601 | spec->shutup = alc_eapd_shutup; |
4871 | 5602 | ||
4872 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5603 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
4873 | if (!spec->loopback.amplist) | ||
4874 | spec->loopback.amplist = alc262_loopbacks; | ||
4875 | #endif | ||
4876 | 5604 | ||
4877 | return 0; | 5605 | return 0; |
4878 | 5606 | ||
@@ -4966,17 +5694,7 @@ static int patch_alc268(struct hda_codec *codec) | |||
4966 | (0 << AC_AMPCAP_MUTE_SHIFT)); | 5694 | (0 << AC_AMPCAP_MUTE_SHIFT)); |
4967 | } | 5695 | } |
4968 | 5696 | ||
4969 | if (!spec->no_analog && !spec->adc_nids) { | ||
4970 | alc_auto_fill_adc_caps(codec); | ||
4971 | alc_rebuild_imux_for_auto_mic(codec); | ||
4972 | alc_remove_invalid_adc_nids(codec); | ||
4973 | } | ||
4974 | |||
4975 | if (!spec->no_analog && !spec->cap_mixer) | ||
4976 | set_capture_mixer(codec); | ||
4977 | |||
4978 | codec->patch_ops = alc_patch_ops; | 5697 | codec->patch_ops = alc_patch_ops; |
4979 | spec->init_hook = alc_auto_init_std; | ||
4980 | spec->shutup = alc_eapd_shutup; | 5698 | spec->shutup = alc_eapd_shutup; |
4981 | 5699 | ||
4982 | return 0; | 5700 | return 0; |
@@ -4989,10 +5707,6 @@ static int patch_alc268(struct hda_codec *codec) | |||
4989 | /* | 5707 | /* |
4990 | * ALC269 | 5708 | * ALC269 |
4991 | */ | 5709 | */ |
4992 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
4993 | #define alc269_loopbacks alc880_loopbacks | ||
4994 | #endif | ||
4995 | |||
4996 | static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { | 5710 | static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { |
4997 | .substreams = 1, | 5711 | .substreams = 1, |
4998 | .channels_min = 2, | 5712 | .channels_min = 2, |
@@ -5014,35 +5728,6 @@ static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = { | |||
5014 | /* NID is set in alc_build_pcms */ | 5728 | /* NID is set in alc_build_pcms */ |
5015 | }; | 5729 | }; |
5016 | 5730 | ||
5017 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
5018 | static int alc269_mic2_for_mute_led(struct hda_codec *codec) | ||
5019 | { | ||
5020 | switch (codec->subsystem_id) { | ||
5021 | case 0x103c1586: | ||
5022 | return 1; | ||
5023 | } | ||
5024 | return 0; | ||
5025 | } | ||
5026 | |||
5027 | static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid) | ||
5028 | { | ||
5029 | /* update mute-LED according to the speaker mute state */ | ||
5030 | if (nid == 0x01 || nid == 0x14) { | ||
5031 | int pinval; | ||
5032 | if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) & | ||
5033 | HDA_AMP_MUTE) | ||
5034 | pinval = 0x24; | ||
5035 | else | ||
5036 | pinval = 0x20; | ||
5037 | /* mic2 vref pin is used for mute LED control */ | ||
5038 | snd_hda_codec_update_cache(codec, 0x19, 0, | ||
5039 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
5040 | pinval); | ||
5041 | } | ||
5042 | return alc_check_power_status(codec, nid); | ||
5043 | } | ||
5044 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ | ||
5045 | |||
5046 | /* different alc269-variants */ | 5731 | /* different alc269-variants */ |
5047 | enum { | 5732 | enum { |
5048 | ALC269_TYPE_ALC269VA, | 5733 | ALC269_TYPE_ALC269VA, |
@@ -5193,6 +5878,31 @@ static void alc269_fixup_quanta_mute(struct hda_codec *codec, | |||
5193 | spec->automute_hook = alc269_quanta_automute; | 5878 | spec->automute_hook = alc269_quanta_automute; |
5194 | } | 5879 | } |
5195 | 5880 | ||
5881 | /* update mute-LED according to the speaker mute state via mic2 VREF pin */ | ||
5882 | static void alc269_fixup_mic2_mute_hook(void *private_data, int enabled) | ||
5883 | { | ||
5884 | struct hda_codec *codec = private_data; | ||
5885 | unsigned int pinval = enabled ? 0x20 : 0x24; | ||
5886 | snd_hda_codec_update_cache(codec, 0x19, 0, | ||
5887 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
5888 | pinval); | ||
5889 | } | ||
5890 | |||
5891 | static void alc269_fixup_mic2_mute(struct hda_codec *codec, | ||
5892 | const struct alc_fixup *fix, int action) | ||
5893 | { | ||
5894 | struct alc_spec *spec = codec->spec; | ||
5895 | switch (action) { | ||
5896 | case ALC_FIXUP_ACT_BUILD: | ||
5897 | spec->vmaster_mute.hook = alc269_fixup_mic2_mute_hook; | ||
5898 | snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true); | ||
5899 | /* fallthru */ | ||
5900 | case ALC_FIXUP_ACT_INIT: | ||
5901 | snd_hda_sync_vmaster_hook(&spec->vmaster_mute); | ||
5902 | break; | ||
5903 | } | ||
5904 | } | ||
5905 | |||
5196 | enum { | 5906 | enum { |
5197 | ALC269_FIXUP_SONY_VAIO, | 5907 | ALC269_FIXUP_SONY_VAIO, |
5198 | ALC275_FIXUP_SONY_VAIO_GPIO2, | 5908 | ALC275_FIXUP_SONY_VAIO_GPIO2, |
@@ -5210,6 +5920,7 @@ enum { | |||
5210 | ALC269_FIXUP_DMIC, | 5920 | ALC269_FIXUP_DMIC, |
5211 | ALC269VB_FIXUP_AMIC, | 5921 | ALC269VB_FIXUP_AMIC, |
5212 | ALC269VB_FIXUP_DMIC, | 5922 | ALC269VB_FIXUP_DMIC, |
5923 | ALC269_FIXUP_MIC2_MUTE_LED, | ||
5213 | }; | 5924 | }; |
5214 | 5925 | ||
5215 | static const struct alc_fixup alc269_fixups[] = { | 5926 | static const struct alc_fixup alc269_fixups[] = { |
@@ -5330,9 +6041,14 @@ static const struct alc_fixup alc269_fixups[] = { | |||
5330 | { } | 6041 | { } |
5331 | }, | 6042 | }, |
5332 | }, | 6043 | }, |
6044 | [ALC269_FIXUP_MIC2_MUTE_LED] = { | ||
6045 | .type = ALC_FIXUP_FUNC, | ||
6046 | .v.func = alc269_fixup_mic2_mute, | ||
6047 | }, | ||
5333 | }; | 6048 | }; |
5334 | 6049 | ||
5335 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 6050 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
6051 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), | ||
5336 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), | 6052 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), |
5337 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), | 6053 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), |
5338 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), | 6054 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), |
@@ -5355,7 +6071,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
5355 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), | 6071 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), |
5356 | SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), | 6072 | SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), |
5357 | 6073 | ||
5358 | #if 1 | 6074 | #if 0 |
5359 | /* Below is a quirk table taken from the old code. | 6075 | /* Below is a quirk table taken from the old code. |
5360 | * Basically the device should work as is without the fixup table. | 6076 | * Basically the device should work as is without the fixup table. |
5361 | * If BIOS doesn't give a proper info, enable the corresponding | 6077 | * If BIOS doesn't give a proper info, enable the corresponding |
@@ -5364,7 +6080,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
5364 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", | 6080 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", |
5365 | ALC269_FIXUP_AMIC), | 6081 | ALC269_FIXUP_AMIC), |
5366 | SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), | 6082 | SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), |
5367 | SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269_FIXUP_AMIC), | ||
5368 | SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), | 6083 | SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), |
5369 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), | 6084 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), |
5370 | SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), | 6085 | SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), |
@@ -5414,10 +6129,14 @@ static const struct alc_model_fixup alc269_fixup_models[] = { | |||
5414 | }; | 6129 | }; |
5415 | 6130 | ||
5416 | 6131 | ||
5417 | static int alc269_fill_coef(struct hda_codec *codec) | 6132 | static void alc269_fill_coef(struct hda_codec *codec) |
5418 | { | 6133 | { |
6134 | struct alc_spec *spec = codec->spec; | ||
5419 | int val; | 6135 | int val; |
5420 | 6136 | ||
6137 | if (spec->codec_variant != ALC269_TYPE_ALC269VB) | ||
6138 | return; | ||
6139 | |||
5421 | if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { | 6140 | if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { |
5422 | alc_write_coef_idx(codec, 0xf, 0x960b); | 6141 | alc_write_coef_idx(codec, 0xf, 0x960b); |
5423 | alc_write_coef_idx(codec, 0xe, 0x8817); | 6142 | alc_write_coef_idx(codec, 0xe, 0x8817); |
@@ -5452,8 +6171,6 @@ static int alc269_fill_coef(struct hda_codec *codec) | |||
5452 | 6171 | ||
5453 | val = alc_read_coef_idx(codec, 0x4); /* HP */ | 6172 | val = alc_read_coef_idx(codec, 0x4); /* HP */ |
5454 | alc_write_coef_idx(codec, 0x4, val | (1<<11)); | 6173 | alc_write_coef_idx(codec, 0x4, val | (1<<11)); |
5455 | |||
5456 | return 0; | ||
5457 | } | 6174 | } |
5458 | 6175 | ||
5459 | /* | 6176 | /* |
@@ -5497,6 +6214,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
5497 | } | 6214 | } |
5498 | if (err < 0) | 6215 | if (err < 0) |
5499 | goto error; | 6216 | goto error; |
6217 | spec->init_hook = alc269_fill_coef; | ||
5500 | alc269_fill_coef(codec); | 6218 | alc269_fill_coef(codec); |
5501 | } | 6219 | } |
5502 | 6220 | ||
@@ -5509,15 +6227,6 @@ static int patch_alc269(struct hda_codec *codec) | |||
5509 | if (err < 0) | 6227 | if (err < 0) |
5510 | goto error; | 6228 | goto error; |
5511 | 6229 | ||
5512 | if (!spec->no_analog && !spec->adc_nids) { | ||
5513 | alc_auto_fill_adc_caps(codec); | ||
5514 | alc_rebuild_imux_for_auto_mic(codec); | ||
5515 | alc_remove_invalid_adc_nids(codec); | ||
5516 | } | ||
5517 | |||
5518 | if (!spec->no_analog && !spec->cap_mixer) | ||
5519 | set_capture_mixer(codec); | ||
5520 | |||
5521 | if (!spec->no_analog && has_cdefine_beep(codec)) { | 6230 | if (!spec->no_analog && has_cdefine_beep(codec)) { |
5522 | err = snd_hda_attach_beep_device(codec, 0x1); | 6231 | err = snd_hda_attach_beep_device(codec, 0x1); |
5523 | if (err < 0) | 6232 | if (err < 0) |
@@ -5525,21 +6234,13 @@ static int patch_alc269(struct hda_codec *codec) | |||
5525 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | 6234 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); |
5526 | } | 6235 | } |
5527 | 6236 | ||
5528 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | ||
5529 | |||
5530 | codec->patch_ops = alc_patch_ops; | 6237 | codec->patch_ops = alc_patch_ops; |
5531 | #ifdef CONFIG_PM | 6238 | #ifdef CONFIG_PM |
5532 | codec->patch_ops.resume = alc269_resume; | 6239 | codec->patch_ops.resume = alc269_resume; |
5533 | #endif | 6240 | #endif |
5534 | spec->init_hook = alc_auto_init_std; | ||
5535 | spec->shutup = alc269_shutup; | 6241 | spec->shutup = alc269_shutup; |
5536 | 6242 | ||
5537 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 6243 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
5538 | if (!spec->loopback.amplist) | ||
5539 | spec->loopback.amplist = alc269_loopbacks; | ||
5540 | if (alc269_mic2_for_mute_led(codec)) | ||
5541 | codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps; | ||
5542 | #endif | ||
5543 | 6244 | ||
5544 | return 0; | 6245 | return 0; |
5545 | 6246 | ||
@@ -5559,24 +6260,43 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
5559 | return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids); | 6260 | return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids); |
5560 | } | 6261 | } |
5561 | 6262 | ||
5562 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
5563 | static const struct hda_amp_list alc861_loopbacks[] = { | ||
5564 | { 0x15, HDA_INPUT, 0 }, | ||
5565 | { 0x15, HDA_INPUT, 1 }, | ||
5566 | { 0x15, HDA_INPUT, 2 }, | ||
5567 | { 0x15, HDA_INPUT, 3 }, | ||
5568 | { } /* end */ | ||
5569 | }; | ||
5570 | #endif | ||
5571 | |||
5572 | |||
5573 | /* Pin config fixes */ | 6263 | /* Pin config fixes */ |
5574 | enum { | 6264 | enum { |
5575 | PINFIX_FSC_AMILO_PI1505, | 6265 | ALC861_FIXUP_FSC_AMILO_PI1505, |
6266 | ALC861_FIXUP_AMP_VREF_0F, | ||
6267 | ALC861_FIXUP_NO_JACK_DETECT, | ||
6268 | ALC861_FIXUP_ASUS_A6RP, | ||
5576 | }; | 6269 | }; |
5577 | 6270 | ||
6271 | /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ | ||
6272 | static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, | ||
6273 | const struct alc_fixup *fix, int action) | ||
6274 | { | ||
6275 | struct alc_spec *spec = codec->spec; | ||
6276 | unsigned int val; | ||
6277 | |||
6278 | if (action != ALC_FIXUP_ACT_INIT) | ||
6279 | return; | ||
6280 | val = snd_hda_codec_read(codec, 0x0f, 0, | ||
6281 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
6282 | if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) | ||
6283 | val |= AC_PINCTL_IN_EN; | ||
6284 | val |= AC_PINCTL_VREF_50; | ||
6285 | snd_hda_codec_write(codec, 0x0f, 0, | ||
6286 | AC_VERB_SET_PIN_WIDGET_CONTROL, val); | ||
6287 | spec->keep_vref_in_automute = 1; | ||
6288 | } | ||
6289 | |||
6290 | /* suppress the jack-detection */ | ||
6291 | static void alc_fixup_no_jack_detect(struct hda_codec *codec, | ||
6292 | const struct alc_fixup *fix, int action) | ||
6293 | { | ||
6294 | if (action == ALC_FIXUP_ACT_PRE_PROBE) | ||
6295 | codec->no_jack_detect = 1; | ||
6296 | } | ||
6297 | |||
5578 | static const struct alc_fixup alc861_fixups[] = { | 6298 | static const struct alc_fixup alc861_fixups[] = { |
5579 | [PINFIX_FSC_AMILO_PI1505] = { | 6299 | [ALC861_FIXUP_FSC_AMILO_PI1505] = { |
5580 | .type = ALC_FIXUP_PINS, | 6300 | .type = ALC_FIXUP_PINS, |
5581 | .v.pins = (const struct alc_pincfg[]) { | 6301 | .v.pins = (const struct alc_pincfg[]) { |
5582 | { 0x0b, 0x0221101f }, /* HP */ | 6302 | { 0x0b, 0x0221101f }, /* HP */ |
@@ -5584,10 +6304,29 @@ static const struct alc_fixup alc861_fixups[] = { | |||
5584 | { } | 6304 | { } |
5585 | } | 6305 | } |
5586 | }, | 6306 | }, |
6307 | [ALC861_FIXUP_AMP_VREF_0F] = { | ||
6308 | .type = ALC_FIXUP_FUNC, | ||
6309 | .v.func = alc861_fixup_asus_amp_vref_0f, | ||
6310 | }, | ||
6311 | [ALC861_FIXUP_NO_JACK_DETECT] = { | ||
6312 | .type = ALC_FIXUP_FUNC, | ||
6313 | .v.func = alc_fixup_no_jack_detect, | ||
6314 | }, | ||
6315 | [ALC861_FIXUP_ASUS_A6RP] = { | ||
6316 | .type = ALC_FIXUP_FUNC, | ||
6317 | .v.func = alc861_fixup_asus_amp_vref_0f, | ||
6318 | .chained = true, | ||
6319 | .chain_id = ALC861_FIXUP_NO_JACK_DETECT, | ||
6320 | } | ||
5587 | }; | 6321 | }; |
5588 | 6322 | ||
5589 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { | 6323 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { |
5590 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), | 6324 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP), |
6325 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F), | ||
6326 | SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT), | ||
6327 | SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F), | ||
6328 | SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F), | ||
6329 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505), | ||
5591 | {} | 6330 | {} |
5592 | }; | 6331 | }; |
5593 | 6332 | ||
@@ -5614,15 +6353,6 @@ static int patch_alc861(struct hda_codec *codec) | |||
5614 | if (err < 0) | 6353 | if (err < 0) |
5615 | goto error; | 6354 | goto error; |
5616 | 6355 | ||
5617 | if (!spec->no_analog && !spec->adc_nids) { | ||
5618 | alc_auto_fill_adc_caps(codec); | ||
5619 | alc_rebuild_imux_for_auto_mic(codec); | ||
5620 | alc_remove_invalid_adc_nids(codec); | ||
5621 | } | ||
5622 | |||
5623 | if (!spec->no_analog && !spec->cap_mixer) | ||
5624 | set_capture_mixer(codec); | ||
5625 | |||
5626 | if (!spec->no_analog) { | 6356 | if (!spec->no_analog) { |
5627 | err = snd_hda_attach_beep_device(codec, 0x23); | 6357 | err = snd_hda_attach_beep_device(codec, 0x23); |
5628 | if (err < 0) | 6358 | if (err < 0) |
@@ -5630,16 +6360,13 @@ static int patch_alc861(struct hda_codec *codec) | |||
5630 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); | 6360 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); |
5631 | } | 6361 | } |
5632 | 6362 | ||
5633 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | ||
5634 | |||
5635 | codec->patch_ops = alc_patch_ops; | 6363 | codec->patch_ops = alc_patch_ops; |
5636 | spec->init_hook = alc_auto_init_std; | ||
5637 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 6364 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5638 | spec->power_hook = alc_power_eapd; | 6365 | spec->power_hook = alc_power_eapd; |
5639 | if (!spec->loopback.amplist) | ||
5640 | spec->loopback.amplist = alc861_loopbacks; | ||
5641 | #endif | 6366 | #endif |
5642 | 6367 | ||
6368 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | ||
6369 | |||
5643 | return 0; | 6370 | return 0; |
5644 | 6371 | ||
5645 | error: | 6372 | error: |
@@ -5654,10 +6381,6 @@ static int patch_alc861(struct hda_codec *codec) | |||
5654 | * | 6381 | * |
5655 | * In addition, an independent DAC | 6382 | * In addition, an independent DAC |
5656 | */ | 6383 | */ |
5657 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
5658 | #define alc861vd_loopbacks alc880_loopbacks | ||
5659 | #endif | ||
5660 | |||
5661 | static int alc861vd_parse_auto_config(struct hda_codec *codec) | 6384 | static int alc861vd_parse_auto_config(struct hda_codec *codec) |
5662 | { | 6385 | { |
5663 | static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; | 6386 | static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; |
@@ -5738,15 +6461,6 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
5738 | add_verb(spec, alc660vd_eapd_verbs); | 6461 | add_verb(spec, alc660vd_eapd_verbs); |
5739 | } | 6462 | } |
5740 | 6463 | ||
5741 | if (!spec->no_analog && !spec->adc_nids) { | ||
5742 | alc_auto_fill_adc_caps(codec); | ||
5743 | alc_rebuild_imux_for_auto_mic(codec); | ||
5744 | alc_remove_invalid_adc_nids(codec); | ||
5745 | } | ||
5746 | |||
5747 | if (!spec->no_analog && !spec->cap_mixer) | ||
5748 | set_capture_mixer(codec); | ||
5749 | |||
5750 | if (!spec->no_analog) { | 6464 | if (!spec->no_analog) { |
5751 | err = snd_hda_attach_beep_device(codec, 0x23); | 6465 | err = snd_hda_attach_beep_device(codec, 0x23); |
5752 | if (err < 0) | 6466 | if (err < 0) |
@@ -5754,16 +6468,11 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
5754 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 6468 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
5755 | } | 6469 | } |
5756 | 6470 | ||
5757 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | ||
5758 | |||
5759 | codec->patch_ops = alc_patch_ops; | 6471 | codec->patch_ops = alc_patch_ops; |
5760 | 6472 | ||
5761 | spec->init_hook = alc_auto_init_std; | ||
5762 | spec->shutup = alc_eapd_shutup; | 6473 | spec->shutup = alc_eapd_shutup; |
5763 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 6474 | |
5764 | if (!spec->loopback.amplist) | 6475 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
5765 | spec->loopback.amplist = alc861vd_loopbacks; | ||
5766 | #endif | ||
5767 | 6476 | ||
5768 | return 0; | 6477 | return 0; |
5769 | 6478 | ||
@@ -5783,9 +6492,6 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
5783 | * In addition, an independent DAC for the multi-playback (not used in this | 6492 | * In addition, an independent DAC for the multi-playback (not used in this |
5784 | * driver yet). | 6493 | * driver yet). |
5785 | */ | 6494 | */ |
5786 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
5787 | #define alc662_loopbacks alc880_loopbacks | ||
5788 | #endif | ||
5789 | 6495 | ||
5790 | /* | 6496 | /* |
5791 | * BIOS auto configuration | 6497 | * BIOS auto configuration |
@@ -5835,6 +6541,7 @@ enum { | |||
5835 | ALC662_FIXUP_ASUS_MODE6, | 6541 | ALC662_FIXUP_ASUS_MODE6, |
5836 | ALC662_FIXUP_ASUS_MODE7, | 6542 | ALC662_FIXUP_ASUS_MODE7, |
5837 | ALC662_FIXUP_ASUS_MODE8, | 6543 | ALC662_FIXUP_ASUS_MODE8, |
6544 | ALC662_FIXUP_NO_JACK_DETECT, | ||
5838 | }; | 6545 | }; |
5839 | 6546 | ||
5840 | static const struct alc_fixup alc662_fixups[] = { | 6547 | static const struct alc_fixup alc662_fixups[] = { |
@@ -5980,6 +6687,10 @@ static const struct alc_fixup alc662_fixups[] = { | |||
5980 | .chained = true, | 6687 | .chained = true, |
5981 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 6688 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5982 | }, | 6689 | }, |
6690 | [ALC662_FIXUP_NO_JACK_DETECT] = { | ||
6691 | .type = ALC_FIXUP_FUNC, | ||
6692 | .v.func = alc_fixup_no_jack_detect, | ||
6693 | }, | ||
5983 | }; | 6694 | }; |
5984 | 6695 | ||
5985 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { | 6696 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
@@ -5988,6 +6699,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { | |||
5988 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), | 6699 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), |
5989 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | 6700 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
5990 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), | 6701 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), |
6702 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), | ||
5991 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), | 6703 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), |
5992 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), | 6704 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), |
5993 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), | 6705 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), |
@@ -6109,15 +6821,6 @@ static int patch_alc662(struct hda_codec *codec) | |||
6109 | if (err < 0) | 6821 | if (err < 0) |
6110 | goto error; | 6822 | goto error; |
6111 | 6823 | ||
6112 | if (!spec->no_analog && !spec->adc_nids) { | ||
6113 | alc_auto_fill_adc_caps(codec); | ||
6114 | alc_rebuild_imux_for_auto_mic(codec); | ||
6115 | alc_remove_invalid_adc_nids(codec); | ||
6116 | } | ||
6117 | |||
6118 | if (!spec->no_analog && !spec->cap_mixer) | ||
6119 | set_capture_mixer(codec); | ||
6120 | |||
6121 | if (!spec->no_analog && has_cdefine_beep(codec)) { | 6824 | if (!spec->no_analog && has_cdefine_beep(codec)) { |
6122 | err = snd_hda_attach_beep_device(codec, 0x1); | 6825 | err = snd_hda_attach_beep_device(codec, 0x1); |
6123 | if (err < 0) | 6826 | if (err < 0) |
@@ -6137,16 +6840,10 @@ static int patch_alc662(struct hda_codec *codec) | |||
6137 | } | 6840 | } |
6138 | } | 6841 | } |
6139 | 6842 | ||
6140 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | ||
6141 | |||
6142 | codec->patch_ops = alc_patch_ops; | 6843 | codec->patch_ops = alc_patch_ops; |
6143 | spec->init_hook = alc_auto_init_std; | ||
6144 | spec->shutup = alc_eapd_shutup; | 6844 | spec->shutup = alc_eapd_shutup; |
6145 | 6845 | ||
6146 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 6846 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
6147 | if (!spec->loopback.amplist) | ||
6148 | spec->loopback.amplist = alc662_loopbacks; | ||
6149 | #endif | ||
6150 | 6847 | ||
6151 | return 0; | 6848 | return 0; |
6152 | 6849 | ||
@@ -6186,11 +6883,7 @@ static int patch_alc680(struct hda_codec *codec) | |||
6186 | return err; | 6883 | return err; |
6187 | } | 6884 | } |
6188 | 6885 | ||
6189 | if (!spec->no_analog && !spec->cap_mixer) | ||
6190 | set_capture_mixer(codec); | ||
6191 | |||
6192 | codec->patch_ops = alc_patch_ops; | 6886 | codec->patch_ops = alc_patch_ops; |
6193 | spec->init_hook = alc_auto_init_std; | ||
6194 | 6887 | ||
6195 | return 0; | 6888 | return 0; |
6196 | } | 6889 | } |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 3556408d6ece..33a9946b492c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -99,6 +99,7 @@ enum { | |||
99 | STAC_DELL_VOSTRO_3500, | 99 | STAC_DELL_VOSTRO_3500, |
100 | STAC_92HD83XXX_HP_cNB11_INTQUAD, | 100 | STAC_92HD83XXX_HP_cNB11_INTQUAD, |
101 | STAC_HP_DV7_4000, | 101 | STAC_HP_DV7_4000, |
102 | STAC_HP_ZEPHYR, | ||
102 | STAC_92HD83XXX_MODELS | 103 | STAC_92HD83XXX_MODELS |
103 | }; | 104 | }; |
104 | 105 | ||
@@ -309,6 +310,8 @@ struct sigmatel_spec { | |||
309 | unsigned long auto_capvols[MAX_ADCS_NUM]; | 310 | unsigned long auto_capvols[MAX_ADCS_NUM]; |
310 | unsigned auto_dmic_cnt; | 311 | unsigned auto_dmic_cnt; |
311 | hda_nid_t auto_dmic_nids[MAX_DMICS_NUM]; | 312 | hda_nid_t auto_dmic_nids[MAX_DMICS_NUM]; |
313 | |||
314 | struct hda_vmaster_mute_hook vmaster_mute; | ||
312 | }; | 315 | }; |
313 | 316 | ||
314 | static const hda_nid_t stac9200_adc_nids[1] = { | 317 | static const hda_nid_t stac9200_adc_nids[1] = { |
@@ -662,7 +665,6 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol, | |||
662 | return 0; | 665 | return 0; |
663 | } | 666 | } |
664 | 667 | ||
665 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
666 | static int stac_vrefout_set(struct hda_codec *codec, | 668 | static int stac_vrefout_set(struct hda_codec *codec, |
667 | hda_nid_t nid, unsigned int new_vref) | 669 | hda_nid_t nid, unsigned int new_vref) |
668 | { | 670 | { |
@@ -686,7 +688,6 @@ static int stac_vrefout_set(struct hda_codec *codec, | |||
686 | 688 | ||
687 | return 1; | 689 | return 1; |
688 | } | 690 | } |
689 | #endif | ||
690 | 691 | ||
691 | static unsigned int stac92xx_vref_set(struct hda_codec *codec, | 692 | static unsigned int stac92xx_vref_set(struct hda_codec *codec, |
692 | hda_nid_t nid, unsigned int new_vref) | 693 | hda_nid_t nid, unsigned int new_vref) |
@@ -894,6 +895,13 @@ static const struct hda_verb stac92hd83xxx_core_init[] = { | |||
894 | {} | 895 | {} |
895 | }; | 896 | }; |
896 | 897 | ||
898 | static const struct hda_verb stac92hd83xxx_hp_zephyr_init[] = { | ||
899 | { 0x22, 0x785, 0x43 }, | ||
900 | { 0x22, 0x782, 0xe0 }, | ||
901 | { 0x22, 0x795, 0x00 }, | ||
902 | {} | ||
903 | }; | ||
904 | |||
897 | static const struct hda_verb stac92hd71bxx_core_init[] = { | 905 | static const struct hda_verb stac92hd71bxx_core_init[] = { |
898 | /* set master volume and direct control */ | 906 | /* set master volume and direct control */ |
899 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 907 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
@@ -999,8 +1007,8 @@ static const struct hda_verb stac9205_core_init[] = { | |||
999 | } | 1007 | } |
1000 | 1008 | ||
1001 | static const struct snd_kcontrol_new stac9200_mixer[] = { | 1009 | static const struct snd_kcontrol_new stac9200_mixer[] = { |
1002 | HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xb, 0, HDA_OUTPUT), | 1010 | HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xb, 0, HDA_OUTPUT), |
1003 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), | 1011 | HDA_CODEC_MUTE("PCM Playback Switch", 0xb, 0, HDA_OUTPUT), |
1004 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), | 1012 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), |
1005 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), | 1013 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), |
1006 | { } /* end */ | 1014 | { } /* end */ |
@@ -1027,8 +1035,8 @@ static const struct snd_kcontrol_new stac92hd71bxx_loopback[] = { | |||
1027 | }; | 1035 | }; |
1028 | 1036 | ||
1029 | static const struct snd_kcontrol_new stac925x_mixer[] = { | 1037 | static const struct snd_kcontrol_new stac925x_mixer[] = { |
1030 | HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xe, 0, HDA_OUTPUT), | 1038 | HDA_CODEC_VOLUME_MIN_MUTE("PCM Playback Volume", 0xe, 0, HDA_OUTPUT), |
1031 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), | 1039 | HDA_CODEC_MUTE("PCM Playback Switch", 0x0e, 0, HDA_OUTPUT), |
1032 | { } /* end */ | 1040 | { } /* end */ |
1033 | }; | 1041 | }; |
1034 | 1042 | ||
@@ -1060,34 +1068,25 @@ static struct snd_kcontrol_new stac_smux_mixer = { | |||
1060 | .put = stac92xx_smux_enum_put, | 1068 | .put = stac92xx_smux_enum_put, |
1061 | }; | 1069 | }; |
1062 | 1070 | ||
1063 | static const char * const slave_vols[] = { | 1071 | static const char * const slave_pfxs[] = { |
1064 | "Front Playback Volume", | 1072 | "Front", "Surround", "Center", "LFE", "Side", |
1065 | "Surround Playback Volume", | 1073 | "Headphone", "Speaker", "IEC958", |
1066 | "Center Playback Volume", | ||
1067 | "LFE Playback Volume", | ||
1068 | "Side Playback Volume", | ||
1069 | "Headphone Playback Volume", | ||
1070 | "Speaker Playback Volume", | ||
1071 | NULL | 1074 | NULL |
1072 | }; | 1075 | }; |
1073 | 1076 | ||
1074 | static const char * const slave_sws[] = { | 1077 | static void stac92xx_update_led_status(struct hda_codec *codec, int enabled); |
1075 | "Front Playback Switch", | 1078 | |
1076 | "Surround Playback Switch", | 1079 | static void stac92xx_vmaster_hook(void *private_data, int val) |
1077 | "Center Playback Switch", | 1080 | { |
1078 | "LFE Playback Switch", | 1081 | stac92xx_update_led_status(private_data, val); |
1079 | "Side Playback Switch", | 1082 | } |
1080 | "Headphone Playback Switch", | ||
1081 | "Speaker Playback Switch", | ||
1082 | "IEC958 Playback Switch", | ||
1083 | NULL | ||
1084 | }; | ||
1085 | 1083 | ||
1086 | static void stac92xx_free_kctls(struct hda_codec *codec); | 1084 | static void stac92xx_free_kctls(struct hda_codec *codec); |
1087 | 1085 | ||
1088 | static int stac92xx_build_controls(struct hda_codec *codec) | 1086 | static int stac92xx_build_controls(struct hda_codec *codec) |
1089 | { | 1087 | { |
1090 | struct sigmatel_spec *spec = codec->spec; | 1088 | struct sigmatel_spec *spec = codec->spec; |
1089 | unsigned int vmaster_tlv[4]; | ||
1091 | int err; | 1090 | int err; |
1092 | int i; | 1091 | int i; |
1093 | 1092 | ||
@@ -1144,22 +1143,28 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
1144 | } | 1143 | } |
1145 | 1144 | ||
1146 | /* if we have no master control, let's create it */ | 1145 | /* if we have no master control, let's create it */ |
1147 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { | 1146 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], |
1148 | unsigned int vmaster_tlv[4]; | 1147 | HDA_OUTPUT, vmaster_tlv); |
1149 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], | 1148 | /* correct volume offset */ |
1150 | HDA_OUTPUT, vmaster_tlv); | 1149 | vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset; |
1151 | /* correct volume offset */ | 1150 | /* minimum value is actually mute */ |
1152 | vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset; | 1151 | vmaster_tlv[3] |= TLV_DB_SCALE_MUTE; |
1153 | /* minimum value is actually mute */ | 1152 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", |
1154 | vmaster_tlv[3] |= TLV_DB_SCALE_MUTE; | 1153 | vmaster_tlv, slave_pfxs, |
1155 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | 1154 | "Playback Volume"); |
1156 | vmaster_tlv, slave_vols); | 1155 | if (err < 0) |
1157 | if (err < 0) | 1156 | return err; |
1158 | return err; | 1157 | |
1159 | } | 1158 | err = __snd_hda_add_vmaster(codec, "Master Playback Switch", |
1160 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | 1159 | NULL, slave_pfxs, |
1161 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", | 1160 | "Playback Switch", true, |
1162 | NULL, slave_sws); | 1161 | &spec->vmaster_mute.sw_kctl); |
1162 | if (err < 0) | ||
1163 | return err; | ||
1164 | |||
1165 | if (spec->gpio_led) { | ||
1166 | spec->vmaster_mute.hook = stac92xx_vmaster_hook; | ||
1167 | err = snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute, true); | ||
1163 | if (err < 0) | 1168 | if (err < 0) |
1164 | return err; | 1169 | return err; |
1165 | } | 1170 | } |
@@ -1608,7 +1613,7 @@ static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { | |||
1608 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, | 1613 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, |
1609 | "Alienware M17x", STAC_ALIENWARE_M17X), | 1614 | "Alienware M17x", STAC_ALIENWARE_M17X), |
1610 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, | 1615 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, |
1611 | "Alienware M17x", STAC_ALIENWARE_M17X), | 1616 | "Alienware M17x R3", STAC_DELL_EQ), |
1612 | {} /* terminator */ | 1617 | {} /* terminator */ |
1613 | }; | 1618 | }; |
1614 | 1619 | ||
@@ -1636,6 +1641,12 @@ static const unsigned int hp_dv7_4000_pin_configs[10] = { | |||
1636 | 0x40f000f0, 0x40f000f0, | 1641 | 0x40f000f0, 0x40f000f0, |
1637 | }; | 1642 | }; |
1638 | 1643 | ||
1644 | static const unsigned int hp_zephyr_pin_configs[10] = { | ||
1645 | 0x01813050, 0x0421201f, 0x04a1205e, 0x96130310, | ||
1646 | 0x96130310, 0x0101401f, 0x1111611f, 0xd5a30130, | ||
1647 | 0, 0, | ||
1648 | }; | ||
1649 | |||
1639 | static const unsigned int hp_cNB11_intquad_pin_configs[10] = { | 1650 | static const unsigned int hp_cNB11_intquad_pin_configs[10] = { |
1640 | 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110, | 1651 | 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110, |
1641 | 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130, | 1652 | 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130, |
@@ -1649,6 +1660,7 @@ static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { | |||
1649 | [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs, | 1660 | [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs, |
1650 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, | 1661 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs, |
1651 | [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, | 1662 | [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, |
1663 | [STAC_HP_ZEPHYR] = hp_zephyr_pin_configs, | ||
1652 | }; | 1664 | }; |
1653 | 1665 | ||
1654 | static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { | 1666 | static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { |
@@ -1659,6 +1671,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { | |||
1659 | [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", | 1671 | [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", |
1660 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", | 1672 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", |
1661 | [STAC_HP_DV7_4000] = "hp-dv7-4000", | 1673 | [STAC_HP_DV7_4000] = "hp-dv7-4000", |
1674 | [STAC_HP_ZEPHYR] = "hp-zephyr", | ||
1662 | }; | 1675 | }; |
1663 | 1676 | ||
1664 | static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | 1677 | static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { |
@@ -1711,6 +1724,14 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | |||
1711 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), | 1724 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), |
1712 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593, | 1725 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593, |
1713 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), | 1726 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), |
1727 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561, | ||
1728 | "HP", STAC_HP_ZEPHYR), | ||
1729 | {} /* terminator */ | ||
1730 | }; | ||
1731 | |||
1732 | static const struct snd_pci_quirk stac92hd83xxx_codec_id_cfg_tbl[] = { | ||
1733 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3561, | ||
1734 | "HP", STAC_HP_ZEPHYR), | ||
1714 | {} /* terminator */ | 1735 | {} /* terminator */ |
1715 | }; | 1736 | }; |
1716 | 1737 | ||
@@ -4163,13 +4184,15 @@ static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, | |||
4163 | return 1; | 4184 | return 1; |
4164 | } | 4185 | } |
4165 | 4186 | ||
4166 | static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) | 4187 | static int is_nid_out_jack_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) |
4167 | { | 4188 | { |
4168 | int i; | 4189 | int i; |
4169 | for (i = 0; i < cfg->hp_outs; i++) | 4190 | for (i = 0; i < cfg->hp_outs; i++) |
4170 | if (cfg->hp_pins[i] == nid) | 4191 | if (cfg->hp_pins[i] == nid) |
4171 | return 1; /* nid is a HP-Out */ | 4192 | return 1; /* nid is a HP-Out */ |
4172 | 4193 | for (i = 0; i < cfg->line_outs; i++) | |
4194 | if (cfg->line_out_pins[i] == nid) | ||
4195 | return 1; /* nid is a line-Out */ | ||
4173 | return 0; /* nid is not a HP-Out */ | 4196 | return 0; /* nid is not a HP-Out */ |
4174 | }; | 4197 | }; |
4175 | 4198 | ||
@@ -4375,7 +4398,7 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4375 | continue; | 4398 | continue; |
4376 | } | 4399 | } |
4377 | 4400 | ||
4378 | if (is_nid_hp_pin(cfg, nid)) | 4401 | if (is_nid_out_jack_pin(cfg, nid)) |
4379 | continue; /* already has an unsol event */ | 4402 | continue; /* already has an unsol event */ |
4380 | 4403 | ||
4381 | pinctl = snd_hda_codec_read(codec, nid, 0, | 4404 | pinctl = snd_hda_codec_read(codec, nid, 0, |
@@ -4408,8 +4431,7 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4408 | snd_hda_jack_report_sync(codec); | 4431 | snd_hda_jack_report_sync(codec); |
4409 | 4432 | ||
4410 | /* sync mute LED */ | 4433 | /* sync mute LED */ |
4411 | if (spec->gpio_led) | 4434 | snd_hda_sync_vmaster_hook(&spec->vmaster_mute); |
4412 | hda_call_check_power_status(codec, 0x01); | ||
4413 | if (spec->dac_list) | 4435 | if (spec->dac_list) |
4414 | stac92xx_power_down(codec); | 4436 | stac92xx_power_down(codec); |
4415 | return 0; | 4437 | return 0; |
@@ -4627,7 +4649,7 @@ static void stac92xx_hp_detect(struct hda_codec *codec) | |||
4627 | unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; | 4649 | unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; |
4628 | if (no_hp_sensing(spec, i)) | 4650 | if (no_hp_sensing(spec, i)) |
4629 | continue; | 4651 | continue; |
4630 | if (presence) | 4652 | if (1 /*presence*/) |
4631 | stac92xx_set_pinctl(codec, cfg->hp_pins[i], val); | 4653 | stac92xx_set_pinctl(codec, cfg->hp_pins[i], val); |
4632 | #if 0 /* FIXME */ | 4654 | #if 0 /* FIXME */ |
4633 | /* Resetting the pinctl like below may lead to (a sort of) regressions | 4655 | /* Resetting the pinctl like below may lead to (a sort of) regressions |
@@ -4868,7 +4890,14 @@ static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity) | |||
4868 | /* BIOS bug: unfilled OEM string */ | 4890 | /* BIOS bug: unfilled OEM string */ |
4869 | if (strstr(dev->name, "HP_Mute_LED_P_G")) { | 4891 | if (strstr(dev->name, "HP_Mute_LED_P_G")) { |
4870 | set_hp_led_gpio(codec); | 4892 | set_hp_led_gpio(codec); |
4871 | spec->gpio_led_polarity = 1; | 4893 | switch (codec->subsystem_id) { |
4894 | case 0x103c148a: | ||
4895 | spec->gpio_led_polarity = 0; | ||
4896 | break; | ||
4897 | default: | ||
4898 | spec->gpio_led_polarity = 1; | ||
4899 | break; | ||
4900 | } | ||
4872 | return 1; | 4901 | return 1; |
4873 | } | 4902 | } |
4874 | } | 4903 | } |
@@ -4980,7 +5009,6 @@ static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) | |||
4980 | return 0; | 5009 | return 0; |
4981 | } | 5010 | } |
4982 | 5011 | ||
4983 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
4984 | static int stac92xx_pre_resume(struct hda_codec *codec) | 5012 | static int stac92xx_pre_resume(struct hda_codec *codec) |
4985 | { | 5013 | { |
4986 | struct sigmatel_spec *spec = codec->spec; | 5014 | struct sigmatel_spec *spec = codec->spec; |
@@ -5015,83 +5043,41 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg, | |||
5015 | afg_power_state); | 5043 | afg_power_state); |
5016 | snd_hda_codec_set_power_to_all(codec, fg, power_state, true); | 5044 | snd_hda_codec_set_power_to_all(codec, fg, power_state, true); |
5017 | } | 5045 | } |
5046 | #else | ||
5047 | #define stac92xx_suspend NULL | ||
5048 | #define stac92xx_resume NULL | ||
5049 | #define stac92xx_pre_resume NULL | ||
5050 | #define stac92xx_set_power_state NULL | ||
5051 | #endif /* CONFIG_PM */ | ||
5018 | 5052 | ||
5019 | /* | 5053 | /* update mute-LED accoring to the master switch */ |
5020 | * For this feature CONFIG_SND_HDA_POWER_SAVE is needed | 5054 | static void stac92xx_update_led_status(struct hda_codec *codec, int enabled) |
5021 | * as mute LED state is updated in check_power_status hook | ||
5022 | */ | ||
5023 | static int stac92xx_update_led_status(struct hda_codec *codec) | ||
5024 | { | 5055 | { |
5025 | struct sigmatel_spec *spec = codec->spec; | 5056 | struct sigmatel_spec *spec = codec->spec; |
5026 | int i, num_ext_dacs, muted = 1; | 5057 | int muted = !enabled; |
5027 | unsigned int muted_lvl, notmtd_lvl; | ||
5028 | hda_nid_t nid; | ||
5029 | 5058 | ||
5030 | if (!spec->gpio_led) | 5059 | if (!spec->gpio_led) |
5031 | return 0; | 5060 | return; |
5061 | |||
5062 | /* LED state is inverted on these systems */ | ||
5063 | if (spec->gpio_led_polarity) | ||
5064 | muted = !muted; | ||
5032 | 5065 | ||
5033 | for (i = 0; i < spec->multiout.num_dacs; i++) { | ||
5034 | nid = spec->multiout.dac_nids[i]; | ||
5035 | if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & | ||
5036 | HDA_AMP_MUTE)) { | ||
5037 | muted = 0; /* something heard */ | ||
5038 | break; | ||
5039 | } | ||
5040 | } | ||
5041 | if (muted && spec->multiout.hp_nid) | ||
5042 | if (!(snd_hda_codec_amp_read(codec, | ||
5043 | spec->multiout.hp_nid, 0, HDA_OUTPUT, 0) & | ||
5044 | HDA_AMP_MUTE)) { | ||
5045 | muted = 0; /* HP is not muted */ | ||
5046 | } | ||
5047 | num_ext_dacs = ARRAY_SIZE(spec->multiout.extra_out_nid); | ||
5048 | for (i = 0; muted && i < num_ext_dacs; i++) { | ||
5049 | nid = spec->multiout.extra_out_nid[i]; | ||
5050 | if (nid == 0) | ||
5051 | break; | ||
5052 | if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & | ||
5053 | HDA_AMP_MUTE)) { | ||
5054 | muted = 0; /* extra output is not muted */ | ||
5055 | } | ||
5056 | } | ||
5057 | /*polarity defines *not* muted state level*/ | 5066 | /*polarity defines *not* muted state level*/ |
5058 | if (!spec->vref_mute_led_nid) { | 5067 | if (!spec->vref_mute_led_nid) { |
5059 | if (muted) | 5068 | if (muted) |
5060 | spec->gpio_data &= ~spec->gpio_led; /* orange */ | 5069 | spec->gpio_data &= ~spec->gpio_led; /* orange */ |
5061 | else | 5070 | else |
5062 | spec->gpio_data |= spec->gpio_led; /* white */ | 5071 | spec->gpio_data |= spec->gpio_led; /* white */ |
5063 | |||
5064 | if (!spec->gpio_led_polarity) { | ||
5065 | /* LED state is inverted on these systems */ | ||
5066 | spec->gpio_data ^= spec->gpio_led; | ||
5067 | } | ||
5068 | stac_gpio_set(codec, spec->gpio_mask, | 5072 | stac_gpio_set(codec, spec->gpio_mask, |
5069 | spec->gpio_dir, spec->gpio_data); | 5073 | spec->gpio_dir, spec->gpio_data); |
5070 | } else { | 5074 | } else { |
5071 | notmtd_lvl = spec->gpio_led_polarity ? | 5075 | spec->vref_led = muted ? AC_PINCTL_VREF_50 : AC_PINCTL_VREF_GRD; |
5072 | AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_GRD; | ||
5073 | muted_lvl = spec->gpio_led_polarity ? | ||
5074 | AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; | ||
5075 | spec->vref_led = muted ? muted_lvl : notmtd_lvl; | ||
5076 | stac_vrefout_set(codec, spec->vref_mute_led_nid, | 5076 | stac_vrefout_set(codec, spec->vref_mute_led_nid, |
5077 | spec->vref_led); | 5077 | spec->vref_led); |
5078 | } | 5078 | } |
5079 | return 0; | ||
5080 | } | 5079 | } |
5081 | 5080 | ||
5082 | /* | ||
5083 | * use power check for controlling mute led of HP notebooks | ||
5084 | */ | ||
5085 | static int stac92xx_check_power_status(struct hda_codec *codec, | ||
5086 | hda_nid_t nid) | ||
5087 | { | ||
5088 | stac92xx_update_led_status(codec); | ||
5089 | |||
5090 | return 0; | ||
5091 | } | ||
5092 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ | ||
5093 | #endif /* CONFIG_PM */ | ||
5094 | |||
5095 | static const struct hda_codec_ops stac92xx_patch_ops = { | 5081 | static const struct hda_codec_ops stac92xx_patch_ops = { |
5096 | .build_controls = stac92xx_build_controls, | 5082 | .build_controls = stac92xx_build_controls, |
5097 | .build_pcms = stac92xx_build_pcms, | 5083 | .build_pcms = stac92xx_build_pcms, |
@@ -5571,6 +5557,12 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
5571 | STAC_92HD83XXX_MODELS, | 5557 | STAC_92HD83XXX_MODELS, |
5572 | stac92hd83xxx_models, | 5558 | stac92hd83xxx_models, |
5573 | stac92hd83xxx_cfg_tbl); | 5559 | stac92hd83xxx_cfg_tbl); |
5560 | /* check codec subsystem id if not found */ | ||
5561 | if (spec->board_config < 0) | ||
5562 | spec->board_config = | ||
5563 | snd_hda_check_board_codec_sid_config(codec, | ||
5564 | STAC_92HD83XXX_MODELS, stac92hd83xxx_models, | ||
5565 | stac92hd83xxx_codec_id_cfg_tbl); | ||
5574 | again: | 5566 | again: |
5575 | if (spec->board_config < 0) | 5567 | if (spec->board_config < 0) |
5576 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | 5568 | snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", |
@@ -5581,12 +5573,17 @@ again: | |||
5581 | 5573 | ||
5582 | codec->patch_ops = stac92xx_patch_ops; | 5574 | codec->patch_ops = stac92xx_patch_ops; |
5583 | 5575 | ||
5576 | switch (spec->board_config) { | ||
5577 | case STAC_HP_ZEPHYR: | ||
5578 | spec->init = stac92hd83xxx_hp_zephyr_init; | ||
5579 | break; | ||
5580 | } | ||
5581 | |||
5584 | if (find_mute_led_cfg(codec, -1/*no default cfg*/)) | 5582 | if (find_mute_led_cfg(codec, -1/*no default cfg*/)) |
5585 | snd_printd("mute LED gpio %d polarity %d\n", | 5583 | snd_printd("mute LED gpio %d polarity %d\n", |
5586 | spec->gpio_led, | 5584 | spec->gpio_led, |
5587 | spec->gpio_led_polarity); | 5585 | spec->gpio_led_polarity); |
5588 | 5586 | ||
5589 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
5590 | if (spec->gpio_led) { | 5587 | if (spec->gpio_led) { |
5591 | if (!spec->vref_mute_led_nid) { | 5588 | if (!spec->vref_mute_led_nid) { |
5592 | spec->gpio_mask |= spec->gpio_led; | 5589 | spec->gpio_mask |= spec->gpio_led; |
@@ -5596,11 +5593,10 @@ again: | |||
5596 | codec->patch_ops.set_power_state = | 5593 | codec->patch_ops.set_power_state = |
5597 | stac92xx_set_power_state; | 5594 | stac92xx_set_power_state; |
5598 | } | 5595 | } |
5596 | #ifdef CONFIG_PM | ||
5599 | codec->patch_ops.pre_resume = stac92xx_pre_resume; | 5597 | codec->patch_ops.pre_resume = stac92xx_pre_resume; |
5600 | codec->patch_ops.check_power_status = | 5598 | #endif |
5601 | stac92xx_check_power_status; | ||
5602 | } | 5599 | } |
5603 | #endif | ||
5604 | 5600 | ||
5605 | err = stac92xx_parse_auto_config(codec); | 5601 | err = stac92xx_parse_auto_config(codec); |
5606 | if (!err) { | 5602 | if (!err) { |
@@ -5897,7 +5893,6 @@ again: | |||
5897 | spec->gpio_led, | 5893 | spec->gpio_led, |
5898 | spec->gpio_led_polarity); | 5894 | spec->gpio_led_polarity); |
5899 | 5895 | ||
5900 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
5901 | if (spec->gpio_led) { | 5896 | if (spec->gpio_led) { |
5902 | if (!spec->vref_mute_led_nid) { | 5897 | if (!spec->vref_mute_led_nid) { |
5903 | spec->gpio_mask |= spec->gpio_led; | 5898 | spec->gpio_mask |= spec->gpio_led; |
@@ -5907,11 +5902,10 @@ again: | |||
5907 | codec->patch_ops.set_power_state = | 5902 | codec->patch_ops.set_power_state = |
5908 | stac92xx_set_power_state; | 5903 | stac92xx_set_power_state; |
5909 | } | 5904 | } |
5905 | #ifdef CONFIG_PM | ||
5910 | codec->patch_ops.pre_resume = stac92xx_pre_resume; | 5906 | codec->patch_ops.pre_resume = stac92xx_pre_resume; |
5911 | codec->patch_ops.check_power_status = | 5907 | #endif |
5912 | stac92xx_check_power_status; | ||
5913 | } | 5908 | } |
5914 | #endif | ||
5915 | 5909 | ||
5916 | spec->multiout.dac_nids = spec->dac_nids; | 5910 | spec->multiout.dac_nids = spec->dac_nids; |
5917 | 5911 | ||
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 03e63fed9caf..06214fdc9486 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -199,6 +199,9 @@ struct via_spec { | |||
199 | unsigned int no_pin_power_ctl; | 199 | unsigned int no_pin_power_ctl; |
200 | enum VIA_HDA_CODEC codec_type; | 200 | enum VIA_HDA_CODEC codec_type; |
201 | 201 | ||
202 | /* analog low-power control */ | ||
203 | bool alc_mode; | ||
204 | |||
202 | /* smart51 setup */ | 205 | /* smart51 setup */ |
203 | unsigned int smart51_nums; | 206 | unsigned int smart51_nums; |
204 | hda_nid_t smart51_pins[2]; | 207 | hda_nid_t smart51_pins[2]; |
@@ -547,7 +550,10 @@ static void via_auto_init_output(struct hda_codec *codec, | |||
547 | pin = path->path[path->depth - 1]; | 550 | pin = path->path[path->depth - 1]; |
548 | 551 | ||
549 | init_output_pin(codec, pin, pin_type); | 552 | init_output_pin(codec, pin, pin_type); |
550 | caps = query_amp_caps(codec, pin, HDA_OUTPUT); | 553 | if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) |
554 | caps = query_amp_caps(codec, pin, HDA_OUTPUT); | ||
555 | else | ||
556 | caps = 0; | ||
551 | if (caps & AC_AMPCAP_MUTE) { | 557 | if (caps & AC_AMPCAP_MUTE) { |
552 | unsigned int val; | 558 | unsigned int val; |
553 | val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; | 559 | val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT; |
@@ -642,6 +648,10 @@ static void via_auto_init_analog_input(struct hda_codec *codec) | |||
642 | 648 | ||
643 | /* init ADCs */ | 649 | /* init ADCs */ |
644 | for (i = 0; i < spec->num_adc_nids; i++) { | 650 | for (i = 0; i < spec->num_adc_nids; i++) { |
651 | hda_nid_t nid = spec->adc_nids[i]; | ||
652 | if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP) || | ||
653 | !(query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE)) | ||
654 | continue; | ||
645 | snd_hda_codec_write(codec, spec->adc_nids[i], 0, | 655 | snd_hda_codec_write(codec, spec->adc_nids[i], 0, |
646 | AC_VERB_SET_AMP_GAIN_MUTE, | 656 | AC_VERB_SET_AMP_GAIN_MUTE, |
647 | AMP_IN_UNMUTE(0)); | 657 | AMP_IN_UNMUTE(0)); |
@@ -663,6 +673,9 @@ static void via_auto_init_analog_input(struct hda_codec *codec) | |||
663 | /* init input-src */ | 673 | /* init input-src */ |
664 | for (i = 0; i < spec->num_adc_nids; i++) { | 674 | for (i = 0; i < spec->num_adc_nids; i++) { |
665 | int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx; | 675 | int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx; |
676 | /* secondary ADCs must have the unique MUX */ | ||
677 | if (i > 0 && !spec->mux_nids[i]) | ||
678 | break; | ||
666 | if (spec->mux_nids[adc_idx]) { | 679 | if (spec->mux_nids[adc_idx]) { |
667 | int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx; | 680 | int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx; |
668 | snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0, | 681 | snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0, |
@@ -687,6 +700,15 @@ static void via_auto_init_analog_input(struct hda_codec *codec) | |||
687 | } | 700 | } |
688 | } | 701 | } |
689 | 702 | ||
703 | static void update_power_state(struct hda_codec *codec, hda_nid_t nid, | ||
704 | unsigned int parm) | ||
705 | { | ||
706 | if (snd_hda_codec_read(codec, nid, 0, | ||
707 | AC_VERB_GET_POWER_STATE, 0) == parm) | ||
708 | return; | ||
709 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); | ||
710 | } | ||
711 | |||
690 | static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, | 712 | static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, |
691 | unsigned int *affected_parm) | 713 | unsigned int *affected_parm) |
692 | { | 714 | { |
@@ -709,7 +731,7 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, | |||
709 | } else | 731 | } else |
710 | parm = AC_PWRST_D3; | 732 | parm = AC_PWRST_D3; |
711 | 733 | ||
712 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); | 734 | update_power_state(codec, nid, parm); |
713 | } | 735 | } |
714 | 736 | ||
715 | static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol, | 737 | static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol, |
@@ -749,6 +771,7 @@ static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol, | |||
749 | return 0; | 771 | return 0; |
750 | spec->no_pin_power_ctl = val; | 772 | spec->no_pin_power_ctl = val; |
751 | set_widgets_power_state(codec); | 773 | set_widgets_power_state(codec); |
774 | analog_low_current_mode(codec); | ||
752 | return 1; | 775 | return 1; |
753 | } | 776 | } |
754 | 777 | ||
@@ -1036,13 +1059,19 @@ static bool is_aa_path_mute(struct hda_codec *codec) | |||
1036 | } | 1059 | } |
1037 | 1060 | ||
1038 | /* enter/exit analog low-current mode */ | 1061 | /* enter/exit analog low-current mode */ |
1039 | static void analog_low_current_mode(struct hda_codec *codec) | 1062 | static void __analog_low_current_mode(struct hda_codec *codec, bool force) |
1040 | { | 1063 | { |
1041 | struct via_spec *spec = codec->spec; | 1064 | struct via_spec *spec = codec->spec; |
1042 | bool enable; | 1065 | bool enable; |
1043 | unsigned int verb, parm; | 1066 | unsigned int verb, parm; |
1044 | 1067 | ||
1045 | enable = is_aa_path_mute(codec) && (spec->opened_streams != 0); | 1068 | if (spec->no_pin_power_ctl) |
1069 | enable = false; | ||
1070 | else | ||
1071 | enable = is_aa_path_mute(codec) && !spec->opened_streams; | ||
1072 | if (enable == spec->alc_mode && !force) | ||
1073 | return; | ||
1074 | spec->alc_mode = enable; | ||
1046 | 1075 | ||
1047 | /* decide low current mode's verb & parameter */ | 1076 | /* decide low current mode's verb & parameter */ |
1048 | switch (spec->codec_type) { | 1077 | switch (spec->codec_type) { |
@@ -1074,6 +1103,11 @@ static void analog_low_current_mode(struct hda_codec *codec) | |||
1074 | snd_hda_codec_write(codec, codec->afg, 0, verb, parm); | 1103 | snd_hda_codec_write(codec, codec->afg, 0, verb, parm); |
1075 | } | 1104 | } |
1076 | 1105 | ||
1106 | static void analog_low_current_mode(struct hda_codec *codec) | ||
1107 | { | ||
1108 | return __analog_low_current_mode(codec, false); | ||
1109 | } | ||
1110 | |||
1077 | /* | 1111 | /* |
1078 | * generic initialization of ADC, input mixers and output mixers | 1112 | * generic initialization of ADC, input mixers and output mixers |
1079 | */ | 1113 | */ |
@@ -1418,25 +1452,9 @@ static const struct hda_pcm_stream via_pcm_digital_capture = { | |||
1418 | /* | 1452 | /* |
1419 | * slave controls for virtual master | 1453 | * slave controls for virtual master |
1420 | */ | 1454 | */ |
1421 | static const char * const via_slave_vols[] = { | 1455 | static const char * const via_slave_pfxs[] = { |
1422 | "Front Playback Volume", | 1456 | "Front", "Surround", "Center", "LFE", "Side", |
1423 | "Surround Playback Volume", | 1457 | "Headphone", "Speaker", |
1424 | "Center Playback Volume", | ||
1425 | "LFE Playback Volume", | ||
1426 | "Side Playback Volume", | ||
1427 | "Headphone Playback Volume", | ||
1428 | "Speaker Playback Volume", | ||
1429 | NULL, | ||
1430 | }; | ||
1431 | |||
1432 | static const char * const via_slave_sws[] = { | ||
1433 | "Front Playback Switch", | ||
1434 | "Surround Playback Switch", | ||
1435 | "Center Playback Switch", | ||
1436 | "LFE Playback Switch", | ||
1437 | "Side Playback Switch", | ||
1438 | "Headphone Playback Switch", | ||
1439 | "Speaker Playback Switch", | ||
1440 | NULL, | 1458 | NULL, |
1441 | }; | 1459 | }; |
1442 | 1460 | ||
@@ -1446,6 +1464,7 @@ static int via_build_controls(struct hda_codec *codec) | |||
1446 | struct snd_kcontrol *kctl; | 1464 | struct snd_kcontrol *kctl; |
1447 | int err, i; | 1465 | int err, i; |
1448 | 1466 | ||
1467 | spec->no_pin_power_ctl = 1; | ||
1449 | if (spec->set_widgets_power_state) | 1468 | if (spec->set_widgets_power_state) |
1450 | if (!via_clone_control(spec, &via_pin_power_ctl_enum)) | 1469 | if (!via_clone_control(spec, &via_pin_power_ctl_enum)) |
1451 | return -ENOMEM; | 1470 | return -ENOMEM; |
@@ -1480,13 +1499,15 @@ static int via_build_controls(struct hda_codec *codec) | |||
1480 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], | 1499 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], |
1481 | HDA_OUTPUT, vmaster_tlv); | 1500 | HDA_OUTPUT, vmaster_tlv); |
1482 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | 1501 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", |
1483 | vmaster_tlv, via_slave_vols); | 1502 | vmaster_tlv, via_slave_pfxs, |
1503 | "Playback Volume"); | ||
1484 | if (err < 0) | 1504 | if (err < 0) |
1485 | return err; | 1505 | return err; |
1486 | } | 1506 | } |
1487 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | 1507 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { |
1488 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", | 1508 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", |
1489 | NULL, via_slave_sws); | 1509 | NULL, via_slave_pfxs, |
1510 | "Playback Switch"); | ||
1490 | if (err < 0) | 1511 | if (err < 0) |
1491 | return err; | 1512 | return err; |
1492 | } | 1513 | } |
@@ -1494,15 +1515,13 @@ static int via_build_controls(struct hda_codec *codec) | |||
1494 | /* assign Capture Source enums to NID */ | 1515 | /* assign Capture Source enums to NID */ |
1495 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); | 1516 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); |
1496 | for (i = 0; kctl && i < kctl->count; i++) { | 1517 | for (i = 0; kctl && i < kctl->count; i++) { |
1518 | if (!spec->mux_nids[i]) | ||
1519 | continue; | ||
1497 | err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]); | 1520 | err = snd_hda_add_nid(codec, kctl, i, spec->mux_nids[i]); |
1498 | if (err < 0) | 1521 | if (err < 0) |
1499 | return err; | 1522 | return err; |
1500 | } | 1523 | } |
1501 | 1524 | ||
1502 | /* init power states */ | ||
1503 | set_widgets_power_state(codec); | ||
1504 | analog_low_current_mode(codec); | ||
1505 | |||
1506 | via_free_kctls(codec); /* no longer needed */ | 1525 | via_free_kctls(codec); /* no longer needed */ |
1507 | 1526 | ||
1508 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | 1527 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); |
@@ -2295,10 +2314,7 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
2295 | 2314 | ||
2296 | if (mux) { | 2315 | if (mux) { |
2297 | /* switch to D0 beofre change index */ | 2316 | /* switch to D0 beofre change index */ |
2298 | if (snd_hda_codec_read(codec, mux, 0, | 2317 | update_power_state(codec, mux, AC_PWRST_D0); |
2299 | AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0) | ||
2300 | snd_hda_codec_write(codec, mux, 0, | ||
2301 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
2302 | snd_hda_codec_write(codec, mux, 0, | 2318 | snd_hda_codec_write(codec, mux, 0, |
2303 | AC_VERB_SET_CONNECT_SEL, | 2319 | AC_VERB_SET_CONNECT_SEL, |
2304 | spec->inputs[cur].mux_idx); | 2320 | spec->inputs[cur].mux_idx); |
@@ -2467,6 +2483,8 @@ static int create_mic_boost_ctls(struct hda_codec *codec) | |||
2467 | { | 2483 | { |
2468 | struct via_spec *spec = codec->spec; | 2484 | struct via_spec *spec = codec->spec; |
2469 | const struct auto_pin_cfg *cfg = &spec->autocfg; | 2485 | const struct auto_pin_cfg *cfg = &spec->autocfg; |
2486 | const char *prev_label = NULL; | ||
2487 | int type_idx = 0; | ||
2470 | int i, err; | 2488 | int i, err; |
2471 | 2489 | ||
2472 | for (i = 0; i < cfg->num_inputs; i++) { | 2490 | for (i = 0; i < cfg->num_inputs; i++) { |
@@ -2481,8 +2499,13 @@ static int create_mic_boost_ctls(struct hda_codec *codec) | |||
2481 | if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS)) | 2499 | if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS)) |
2482 | continue; | 2500 | continue; |
2483 | label = hda_get_autocfg_input_label(codec, cfg, i); | 2501 | label = hda_get_autocfg_input_label(codec, cfg, i); |
2502 | if (prev_label && !strcmp(label, prev_label)) | ||
2503 | type_idx++; | ||
2504 | else | ||
2505 | type_idx = 0; | ||
2506 | prev_label = label; | ||
2484 | snprintf(name, sizeof(name), "%s Boost Volume", label); | 2507 | snprintf(name, sizeof(name), "%s Boost Volume", label); |
2485 | err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, | 2508 | err = __via_add_control(spec, VIA_CTL_WIDGET_VOL, name, type_idx, |
2486 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT)); | 2509 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT)); |
2487 | if (err < 0) | 2510 | if (err < 0) |
2488 | return err; | 2511 | return err; |
@@ -2776,6 +2799,10 @@ static int via_init(struct hda_codec *codec) | |||
2776 | for (i = 0; i < spec->num_iverbs; i++) | 2799 | for (i = 0; i < spec->num_iverbs; i++) |
2777 | snd_hda_sequence_write(codec, spec->init_verbs[i]); | 2800 | snd_hda_sequence_write(codec, spec->init_verbs[i]); |
2778 | 2801 | ||
2802 | /* init power states */ | ||
2803 | set_widgets_power_state(codec); | ||
2804 | __analog_low_current_mode(codec, true); | ||
2805 | |||
2779 | via_auto_init_multi_out(codec); | 2806 | via_auto_init_multi_out(codec); |
2780 | via_auto_init_hp_out(codec); | 2807 | via_auto_init_hp_out(codec); |
2781 | via_auto_init_speaker_out(codec); | 2808 | via_auto_init_speaker_out(codec); |
@@ -2922,9 +2949,9 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) | |||
2922 | if (imux_is_smixer) | 2949 | if (imux_is_smixer) |
2923 | parm = AC_PWRST_D0; | 2950 | parm = AC_PWRST_D0; |
2924 | /* SW0 (17h), AIW 0/1 (13h/14h) */ | 2951 | /* SW0 (17h), AIW 0/1 (13h/14h) */ |
2925 | snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm); | 2952 | update_power_state(codec, 0x17, parm); |
2926 | snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); | 2953 | update_power_state(codec, 0x13, parm); |
2927 | snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm); | 2954 | update_power_state(codec, 0x14, parm); |
2928 | 2955 | ||
2929 | /* outputs */ | 2956 | /* outputs */ |
2930 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ | 2957 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ |
@@ -2932,8 +2959,8 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) | |||
2932 | set_pin_power_state(codec, 0x19, &parm); | 2959 | set_pin_power_state(codec, 0x19, &parm); |
2933 | if (spec->smart51_enabled) | 2960 | if (spec->smart51_enabled) |
2934 | set_pin_power_state(codec, 0x1b, &parm); | 2961 | set_pin_power_state(codec, 0x1b, &parm); |
2935 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); | 2962 | update_power_state(codec, 0x18, parm); |
2936 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); | 2963 | update_power_state(codec, 0x11, parm); |
2937 | 2964 | ||
2938 | /* PW6 (22h), SW2 (26h), AOW2 (24h) */ | 2965 | /* PW6 (22h), SW2 (26h), AOW2 (24h) */ |
2939 | if (is_8ch) { | 2966 | if (is_8ch) { |
@@ -2941,20 +2968,16 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) | |||
2941 | set_pin_power_state(codec, 0x22, &parm); | 2968 | set_pin_power_state(codec, 0x22, &parm); |
2942 | if (spec->smart51_enabled) | 2969 | if (spec->smart51_enabled) |
2943 | set_pin_power_state(codec, 0x1a, &parm); | 2970 | set_pin_power_state(codec, 0x1a, &parm); |
2944 | snd_hda_codec_write(codec, 0x26, 0, | 2971 | update_power_state(codec, 0x26, parm); |
2945 | AC_VERB_SET_POWER_STATE, parm); | 2972 | update_power_state(codec, 0x24, parm); |
2946 | snd_hda_codec_write(codec, 0x24, 0, | ||
2947 | AC_VERB_SET_POWER_STATE, parm); | ||
2948 | } else if (codec->vendor_id == 0x11064397) { | 2973 | } else if (codec->vendor_id == 0x11064397) { |
2949 | /* PW7(23h), SW2(27h), AOW2(25h) */ | 2974 | /* PW7(23h), SW2(27h), AOW2(25h) */ |
2950 | parm = AC_PWRST_D3; | 2975 | parm = AC_PWRST_D3; |
2951 | set_pin_power_state(codec, 0x23, &parm); | 2976 | set_pin_power_state(codec, 0x23, &parm); |
2952 | if (spec->smart51_enabled) | 2977 | if (spec->smart51_enabled) |
2953 | set_pin_power_state(codec, 0x1a, &parm); | 2978 | set_pin_power_state(codec, 0x1a, &parm); |
2954 | snd_hda_codec_write(codec, 0x27, 0, | 2979 | update_power_state(codec, 0x27, parm); |
2955 | AC_VERB_SET_POWER_STATE, parm); | 2980 | update_power_state(codec, 0x25, parm); |
2956 | snd_hda_codec_write(codec, 0x25, 0, | ||
2957 | AC_VERB_SET_POWER_STATE, parm); | ||
2958 | } | 2981 | } |
2959 | 2982 | ||
2960 | /* PW 3/4/7 (1ch/1dh/23h) */ | 2983 | /* PW 3/4/7 (1ch/1dh/23h) */ |
@@ -2966,17 +2989,13 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec) | |||
2966 | set_pin_power_state(codec, 0x23, &parm); | 2989 | set_pin_power_state(codec, 0x23, &parm); |
2967 | 2990 | ||
2968 | /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */ | 2991 | /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */ |
2969 | snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, | 2992 | update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm); |
2970 | imux_is_smixer ? AC_PWRST_D0 : parm); | 2993 | update_power_state(codec, 0x10, parm); |
2971 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); | ||
2972 | if (is_8ch) { | 2994 | if (is_8ch) { |
2973 | snd_hda_codec_write(codec, 0x25, 0, | 2995 | update_power_state(codec, 0x25, parm); |
2974 | AC_VERB_SET_POWER_STATE, parm); | 2996 | update_power_state(codec, 0x27, parm); |
2975 | snd_hda_codec_write(codec, 0x27, 0, | ||
2976 | AC_VERB_SET_POWER_STATE, parm); | ||
2977 | } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode) | 2997 | } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode) |
2978 | snd_hda_codec_write(codec, 0x25, 0, | 2998 | update_power_state(codec, 0x25, parm); |
2979 | AC_VERB_SET_POWER_STATE, parm); | ||
2980 | } | 2999 | } |
2981 | 3000 | ||
2982 | static int patch_vt1708S(struct hda_codec *codec); | 3001 | static int patch_vt1708S(struct hda_codec *codec); |
@@ -3149,10 +3168,10 @@ static void set_widgets_power_state_vt1702(struct hda_codec *codec) | |||
3149 | if (imux_is_smixer) | 3168 | if (imux_is_smixer) |
3150 | parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */ | 3169 | parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */ |
3151 | /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */ | 3170 | /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */ |
3152 | snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); | 3171 | update_power_state(codec, 0x13, parm); |
3153 | snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, parm); | 3172 | update_power_state(codec, 0x12, parm); |
3154 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); | 3173 | update_power_state(codec, 0x1f, parm); |
3155 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, parm); | 3174 | update_power_state(codec, 0x20, parm); |
3156 | 3175 | ||
3157 | /* outputs */ | 3176 | /* outputs */ |
3158 | /* PW 3/4 (16h/17h) */ | 3177 | /* PW 3/4 (16h/17h) */ |
@@ -3160,10 +3179,9 @@ static void set_widgets_power_state_vt1702(struct hda_codec *codec) | |||
3160 | set_pin_power_state(codec, 0x17, &parm); | 3179 | set_pin_power_state(codec, 0x17, &parm); |
3161 | set_pin_power_state(codec, 0x16, &parm); | 3180 | set_pin_power_state(codec, 0x16, &parm); |
3162 | /* MW0 (1ah), AOW 0/1 (10h/1dh) */ | 3181 | /* MW0 (1ah), AOW 0/1 (10h/1dh) */ |
3163 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, | 3182 | update_power_state(codec, 0x1a, imux_is_smixer ? AC_PWRST_D0 : parm); |
3164 | imux_is_smixer ? AC_PWRST_D0 : parm); | 3183 | update_power_state(codec, 0x10, parm); |
3165 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); | 3184 | update_power_state(codec, 0x1d, parm); |
3166 | snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm); | ||
3167 | } | 3185 | } |
3168 | 3186 | ||
3169 | static int patch_vt1702(struct hda_codec *codec) | 3187 | static int patch_vt1702(struct hda_codec *codec) |
@@ -3228,52 +3246,48 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec) | |||
3228 | if (imux_is_smixer) | 3246 | if (imux_is_smixer) |
3229 | parm = AC_PWRST_D0; | 3247 | parm = AC_PWRST_D0; |
3230 | /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */ | 3248 | /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */ |
3231 | snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); | 3249 | update_power_state(codec, 0x1e, parm); |
3232 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); | 3250 | update_power_state(codec, 0x1f, parm); |
3233 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); | 3251 | update_power_state(codec, 0x10, parm); |
3234 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); | 3252 | update_power_state(codec, 0x11, parm); |
3235 | 3253 | ||
3236 | /* outputs */ | 3254 | /* outputs */ |
3237 | /* PW3 (27h), MW2 (1ah), AOW3 (bh) */ | 3255 | /* PW3 (27h), MW2 (1ah), AOW3 (bh) */ |
3238 | parm = AC_PWRST_D3; | 3256 | parm = AC_PWRST_D3; |
3239 | set_pin_power_state(codec, 0x27, &parm); | 3257 | set_pin_power_state(codec, 0x27, &parm); |
3240 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm); | 3258 | update_power_state(codec, 0x1a, parm); |
3241 | snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm); | 3259 | update_power_state(codec, 0xb, parm); |
3242 | 3260 | ||
3243 | /* PW2 (26h), AOW2 (ah) */ | 3261 | /* PW2 (26h), AOW2 (ah) */ |
3244 | parm = AC_PWRST_D3; | 3262 | parm = AC_PWRST_D3; |
3245 | set_pin_power_state(codec, 0x26, &parm); | 3263 | set_pin_power_state(codec, 0x26, &parm); |
3246 | if (spec->smart51_enabled) | 3264 | if (spec->smart51_enabled) |
3247 | set_pin_power_state(codec, 0x2b, &parm); | 3265 | set_pin_power_state(codec, 0x2b, &parm); |
3248 | snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, parm); | 3266 | update_power_state(codec, 0xa, parm); |
3249 | 3267 | ||
3250 | /* PW0 (24h), AOW0 (8h) */ | 3268 | /* PW0 (24h), AOW0 (8h) */ |
3251 | parm = AC_PWRST_D3; | 3269 | parm = AC_PWRST_D3; |
3252 | set_pin_power_state(codec, 0x24, &parm); | 3270 | set_pin_power_state(codec, 0x24, &parm); |
3253 | if (!spec->hp_independent_mode) /* check for redirected HP */ | 3271 | if (!spec->hp_independent_mode) /* check for redirected HP */ |
3254 | set_pin_power_state(codec, 0x28, &parm); | 3272 | set_pin_power_state(codec, 0x28, &parm); |
3255 | snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); | 3273 | update_power_state(codec, 0x8, parm); |
3256 | /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ | 3274 | /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ |
3257 | snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE, | 3275 | update_power_state(codec, 0x21, imux_is_smixer ? AC_PWRST_D0 : parm); |
3258 | imux_is_smixer ? AC_PWRST_D0 : parm); | ||
3259 | 3276 | ||
3260 | /* PW1 (25h), AOW1 (9h) */ | 3277 | /* PW1 (25h), AOW1 (9h) */ |
3261 | parm = AC_PWRST_D3; | 3278 | parm = AC_PWRST_D3; |
3262 | set_pin_power_state(codec, 0x25, &parm); | 3279 | set_pin_power_state(codec, 0x25, &parm); |
3263 | if (spec->smart51_enabled) | 3280 | if (spec->smart51_enabled) |
3264 | set_pin_power_state(codec, 0x2a, &parm); | 3281 | set_pin_power_state(codec, 0x2a, &parm); |
3265 | snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm); | 3282 | update_power_state(codec, 0x9, parm); |
3266 | 3283 | ||
3267 | if (spec->hp_independent_mode) { | 3284 | if (spec->hp_independent_mode) { |
3268 | /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ | 3285 | /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ |
3269 | parm = AC_PWRST_D3; | 3286 | parm = AC_PWRST_D3; |
3270 | set_pin_power_state(codec, 0x28, &parm); | 3287 | set_pin_power_state(codec, 0x28, &parm); |
3271 | snd_hda_codec_write(codec, 0x1b, 0, | 3288 | update_power_state(codec, 0x1b, parm); |
3272 | AC_VERB_SET_POWER_STATE, parm); | 3289 | update_power_state(codec, 0x34, parm); |
3273 | snd_hda_codec_write(codec, 0x34, 0, | 3290 | update_power_state(codec, 0xc, parm); |
3274 | AC_VERB_SET_POWER_STATE, parm); | ||
3275 | snd_hda_codec_write(codec, 0xc, 0, | ||
3276 | AC_VERB_SET_POWER_STATE, parm); | ||
3277 | } | 3291 | } |
3278 | } | 3292 | } |
3279 | 3293 | ||
@@ -3433,8 +3447,8 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3433 | if (imux_is_smixer) | 3447 | if (imux_is_smixer) |
3434 | parm = AC_PWRST_D0; | 3448 | parm = AC_PWRST_D0; |
3435 | /* SW0 (17h), AIW0(13h) */ | 3449 | /* SW0 (17h), AIW0(13h) */ |
3436 | snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm); | 3450 | update_power_state(codec, 0x17, parm); |
3437 | snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); | 3451 | update_power_state(codec, 0x13, parm); |
3438 | 3452 | ||
3439 | parm = AC_PWRST_D3; | 3453 | parm = AC_PWRST_D3; |
3440 | set_pin_power_state(codec, 0x1e, &parm); | 3454 | set_pin_power_state(codec, 0x1e, &parm); |
@@ -3442,12 +3456,11 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3442 | if (spec->dmic_enabled) | 3456 | if (spec->dmic_enabled) |
3443 | set_pin_power_state(codec, 0x22, &parm); | 3457 | set_pin_power_state(codec, 0x22, &parm); |
3444 | else | 3458 | else |
3445 | snd_hda_codec_write(codec, 0x22, 0, | 3459 | update_power_state(codec, 0x22, AC_PWRST_D3); |
3446 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
3447 | 3460 | ||
3448 | /* SW2(26h), AIW1(14h) */ | 3461 | /* SW2(26h), AIW1(14h) */ |
3449 | snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, parm); | 3462 | update_power_state(codec, 0x26, parm); |
3450 | snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm); | 3463 | update_power_state(codec, 0x14, parm); |
3451 | 3464 | ||
3452 | /* outputs */ | 3465 | /* outputs */ |
3453 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ | 3466 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ |
@@ -3456,8 +3469,8 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3456 | /* Smart 5.1 PW2(1bh) */ | 3469 | /* Smart 5.1 PW2(1bh) */ |
3457 | if (spec->smart51_enabled) | 3470 | if (spec->smart51_enabled) |
3458 | set_pin_power_state(codec, 0x1b, &parm); | 3471 | set_pin_power_state(codec, 0x1b, &parm); |
3459 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); | 3472 | update_power_state(codec, 0x18, parm); |
3460 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); | 3473 | update_power_state(codec, 0x11, parm); |
3461 | 3474 | ||
3462 | /* PW7 (23h), SW3 (27h), AOW3 (25h) */ | 3475 | /* PW7 (23h), SW3 (27h), AOW3 (25h) */ |
3463 | parm = AC_PWRST_D3; | 3476 | parm = AC_PWRST_D3; |
@@ -3465,12 +3478,12 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3465 | /* Smart 5.1 PW1(1ah) */ | 3478 | /* Smart 5.1 PW1(1ah) */ |
3466 | if (spec->smart51_enabled) | 3479 | if (spec->smart51_enabled) |
3467 | set_pin_power_state(codec, 0x1a, &parm); | 3480 | set_pin_power_state(codec, 0x1a, &parm); |
3468 | snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm); | 3481 | update_power_state(codec, 0x27, parm); |
3469 | 3482 | ||
3470 | /* Smart 5.1 PW5(1eh) */ | 3483 | /* Smart 5.1 PW5(1eh) */ |
3471 | if (spec->smart51_enabled) | 3484 | if (spec->smart51_enabled) |
3472 | set_pin_power_state(codec, 0x1e, &parm); | 3485 | set_pin_power_state(codec, 0x1e, &parm); |
3473 | snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, parm); | 3486 | update_power_state(codec, 0x25, parm); |
3474 | 3487 | ||
3475 | /* Mono out */ | 3488 | /* Mono out */ |
3476 | /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/ | 3489 | /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/ |
@@ -3486,9 +3499,9 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3486 | mono_out = 1; | 3499 | mono_out = 1; |
3487 | } | 3500 | } |
3488 | parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3; | 3501 | parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3; |
3489 | snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, parm); | 3502 | update_power_state(codec, 0x28, parm); |
3490 | snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, parm); | 3503 | update_power_state(codec, 0x29, parm); |
3491 | snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, parm); | 3504 | update_power_state(codec, 0x2a, parm); |
3492 | 3505 | ||
3493 | /* PW 3/4 (1ch/1dh) */ | 3506 | /* PW 3/4 (1ch/1dh) */ |
3494 | parm = AC_PWRST_D3; | 3507 | parm = AC_PWRST_D3; |
@@ -3496,15 +3509,12 @@ static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | |||
3496 | set_pin_power_state(codec, 0x1d, &parm); | 3509 | set_pin_power_state(codec, 0x1d, &parm); |
3497 | /* HP Independent Mode, power on AOW3 */ | 3510 | /* HP Independent Mode, power on AOW3 */ |
3498 | if (spec->hp_independent_mode) | 3511 | if (spec->hp_independent_mode) |
3499 | snd_hda_codec_write(codec, 0x25, 0, | 3512 | update_power_state(codec, 0x25, parm); |
3500 | AC_VERB_SET_POWER_STATE, parm); | ||
3501 | 3513 | ||
3502 | /* force to D0 for internal Speaker */ | 3514 | /* force to D0 for internal Speaker */ |
3503 | /* MW0 (16h), AOW0 (10h) */ | 3515 | /* MW0 (16h), AOW0 (10h) */ |
3504 | snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, | 3516 | update_power_state(codec, 0x16, imux_is_smixer ? AC_PWRST_D0 : parm); |
3505 | imux_is_smixer ? AC_PWRST_D0 : parm); | 3517 | update_power_state(codec, 0x10, mono_out ? AC_PWRST_D0 : parm); |
3506 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, | ||
3507 | mono_out ? AC_PWRST_D0 : parm); | ||
3508 | } | 3518 | } |
3509 | 3519 | ||
3510 | static int patch_vt1716S(struct hda_codec *codec) | 3520 | static int patch_vt1716S(struct hda_codec *codec) |
@@ -3580,54 +3590,45 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) | |||
3580 | set_pin_power_state(codec, 0x2b, &parm); | 3590 | set_pin_power_state(codec, 0x2b, &parm); |
3581 | parm = AC_PWRST_D0; | 3591 | parm = AC_PWRST_D0; |
3582 | /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */ | 3592 | /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */ |
3583 | snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); | 3593 | update_power_state(codec, 0x1e, parm); |
3584 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); | 3594 | update_power_state(codec, 0x1f, parm); |
3585 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); | 3595 | update_power_state(codec, 0x10, parm); |
3586 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); | 3596 | update_power_state(codec, 0x11, parm); |
3587 | 3597 | ||
3588 | /* outputs */ | 3598 | /* outputs */ |
3589 | /* AOW0 (8h)*/ | 3599 | /* AOW0 (8h)*/ |
3590 | snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); | 3600 | update_power_state(codec, 0x8, parm); |
3591 | 3601 | ||
3592 | if (spec->codec_type == VT1802) { | 3602 | if (spec->codec_type == VT1802) { |
3593 | /* PW4 (28h), MW4 (18h), MUX4(38h) */ | 3603 | /* PW4 (28h), MW4 (18h), MUX4(38h) */ |
3594 | parm = AC_PWRST_D3; | 3604 | parm = AC_PWRST_D3; |
3595 | set_pin_power_state(codec, 0x28, &parm); | 3605 | set_pin_power_state(codec, 0x28, &parm); |
3596 | snd_hda_codec_write(codec, 0x18, 0, | 3606 | update_power_state(codec, 0x18, parm); |
3597 | AC_VERB_SET_POWER_STATE, parm); | 3607 | update_power_state(codec, 0x38, parm); |
3598 | snd_hda_codec_write(codec, 0x38, 0, | ||
3599 | AC_VERB_SET_POWER_STATE, parm); | ||
3600 | } else { | 3608 | } else { |
3601 | /* PW4 (26h), MW4 (1ch), MUX4(37h) */ | 3609 | /* PW4 (26h), MW4 (1ch), MUX4(37h) */ |
3602 | parm = AC_PWRST_D3; | 3610 | parm = AC_PWRST_D3; |
3603 | set_pin_power_state(codec, 0x26, &parm); | 3611 | set_pin_power_state(codec, 0x26, &parm); |
3604 | snd_hda_codec_write(codec, 0x1c, 0, | 3612 | update_power_state(codec, 0x1c, parm); |
3605 | AC_VERB_SET_POWER_STATE, parm); | 3613 | update_power_state(codec, 0x37, parm); |
3606 | snd_hda_codec_write(codec, 0x37, 0, | ||
3607 | AC_VERB_SET_POWER_STATE, parm); | ||
3608 | } | 3614 | } |
3609 | 3615 | ||
3610 | if (spec->codec_type == VT1802) { | 3616 | if (spec->codec_type == VT1802) { |
3611 | /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ | 3617 | /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ |
3612 | parm = AC_PWRST_D3; | 3618 | parm = AC_PWRST_D3; |
3613 | set_pin_power_state(codec, 0x25, &parm); | 3619 | set_pin_power_state(codec, 0x25, &parm); |
3614 | snd_hda_codec_write(codec, 0x15, 0, | 3620 | update_power_state(codec, 0x15, parm); |
3615 | AC_VERB_SET_POWER_STATE, parm); | 3621 | update_power_state(codec, 0x35, parm); |
3616 | snd_hda_codec_write(codec, 0x35, 0, | ||
3617 | AC_VERB_SET_POWER_STATE, parm); | ||
3618 | } else { | 3622 | } else { |
3619 | /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */ | 3623 | /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */ |
3620 | parm = AC_PWRST_D3; | 3624 | parm = AC_PWRST_D3; |
3621 | set_pin_power_state(codec, 0x25, &parm); | 3625 | set_pin_power_state(codec, 0x25, &parm); |
3622 | snd_hda_codec_write(codec, 0x19, 0, | 3626 | update_power_state(codec, 0x19, parm); |
3623 | AC_VERB_SET_POWER_STATE, parm); | 3627 | update_power_state(codec, 0x35, parm); |
3624 | snd_hda_codec_write(codec, 0x35, 0, | ||
3625 | AC_VERB_SET_POWER_STATE, parm); | ||
3626 | } | 3628 | } |
3627 | 3629 | ||
3628 | if (spec->hp_independent_mode) | 3630 | if (spec->hp_independent_mode) |
3629 | snd_hda_codec_write(codec, 0x9, 0, | 3631 | update_power_state(codec, 0x9, AC_PWRST_D0); |
3630 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
3631 | 3632 | ||
3632 | /* Class-D */ | 3633 | /* Class-D */ |
3633 | /* PW0 (24h), MW0(18h/14h), MUX0(34h) */ | 3634 | /* PW0 (24h), MW0(18h/14h), MUX0(34h) */ |
@@ -3637,12 +3638,10 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) | |||
3637 | set_pin_power_state(codec, 0x24, &parm); | 3638 | set_pin_power_state(codec, 0x24, &parm); |
3638 | parm = present ? AC_PWRST_D3 : AC_PWRST_D0; | 3639 | parm = present ? AC_PWRST_D3 : AC_PWRST_D0; |
3639 | if (spec->codec_type == VT1802) | 3640 | if (spec->codec_type == VT1802) |
3640 | snd_hda_codec_write(codec, 0x14, 0, | 3641 | update_power_state(codec, 0x14, parm); |
3641 | AC_VERB_SET_POWER_STATE, parm); | ||
3642 | else | 3642 | else |
3643 | snd_hda_codec_write(codec, 0x18, 0, | 3643 | update_power_state(codec, 0x18, parm); |
3644 | AC_VERB_SET_POWER_STATE, parm); | 3644 | update_power_state(codec, 0x34, parm); |
3645 | snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm); | ||
3646 | 3645 | ||
3647 | /* Mono Out */ | 3646 | /* Mono Out */ |
3648 | present = snd_hda_jack_detect(codec, 0x26); | 3647 | present = snd_hda_jack_detect(codec, 0x26); |
@@ -3650,28 +3649,20 @@ static void set_widgets_power_state_vt2002P(struct hda_codec *codec) | |||
3650 | parm = present ? AC_PWRST_D3 : AC_PWRST_D0; | 3649 | parm = present ? AC_PWRST_D3 : AC_PWRST_D0; |
3651 | if (spec->codec_type == VT1802) { | 3650 | if (spec->codec_type == VT1802) { |
3652 | /* PW15 (33h), MW8(1ch), MUX8(3ch) */ | 3651 | /* PW15 (33h), MW8(1ch), MUX8(3ch) */ |
3653 | snd_hda_codec_write(codec, 0x33, 0, | 3652 | update_power_state(codec, 0x33, parm); |
3654 | AC_VERB_SET_POWER_STATE, parm); | 3653 | update_power_state(codec, 0x1c, parm); |
3655 | snd_hda_codec_write(codec, 0x1c, 0, | 3654 | update_power_state(codec, 0x3c, parm); |
3656 | AC_VERB_SET_POWER_STATE, parm); | ||
3657 | snd_hda_codec_write(codec, 0x3c, 0, | ||
3658 | AC_VERB_SET_POWER_STATE, parm); | ||
3659 | } else { | 3655 | } else { |
3660 | /* PW15 (31h), MW8(17h), MUX8(3bh) */ | 3656 | /* PW15 (31h), MW8(17h), MUX8(3bh) */ |
3661 | snd_hda_codec_write(codec, 0x31, 0, | 3657 | update_power_state(codec, 0x31, parm); |
3662 | AC_VERB_SET_POWER_STATE, parm); | 3658 | update_power_state(codec, 0x17, parm); |
3663 | snd_hda_codec_write(codec, 0x17, 0, | 3659 | update_power_state(codec, 0x3b, parm); |
3664 | AC_VERB_SET_POWER_STATE, parm); | ||
3665 | snd_hda_codec_write(codec, 0x3b, 0, | ||
3666 | AC_VERB_SET_POWER_STATE, parm); | ||
3667 | } | 3660 | } |
3668 | /* MW9 (21h) */ | 3661 | /* MW9 (21h) */ |
3669 | if (imux_is_smixer || !is_aa_path_mute(codec)) | 3662 | if (imux_is_smixer || !is_aa_path_mute(codec)) |
3670 | snd_hda_codec_write(codec, 0x21, 0, | 3663 | update_power_state(codec, 0x21, AC_PWRST_D0); |
3671 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
3672 | else | 3664 | else |
3673 | snd_hda_codec_write(codec, 0x21, 0, | 3665 | update_power_state(codec, 0x21, AC_PWRST_D3); |
3674 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
3675 | } | 3666 | } |
3676 | 3667 | ||
3677 | /* patch for vt2002P */ | 3668 | /* patch for vt2002P */ |
@@ -3731,30 +3722,28 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec) | |||
3731 | set_pin_power_state(codec, 0x2b, &parm); | 3722 | set_pin_power_state(codec, 0x2b, &parm); |
3732 | parm = AC_PWRST_D0; | 3723 | parm = AC_PWRST_D0; |
3733 | /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */ | 3724 | /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */ |
3734 | snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); | 3725 | update_power_state(codec, 0x1e, parm); |
3735 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); | 3726 | update_power_state(codec, 0x1f, parm); |
3736 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); | 3727 | update_power_state(codec, 0x10, parm); |
3737 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); | 3728 | update_power_state(codec, 0x11, parm); |
3738 | 3729 | ||
3739 | /* outputs */ | 3730 | /* outputs */ |
3740 | /* AOW0 (8h)*/ | 3731 | /* AOW0 (8h)*/ |
3741 | snd_hda_codec_write(codec, 0x8, 0, | 3732 | update_power_state(codec, 0x8, AC_PWRST_D0); |
3742 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
3743 | 3733 | ||
3744 | /* PW4 (28h), MW4 (18h), MUX4(38h) */ | 3734 | /* PW4 (28h), MW4 (18h), MUX4(38h) */ |
3745 | parm = AC_PWRST_D3; | 3735 | parm = AC_PWRST_D3; |
3746 | set_pin_power_state(codec, 0x28, &parm); | 3736 | set_pin_power_state(codec, 0x28, &parm); |
3747 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); | 3737 | update_power_state(codec, 0x18, parm); |
3748 | snd_hda_codec_write(codec, 0x38, 0, AC_VERB_SET_POWER_STATE, parm); | 3738 | update_power_state(codec, 0x38, parm); |
3749 | 3739 | ||
3750 | /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ | 3740 | /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ |
3751 | parm = AC_PWRST_D3; | 3741 | parm = AC_PWRST_D3; |
3752 | set_pin_power_state(codec, 0x25, &parm); | 3742 | set_pin_power_state(codec, 0x25, &parm); |
3753 | snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_POWER_STATE, parm); | 3743 | update_power_state(codec, 0x15, parm); |
3754 | snd_hda_codec_write(codec, 0x35, 0, AC_VERB_SET_POWER_STATE, parm); | 3744 | update_power_state(codec, 0x35, parm); |
3755 | if (spec->hp_independent_mode) | 3745 | if (spec->hp_independent_mode) |
3756 | snd_hda_codec_write(codec, 0x9, 0, | 3746 | update_power_state(codec, 0x9, AC_PWRST_D0); |
3757 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
3758 | 3747 | ||
3759 | /* Internal Speaker */ | 3748 | /* Internal Speaker */ |
3760 | /* PW0 (24h), MW0(14h), MUX0(34h) */ | 3749 | /* PW0 (24h), MW0(14h), MUX0(34h) */ |
@@ -3763,15 +3752,11 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec) | |||
3763 | parm = AC_PWRST_D3; | 3752 | parm = AC_PWRST_D3; |
3764 | set_pin_power_state(codec, 0x24, &parm); | 3753 | set_pin_power_state(codec, 0x24, &parm); |
3765 | if (present) { | 3754 | if (present) { |
3766 | snd_hda_codec_write(codec, 0x14, 0, | 3755 | update_power_state(codec, 0x14, AC_PWRST_D3); |
3767 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | 3756 | update_power_state(codec, 0x34, AC_PWRST_D3); |
3768 | snd_hda_codec_write(codec, 0x34, 0, | ||
3769 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
3770 | } else { | 3757 | } else { |
3771 | snd_hda_codec_write(codec, 0x14, 0, | 3758 | update_power_state(codec, 0x14, AC_PWRST_D0); |
3772 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | 3759 | update_power_state(codec, 0x34, AC_PWRST_D0); |
3773 | snd_hda_codec_write(codec, 0x34, 0, | ||
3774 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
3775 | } | 3760 | } |
3776 | 3761 | ||
3777 | 3762 | ||
@@ -3782,26 +3767,20 @@ static void set_widgets_power_state_vt1812(struct hda_codec *codec) | |||
3782 | parm = AC_PWRST_D3; | 3767 | parm = AC_PWRST_D3; |
3783 | set_pin_power_state(codec, 0x31, &parm); | 3768 | set_pin_power_state(codec, 0x31, &parm); |
3784 | if (present) { | 3769 | if (present) { |
3785 | snd_hda_codec_write(codec, 0x1c, 0, | 3770 | update_power_state(codec, 0x1c, AC_PWRST_D3); |
3786 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | 3771 | update_power_state(codec, 0x3c, AC_PWRST_D3); |
3787 | snd_hda_codec_write(codec, 0x3c, 0, | 3772 | update_power_state(codec, 0x3e, AC_PWRST_D3); |
3788 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
3789 | snd_hda_codec_write(codec, 0x3e, 0, | ||
3790 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
3791 | } else { | 3773 | } else { |
3792 | snd_hda_codec_write(codec, 0x1c, 0, | 3774 | update_power_state(codec, 0x1c, AC_PWRST_D0); |
3793 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | 3775 | update_power_state(codec, 0x3c, AC_PWRST_D0); |
3794 | snd_hda_codec_write(codec, 0x3c, 0, | 3776 | update_power_state(codec, 0x3e, AC_PWRST_D0); |
3795 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
3796 | snd_hda_codec_write(codec, 0x3e, 0, | ||
3797 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
3798 | } | 3777 | } |
3799 | 3778 | ||
3800 | /* PW15 (33h), MW15 (1dh), MUX15(3dh) */ | 3779 | /* PW15 (33h), MW15 (1dh), MUX15(3dh) */ |
3801 | parm = AC_PWRST_D3; | 3780 | parm = AC_PWRST_D3; |
3802 | set_pin_power_state(codec, 0x33, &parm); | 3781 | set_pin_power_state(codec, 0x33, &parm); |
3803 | snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm); | 3782 | update_power_state(codec, 0x1d, parm); |
3804 | snd_hda_codec_write(codec, 0x3d, 0, AC_VERB_SET_POWER_STATE, parm); | 3783 | update_power_state(codec, 0x3d, parm); |
3805 | 3784 | ||
3806 | } | 3785 | } |
3807 | 3786 | ||
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 92362973764d..812d10e43ae0 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c | |||
@@ -1013,6 +1013,25 @@ static int set_rate_constraints(struct snd_ice1712 *ice, | |||
1013 | ice->hw_rates); | 1013 | ice->hw_rates); |
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | /* if the card has the internal rate locked (is_pro_locked), limit runtime | ||
1017 | hw rates to the current internal rate only. | ||
1018 | */ | ||
1019 | static void constrain_rate_if_locked(struct snd_pcm_substream *substream) | ||
1020 | { | ||
1021 | struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); | ||
1022 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
1023 | unsigned int rate; | ||
1024 | if (is_pro_rate_locked(ice)) { | ||
1025 | rate = ice->get_rate(ice); | ||
1026 | if (rate >= runtime->hw.rate_min | ||
1027 | && rate <= runtime->hw.rate_max) { | ||
1028 | runtime->hw.rate_min = rate; | ||
1029 | runtime->hw.rate_max = rate; | ||
1030 | } | ||
1031 | } | ||
1032 | } | ||
1033 | |||
1034 | |||
1016 | /* multi-channel playback needs alignment 8x32bit regardless of the channels | 1035 | /* multi-channel playback needs alignment 8x32bit regardless of the channels |
1017 | * actually used | 1036 | * actually used |
1018 | */ | 1037 | */ |
@@ -1046,6 +1065,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream) | |||
1046 | VT1724_BUFFER_ALIGN); | 1065 | VT1724_BUFFER_ALIGN); |
1047 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, | 1066 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, |
1048 | VT1724_BUFFER_ALIGN); | 1067 | VT1724_BUFFER_ALIGN); |
1068 | constrain_rate_if_locked(substream); | ||
1049 | if (ice->pro_open) | 1069 | if (ice->pro_open) |
1050 | ice->pro_open(ice, substream); | 1070 | ice->pro_open(ice, substream); |
1051 | return 0; | 1071 | return 0; |
@@ -1066,6 +1086,7 @@ static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream) | |||
1066 | VT1724_BUFFER_ALIGN); | 1086 | VT1724_BUFFER_ALIGN); |
1067 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, | 1087 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, |
1068 | VT1724_BUFFER_ALIGN); | 1088 | VT1724_BUFFER_ALIGN); |
1089 | constrain_rate_if_locked(substream); | ||
1069 | if (ice->pro_open) | 1090 | if (ice->pro_open) |
1070 | ice->pro_open(ice, substream); | 1091 | ice->pro_open(ice, substream); |
1071 | return 0; | 1092 | return 0; |
@@ -1215,6 +1236,7 @@ static int snd_vt1724_playback_spdif_open(struct snd_pcm_substream *substream) | |||
1215 | VT1724_BUFFER_ALIGN); | 1236 | VT1724_BUFFER_ALIGN); |
1216 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, | 1237 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, |
1217 | VT1724_BUFFER_ALIGN); | 1238 | VT1724_BUFFER_ALIGN); |
1239 | constrain_rate_if_locked(substream); | ||
1218 | if (ice->spdif.ops.open) | 1240 | if (ice->spdif.ops.open) |
1219 | ice->spdif.ops.open(ice, substream); | 1241 | ice->spdif.ops.open(ice, substream); |
1220 | return 0; | 1242 | return 0; |
@@ -1251,6 +1273,7 @@ static int snd_vt1724_capture_spdif_open(struct snd_pcm_substream *substream) | |||
1251 | VT1724_BUFFER_ALIGN); | 1273 | VT1724_BUFFER_ALIGN); |
1252 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, | 1274 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, |
1253 | VT1724_BUFFER_ALIGN); | 1275 | VT1724_BUFFER_ALIGN); |
1276 | constrain_rate_if_locked(substream); | ||
1254 | if (ice->spdif.ops.open) | 1277 | if (ice->spdif.ops.open) |
1255 | ice->spdif.ops.open(ice, substream); | 1278 | ice->spdif.ops.open(ice, substream); |
1256 | return 0; | 1279 | return 0; |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 9f3b01bb72c8..e0a4263baa20 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -2102,6 +2102,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { | |||
2102 | }, | 2102 | }, |
2103 | { | 2103 | { |
2104 | .subvendor = 0x161f, | 2104 | .subvendor = 0x161f, |
2105 | .subdevice = 0x202f, | ||
2106 | .name = "Gateway M520", | ||
2107 | .type = AC97_TUNE_INV_EAPD | ||
2108 | }, | ||
2109 | { | ||
2110 | .subvendor = 0x161f, | ||
2105 | .subdevice = 0x203a, | 2111 | .subdevice = 0x203a, |
2106 | .name = "Gateway 4525GZ", /* AD1981B */ | 2112 | .name = "Gateway 4525GZ", /* AD1981B */ |
2107 | .type = AC97_TUNE_INV_EAPD | 2113 | .type = AC97_TUNE_INV_EAPD |
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 26c7e8bcb229..c0dbb52d45be 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c | |||
@@ -618,9 +618,12 @@ static int ac97_volume_get(struct snd_kcontrol *ctl, | |||
618 | mutex_lock(&chip->mutex); | 618 | mutex_lock(&chip->mutex); |
619 | reg = oxygen_read_ac97(chip, codec, index); | 619 | reg = oxygen_read_ac97(chip, codec, index); |
620 | mutex_unlock(&chip->mutex); | 620 | mutex_unlock(&chip->mutex); |
621 | value->value.integer.value[0] = 31 - (reg & 0x1f); | 621 | if (!stereo) { |
622 | if (stereo) | 622 | value->value.integer.value[0] = 31 - (reg & 0x1f); |
623 | value->value.integer.value[1] = 31 - ((reg >> 8) & 0x1f); | 623 | } else { |
624 | value->value.integer.value[0] = 31 - ((reg >> 8) & 0x1f); | ||
625 | value->value.integer.value[1] = 31 - (reg & 0x1f); | ||
626 | } | ||
624 | return 0; | 627 | return 0; |
625 | } | 628 | } |
626 | 629 | ||
@@ -636,14 +639,14 @@ static int ac97_volume_put(struct snd_kcontrol *ctl, | |||
636 | 639 | ||
637 | mutex_lock(&chip->mutex); | 640 | mutex_lock(&chip->mutex); |
638 | oldreg = oxygen_read_ac97(chip, codec, index); | 641 | oldreg = oxygen_read_ac97(chip, codec, index); |
639 | newreg = oldreg; | 642 | if (!stereo) { |
640 | newreg = (newreg & ~0x1f) | | 643 | newreg = oldreg & ~0x1f; |
641 | (31 - (value->value.integer.value[0] & 0x1f)); | 644 | newreg |= 31 - (value->value.integer.value[0] & 0x1f); |
642 | if (stereo) | 645 | } else { |
643 | newreg = (newreg & ~0x1f00) | | 646 | newreg = oldreg & ~0x1f1f; |
644 | ((31 - (value->value.integer.value[1] & 0x1f)) << 8); | 647 | newreg |= (31 - (value->value.integer.value[0] & 0x1f)) << 8; |
645 | else | 648 | newreg |= 31 - (value->value.integer.value[1] & 0x1f); |
646 | newreg = (newreg & ~0x1f00) | ((newreg & 0x1f) << 8); | 649 | } |
647 | change = newreg != oldreg; | 650 | change = newreg != oldreg; |
648 | if (change) | 651 | if (change) |
649 | oxygen_write_ac97(chip, codec, index, newreg); | 652 | oxygen_write_ac97(chip, codec, index, newreg); |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index cc9f6c83d661..bc030a2088da 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -6333,6 +6333,7 @@ static int __devinit snd_hdspm_create_hwdep(struct snd_card *card, | |||
6333 | 6333 | ||
6334 | hw->ops.open = snd_hdspm_hwdep_dummy_op; | 6334 | hw->ops.open = snd_hdspm_hwdep_dummy_op; |
6335 | hw->ops.ioctl = snd_hdspm_hwdep_ioctl; | 6335 | hw->ops.ioctl = snd_hdspm_hwdep_ioctl; |
6336 | hw->ops.ioctl_compat = snd_hdspm_hwdep_ioctl; | ||
6336 | hw->ops.release = snd_hdspm_hwdep_dummy_op; | 6337 | hw->ops.release = snd_hdspm_hwdep_dummy_op; |
6337 | 6338 | ||
6338 | return 0; | 6339 | return 0; |
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index e57b89e8aa89..94ab728f5ca8 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c | |||
@@ -286,17 +286,22 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, | |||
286 | snd_card_free(card); | 286 | snd_card_free(card); |
287 | return err; | 287 | return err; |
288 | } | 288 | } |
289 | if ((err = snd_ymfpci_pcm_4ch(chip, 2, NULL)) < 0) { | 289 | err = snd_ymfpci_mixer(chip, rear_switch[dev]); |
290 | if (err < 0) { | ||
290 | snd_card_free(card); | 291 | snd_card_free(card); |
291 | return err; | 292 | return err; |
292 | } | 293 | } |
293 | if ((err = snd_ymfpci_pcm2(chip, 3, NULL)) < 0) { | 294 | if (chip->ac97->ext_id & AC97_EI_SDAC) { |
294 | snd_card_free(card); | 295 | err = snd_ymfpci_pcm_4ch(chip, 2, NULL); |
295 | return err; | 296 | if (err < 0) { |
296 | } | 297 | snd_card_free(card); |
297 | if ((err = snd_ymfpci_mixer(chip, rear_switch[dev])) < 0) { | 298 | return err; |
298 | snd_card_free(card); | 299 | } |
299 | return err; | 300 | err = snd_ymfpci_pcm2(chip, 3, NULL); |
301 | if (err < 0) { | ||
302 | snd_card_free(card); | ||
303 | return err; | ||
304 | } | ||
300 | } | 305 | } |
301 | if ((err = snd_ymfpci_timer(chip, 0)) < 0) { | 306 | if ((err = snd_ymfpci_timer(chip, 0)) < 0) { |
302 | snd_card_free(card); | 307 | snd_card_free(card); |
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 03ee4e365311..a8159b81e9c4 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c | |||
@@ -1614,6 +1614,14 @@ static int snd_ymfpci_put_dup4ch(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1614 | return change; | 1614 | return change; |
1615 | } | 1615 | } |
1616 | 1616 | ||
1617 | static struct snd_kcontrol_new snd_ymfpci_dup4ch __devinitdata = { | ||
1618 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1619 | .name = "4ch Duplication", | ||
1620 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
1621 | .info = snd_ymfpci_info_dup4ch, | ||
1622 | .get = snd_ymfpci_get_dup4ch, | ||
1623 | .put = snd_ymfpci_put_dup4ch, | ||
1624 | }; | ||
1617 | 1625 | ||
1618 | static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = { | 1626 | static struct snd_kcontrol_new snd_ymfpci_controls[] __devinitdata = { |
1619 | { | 1627 | { |
@@ -1642,13 +1650,6 @@ YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,VOLUME), 1, YDSXGR_SPDIFLOOPVOL), | |||
1642 | YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL, 0), | 1650 | YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 0, YDSXGR_SPDIFOUTCTRL, 0), |
1643 | YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL, 0), | 1651 | YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL, 0), |
1644 | YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("Loop",NONE,NONE), 0, YDSXGR_SPDIFINCTRL, 4), | 1652 | YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("Loop",NONE,NONE), 0, YDSXGR_SPDIFINCTRL, 4), |
1645 | { | ||
1646 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1647 | .name = "4ch Duplication", | ||
1648 | .info = snd_ymfpci_info_dup4ch, | ||
1649 | .get = snd_ymfpci_get_dup4ch, | ||
1650 | .put = snd_ymfpci_put_dup4ch, | ||
1651 | }, | ||
1652 | }; | 1653 | }; |
1653 | 1654 | ||
1654 | 1655 | ||
@@ -1838,6 +1839,12 @@ int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) | |||
1838 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip))) < 0) | 1839 | if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_controls[idx], chip))) < 0) |
1839 | return err; | 1840 | return err; |
1840 | } | 1841 | } |
1842 | if (chip->ac97->ext_id & AC97_EI_SDAC) { | ||
1843 | kctl = snd_ctl_new1(&snd_ymfpci_dup4ch, chip); | ||
1844 | err = snd_ctl_add(chip->card, kctl); | ||
1845 | if (err < 0) | ||
1846 | return err; | ||
1847 | } | ||
1841 | 1848 | ||
1842 | /* add S/PDIF control */ | 1849 | /* add S/PDIF control */ |
1843 | if (snd_BUG_ON(!chip->pcm_spdif)) | 1850 | if (snd_BUG_ON(!chip->pcm_spdif)) |
@@ -2310,6 +2317,10 @@ int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state) | |||
2310 | for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++) | 2317 | for (i = 0; i < YDSXGR_NUM_SAVED_REGS; i++) |
2311 | chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]); | 2318 | chip->saved_regs[i] = snd_ymfpci_readl(chip, saved_regs_index[i]); |
2312 | chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE); | 2319 | chip->saved_ydsxgr_mode = snd_ymfpci_readl(chip, YDSXGR_MODE); |
2320 | pci_read_config_word(chip->pci, PCIR_DSXG_LEGACY, | ||
2321 | &chip->saved_dsxg_legacy); | ||
2322 | pci_read_config_word(chip->pci, PCIR_DSXG_ELEGACY, | ||
2323 | &chip->saved_dsxg_elegacy); | ||
2313 | snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); | 2324 | snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); |
2314 | snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0); | 2325 | snd_ymfpci_writel(chip, YDSXGR_BUF441OUTVOL, 0); |
2315 | snd_ymfpci_disable_dsp(chip); | 2326 | snd_ymfpci_disable_dsp(chip); |
@@ -2344,6 +2355,11 @@ int snd_ymfpci_resume(struct pci_dev *pci) | |||
2344 | 2355 | ||
2345 | snd_ac97_resume(chip->ac97); | 2356 | snd_ac97_resume(chip->ac97); |
2346 | 2357 | ||
2358 | pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, | ||
2359 | chip->saved_dsxg_legacy); | ||
2360 | pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY, | ||
2361 | chip->saved_dsxg_elegacy); | ||
2362 | |||
2347 | /* start hw again */ | 2363 | /* start hw again */ |
2348 | if (chip->start_count > 0) { | 2364 | if (chip->start_count > 0) { |
2349 | spin_lock_irq(&chip->reg_lock); | 2365 | spin_lock_irq(&chip->reg_lock); |
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 35e662d270e6..91c985599d32 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig | |||
@@ -25,6 +25,9 @@ if SND_SOC | |||
25 | config SND_SOC_AC97_BUS | 25 | config SND_SOC_AC97_BUS |
26 | bool | 26 | bool |
27 | 27 | ||
28 | config SND_SOC_DMAENGINE_PCM | ||
29 | bool | ||
30 | |||
28 | # All the supported SoCs | 31 | # All the supported SoCs |
29 | source "sound/soc/atmel/Kconfig" | 32 | source "sound/soc/atmel/Kconfig" |
30 | source "sound/soc/au1x/Kconfig" | 33 | source "sound/soc/au1x/Kconfig" |
diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 9ea8ac827adc..2feaf376e94b 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile | |||
@@ -1,6 +1,9 @@ | |||
1 | snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o | 1 | snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o |
2 | snd-soc-core-objs += soc-pcm.o soc-io.o | 2 | snd-soc-core-objs += soc-pcm.o soc-io.o |
3 | 3 | ||
4 | snd-soc-dmaengine-pcm-objs := soc-dmaengine-pcm.o | ||
5 | obj-$(CONFIG_SND_SOC_DMAENGINE_PCM) += snd-soc-dmaengine-pcm.o | ||
6 | |||
4 | obj-$(CONFIG_SND_SOC) += snd-soc-core.o | 7 | obj-$(CONFIG_SND_SOC) += snd-soc-core.o |
5 | obj-$(CONFIG_SND_SOC) += codecs/ | 8 | obj-$(CONFIG_SND_SOC) += codecs/ |
6 | obj-$(CONFIG_SND_SOC) += atmel/ | 9 | obj-$(CONFIG_SND_SOC) += atmel/ |
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c index a21ff459e5d3..9b84f985770e 100644 --- a/sound/soc/atmel/atmel-pcm.c +++ b/sound/soc/atmel/atmel-pcm.c | |||
@@ -362,7 +362,7 @@ static struct snd_pcm_ops atmel_pcm_ops = { | |||
362 | /*--------------------------------------------------------------------------*\ | 362 | /*--------------------------------------------------------------------------*\ |
363 | * ASoC platform driver | 363 | * ASoC platform driver |
364 | \*--------------------------------------------------------------------------*/ | 364 | \*--------------------------------------------------------------------------*/ |
365 | static u64 atmel_pcm_dmamask = 0xffffffff; | 365 | static u64 atmel_pcm_dmamask = DMA_BIT_MASK(32); |
366 | 366 | ||
367 | static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) | 367 | static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) |
368 | { | 368 | { |
@@ -373,7 +373,7 @@ static int atmel_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
373 | if (!card->dev->dma_mask) | 373 | if (!card->dev->dma_mask) |
374 | card->dev->dma_mask = &atmel_pcm_dmamask; | 374 | card->dev->dma_mask = &atmel_pcm_dmamask; |
375 | if (!card->dev->coherent_dma_mask) | 375 | if (!card->dev->coherent_dma_mask) |
376 | card->dev->coherent_dma_mask = 0xffffffff; | 376 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); |
377 | 377 | ||
378 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | 378 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { |
379 | ret = atmel_pcm_preallocate_dma_buffer(pcm, | 379 | ret = atmel_pcm_preallocate_dma_buffer(pcm, |
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c index 4ca667d477f9..f65f08beac31 100644 --- a/sound/soc/atmel/snd-soc-afeb9260.c +++ b/sound/soc/atmel/snd-soc-afeb9260.c | |||
@@ -46,29 +46,8 @@ static int afeb9260_hw_params(struct snd_pcm_substream *substream, | |||
46 | { | 46 | { |
47 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 47 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
48 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 48 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
49 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
50 | int err; | 49 | int err; |
51 | 50 | ||
52 | /* Set codec DAI configuration */ | ||
53 | err = snd_soc_dai_set_fmt(codec_dai, | ||
54 | SND_SOC_DAIFMT_I2S| | ||
55 | SND_SOC_DAIFMT_NB_IF | | ||
56 | SND_SOC_DAIFMT_CBM_CFM); | ||
57 | if (err < 0) { | ||
58 | printk(KERN_ERR "can't set codec DAI configuration\n"); | ||
59 | return err; | ||
60 | } | ||
61 | |||
62 | /* Set cpu DAI configuration */ | ||
63 | err = snd_soc_dai_set_fmt(cpu_dai, | ||
64 | SND_SOC_DAIFMT_I2S | | ||
65 | SND_SOC_DAIFMT_NB_IF | | ||
66 | SND_SOC_DAIFMT_CBM_CFM); | ||
67 | if (err < 0) { | ||
68 | printk(KERN_ERR "can't set cpu DAI configuration\n"); | ||
69 | return err; | ||
70 | } | ||
71 | |||
72 | /* Set the codec system clock for DAC and ADC */ | 51 | /* Set the codec system clock for DAC and ADC */ |
73 | err = | 52 | err = |
74 | snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN); | 53 | snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN); |
@@ -91,7 +70,7 @@ static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = { | |||
91 | SND_SOC_DAPM_MIC("Mic Jack", NULL), | 70 | SND_SOC_DAPM_MIC("Mic Jack", NULL), |
92 | }; | 71 | }; |
93 | 72 | ||
94 | static const struct snd_soc_dapm_route audio_map[] = { | 73 | static const struct snd_soc_dapm_route afeb9260_audio_map[] = { |
95 | {"Headphone Jack", NULL, "LHPOUT"}, | 74 | {"Headphone Jack", NULL, "LHPOUT"}, |
96 | {"Headphone Jack", NULL, "RHPOUT"}, | 75 | {"Headphone Jack", NULL, "RHPOUT"}, |
97 | 76 | ||
@@ -106,13 +85,6 @@ static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) | |||
106 | struct snd_soc_codec *codec = rtd->codec; | 85 | struct snd_soc_codec *codec = rtd->codec; |
107 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 86 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
108 | 87 | ||
109 | /* Add afeb9260 specific widgets */ | ||
110 | snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, | ||
111 | ARRAY_SIZE(tlv320aic23_dapm_widgets)); | ||
112 | |||
113 | /* Set up afeb9260 specific audio path audio_map */ | ||
114 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
115 | |||
116 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | 88 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); |
117 | snd_soc_dapm_enable_pin(dapm, "Line In"); | 89 | snd_soc_dapm_enable_pin(dapm, "Line In"); |
118 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | 90 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); |
@@ -129,6 +101,8 @@ static struct snd_soc_dai_link afeb9260_dai = { | |||
129 | .platform_name = "atmel_pcm-audio", | 101 | .platform_name = "atmel_pcm-audio", |
130 | .codec_name = "tlv320aic23-codec.0-001a", | 102 | .codec_name = "tlv320aic23-codec.0-001a", |
131 | .init = afeb9260_tlv320aic23_init, | 103 | .init = afeb9260_tlv320aic23_init, |
104 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF | | ||
105 | SND_SOC_DAIFMT_CBM_CFM, | ||
132 | .ops = &afeb9260_ops, | 106 | .ops = &afeb9260_ops, |
133 | }; | 107 | }; |
134 | 108 | ||
@@ -138,6 +112,11 @@ static struct snd_soc_card snd_soc_machine_afeb9260 = { | |||
138 | .owner = THIS_MODULE, | 112 | .owner = THIS_MODULE, |
139 | .dai_link = &afeb9260_dai, | 113 | .dai_link = &afeb9260_dai, |
140 | .num_links = 1, | 114 | .num_links = 1, |
115 | |||
116 | .dapm_widgets = tlv320aic23_dapm_widgets, | ||
117 | .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), | ||
118 | .dapm_routes = afeb9260_audio_map, | ||
119 | .num_dapm_routes = ARRAY_SIZE(afeb9260_audio_map), | ||
141 | }; | 120 | }; |
142 | 121 | ||
143 | static struct platform_device *afeb9260_snd_device; | 122 | static struct platform_device *afeb9260_snd_device; |
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c index 60962ce6cd4d..d542d4063771 100644 --- a/sound/soc/blackfin/bf5xx-ad1836.c +++ b/sound/soc/blackfin/bf5xx-ad1836.c | |||
@@ -40,20 +40,8 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream, | |||
40 | { | 40 | { |
41 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 41 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
42 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 42 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
43 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
44 | unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7}; | 43 | unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7}; |
45 | int ret = 0; | 44 | int ret = 0; |
46 | /* set cpu DAI configuration */ | ||
47 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | | ||
48 | SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); | ||
49 | if (ret < 0) | ||
50 | return ret; | ||
51 | |||
52 | /* set codec DAI configuration */ | ||
53 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A | | ||
54 | SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); | ||
55 | if (ret < 0) | ||
56 | return ret; | ||
57 | 45 | ||
58 | /* set cpu DAI channel mapping */ | 46 | /* set cpu DAI channel mapping */ |
59 | ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map), | 47 | ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map), |
@@ -68,6 +56,9 @@ static struct snd_soc_ops bf5xx_ad1836_ops = { | |||
68 | .hw_params = bf5xx_ad1836_hw_params, | 56 | .hw_params = bf5xx_ad1836_hw_params, |
69 | }; | 57 | }; |
70 | 58 | ||
59 | #define BF5XX_AD1836_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \ | ||
60 | SND_SOC_DAIFMT_CBM_CFM) | ||
61 | |||
71 | static struct snd_soc_dai_link bf5xx_ad1836_dai[] = { | 62 | static struct snd_soc_dai_link bf5xx_ad1836_dai[] = { |
72 | { | 63 | { |
73 | .name = "ad1836", | 64 | .name = "ad1836", |
@@ -77,6 +68,7 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai[] = { | |||
77 | .platform_name = "bfin-tdm-pcm-audio", | 68 | .platform_name = "bfin-tdm-pcm-audio", |
78 | .codec_name = "spi0.4", | 69 | .codec_name = "spi0.4", |
79 | .ops = &bf5xx_ad1836_ops, | 70 | .ops = &bf5xx_ad1836_ops, |
71 | .dai_fmt = BF5XX_AD1836_DAIFMT, | ||
80 | }, | 72 | }, |
81 | { | 73 | { |
82 | .name = "ad1836", | 74 | .name = "ad1836", |
@@ -86,6 +78,7 @@ static struct snd_soc_dai_link bf5xx_ad1836_dai[] = { | |||
86 | .platform_name = "bfin-tdm-pcm-audio", | 78 | .platform_name = "bfin-tdm-pcm-audio", |
87 | .codec_name = "spi0.4", | 79 | .codec_name = "spi0.4", |
88 | .ops = &bf5xx_ad1836_ops, | 80 | .ops = &bf5xx_ad1836_ops, |
81 | .dai_fmt = BF5XX_AD1836_DAIFMT, | ||
89 | }, | 82 | }, |
90 | }; | 83 | }; |
91 | 84 | ||
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c index 2d8d82dbc159..0e55e9f2a514 100644 --- a/sound/soc/blackfin/bf5xx-ad193x.c +++ b/sound/soc/blackfin/bf5xx-ad193x.c | |||
@@ -60,18 +60,6 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream, | |||
60 | break; | 60 | break; |
61 | } | 61 | } |
62 | 62 | ||
63 | /* set cpu DAI configuration */ | ||
64 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | | ||
65 | SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); | ||
66 | if (ret < 0) | ||
67 | return ret; | ||
68 | |||
69 | /* set codec DAI configuration */ | ||
70 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A | | ||
71 | SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); | ||
72 | if (ret < 0) | ||
73 | return ret; | ||
74 | |||
75 | /* set the codec system clock for DAC and ADC */ | 63 | /* set the codec system clock for DAC and ADC */ |
76 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, | 64 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, |
77 | SND_SOC_CLOCK_IN); | 65 | SND_SOC_CLOCK_IN); |
@@ -92,6 +80,9 @@ static int bf5xx_ad193x_hw_params(struct snd_pcm_substream *substream, | |||
92 | return 0; | 80 | return 0; |
93 | } | 81 | } |
94 | 82 | ||
83 | #define BF5XX_AD193X_DAIFMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_IF | \ | ||
84 | SND_SOC_DAIFMT_CBM_CFM) | ||
85 | |||
95 | static struct snd_soc_ops bf5xx_ad193x_ops = { | 86 | static struct snd_soc_ops bf5xx_ad193x_ops = { |
96 | .hw_params = bf5xx_ad193x_hw_params, | 87 | .hw_params = bf5xx_ad193x_hw_params, |
97 | }; | 88 | }; |
@@ -105,6 +96,7 @@ static struct snd_soc_dai_link bf5xx_ad193x_dai[] = { | |||
105 | .platform_name = "bfin-tdm-pcm-audio", | 96 | .platform_name = "bfin-tdm-pcm-audio", |
106 | .codec_name = "spi0.5", | 97 | .codec_name = "spi0.5", |
107 | .ops = &bf5xx_ad193x_ops, | 98 | .ops = &bf5xx_ad193x_ops, |
99 | .dai_fmt = BF5XX_AD193X_DAIFMT, | ||
108 | }, | 100 | }, |
109 | { | 101 | { |
110 | .name = "ad193x", | 102 | .name = "ad193x", |
@@ -114,6 +106,7 @@ static struct snd_soc_dai_link bf5xx_ad193x_dai[] = { | |||
114 | .platform_name = "bfin-tdm-pcm-audio", | 106 | .platform_name = "bfin-tdm-pcm-audio", |
115 | .codec_name = "spi0.5", | 107 | .codec_name = "spi0.5", |
116 | .ops = &bf5xx_ad193x_ops, | 108 | .ops = &bf5xx_ad193x_ops, |
109 | .dai_fmt = BF5XX_AD193X_DAIFMT, | ||
117 | }, | 110 | }, |
118 | }; | 111 | }; |
119 | 112 | ||
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c index 8e49508596da..61cc91d4a028 100644 --- a/sound/soc/blackfin/bf5xx-ad73311.c +++ b/sound/soc/blackfin/bf5xx-ad73311.c | |||
@@ -145,29 +145,8 @@ static int bf5xx_probe(struct snd_soc_card *card) | |||
145 | return 0; | 145 | return 0; |
146 | } | 146 | } |
147 | 147 | ||
148 | static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream, | 148 | #define BF5XX_AD7311_DAI_FMT (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF | \ |
149 | struct snd_pcm_hw_params *params) | 149 | SND_SOC_DAIFMT_CBM_CFM) |
150 | { | ||
151 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
152 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
153 | int ret = 0; | ||
154 | |||
155 | pr_debug("%s rate %d format %x\n", __func__, params_rate(params), | ||
156 | params_format(params)); | ||
157 | |||
158 | /* set cpu DAI configuration */ | ||
159 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | | ||
160 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
161 | if (ret < 0) | ||
162 | return ret; | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | |||
168 | static struct snd_soc_ops bf5xx_ad73311_ops = { | ||
169 | .hw_params = bf5xx_ad73311_hw_params, | ||
170 | }; | ||
171 | 150 | ||
172 | static struct snd_soc_dai_link bf5xx_ad73311_dai[] = { | 151 | static struct snd_soc_dai_link bf5xx_ad73311_dai[] = { |
173 | { | 152 | { |
@@ -177,7 +156,7 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai[] = { | |||
177 | .codec_dai_name = "ad73311-hifi", | 156 | .codec_dai_name = "ad73311-hifi", |
178 | .platform_name = "bfin-i2s-pcm-audio", | 157 | .platform_name = "bfin-i2s-pcm-audio", |
179 | .codec_name = "ad73311", | 158 | .codec_name = "ad73311", |
180 | .ops = &bf5xx_ad73311_ops, | 159 | .dai_fmt = BF5XX_AD7311_DAI_FMT, |
181 | }, | 160 | }, |
182 | { | 161 | { |
183 | .name = "ad73311", | 162 | .name = "ad73311", |
@@ -186,7 +165,7 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai[] = { | |||
186 | .codec_dai_name = "ad73311-hifi", | 165 | .codec_dai_name = "ad73311-hifi", |
187 | .platform_name = "bfin-i2s-pcm-audio", | 166 | .platform_name = "bfin-i2s-pcm-audio", |
188 | .codec_name = "ad73311", | 167 | .codec_name = "ad73311", |
189 | .ops = &bf5xx_ad73311_ops, | 168 | .dai_fmt = BF5XX_AD7311_DAI_FMT, |
190 | }, | 169 | }, |
191 | }; | 170 | }; |
192 | 171 | ||
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c index 030303238042..df3ac73f8778 100644 --- a/sound/soc/blackfin/bf5xx-ssm2602.c +++ b/sound/soc/blackfin/bf5xx-ssm2602.c | |||
@@ -49,7 +49,6 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream, | |||
49 | { | 49 | { |
50 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 50 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
51 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 51 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
52 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
53 | unsigned int clk = 0; | 52 | unsigned int clk = 0; |
54 | int ret = 0; | 53 | int ret = 0; |
55 | 54 | ||
@@ -75,21 +74,6 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream, | |||
75 | break; | 74 | break; |
76 | } | 75 | } |
77 | 76 | ||
78 | /* | ||
79 | * CODEC is master for BCLK and LRC in this configuration. | ||
80 | */ | ||
81 | |||
82 | /* set codec DAI configuration */ | ||
83 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
84 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
85 | if (ret < 0) | ||
86 | return ret; | ||
87 | /* set cpu DAI configuration */ | ||
88 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
89 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
90 | if (ret < 0) | ||
91 | return ret; | ||
92 | |||
93 | ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk, | 77 | ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk, |
94 | SND_SOC_CLOCK_IN); | 78 | SND_SOC_CLOCK_IN); |
95 | if (ret < 0) | 79 | if (ret < 0) |
@@ -102,6 +86,10 @@ static struct snd_soc_ops bf5xx_ssm2602_ops = { | |||
102 | .hw_params = bf5xx_ssm2602_hw_params, | 86 | .hw_params = bf5xx_ssm2602_hw_params, |
103 | }; | 87 | }; |
104 | 88 | ||
89 | /* CODEC is master for BCLK and LRC in this configuration. */ | ||
90 | #define BF5XX_SSM2602_DAIFMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \ | ||
91 | SND_SOC_DAIFMT_CBM_CFM) | ||
92 | |||
105 | static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = { | 93 | static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = { |
106 | { | 94 | { |
107 | .name = "ssm2602", | 95 | .name = "ssm2602", |
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c index 26b271c62efa..f3adbdbdd5e1 100644 --- a/sound/soc/blackfin/bfin-eval-adau1373.c +++ b/sound/soc/blackfin/bfin-eval-adau1373.c | |||
@@ -67,21 +67,10 @@ static int bfin_eval_adau1373_hw_params(struct snd_pcm_substream *substream, | |||
67 | struct snd_pcm_hw_params *params) | 67 | struct snd_pcm_hw_params *params) |
68 | { | 68 | { |
69 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 69 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
70 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
71 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 70 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
72 | int ret; | 71 | int ret; |
73 | int pll_rate; | 72 | int pll_rate; |
74 | 73 | ||
75 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
76 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
77 | if (ret) | ||
78 | return ret; | ||
79 | |||
80 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
81 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
82 | if (ret) | ||
83 | return ret; | ||
84 | |||
85 | switch (params_rate(params)) { | 74 | switch (params_rate(params)) { |
86 | case 48000: | 75 | case 48000: |
87 | case 8000: | 76 | case 8000: |
@@ -143,6 +132,8 @@ static struct snd_soc_dai_link bfin_eval_adau1373_dai = { | |||
143 | .codec_name = "adau1373.0-001a", | 132 | .codec_name = "adau1373.0-001a", |
144 | .ops = &bfin_eval_adau1373_ops, | 133 | .ops = &bfin_eval_adau1373_ops, |
145 | .init = bfin_eval_adau1373_codec_init, | 134 | .init = bfin_eval_adau1373_codec_init, |
135 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
136 | SND_SOC_DAIFMT_CBM_CFM, | ||
146 | }; | 137 | }; |
147 | 138 | ||
148 | static struct snd_soc_card bfin_eval_adau1373 = { | 139 | static struct snd_soc_card bfin_eval_adau1373 = { |
diff --git a/sound/soc/blackfin/bfin-eval-adau1701.c b/sound/soc/blackfin/bfin-eval-adau1701.c index c0064fa1dca6..b0531fc9d814 100644 --- a/sound/soc/blackfin/bfin-eval-adau1701.c +++ b/sound/soc/blackfin/bfin-eval-adau1701.c | |||
@@ -37,20 +37,9 @@ static int bfin_eval_adau1701_hw_params(struct snd_pcm_substream *substream, | |||
37 | struct snd_pcm_hw_params *params) | 37 | struct snd_pcm_hw_params *params) |
38 | { | 38 | { |
39 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 39 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
40 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
41 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 40 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
42 | int ret; | 41 | int ret; |
43 | 42 | ||
44 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
45 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
46 | if (ret) | ||
47 | return ret; | ||
48 | |||
49 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
50 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
51 | if (ret) | ||
52 | return ret; | ||
53 | |||
54 | ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1701_CLK_SRC_OSC, 12288000, | 43 | ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1701_CLK_SRC_OSC, 12288000, |
55 | SND_SOC_CLOCK_IN); | 44 | SND_SOC_CLOCK_IN); |
56 | 45 | ||
@@ -61,6 +50,9 @@ static struct snd_soc_ops bfin_eval_adau1701_ops = { | |||
61 | .hw_params = bfin_eval_adau1701_hw_params, | 50 | .hw_params = bfin_eval_adau1701_hw_params, |
62 | }; | 51 | }; |
63 | 52 | ||
53 | #define BFIN_EVAL_ADAU1701_DAI_FMT (SND_SOC_DAIFMT_I2S | \ | ||
54 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM) | ||
55 | |||
64 | static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = { | 56 | static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = { |
65 | { | 57 | { |
66 | .name = "adau1701", | 58 | .name = "adau1701", |
@@ -70,6 +62,7 @@ static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = { | |||
70 | .platform_name = "bfin-i2s-pcm-audio", | 62 | .platform_name = "bfin-i2s-pcm-audio", |
71 | .codec_name = "adau1701.0-0034", | 63 | .codec_name = "adau1701.0-0034", |
72 | .ops = &bfin_eval_adau1701_ops, | 64 | .ops = &bfin_eval_adau1701_ops, |
65 | .dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT, | ||
73 | }, | 66 | }, |
74 | { | 67 | { |
75 | .name = "adau1701", | 68 | .name = "adau1701", |
@@ -79,6 +72,7 @@ static struct snd_soc_dai_link bfin_eval_adau1701_dai[] = { | |||
79 | .platform_name = "bfin-i2s-pcm-audio", | 72 | .platform_name = "bfin-i2s-pcm-audio", |
80 | .codec_name = "adau1701.0-0034", | 73 | .codec_name = "adau1701.0-0034", |
81 | .ops = &bfin_eval_adau1701_ops, | 74 | .ops = &bfin_eval_adau1701_ops, |
75 | .dai_fmt = BFIN_EVAL_ADAU1701_DAI_FMT, | ||
82 | }, | 76 | }, |
83 | }; | 77 | }; |
84 | 78 | ||
diff --git a/sound/soc/blackfin/bfin-eval-adav80x.c b/sound/soc/blackfin/bfin-eval-adav80x.c index 4ef079f95e2e..84b09987b7f3 100644 --- a/sound/soc/blackfin/bfin-eval-adav80x.c +++ b/sound/soc/blackfin/bfin-eval-adav80x.c | |||
@@ -34,20 +34,9 @@ static int bfin_eval_adav80x_hw_params(struct snd_pcm_substream *substream, | |||
34 | struct snd_pcm_hw_params *params) | 34 | struct snd_pcm_hw_params *params) |
35 | { | 35 | { |
36 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 36 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
37 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
38 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 37 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
39 | int ret; | 38 | int ret; |
40 | 39 | ||
41 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
42 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
43 | if (ret) | ||
44 | return ret; | ||
45 | |||
46 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
47 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
48 | if (ret) | ||
49 | return ret; | ||
50 | |||
51 | ret = snd_soc_dai_set_pll(codec_dai, ADAV80X_PLL1, ADAV80X_PLL_SRC_XTAL, | 40 | ret = snd_soc_dai_set_pll(codec_dai, ADAV80X_PLL1, ADAV80X_PLL_SRC_XTAL, |
52 | 27000000, params_rate(params) * 256); | 41 | 27000000, params_rate(params) * 256); |
53 | if (ret) | 42 | if (ret) |
@@ -88,6 +77,8 @@ static struct snd_soc_dai_link bfin_eval_adav80x_dais[] = { | |||
88 | .platform_name = "bfin-i2s-pcm-audio", | 77 | .platform_name = "bfin-i2s-pcm-audio", |
89 | .init = bfin_eval_adav80x_codec_init, | 78 | .init = bfin_eval_adav80x_codec_init, |
90 | .ops = &bfin_eval_adav80x_ops, | 79 | .ops = &bfin_eval_adav80x_ops, |
80 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
81 | SND_SOC_DAIFMT_CBM_CFM, | ||
91 | }, | 82 | }, |
92 | }; | 83 | }; |
93 | 84 | ||
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 7c205e77d83a..6508e8b790bb 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -40,6 +40,7 @@ config SND_SOC_ALL_CODECS | |||
40 | select SND_SOC_MAX98088 if I2C | 40 | select SND_SOC_MAX98088 if I2C |
41 | select SND_SOC_MAX98095 if I2C | 41 | select SND_SOC_MAX98095 if I2C |
42 | select SND_SOC_MAX9850 if I2C | 42 | select SND_SOC_MAX9850 if I2C |
43 | select SND_SOC_MAX9768 if I2C | ||
43 | select SND_SOC_MAX9877 if I2C | 44 | select SND_SOC_MAX9877 if I2C |
44 | select SND_SOC_PCM3008 | 45 | select SND_SOC_PCM3008 |
45 | select SND_SOC_RT5631 if I2C | 46 | select SND_SOC_RT5631 if I2C |
@@ -62,6 +63,7 @@ config SND_SOC_ALL_CODECS | |||
62 | select SND_SOC_WL1273 if MFD_WL1273_CORE | 63 | select SND_SOC_WL1273 if MFD_WL1273_CORE |
63 | select SND_SOC_WM1250_EV1 if I2C | 64 | select SND_SOC_WM1250_EV1 if I2C |
64 | select SND_SOC_WM2000 if I2C | 65 | select SND_SOC_WM2000 if I2C |
66 | select SND_SOC_WM2200 if I2C | ||
65 | select SND_SOC_WM5100 if I2C | 67 | select SND_SOC_WM5100 if I2C |
66 | select SND_SOC_WM8350 if MFD_WM8350 | 68 | select SND_SOC_WM8350 if MFD_WM8350 |
67 | select SND_SOC_WM8400 if MFD_WM8400 | 69 | select SND_SOC_WM8400 if MFD_WM8400 |
@@ -292,6 +294,9 @@ config SND_SOC_WM1250_EV1 | |||
292 | config SND_SOC_WM2000 | 294 | config SND_SOC_WM2000 |
293 | tristate | 295 | tristate |
294 | 296 | ||
297 | config SND_SOC_WM2200 | ||
298 | tristate | ||
299 | |||
295 | config SND_SOC_WM5100 | 300 | config SND_SOC_WM5100 |
296 | tristate | 301 | tristate |
297 | 302 | ||
@@ -425,6 +430,9 @@ config SND_SOC_WM9713 | |||
425 | config SND_SOC_LM4857 | 430 | config SND_SOC_LM4857 |
426 | tristate | 431 | tristate |
427 | 432 | ||
433 | config SND_SOC_MAX9768 | ||
434 | tristate | ||
435 | |||
428 | config SND_SOC_MAX9877 | 436 | config SND_SOC_MAX9877 |
429 | tristate | 437 | tristate |
430 | 438 | ||
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index de8078178f86..6662eb0cdcc0 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -25,6 +25,7 @@ snd-soc-dmic-objs := dmic.o | |||
25 | snd-soc-jz4740-codec-objs := jz4740.o | 25 | snd-soc-jz4740-codec-objs := jz4740.o |
26 | snd-soc-l3-objs := l3.o | 26 | snd-soc-l3-objs := l3.o |
27 | snd-soc-lm4857-objs := lm4857.o | 27 | snd-soc-lm4857-objs := lm4857.o |
28 | snd-soc-max9768-objs := max9768.o | ||
28 | snd-soc-max98088-objs := max98088.o | 29 | snd-soc-max98088-objs := max98088.o |
29 | snd-soc-max98095-objs := max98095.o | 30 | snd-soc-max98095-objs := max98095.o |
30 | snd-soc-max9850-objs := max9850.o | 31 | snd-soc-max9850-objs := max9850.o |
@@ -51,6 +52,7 @@ snd-soc-uda1380-objs := uda1380.o | |||
51 | snd-soc-wl1273-objs := wl1273.o | 52 | snd-soc-wl1273-objs := wl1273.o |
52 | snd-soc-wm1250-ev1-objs := wm1250-ev1.o | 53 | snd-soc-wm1250-ev1-objs := wm1250-ev1.o |
53 | snd-soc-wm2000-objs := wm2000.o | 54 | snd-soc-wm2000-objs := wm2000.o |
55 | snd-soc-wm2200-objs := wm2200.o | ||
54 | snd-soc-wm5100-objs := wm5100.o wm5100-tables.o | 56 | snd-soc-wm5100-objs := wm5100.o wm5100-tables.o |
55 | snd-soc-wm8350-objs := wm8350.o | 57 | snd-soc-wm8350-objs := wm8350.o |
56 | snd-soc-wm8400-objs := wm8400.o | 58 | snd-soc-wm8400-objs := wm8400.o |
@@ -129,6 +131,7 @@ obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o | |||
129 | obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o | 131 | obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o |
130 | obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o | 132 | obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o |
131 | obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o | 133 | obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o |
134 | obj-$(CONFIG_SND_SOC_MAX9768) += snd-soc-max9768.o | ||
132 | obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o | 135 | obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o |
133 | obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o | 136 | obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o |
134 | obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o | 137 | obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o |
@@ -153,6 +156,7 @@ obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o | |||
153 | obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o | 156 | obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o |
154 | obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o | 157 | obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o |
155 | obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o | 158 | obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o |
159 | obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o | ||
156 | obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o | 160 | obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o |
157 | obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o | 161 | obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o |
158 | obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o | 162 | obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o |
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index 982d201c2e86..12e3b4118557 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c | |||
@@ -277,7 +277,7 @@ static int ad1836_probe(struct snd_soc_codec *codec) | |||
277 | if (ad1836->type == AD1836) { | 277 | if (ad1836->type == AD1836) { |
278 | /* left/right diff:PGA/MUX */ | 278 | /* left/right diff:PGA/MUX */ |
279 | snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A); | 279 | snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A); |
280 | ret = snd_soc_add_controls(codec, ad1836_controls, | 280 | ret = snd_soc_add_codec_controls(codec, ad1836_controls, |
281 | ARRAY_SIZE(ad1836_controls)); | 281 | ARRAY_SIZE(ad1836_controls)); |
282 | if (ret) | 282 | if (ret) |
283 | return ret; | 283 | return ret; |
@@ -285,11 +285,11 @@ static int ad1836_probe(struct snd_soc_codec *codec) | |||
285 | snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00); | 285 | snd_soc_write(codec, AD1836_ADC_CTRL3, 0x00); |
286 | } | 286 | } |
287 | 287 | ||
288 | ret = snd_soc_add_controls(codec, ad183x_dac_controls, num_dacs * 2); | 288 | ret = snd_soc_add_codec_controls(codec, ad183x_dac_controls, num_dacs * 2); |
289 | if (ret) | 289 | if (ret) |
290 | return ret; | 290 | return ret; |
291 | 291 | ||
292 | ret = snd_soc_add_controls(codec, ad183x_adc_controls, num_adcs); | 292 | ret = snd_soc_add_codec_controls(codec, ad183x_adc_controls, num_adcs); |
293 | if (ret) | 293 | if (ret) |
294 | return ret; | 294 | return ret; |
295 | 295 | ||
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 9bba7f849464..8c39dddd7d00 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c | |||
@@ -228,7 +228,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) | |||
228 | ext_status = ac97_read(codec, AC97_EXTENDED_STATUS); | 228 | ext_status = ac97_read(codec, AC97_EXTENDED_STATUS); |
229 | ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800); | 229 | ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800); |
230 | 230 | ||
231 | snd_soc_add_controls(codec, ad1980_snd_ac97_controls, | 231 | snd_soc_add_codec_controls(codec, ad1980_snd_ac97_controls, |
232 | ARRAY_SIZE(ad1980_snd_ac97_controls)); | 232 | ARRAY_SIZE(ad1980_snd_ac97_controls)); |
233 | 233 | ||
234 | return 0; | 234 | return 0; |
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 971ba4529171..44f59064d8de 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c | |||
@@ -1244,8 +1244,6 @@ static int adau1373_probe(struct snd_soc_codec *codec) | |||
1244 | return ret; | 1244 | return ret; |
1245 | } | 1245 | } |
1246 | 1246 | ||
1247 | codec->dapm.idle_bias_off = true; | ||
1248 | |||
1249 | if (pdata) { | 1247 | if (pdata) { |
1250 | if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting)) | 1248 | if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting)) |
1251 | return -EINVAL; | 1249 | return -EINVAL; |
@@ -1259,7 +1257,7 @@ static int adau1373_probe(struct snd_soc_codec *codec) | |||
1259 | pdata->drc_setting[i]); | 1257 | pdata->drc_setting[i]); |
1260 | } | 1258 | } |
1261 | 1259 | ||
1262 | snd_soc_add_controls(codec, adau1373_drc_controls, | 1260 | snd_soc_add_codec_controls(codec, adau1373_drc_controls, |
1263 | pdata->num_drc); | 1261 | pdata->num_drc); |
1264 | 1262 | ||
1265 | val = 0; | 1263 | val = 0; |
@@ -1284,7 +1282,7 @@ static int adau1373_probe(struct snd_soc_codec *codec) | |||
1284 | } | 1282 | } |
1285 | 1283 | ||
1286 | if (!lineout_differential) { | 1284 | if (!lineout_differential) { |
1287 | snd_soc_add_controls(codec, adau1373_lineout2_controls, | 1285 | snd_soc_add_codec_controls(codec, adau1373_lineout2_controls, |
1288 | ARRAY_SIZE(adau1373_lineout2_controls)); | 1286 | ARRAY_SIZE(adau1373_lineout2_controls)); |
1289 | } | 1287 | } |
1290 | 1288 | ||
@@ -1340,6 +1338,7 @@ static struct snd_soc_codec_driver adau1373_codec_driver = { | |||
1340 | .suspend = adau1373_suspend, | 1338 | .suspend = adau1373_suspend, |
1341 | .resume = adau1373_resume, | 1339 | .resume = adau1373_resume, |
1342 | .set_bias_level = adau1373_set_bias_level, | 1340 | .set_bias_level = adau1373_set_bias_level, |
1341 | .idle_bias_off = true, | ||
1343 | .reg_cache_size = ARRAY_SIZE(adau1373_default_regs), | 1342 | .reg_cache_size = ARRAY_SIZE(adau1373_default_regs), |
1344 | .reg_cache_default = adau1373_default_regs, | 1343 | .reg_cache_default = adau1373_default_regs, |
1345 | .reg_word_size = sizeof(uint8_t), | 1344 | .reg_word_size = sizeof(uint8_t), |
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 6b325ea03869..78e9ce48bb99 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c | |||
@@ -457,7 +457,6 @@ static int adau1701_probe(struct snd_soc_codec *codec) | |||
457 | { | 457 | { |
458 | int ret; | 458 | int ret; |
459 | 459 | ||
460 | codec->dapm.idle_bias_off = 1; | ||
461 | codec->control_data = to_i2c_client(codec->dev); | 460 | codec->control_data = to_i2c_client(codec->dev); |
462 | 461 | ||
463 | ret = adau1701_load_firmware(codec); | 462 | ret = adau1701_load_firmware(codec); |
@@ -473,6 +472,7 @@ static int adau1701_probe(struct snd_soc_codec *codec) | |||
473 | static struct snd_soc_codec_driver adau1701_codec_drv = { | 472 | static struct snd_soc_codec_driver adau1701_codec_drv = { |
474 | .probe = adau1701_probe, | 473 | .probe = adau1701_probe, |
475 | .set_bias_level = adau1701_set_bias_level, | 474 | .set_bias_level = adau1701_set_bias_level, |
475 | .idle_bias_off = true, | ||
476 | 476 | ||
477 | .reg_cache_size = ADAU1701_NUM_REGS, | 477 | .reg_cache_size = ADAU1701_NUM_REGS, |
478 | .reg_word_size = sizeof(u16), | 478 | .reg_word_size = sizeof(u16), |
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index d27b5e4cce99..ceb96ecf5588 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c | |||
@@ -46,75 +46,15 @@ | |||
46 | #define DRV_NAME "ak4104-codec" | 46 | #define DRV_NAME "ak4104-codec" |
47 | 47 | ||
48 | struct ak4104_private { | 48 | struct ak4104_private { |
49 | enum snd_soc_control_type control_type; | 49 | struct regmap *regmap; |
50 | void *control_data; | ||
51 | }; | 50 | }; |
52 | 51 | ||
53 | static int ak4104_fill_cache(struct snd_soc_codec *codec) | ||
54 | { | ||
55 | int i; | ||
56 | u8 *reg_cache = codec->reg_cache; | ||
57 | struct spi_device *spi = codec->control_data; | ||
58 | |||
59 | for (i = 0; i < codec->driver->reg_cache_size; i++) { | ||
60 | int ret = spi_w8r8(spi, i | AK4104_READ); | ||
61 | if (ret < 0) { | ||
62 | dev_err(&spi->dev, "SPI write failure\n"); | ||
63 | return ret; | ||
64 | } | ||
65 | |||
66 | reg_cache[i] = ret; | ||
67 | } | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static unsigned int ak4104_read_reg_cache(struct snd_soc_codec *codec, | ||
73 | unsigned int reg) | ||
74 | { | ||
75 | u8 *reg_cache = codec->reg_cache; | ||
76 | |||
77 | if (reg >= codec->driver->reg_cache_size) | ||
78 | return -EINVAL; | ||
79 | |||
80 | return reg_cache[reg]; | ||
81 | } | ||
82 | |||
83 | static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg, | ||
84 | unsigned int value) | ||
85 | { | ||
86 | u8 *cache = codec->reg_cache; | ||
87 | struct spi_device *spi = codec->control_data; | ||
88 | |||
89 | if (reg >= codec->driver->reg_cache_size) | ||
90 | return -EINVAL; | ||
91 | |||
92 | /* only write to the hardware if value has changed */ | ||
93 | if (cache[reg] != value) { | ||
94 | u8 tmp[2] = { (reg & AK4104_REG_MASK) | AK4104_WRITE, value }; | ||
95 | |||
96 | if (spi_write(spi, tmp, sizeof(tmp))) { | ||
97 | dev_err(&spi->dev, "SPI write failed\n"); | ||
98 | return -EIO; | ||
99 | } | ||
100 | |||
101 | cache[reg] = value; | ||
102 | } | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai, | 52 | static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai, |
108 | unsigned int format) | 53 | unsigned int format) |
109 | { | 54 | { |
110 | struct snd_soc_codec *codec = codec_dai->codec; | 55 | struct snd_soc_codec *codec = codec_dai->codec; |
111 | int val = 0; | 56 | int val = 0; |
112 | 57 | int ret; | |
113 | val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1); | ||
114 | if (val < 0) | ||
115 | return val; | ||
116 | |||
117 | val &= ~(AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1); | ||
118 | 58 | ||
119 | /* set DAI format */ | 59 | /* set DAI format */ |
120 | switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { | 60 | switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { |
@@ -135,7 +75,13 @@ static int ak4104_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
135 | if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) | 75 | if ((format & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) |
136 | return -EINVAL; | 76 | return -EINVAL; |
137 | 77 | ||
138 | return ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); | 78 | ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1, |
79 | AK4104_CONTROL1_DIF0 | AK4104_CONTROL1_DIF1, | ||
80 | val); | ||
81 | if (ret < 0) | ||
82 | return ret; | ||
83 | |||
84 | return 0; | ||
139 | } | 85 | } |
140 | 86 | ||
141 | static int ak4104_hw_params(struct snd_pcm_substream *substream, | 87 | static int ak4104_hw_params(struct snd_pcm_substream *substream, |
@@ -148,7 +94,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream, | |||
148 | 94 | ||
149 | /* set the IEC958 bits: consumer mode, no copyright bit */ | 95 | /* set the IEC958 bits: consumer mode, no copyright bit */ |
150 | val |= IEC958_AES0_CON_NOT_COPYRIGHT; | 96 | val |= IEC958_AES0_CON_NOT_COPYRIGHT; |
151 | ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(0), val); | 97 | snd_soc_write(codec, AK4104_REG_CHN_STATUS(0), val); |
152 | 98 | ||
153 | val = 0; | 99 | val = 0; |
154 | 100 | ||
@@ -167,7 +113,7 @@ static int ak4104_hw_params(struct snd_pcm_substream *substream, | |||
167 | return -EINVAL; | 113 | return -EINVAL; |
168 | } | 114 | } |
169 | 115 | ||
170 | return ak4104_spi_write(codec, AK4104_REG_CHN_STATUS(3), val); | 116 | return snd_soc_write(codec, AK4104_REG_CHN_STATUS(3), val); |
171 | } | 117 | } |
172 | 118 | ||
173 | static const struct snd_soc_dai_ops ak4101_dai_ops = { | 119 | static const struct snd_soc_dai_ops ak4101_dai_ops = { |
@@ -192,67 +138,57 @@ static struct snd_soc_dai_driver ak4104_dai = { | |||
192 | static int ak4104_probe(struct snd_soc_codec *codec) | 138 | static int ak4104_probe(struct snd_soc_codec *codec) |
193 | { | 139 | { |
194 | struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); | 140 | struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); |
195 | int ret, val; | 141 | int ret; |
196 | |||
197 | codec->control_data = ak4104->control_data; | ||
198 | 142 | ||
199 | /* read all regs and fill the cache */ | 143 | codec->control_data = ak4104->regmap; |
200 | ret = ak4104_fill_cache(codec); | 144 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); |
201 | if (ret < 0) { | 145 | if (ret != 0) |
202 | dev_err(codec->dev, "failed to fill register cache\n"); | ||
203 | return ret; | 146 | return ret; |
204 | } | ||
205 | |||
206 | /* read the 'reserved' register - according to the datasheet, it | ||
207 | * should contain 0x5b. Not a good way to verify the presence of | ||
208 | * the device, but there is no hardware ID register. */ | ||
209 | if (ak4104_read_reg_cache(codec, AK4104_REG_RESERVED) != | ||
210 | AK4104_RESERVED_VAL) | ||
211 | return -ENODEV; | ||
212 | 147 | ||
213 | /* set power-up and non-reset bits */ | 148 | /* set power-up and non-reset bits */ |
214 | val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1); | 149 | ret = snd_soc_update_bits(codec, AK4104_REG_CONTROL1, |
215 | val |= AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN; | 150 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, |
216 | ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); | 151 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN); |
217 | if (ret < 0) | 152 | if (ret < 0) |
218 | return ret; | 153 | return ret; |
219 | 154 | ||
220 | /* enable transmitter */ | 155 | /* enable transmitter */ |
221 | val = ak4104_read_reg_cache(codec, AK4104_REG_TX); | 156 | ret = snd_soc_update_bits(codec, AK4104_REG_TX, |
222 | val |= AK4104_TX_TXE; | 157 | AK4104_TX_TXE, AK4104_TX_TXE); |
223 | ret = ak4104_spi_write(codec, AK4104_REG_TX, val); | ||
224 | if (ret < 0) | 158 | if (ret < 0) |
225 | return ret; | 159 | return ret; |
226 | 160 | ||
227 | dev_info(codec->dev, "SPI device initialized\n"); | ||
228 | return 0; | 161 | return 0; |
229 | } | 162 | } |
230 | 163 | ||
231 | static int ak4104_remove(struct snd_soc_codec *codec) | 164 | static int ak4104_remove(struct snd_soc_codec *codec) |
232 | { | 165 | { |
233 | int val, ret; | 166 | snd_soc_update_bits(codec, AK4104_REG_CONTROL1, |
234 | 167 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0); | |
235 | val = ak4104_read_reg_cache(codec, AK4104_REG_CONTROL1); | ||
236 | if (val < 0) | ||
237 | return val; | ||
238 | |||
239 | /* clear power-up and non-reset bits */ | ||
240 | val &= ~(AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN); | ||
241 | ret = ak4104_spi_write(codec, AK4104_REG_CONTROL1, val); | ||
242 | 168 | ||
243 | return ret; | 169 | return 0; |
244 | } | 170 | } |
245 | 171 | ||
246 | static struct snd_soc_codec_driver soc_codec_device_ak4104 = { | 172 | static struct snd_soc_codec_driver soc_codec_device_ak4104 = { |
247 | .probe = ak4104_probe, | 173 | .probe = ak4104_probe, |
248 | .remove = ak4104_remove, | 174 | .remove = ak4104_remove, |
249 | .reg_cache_size = AK4104_NUM_REGS, | 175 | }; |
250 | .reg_word_size = sizeof(u8), | 176 | |
177 | static const struct regmap_config ak4104_regmap = { | ||
178 | .reg_bits = 8, | ||
179 | .val_bits = 8, | ||
180 | |||
181 | .max_register = AK4104_NUM_REGS - 1, | ||
182 | .read_flag_mask = AK4104_READ, | ||
183 | .write_flag_mask = AK4104_WRITE, | ||
184 | |||
185 | .cache_type = REGCACHE_RBTREE, | ||
251 | }; | 186 | }; |
252 | 187 | ||
253 | static int ak4104_spi_probe(struct spi_device *spi) | 188 | static int ak4104_spi_probe(struct spi_device *spi) |
254 | { | 189 | { |
255 | struct ak4104_private *ak4104; | 190 | struct ak4104_private *ak4104; |
191 | unsigned int val; | ||
256 | int ret; | 192 | int ret; |
257 | 193 | ||
258 | spi->bits_per_word = 8; | 194 | spi->bits_per_word = 8; |
@@ -266,17 +202,41 @@ static int ak4104_spi_probe(struct spi_device *spi) | |||
266 | if (ak4104 == NULL) | 202 | if (ak4104 == NULL) |
267 | return -ENOMEM; | 203 | return -ENOMEM; |
268 | 204 | ||
269 | ak4104->control_data = spi; | 205 | ak4104->regmap = regmap_init_spi(spi, &ak4104_regmap); |
270 | ak4104->control_type = SND_SOC_SPI; | 206 | if (IS_ERR(ak4104->regmap)) { |
207 | ret = PTR_ERR(ak4104->regmap); | ||
208 | return ret; | ||
209 | } | ||
210 | |||
211 | /* read the 'reserved' register - according to the datasheet, it | ||
212 | * should contain 0x5b. Not a good way to verify the presence of | ||
213 | * the device, but there is no hardware ID register. */ | ||
214 | ret = regmap_read(ak4104->regmap, AK4104_REG_RESERVED, &val); | ||
215 | if (ret != 0) | ||
216 | goto err; | ||
217 | if (val != AK4104_RESERVED_VAL) { | ||
218 | ret = -ENODEV; | ||
219 | goto err; | ||
220 | } | ||
221 | |||
271 | spi_set_drvdata(spi, ak4104); | 222 | spi_set_drvdata(spi, ak4104); |
272 | 223 | ||
273 | ret = snd_soc_register_codec(&spi->dev, | 224 | ret = snd_soc_register_codec(&spi->dev, |
274 | &soc_codec_device_ak4104, &ak4104_dai, 1); | 225 | &soc_codec_device_ak4104, &ak4104_dai, 1); |
226 | if (ret != 0) | ||
227 | goto err; | ||
228 | |||
229 | return 0; | ||
230 | |||
231 | err: | ||
232 | regmap_exit(ak4104->regmap); | ||
275 | return ret; | 233 | return ret; |
276 | } | 234 | } |
277 | 235 | ||
278 | static int __devexit ak4104_spi_remove(struct spi_device *spi) | 236 | static int __devexit ak4104_spi_remove(struct spi_device *spi) |
279 | { | 237 | { |
238 | struct ak4104_private *ak4101 = spi_get_drvdata(spi); | ||
239 | regmap_exit(ak4101->regmap); | ||
280 | snd_soc_unregister_codec(&spi->dev); | 240 | snd_soc_unregister_codec(&spi->dev); |
281 | return 0; | 241 | return 0; |
282 | } | 242 | } |
@@ -290,17 +250,7 @@ static struct spi_driver ak4104_spi_driver = { | |||
290 | .remove = __devexit_p(ak4104_spi_remove), | 250 | .remove = __devexit_p(ak4104_spi_remove), |
291 | }; | 251 | }; |
292 | 252 | ||
293 | static int __init ak4104_init(void) | 253 | module_spi_driver(ak4104_spi_driver); |
294 | { | ||
295 | return spi_register_driver(&ak4104_spi_driver); | ||
296 | } | ||
297 | module_init(ak4104_init); | ||
298 | |||
299 | static void __exit ak4104_exit(void) | ||
300 | { | ||
301 | spi_unregister_driver(&ak4104_spi_driver); | ||
302 | } | ||
303 | module_exit(ak4104_exit); | ||
304 | 254 | ||
305 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); | 255 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); |
306 | MODULE_DESCRIPTION("Asahi Kasei AK4104 ALSA SoC driver"); | 256 | MODULE_DESCRIPTION("Asahi Kasei AK4104 ALSA SoC driver"); |
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 9e809e05d066..838ae8b22b50 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/pm.h> | 19 | #include <linux/pm.h> |
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/regmap.h> | ||
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
22 | #include <sound/core.h> | 23 | #include <sound/core.h> |
23 | #include <sound/pcm.h> | 24 | #include <sound/pcm.h> |
@@ -27,24 +28,43 @@ | |||
27 | 28 | ||
28 | #include "ak4535.h" | 29 | #include "ak4535.h" |
29 | 30 | ||
30 | #define AK4535_VERSION "0.3" | ||
31 | |||
32 | /* codec private data */ | 31 | /* codec private data */ |
33 | struct ak4535_priv { | 32 | struct ak4535_priv { |
33 | struct regmap *regmap; | ||
34 | unsigned int sysclk; | 34 | unsigned int sysclk; |
35 | enum snd_soc_control_type control_type; | ||
36 | }; | 35 | }; |
37 | 36 | ||
38 | /* | 37 | /* |
39 | * ak4535 register cache | 38 | * ak4535 register cache |
40 | */ | 39 | */ |
41 | static const u8 ak4535_reg[AK4535_CACHEREGNUM] = { | 40 | static const struct reg_default ak4535_reg_defaults[] = { |
42 | 0x00, 0x80, 0x00, 0x03, | 41 | { 0, 0x00 }, |
43 | 0x02, 0x00, 0x11, 0x01, | 42 | { 1, 0x80 }, |
44 | 0x00, 0x40, 0x36, 0x10, | 43 | { 2, 0x00 }, |
45 | 0x00, 0x00, 0x57, 0x00, | 44 | { 3, 0x03 }, |
45 | { 4, 0x02 }, | ||
46 | { 5, 0x00 }, | ||
47 | { 6, 0x11 }, | ||
48 | { 7, 0x01 }, | ||
49 | { 8, 0x00 }, | ||
50 | { 9, 0x40 }, | ||
51 | { 10, 0x36 }, | ||
52 | { 11, 0x10 }, | ||
53 | { 12, 0x00 }, | ||
54 | { 13, 0x00 }, | ||
55 | { 14, 0x57 }, | ||
46 | }; | 56 | }; |
47 | 57 | ||
58 | static bool ak4535_volatile(struct device *dev, unsigned int reg) | ||
59 | { | ||
60 | switch (reg) { | ||
61 | case AK4535_STATUS: | ||
62 | return true; | ||
63 | default: | ||
64 | return false; | ||
65 | } | ||
66 | } | ||
67 | |||
48 | static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"}; | 68 | static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"}; |
49 | static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"}; | 69 | static const char *ak4535_mono_out[] = {"(L + R)/2", "Hi-Z"}; |
50 | static const char *ak4535_hp_out[] = {"Stereo", "Mono"}; | 70 | static const char *ak4535_hp_out[] = {"Stereo", "Mono"}; |
@@ -372,9 +392,8 @@ static int ak4535_probe(struct snd_soc_codec *codec) | |||
372 | struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); | 392 | struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); |
373 | int ret; | 393 | int ret; |
374 | 394 | ||
375 | printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); | 395 | codec->control_data = ak4535->regmap; |
376 | 396 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | |
377 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4535->control_type); | ||
378 | if (ret < 0) { | 397 | if (ret < 0) { |
379 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 398 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
380 | return ret; | 399 | return ret; |
@@ -382,7 +401,7 @@ static int ak4535_probe(struct snd_soc_codec *codec) | |||
382 | /* power on device */ | 401 | /* power on device */ |
383 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 402 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
384 | 403 | ||
385 | snd_soc_add_controls(codec, ak4535_snd_controls, | 404 | snd_soc_add_codec_controls(codec, ak4535_snd_controls, |
386 | ARRAY_SIZE(ak4535_snd_controls)); | 405 | ARRAY_SIZE(ak4535_snd_controls)); |
387 | return 0; | 406 | return 0; |
388 | } | 407 | } |
@@ -394,22 +413,30 @@ static int ak4535_remove(struct snd_soc_codec *codec) | |||
394 | return 0; | 413 | return 0; |
395 | } | 414 | } |
396 | 415 | ||
416 | static const struct regmap_config ak4535_regmap = { | ||
417 | .reg_bits = 8, | ||
418 | .val_bits = 8, | ||
419 | |||
420 | .max_register = AK4535_STATUS, | ||
421 | .volatile_reg = ak4535_volatile, | ||
422 | |||
423 | .cache_type = REGCACHE_RBTREE, | ||
424 | .reg_defaults = ak4535_reg_defaults, | ||
425 | .num_reg_defaults = ARRAY_SIZE(ak4535_reg_defaults), | ||
426 | }; | ||
427 | |||
397 | static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { | 428 | static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { |
398 | .probe = ak4535_probe, | 429 | .probe = ak4535_probe, |
399 | .remove = ak4535_remove, | 430 | .remove = ak4535_remove, |
400 | .suspend = ak4535_suspend, | 431 | .suspend = ak4535_suspend, |
401 | .resume = ak4535_resume, | 432 | .resume = ak4535_resume, |
402 | .set_bias_level = ak4535_set_bias_level, | 433 | .set_bias_level = ak4535_set_bias_level, |
403 | .reg_cache_size = ARRAY_SIZE(ak4535_reg), | ||
404 | .reg_word_size = sizeof(u8), | ||
405 | .reg_cache_default = ak4535_reg, | ||
406 | .dapm_widgets = ak4535_dapm_widgets, | 434 | .dapm_widgets = ak4535_dapm_widgets, |
407 | .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), | 435 | .num_dapm_widgets = ARRAY_SIZE(ak4535_dapm_widgets), |
408 | .dapm_routes = ak4535_audio_map, | 436 | .dapm_routes = ak4535_audio_map, |
409 | .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map), | 437 | .num_dapm_routes = ARRAY_SIZE(ak4535_audio_map), |
410 | }; | 438 | }; |
411 | 439 | ||
412 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
413 | static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, | 440 | static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, |
414 | const struct i2c_device_id *id) | 441 | const struct i2c_device_id *id) |
415 | { | 442 | { |
@@ -421,17 +448,29 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, | |||
421 | if (ak4535 == NULL) | 448 | if (ak4535 == NULL) |
422 | return -ENOMEM; | 449 | return -ENOMEM; |
423 | 450 | ||
451 | ak4535->regmap = regmap_init_i2c(i2c, &ak4535_regmap); | ||
452 | if (IS_ERR(ak4535->regmap)) { | ||
453 | ret = PTR_ERR(ak4535->regmap); | ||
454 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); | ||
455 | return ret; | ||
456 | } | ||
457 | |||
424 | i2c_set_clientdata(i2c, ak4535); | 458 | i2c_set_clientdata(i2c, ak4535); |
425 | ak4535->control_type = SND_SOC_I2C; | ||
426 | 459 | ||
427 | ret = snd_soc_register_codec(&i2c->dev, | 460 | ret = snd_soc_register_codec(&i2c->dev, |
428 | &soc_codec_dev_ak4535, &ak4535_dai, 1); | 461 | &soc_codec_dev_ak4535, &ak4535_dai, 1); |
462 | if (ret != 0) | ||
463 | regmap_exit(ak4535->regmap); | ||
464 | |||
429 | return ret; | 465 | return ret; |
430 | } | 466 | } |
431 | 467 | ||
432 | static __devexit int ak4535_i2c_remove(struct i2c_client *client) | 468 | static __devexit int ak4535_i2c_remove(struct i2c_client *client) |
433 | { | 469 | { |
470 | struct ak4535_priv *ak4535 = i2c_get_clientdata(client); | ||
471 | |||
434 | snd_soc_unregister_codec(&client->dev); | 472 | snd_soc_unregister_codec(&client->dev); |
473 | regmap_exit(ak4535->regmap); | ||
435 | return 0; | 474 | return 0; |
436 | } | 475 | } |
437 | 476 | ||
@@ -443,36 +482,15 @@ MODULE_DEVICE_TABLE(i2c, ak4535_i2c_id); | |||
443 | 482 | ||
444 | static struct i2c_driver ak4535_i2c_driver = { | 483 | static struct i2c_driver ak4535_i2c_driver = { |
445 | .driver = { | 484 | .driver = { |
446 | .name = "ak4535-codec", | 485 | .name = "ak4535", |
447 | .owner = THIS_MODULE, | 486 | .owner = THIS_MODULE, |
448 | }, | 487 | }, |
449 | .probe = ak4535_i2c_probe, | 488 | .probe = ak4535_i2c_probe, |
450 | .remove = __devexit_p(ak4535_i2c_remove), | 489 | .remove = __devexit_p(ak4535_i2c_remove), |
451 | .id_table = ak4535_i2c_id, | 490 | .id_table = ak4535_i2c_id, |
452 | }; | 491 | }; |
453 | #endif | ||
454 | 492 | ||
455 | static int __init ak4535_modinit(void) | 493 | module_i2c_driver(ak4535_i2c_driver); |
456 | { | ||
457 | int ret = 0; | ||
458 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
459 | ret = i2c_add_driver(&ak4535_i2c_driver); | ||
460 | if (ret != 0) { | ||
461 | printk(KERN_ERR "Failed to register AK4535 I2C driver: %d\n", | ||
462 | ret); | ||
463 | } | ||
464 | #endif | ||
465 | return ret; | ||
466 | } | ||
467 | module_init(ak4535_modinit); | ||
468 | |||
469 | static void __exit ak4535_exit(void) | ||
470 | { | ||
471 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
472 | i2c_del_driver(&ak4535_i2c_driver); | ||
473 | #endif | ||
474 | } | ||
475 | module_exit(ak4535_exit); | ||
476 | 494 | ||
477 | MODULE_DESCRIPTION("Soc AK4535 driver"); | 495 | MODULE_DESCRIPTION("Soc AK4535 driver"); |
478 | MODULE_AUTHOR("Richard Purdie"); | 496 | MODULE_AUTHOR("Richard Purdie"); |
diff --git a/sound/soc/codecs/ak4535.h b/sound/soc/codecs/ak4535.h index 0431e5f634a2..402de1d274bf 100644 --- a/sound/soc/codecs/ak4535.h +++ b/sound/soc/codecs/ak4535.h | |||
@@ -34,6 +34,4 @@ | |||
34 | #define AK4535_VOL 0xe | 34 | #define AK4535_VOL 0xe |
35 | #define AK4535_STATUS 0xf | 35 | #define AK4535_STATUS 0xf |
36 | 36 | ||
37 | #define AK4535_CACHEREGNUM 0x10 | ||
38 | |||
39 | #endif | 37 | #endif |
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 5ef70b5d27e4..f8e10ced244a 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c | |||
@@ -146,13 +146,10 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = { | |||
146 | 146 | ||
147 | SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC, | 147 | SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC, |
148 | 0, 0xFF, 1, out_tlv), | 148 | 0, 0xFF, 1, out_tlv), |
149 | |||
150 | SOC_SINGLE("Headphone Switch", PW_MGMT2, 6, 1, 0), | ||
151 | }; | 149 | }; |
152 | 150 | ||
153 | static const struct snd_kcontrol_new ak4642_hpout_mixer_controls[] = { | 151 | static const struct snd_kcontrol_new ak4642_headphone_control = |
154 | SOC_DAPM_SINGLE("DACH", MD_CTL4, 0, 1, 0), | 152 | SOC_DAPM_SINGLE("Switch", PW_MGMT2, 6, 1, 0); |
155 | }; | ||
156 | 153 | ||
157 | static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = { | 154 | static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = { |
158 | SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0), | 155 | SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0), |
@@ -165,13 +162,12 @@ static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = { | |||
165 | SND_SOC_DAPM_OUTPUT("HPOUTR"), | 162 | SND_SOC_DAPM_OUTPUT("HPOUTR"), |
166 | SND_SOC_DAPM_OUTPUT("LINEOUT"), | 163 | SND_SOC_DAPM_OUTPUT("LINEOUT"), |
167 | 164 | ||
168 | SND_SOC_DAPM_MIXER("HPOUTL Mixer", PW_MGMT2, 5, 0, | 165 | SND_SOC_DAPM_PGA("HPL Out", PW_MGMT2, 5, 0, NULL, 0), |
169 | &ak4642_hpout_mixer_controls[0], | 166 | SND_SOC_DAPM_PGA("HPR Out", PW_MGMT2, 4, 0, NULL, 0), |
170 | ARRAY_SIZE(ak4642_hpout_mixer_controls)), | 167 | SND_SOC_DAPM_SWITCH("Headphone Enable", SND_SOC_NOPM, 0, 0, |
168 | &ak4642_headphone_control), | ||
171 | 169 | ||
172 | SND_SOC_DAPM_MIXER("HPOUTR Mixer", PW_MGMT2, 4, 0, | 170 | SND_SOC_DAPM_PGA("DACH", MD_CTL4, 0, 0, NULL, 0), |
173 | &ak4642_hpout_mixer_controls[0], | ||
174 | ARRAY_SIZE(ak4642_hpout_mixer_controls)), | ||
175 | 171 | ||
176 | SND_SOC_DAPM_MIXER("LINEOUT Mixer", PW_MGMT1, 3, 0, | 172 | SND_SOC_DAPM_MIXER("LINEOUT Mixer", PW_MGMT1, 3, 0, |
177 | &ak4642_lout_mixer_controls[0], | 173 | &ak4642_lout_mixer_controls[0], |
@@ -184,12 +180,17 @@ static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = { | |||
184 | static const struct snd_soc_dapm_route ak4642_intercon[] = { | 180 | static const struct snd_soc_dapm_route ak4642_intercon[] = { |
185 | 181 | ||
186 | /* Outputs */ | 182 | /* Outputs */ |
187 | {"HPOUTL", NULL, "HPOUTL Mixer"}, | 183 | {"HPOUTL", NULL, "HPL Out"}, |
188 | {"HPOUTR", NULL, "HPOUTR Mixer"}, | 184 | {"HPOUTR", NULL, "HPR Out"}, |
189 | {"LINEOUT", NULL, "LINEOUT Mixer"}, | 185 | {"LINEOUT", NULL, "LINEOUT Mixer"}, |
190 | 186 | ||
191 | {"HPOUTL Mixer", "DACH", "DAC"}, | 187 | {"HPL Out", NULL, "Headphone Enable"}, |
192 | {"HPOUTR Mixer", "DACH", "DAC"}, | 188 | {"HPR Out", NULL, "Headphone Enable"}, |
189 | |||
190 | {"Headphone Enable", "Switch", "DACH"}, | ||
191 | |||
192 | {"DACH", NULL, "DAC"}, | ||
193 | |||
193 | {"LINEOUT Mixer", "DACL", "DAC"}, | 194 | {"LINEOUT Mixer", "DACL", "DAC"}, |
194 | }; | 195 | }; |
195 | 196 | ||
@@ -476,7 +477,7 @@ static int ak4642_probe(struct snd_soc_codec *codec) | |||
476 | return ret; | 477 | return ret; |
477 | } | 478 | } |
478 | 479 | ||
479 | snd_soc_add_controls(codec, ak4642_snd_controls, | 480 | snd_soc_add_codec_controls(codec, ak4642_snd_controls, |
480 | ARRAY_SIZE(ak4642_snd_controls)); | 481 | ARRAY_SIZE(ak4642_snd_controls)); |
481 | 482 | ||
482 | ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 483 | ak4642_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index a53b152e6a07..5fb7c2a80e6d 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c | |||
@@ -628,7 +628,7 @@ static int ak4671_probe(struct snd_soc_codec *codec) | |||
628 | return ret; | 628 | return ret; |
629 | } | 629 | } |
630 | 630 | ||
631 | snd_soc_add_controls(codec, ak4671_snd_controls, | 631 | snd_soc_add_codec_controls(codec, ak4671_snd_controls, |
632 | ARRAY_SIZE(ak4671_snd_controls)); | 632 | ARRAY_SIZE(ak4671_snd_controls)); |
633 | 633 | ||
634 | ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 634 | ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index 3feee569ceea..d47b62ddb210 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c | |||
@@ -925,22 +925,22 @@ static int alc5623_probe(struct snd_soc_codec *codec) | |||
925 | 925 | ||
926 | switch (alc5623->id) { | 926 | switch (alc5623->id) { |
927 | case 0x21: | 927 | case 0x21: |
928 | snd_soc_add_controls(codec, alc5621_vol_snd_controls, | 928 | snd_soc_add_codec_controls(codec, alc5621_vol_snd_controls, |
929 | ARRAY_SIZE(alc5621_vol_snd_controls)); | 929 | ARRAY_SIZE(alc5621_vol_snd_controls)); |
930 | break; | 930 | break; |
931 | case 0x22: | 931 | case 0x22: |
932 | snd_soc_add_controls(codec, alc5622_vol_snd_controls, | 932 | snd_soc_add_codec_controls(codec, alc5622_vol_snd_controls, |
933 | ARRAY_SIZE(alc5622_vol_snd_controls)); | 933 | ARRAY_SIZE(alc5622_vol_snd_controls)); |
934 | break; | 934 | break; |
935 | case 0x23: | 935 | case 0x23: |
936 | snd_soc_add_controls(codec, alc5623_vol_snd_controls, | 936 | snd_soc_add_codec_controls(codec, alc5623_vol_snd_controls, |
937 | ARRAY_SIZE(alc5623_vol_snd_controls)); | 937 | ARRAY_SIZE(alc5623_vol_snd_controls)); |
938 | break; | 938 | break; |
939 | default: | 939 | default: |
940 | return -EINVAL; | 940 | return -EINVAL; |
941 | } | 941 | } |
942 | 942 | ||
943 | snd_soc_add_controls(codec, alc5623_snd_controls, | 943 | snd_soc_add_codec_controls(codec, alc5623_snd_controls, |
944 | ARRAY_SIZE(alc5623_snd_controls)); | 944 | ARRAY_SIZE(alc5623_snd_controls)); |
945 | 945 | ||
946 | snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets, | 946 | snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets, |
@@ -992,7 +992,7 @@ static struct snd_soc_codec_driver soc_codec_device_alc5623 = { | |||
992 | * low = 0x1a | 992 | * low = 0x1a |
993 | * high = 0x1b | 993 | * high = 0x1b |
994 | */ | 994 | */ |
995 | static int alc5623_i2c_probe(struct i2c_client *client, | 995 | static __devinit int alc5623_i2c_probe(struct i2c_client *client, |
996 | const struct i2c_device_id *id) | 996 | const struct i2c_device_id *id) |
997 | { | 997 | { |
998 | struct alc5623_platform_data *pdata; | 998 | struct alc5623_platform_data *pdata; |
@@ -1059,7 +1059,7 @@ static int alc5623_i2c_probe(struct i2c_client *client, | |||
1059 | return ret; | 1059 | return ret; |
1060 | } | 1060 | } |
1061 | 1061 | ||
1062 | static int alc5623_i2c_remove(struct i2c_client *client) | 1062 | static __devexit int alc5623_i2c_remove(struct i2c_client *client) |
1063 | { | 1063 | { |
1064 | snd_soc_unregister_codec(&client->dev); | 1064 | snd_soc_unregister_codec(&client->dev); |
1065 | return 0; | 1065 | return 0; |
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c index 390e437d7c5e..e2111e0ccad7 100644 --- a/sound/soc/codecs/alc5632.c +++ b/sound/soc/codecs/alc5632.c | |||
@@ -145,15 +145,14 @@ static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0); | |||
145 | /* -16.5db min scale, 1.5db steps, no mute */ | 145 | /* -16.5db min scale, 1.5db steps, no mute */ |
146 | static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0); | 146 | static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0); |
147 | static const unsigned int boost_tlv[] = { | 147 | static const unsigned int boost_tlv[] = { |
148 | TLV_DB_RANGE_HEAD(3), | 148 | TLV_DB_RANGE_HEAD(2), |
149 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), | 149 | 0, 1, TLV_DB_SCALE_ITEM(0, 2000, 0), |
150 | 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), | 150 | 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0), |
151 | 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), | ||
152 | }; | 151 | }; |
153 | /* 0db min scale, 6 db steps, no mute */ | 152 | /* 0db min scale, 6 db steps, no mute */ |
154 | static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0); | 153 | static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0); |
155 | /* 0db min scalem 0.75db steps, no mute */ | 154 | /* 0db min scalem 0.75db steps, no mute */ |
156 | static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 075, 0); | 155 | static const DECLARE_TLV_DB_SCALE(vdac_tlv, -3525, 75, 0); |
157 | 156 | ||
158 | static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = { | 157 | static const struct snd_kcontrol_new alc5632_vol_snd_controls[] = { |
159 | /* left starts at bit 8, right at bit 0 */ | 158 | /* left starts at bit 8, right at bit 0 */ |
@@ -176,26 +175,32 @@ static const struct snd_kcontrol_new alc5632_snd_controls[] = { | |||
176 | ALC5632_AUX_OUT_VOL, 15, 7, 1, 1), | 175 | ALC5632_AUX_OUT_VOL, 15, 7, 1, 1), |
177 | SOC_SINGLE_TLV("Voice DAC Playback Volume", | 176 | SOC_SINGLE_TLV("Voice DAC Playback Volume", |
178 | ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv), | 177 | ALC5632_VOICE_DAC_VOL, 0, 63, 0, vdac_tlv), |
179 | SOC_SINGLE_TLV("Phone Capture Volume", | 178 | SOC_SINGLE("Voice DAC Playback Switch", |
179 | ALC5632_VOICE_DAC_VOL, 12, 1, 1), | ||
180 | SOC_SINGLE_TLV("Phone Playback Volume", | ||
180 | ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv), | 181 | ALC5632_PHONE_IN_VOL, 8, 31, 1, vol_tlv), |
181 | SOC_DOUBLE_TLV("LineIn Capture Volume", | 182 | SOC_DOUBLE_TLV("LineIn Playback Volume", |
182 | ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv), | 183 | ALC5632_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv), |
183 | SOC_DOUBLE_TLV("Master Playback Volume", | 184 | SOC_DOUBLE_TLV("Master Playback Volume", |
184 | ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv), | 185 | ALC5632_STEREO_DAC_IN_VOL, 8, 0, 63, 1, vdac_tlv), |
185 | SOC_DOUBLE("Master Playback Switch", | 186 | SOC_DOUBLE("Master Playback Switch", |
186 | ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1), | 187 | ALC5632_STEREO_DAC_IN_VOL, 15, 7, 1, 1), |
187 | SOC_SINGLE_TLV("Mic1 Capture Volume", | 188 | SOC_SINGLE_TLV("Mic1 Playback Volume", |
188 | ALC5632_MIC_VOL, 8, 31, 1, vol_tlv), | 189 | ALC5632_MIC_VOL, 8, 31, 1, vol_tlv), |
189 | SOC_SINGLE_TLV("Mic2 Capture Volume", | 190 | SOC_SINGLE_TLV("Mic2 Playback Volume", |
190 | ALC5632_MIC_VOL, 0, 31, 1, vol_tlv), | 191 | ALC5632_MIC_VOL, 0, 31, 1, vol_tlv), |
191 | SOC_DOUBLE_TLV("Rec Capture Volume", | 192 | SOC_DOUBLE_TLV("Rec Capture Volume", |
192 | ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv), | 193 | ALC5632_ADC_REC_GAIN, 8, 0, 31, 0, adc_rec_tlv), |
193 | SOC_SINGLE_TLV("Mic 1 Boost Volume", | 194 | SOC_SINGLE_TLV("Mic 1 Boost Volume", |
194 | ALC5632_MIC_CTRL, 10, 2, 0, boost_tlv), | 195 | ALC5632_MIC_CTRL, 10, 3, 0, boost_tlv), |
195 | SOC_SINGLE_TLV("Mic 2 Boost Volume", | 196 | SOC_SINGLE_TLV("Mic 2 Boost Volume", |
196 | ALC5632_MIC_CTRL, 8, 2, 0, boost_tlv), | 197 | ALC5632_MIC_CTRL, 8, 3, 0, boost_tlv), |
197 | SOC_SINGLE_TLV("Digital Boost Volume", | 198 | SOC_SINGLE_TLV("DMIC Boost Capture Volume", |
198 | ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv), | 199 | ALC5632_DIGI_BOOST_CTRL, 0, 7, 0, dig_tlv), |
200 | SOC_SINGLE("DMIC En Capture Switch", | ||
201 | ALC5632_DIGI_BOOST_CTRL, 15, 1, 0), | ||
202 | SOC_SINGLE("DMIC PreFilter Capture Switch", | ||
203 | ALC5632_DIGI_BOOST_CTRL, 12, 1, 0), | ||
199 | }; | 204 | }; |
200 | 205 | ||
201 | /* | 206 | /* |
@@ -244,36 +249,48 @@ SOC_DAPM_SINGLE("VOICE2SPK Playback Switch", ALC5632_VOICE_DAC_VOL, 14, 1, 1), | |||
244 | 249 | ||
245 | /* Left Record Mixer */ | 250 | /* Left Record Mixer */ |
246 | static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = { | 251 | static const struct snd_kcontrol_new alc5632_captureL_mixer_controls[] = { |
247 | SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1), | 252 | SOC_DAPM_SINGLE("MIC12REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 14, 1, 1), |
248 | SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1), | 253 | SOC_DAPM_SINGLE("MIC22REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 13, 1, 1), |
249 | SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1), | 254 | SOC_DAPM_SINGLE("LIL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 12, 1, 1), |
250 | SOC_DAPM_SINGLE("Left Phone Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1), | 255 | SOC_DAPM_SINGLE("PH2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 11, 1, 1), |
251 | SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1), | 256 | SOC_DAPM_SINGLE("HPL2REC Capture Switch", ALC5632_ADC_REC_MIXER, 10, 1, 1), |
252 | SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1), | 257 | SOC_DAPM_SINGLE("SPK2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 9, 1, 1), |
253 | SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1), | 258 | SOC_DAPM_SINGLE("MONO2REC_L Capture Switch", ALC5632_ADC_REC_MIXER, 8, 1, 1), |
254 | }; | 259 | }; |
255 | 260 | ||
256 | /* Right Record Mixer */ | 261 | /* Right Record Mixer */ |
257 | static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = { | 262 | static const struct snd_kcontrol_new alc5632_captureR_mixer_controls[] = { |
258 | SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1), | 263 | SOC_DAPM_SINGLE("MIC12REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 6, 1, 1), |
259 | SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1), | 264 | SOC_DAPM_SINGLE("MIC22REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 5, 1, 1), |
260 | SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1), | 265 | SOC_DAPM_SINGLE("LIR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 4, 1, 1), |
261 | SOC_DAPM_SINGLE("Right Phone Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1), | 266 | SOC_DAPM_SINGLE("PH2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 3, 1, 1), |
262 | SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1), | 267 | SOC_DAPM_SINGLE("HPR2REC Capture Switch", ALC5632_ADC_REC_MIXER, 2, 1, 1), |
263 | SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1), | 268 | SOC_DAPM_SINGLE("SPK2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 1, 1, 1), |
264 | SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1), | 269 | SOC_DAPM_SINGLE("MONO2REC_R Capture Switch", ALC5632_ADC_REC_MIXER, 0, 1, 1), |
265 | }; | 270 | }; |
266 | 271 | ||
267 | static const char *alc5632_spk_n_sour_sel[] = { | 272 | /* Dmic Mixer */ |
273 | static const struct snd_kcontrol_new alc5632_dmicl_mixer_controls[] = { | ||
274 | SOC_DAPM_SINGLE("DMICL2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 7, 1, 1), | ||
275 | }; | ||
276 | static const struct snd_kcontrol_new alc5632_dmicr_mixer_controls[] = { | ||
277 | SOC_DAPM_SINGLE("DMICR2ADC Capture Switch", ALC5632_DIGI_BOOST_CTRL, 6, 1, 1), | ||
278 | }; | ||
279 | |||
280 | static const char * const alc5632_spk_n_sour_sel[] = { | ||
268 | "RN/-R", "RP/+R", "LN/-R", "Mute"}; | 281 | "RN/-R", "RP/+R", "LN/-R", "Mute"}; |
269 | static const char *alc5632_hpl_out_input_sel[] = { | 282 | static const char * const alc5632_hpl_out_input_sel[] = { |
270 | "Vmid", "HP Left Mix"}; | 283 | "Vmid", "HP Left Mix"}; |
271 | static const char *alc5632_hpr_out_input_sel[] = { | 284 | static const char * const alc5632_hpr_out_input_sel[] = { |
272 | "Vmid", "HP Right Mix"}; | 285 | "Vmid", "HP Right Mix"}; |
273 | static const char *alc5632_spkout_input_sel[] = { | 286 | static const char * const alc5632_spkout_input_sel[] = { |
274 | "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; | 287 | "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; |
275 | static const char *alc5632_aux_out_input_sel[] = { | 288 | static const char * const alc5632_aux_out_input_sel[] = { |
276 | "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; | 289 | "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; |
290 | static const char * const alc5632_adcr_func_sel[] = { | ||
291 | "Stereo ADC", "Voice ADC"}; | ||
292 | static const char * const alc5632_i2s_out_sel[] = { | ||
293 | "ADC LR", "Voice Stereo Digital"}; | ||
277 | 294 | ||
278 | /* auxout output mux */ | 295 | /* auxout output mux */ |
279 | static const struct soc_enum alc5632_aux_out_input_enum = | 296 | static const struct soc_enum alc5632_aux_out_input_enum = |
@@ -312,6 +329,17 @@ static const struct soc_enum alc5632_amp_enum = | |||
312 | static const struct snd_kcontrol_new alc5632_amp_mux_controls = | 329 | static const struct snd_kcontrol_new alc5632_amp_mux_controls = |
313 | SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum); | 330 | SOC_DAPM_ENUM("AB-D Amp Mux", alc5632_amp_enum); |
314 | 331 | ||
332 | /* ADC output select */ | ||
333 | static const struct soc_enum alc5632_adcr_func_enum = | ||
334 | SOC_ENUM_SINGLE(ALC5632_DAC_FUNC_SELECT, 5, 2, alc5632_adcr_func_sel); | ||
335 | static const struct snd_kcontrol_new alc5632_adcr_func_controls = | ||
336 | SOC_DAPM_ENUM("ADCR Mux", alc5632_adcr_func_enum); | ||
337 | |||
338 | /* I2S out select */ | ||
339 | static const struct soc_enum alc5632_i2s_out_enum = | ||
340 | SOC_ENUM_SINGLE(ALC5632_I2S_OUT_CTL, 5, 2, alc5632_i2s_out_sel); | ||
341 | static const struct snd_kcontrol_new alc5632_i2s_out_controls = | ||
342 | SOC_DAPM_ENUM("I2SOut Mux", alc5632_i2s_out_enum); | ||
315 | 343 | ||
316 | static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = { | 344 | static const struct snd_soc_dapm_widget alc5632_dapm_widgets[] = { |
317 | /* Muxes */ | 345 | /* Muxes */ |
@@ -325,6 +353,10 @@ SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, | |||
325 | &alc5632_hpr_out_mux_controls), | 353 | &alc5632_hpr_out_mux_controls), |
326 | SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0, | 354 | SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0, |
327 | &alc5632_spkoutn_mux_controls), | 355 | &alc5632_spkoutn_mux_controls), |
356 | SND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0, | ||
357 | &alc5632_adcr_func_controls), | ||
358 | SND_SOC_DAPM_MUX("I2SOut Mux", ALC5632_PWR_MANAG_ADD1, 11, 0, | ||
359 | &alc5632_i2s_out_controls), | ||
328 | 360 | ||
329 | /* output mixers */ | 361 | /* output mixers */ |
330 | SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0, | 362 | SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0, |
@@ -343,6 +375,12 @@ SND_SOC_DAPM_MIXER("Mono Mix", ALC5632_PWR_MANAG_ADD2, 2, 0, | |||
343 | SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0, | 375 | SND_SOC_DAPM_MIXER("Speaker Mix", ALC5632_PWR_MANAG_ADD2, 3, 0, |
344 | &alc5632_speaker_mixer_controls[0], | 376 | &alc5632_speaker_mixer_controls[0], |
345 | ARRAY_SIZE(alc5632_speaker_mixer_controls)), | 377 | ARRAY_SIZE(alc5632_speaker_mixer_controls)), |
378 | SND_SOC_DAPM_MIXER("DMICL Mix", SND_SOC_NOPM, 0, 0, | ||
379 | &alc5632_dmicl_mixer_controls[0], | ||
380 | ARRAY_SIZE(alc5632_dmicl_mixer_controls)), | ||
381 | SND_SOC_DAPM_MIXER("DMICR Mix", SND_SOC_NOPM, 0, 0, | ||
382 | &alc5632_dmicr_mixer_controls[0], | ||
383 | ARRAY_SIZE(alc5632_dmicr_mixer_controls)), | ||
346 | 384 | ||
347 | /* input mixers */ | 385 | /* input mixers */ |
348 | SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0, | 386 | SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5632_PWR_MANAG_ADD2, 1, 0, |
@@ -352,20 +390,28 @@ SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5632_PWR_MANAG_ADD2, 0, 0, | |||
352 | &alc5632_captureR_mixer_controls[0], | 390 | &alc5632_captureR_mixer_controls[0], |
353 | ARRAY_SIZE(alc5632_captureR_mixer_controls)), | 391 | ARRAY_SIZE(alc5632_captureR_mixer_controls)), |
354 | 392 | ||
355 | SND_SOC_DAPM_DAC("Left DAC", "HiFi Playback", | 393 | SND_SOC_DAPM_AIF_IN("AIFRXL", "Left HiFi Playback", 0, SND_SOC_NOPM, 0, 0), |
356 | ALC5632_PWR_MANAG_ADD2, 9, 0), | 394 | SND_SOC_DAPM_AIF_IN("AIFRXR", "Right HiFi Playback", 0, SND_SOC_NOPM, 0, 0), |
357 | SND_SOC_DAPM_DAC("Right DAC", "HiFi Playback", | 395 | SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0), |
358 | ALC5632_PWR_MANAG_ADD2, 8, 0), | 396 | SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0), |
397 | SND_SOC_DAPM_AIF_IN("VAIFRX", "Voice Playback", 0, SND_SOC_NOPM, 0, 0), | ||
398 | SND_SOC_DAPM_AIF_OUT("VAIFTX", "Voice Capture", 0, SND_SOC_NOPM, 0, 0), | ||
399 | |||
400 | SND_SOC_DAPM_DAC("Voice DAC", NULL, ALC5632_PWR_MANAG_ADD2, 10, 0), | ||
401 | SND_SOC_DAPM_DAC("Left DAC", NULL, ALC5632_PWR_MANAG_ADD2, 9, 0), | ||
402 | SND_SOC_DAPM_DAC("Right DAC", NULL, ALC5632_PWR_MANAG_ADD2, 8, 0), | ||
403 | SND_SOC_DAPM_ADC("Left ADC", NULL, ALC5632_PWR_MANAG_ADD2, 7, 0), | ||
404 | SND_SOC_DAPM_ADC("Right ADC", NULL, ALC5632_PWR_MANAG_ADD2, 6, 0), | ||
405 | |||
359 | SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0), | 406 | SND_SOC_DAPM_MIXER("DAC Left Channel", ALC5632_PWR_MANAG_ADD1, 15, 0, NULL, 0), |
360 | SND_SOC_DAPM_MIXER("DAC Right Channel", | 407 | SND_SOC_DAPM_MIXER("DAC Right Channel", |
361 | ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0), | 408 | ALC5632_PWR_MANAG_ADD1, 14, 0, NULL, 0), |
362 | SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0), | 409 | SND_SOC_DAPM_MIXER("I2S Mix", ALC5632_PWR_MANAG_ADD1, 11, 0, NULL, 0), |
363 | SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0), | 410 | SND_SOC_DAPM_MIXER("Phone Mix", SND_SOC_NOPM, 0, 0, NULL, 0), |
364 | SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0), | 411 | SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0), |
365 | SND_SOC_DAPM_ADC("Left ADC", "HiFi Capture", | 412 | SND_SOC_DAPM_MIXER("Voice Mix", SND_SOC_NOPM, 0, 0, NULL, 0), |
366 | ALC5632_PWR_MANAG_ADD2, 7, 0), | 413 | SND_SOC_DAPM_MIXER("ADCLR", SND_SOC_NOPM, 0, 0, NULL, 0), |
367 | SND_SOC_DAPM_ADC("Right ADC", "HiFi Capture", | 414 | |
368 | ALC5632_PWR_MANAG_ADD2, 6, 0), | ||
369 | SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0), | 415 | SND_SOC_DAPM_PGA("Left Headphone", ALC5632_PWR_MANAG_ADD3, 11, 0, NULL, 0), |
370 | SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0), | 416 | SND_SOC_DAPM_PGA("Right Headphone", ALC5632_PWR_MANAG_ADD3, 10, 0, NULL, 0), |
371 | SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0), | 417 | SND_SOC_DAPM_PGA("Left Speaker", ALC5632_PWR_MANAG_ADD3, 13, 0, NULL, 0), |
@@ -393,10 +439,12 @@ SND_SOC_DAPM_OUTPUT("HPL"), | |||
393 | SND_SOC_DAPM_OUTPUT("HPR"), | 439 | SND_SOC_DAPM_OUTPUT("HPR"), |
394 | SND_SOC_DAPM_OUTPUT("SPKOUT"), | 440 | SND_SOC_DAPM_OUTPUT("SPKOUT"), |
395 | SND_SOC_DAPM_OUTPUT("SPKOUTN"), | 441 | SND_SOC_DAPM_OUTPUT("SPKOUTN"), |
442 | |||
396 | SND_SOC_DAPM_INPUT("LINEINL"), | 443 | SND_SOC_DAPM_INPUT("LINEINL"), |
397 | SND_SOC_DAPM_INPUT("LINEINR"), | 444 | SND_SOC_DAPM_INPUT("LINEINR"), |
398 | SND_SOC_DAPM_INPUT("PHONEP"), | 445 | SND_SOC_DAPM_INPUT("PHONEP"), |
399 | SND_SOC_DAPM_INPUT("PHONEN"), | 446 | SND_SOC_DAPM_INPUT("PHONEN"), |
447 | SND_SOC_DAPM_INPUT("DMICDAT"), | ||
400 | SND_SOC_DAPM_INPUT("MIC1"), | 448 | SND_SOC_DAPM_INPUT("MIC1"), |
401 | SND_SOC_DAPM_INPUT("MIC2"), | 449 | SND_SOC_DAPM_INPUT("MIC2"), |
402 | SND_SOC_DAPM_VMID("Vmid"), | 450 | SND_SOC_DAPM_VMID("Vmid"), |
@@ -404,6 +452,10 @@ SND_SOC_DAPM_VMID("Vmid"), | |||
404 | 452 | ||
405 | 453 | ||
406 | static const struct snd_soc_dapm_route alc5632_dapm_routes[] = { | 454 | static const struct snd_soc_dapm_route alc5632_dapm_routes[] = { |
455 | /* Playback streams */ | ||
456 | {"Left DAC", NULL, "AIFRXL"}, | ||
457 | {"Right DAC", NULL, "AIFRXR"}, | ||
458 | |||
407 | /* virtual mixer - mixes left & right channels */ | 459 | /* virtual mixer - mixes left & right channels */ |
408 | {"I2S Mix", NULL, "Left DAC"}, | 460 | {"I2S Mix", NULL, "Left DAC"}, |
409 | {"I2S Mix", NULL, "Right DAC"}, | 461 | {"I2S Mix", NULL, "Right DAC"}, |
@@ -426,9 +478,12 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = { | |||
426 | {"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"}, | 478 | {"HP Mix", "PHONE2HP Playback Switch", "Phone Mix"}, |
427 | {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"}, | 479 | {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"}, |
428 | {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"}, | 480 | {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"}, |
429 | 481 | {"HP Mix", "VOICE2HP Playback Switch", "Voice Mix"}, | |
430 | {"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"}, | 482 | {"HPR Mix", "DACR2HP Playback Switch", "DAC Right Channel"}, |
431 | {"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"}, | 483 | {"HPL Mix", "DACL2HP Playback Switch", "DAC Left Channel"}, |
484 | {"HPOut Mix", NULL, "HP Mix"}, | ||
485 | {"HPOut Mix", NULL, "HPR Mix"}, | ||
486 | {"HPOut Mix", NULL, "HPL Mix"}, | ||
432 | 487 | ||
433 | /* speaker mixer */ | 488 | /* speaker mixer */ |
434 | {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"}, | 489 | {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"}, |
@@ -436,35 +491,34 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = { | |||
436 | {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"}, | 491 | {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"}, |
437 | {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"}, | 492 | {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"}, |
438 | {"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"}, | 493 | {"Speaker Mix", "DAC2SPK Playback Switch", "DAC Left Channel"}, |
439 | 494 | {"Speaker Mix", "VOICE2SPK Playback Switch", "Voice Mix"}, | |
440 | |||
441 | 495 | ||
442 | /* mono mixer */ | 496 | /* mono mixer */ |
443 | {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"}, | 497 | {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"}, |
444 | {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"}, | 498 | {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"}, |
445 | {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"}, | 499 | {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"}, |
446 | {"Mono Mix", "VOICE2MONO Playback Switch", "Phone Mix"}, | ||
447 | {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"}, | 500 | {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"}, |
448 | {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"}, | 501 | {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"}, |
449 | {"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"}, | 502 | {"Mono Mix", "DAC2MONO Playback Switch", "DAC Left Channel"}, |
503 | {"Mono Mix", "VOICE2MONO Playback Switch", "Voice Mix"}, | ||
450 | 504 | ||
451 | /* Left record mixer */ | 505 | /* Left record mixer */ |
452 | {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"}, | 506 | {"Left Capture Mix", "LIL2REC Capture Switch", "LINEINL"}, |
453 | {"Left Capture Mix", "Left Phone Capture Switch", "PHONEN"}, | 507 | {"Left Capture Mix", "PH2REC_L Capture Switch", "PHONEN"}, |
454 | {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, | 508 | {"Left Capture Mix", "MIC12REC_L Capture Switch", "MIC1 Pre Amp"}, |
455 | {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, | 509 | {"Left Capture Mix", "MIC22REC_L Capture Switch", "MIC2 Pre Amp"}, |
456 | {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"}, | 510 | {"Left Capture Mix", "HPL2REC Capture Switch", "HPL Mix"}, |
457 | {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, | 511 | {"Left Capture Mix", "SPK2REC_L Capture Switch", "Speaker Mix"}, |
458 | {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, | 512 | {"Left Capture Mix", "MONO2REC_L Capture Switch", "Mono Mix"}, |
459 | 513 | ||
460 | /*Right record mixer */ | 514 | /*Right record mixer */ |
461 | {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"}, | 515 | {"Right Capture Mix", "LIR2REC Capture Switch", "LINEINR"}, |
462 | {"Right Capture Mix", "Right Phone Capture Switch", "PHONEP"}, | 516 | {"Right Capture Mix", "PH2REC_R Capture Switch", "PHONEP"}, |
463 | {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, | 517 | {"Right Capture Mix", "MIC12REC_R Capture Switch", "MIC1 Pre Amp"}, |
464 | {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, | 518 | {"Right Capture Mix", "MIC22REC_R Capture Switch", "MIC2 Pre Amp"}, |
465 | {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"}, | 519 | {"Right Capture Mix", "HPR2REC Capture Switch", "HPR Mix"}, |
466 | {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, | 520 | {"Right Capture Mix", "SPK2REC_R Capture Switch", "Speaker Mix"}, |
467 | {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, | 521 | {"Right Capture Mix", "MONO2REC_R Capture Switch", "Mono Mix"}, |
468 | 522 | ||
469 | /* headphone left mux */ | 523 | /* headphone left mux */ |
470 | {"Left Headphone Mux", "HP Left Mix", "HPL Mix"}, | 524 | {"Left Headphone Mux", "HP Left Mix", "HPL Mix"}, |
@@ -504,10 +558,30 @@ static const struct snd_soc_dapm_route alc5632_dapm_routes[] = { | |||
504 | 558 | ||
505 | /* left ADC */ | 559 | /* left ADC */ |
506 | {"Left ADC", NULL, "Left Capture Mix"}, | 560 | {"Left ADC", NULL, "Left Capture Mix"}, |
561 | {"DMICL Mix", "DMICL2ADC Capture Switch", "DMICDAT"}, | ||
562 | {"Left ADC", NULL, "DMICL Mix"}, | ||
563 | {"ADCLR", NULL, "Left ADC"}, | ||
507 | 564 | ||
508 | /* right ADC */ | 565 | /* right ADC */ |
509 | {"Right ADC", NULL, "Right Capture Mix"}, | 566 | {"Right ADC", NULL, "Right Capture Mix"}, |
510 | 567 | {"DMICR Mix", "DMICR2ADC Capture Switch", "DMICDAT"}, | |
568 | {"Right ADC", NULL, "DMICR Mix"}, | ||
569 | {"ADCR Mux", "Stereo ADC", "Right ADC"}, | ||
570 | {"ADCR Mux", "Voice ADC", "Right ADC"}, | ||
571 | {"ADCLR", NULL, "ADCR Mux"}, | ||
572 | {"VAIFTX", NULL, "ADCR Mux"}, | ||
573 | |||
574 | /* Digital I2S out */ | ||
575 | {"I2SOut Mux", "ADC LR", "ADCLR"}, | ||
576 | {"I2SOut Mux", "Voice Stereo Digital", "VAIFRX"}, | ||
577 | {"AIFTXL", NULL, "I2SOut Mux"}, | ||
578 | {"AIFTXR", NULL, "I2SOut Mux"}, | ||
579 | |||
580 | /* Voice Mix */ | ||
581 | {"Voice DAC", NULL, "VAIFRX"}, | ||
582 | {"Voice Mix", NULL, "Voice DAC"}, | ||
583 | |||
584 | /* Speaker Output */ | ||
511 | {"SpeakerOut N Mux", "RN/-R", "Left Speaker"}, | 585 | {"SpeakerOut N Mux", "RN/-R", "Left Speaker"}, |
512 | {"SpeakerOut N Mux", "RP/+R", "Left Speaker"}, | 586 | {"SpeakerOut N Mux", "RP/+R", "Left Speaker"}, |
513 | {"SpeakerOut N Mux", "LN/-R", "Left Speaker"}, | 587 | {"SpeakerOut N Mux", "LN/-R", "Left Speaker"}, |
@@ -714,6 +788,7 @@ static int alc5632_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
714 | struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); | 788 | struct alc5632_priv *alc5632 = snd_soc_codec_get_drvdata(codec); |
715 | 789 | ||
716 | switch (freq) { | 790 | switch (freq) { |
791 | case 4096000: | ||
717 | case 8192000: | 792 | case 8192000: |
718 | case 11289600: | 793 | case 11289600: |
719 | case 12288000: | 794 | case 12288000: |
@@ -994,7 +1069,7 @@ static int alc5632_probe(struct snd_soc_codec *codec) | |||
994 | 1069 | ||
995 | switch (alc5632->id) { | 1070 | switch (alc5632->id) { |
996 | case 0x5c: | 1071 | case 0x5c: |
997 | snd_soc_add_controls(codec, alc5632_vol_snd_controls, | 1072 | snd_soc_add_codec_controls(codec, alc5632_vol_snd_controls, |
998 | ARRAY_SIZE(alc5632_vol_snd_controls)); | 1073 | ARRAY_SIZE(alc5632_vol_snd_controls)); |
999 | break; | 1074 | break; |
1000 | default: | 1075 | default: |
@@ -1109,7 +1184,7 @@ static __devinit int alc5632_i2c_probe(struct i2c_client *client, | |||
1109 | return ret; | 1184 | return ret; |
1110 | } | 1185 | } |
1111 | 1186 | ||
1112 | static int alc5632_i2c_remove(struct i2c_client *client) | 1187 | static __devexit int alc5632_i2c_remove(struct i2c_client *client) |
1113 | { | 1188 | { |
1114 | struct alc5632_priv *alc5632 = i2c_get_clientdata(client); | 1189 | struct alc5632_priv *alc5632 = i2c_get_clientdata(client); |
1115 | snd_soc_unregister_codec(&client->dev); | 1190 | snd_soc_unregister_codec(&client->dev); |
diff --git a/sound/soc/codecs/alc5632.h b/sound/soc/codecs/alc5632.h index 357651ec074e..1b5bda594ea3 100644 --- a/sound/soc/codecs/alc5632.h +++ b/sound/soc/codecs/alc5632.h | |||
@@ -51,6 +51,7 @@ | |||
51 | #define ALC5632_ADC_REC_MONOMIX (1 << 0) | 51 | #define ALC5632_ADC_REC_MONOMIX (1 << 0) |
52 | 52 | ||
53 | #define ALC5632_VOICE_DAC_VOL 0x18 /* voice dac vol */ | 53 | #define ALC5632_VOICE_DAC_VOL 0x18 /* voice dac vol */ |
54 | #define ALC5632_I2S_OUT_CTL 0x1A /* undocumented reg. found in path scheme */ | ||
54 | /* ALC5632_OUTPUT_MIXER_CTRL : */ | 55 | /* ALC5632_OUTPUT_MIXER_CTRL : */ |
55 | /* same remark as for reg 2 line vs speaker */ | 56 | /* same remark as for reg 2 line vs speaker */ |
56 | #define ALC5632_OUTPUT_MIXER_CTRL 0x1C /* out mix ctrl */ | 57 | #define ALC5632_OUTPUT_MIXER_CTRL 0x1C /* out mix ctrl */ |
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 4854b472d5fd..064cd6a93516 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c | |||
@@ -38,8 +38,6 @@ | |||
38 | #include <sound/soc.h> | 38 | #include <sound/soc.h> |
39 | #include <sound/initval.h> | 39 | #include <sound/initval.h> |
40 | 40 | ||
41 | #include <mach/dm365.h> | ||
42 | |||
43 | static inline unsigned int cq93vc_read(struct snd_soc_codec *codec, | 41 | static inline unsigned int cq93vc_read(struct snd_soc_codec *codec, |
44 | unsigned int reg) | 42 | unsigned int reg) |
45 | { | 43 | { |
@@ -159,7 +157,7 @@ static int cq93vc_probe(struct snd_soc_codec *codec) | |||
159 | codec->control_data = davinci_vc; | 157 | codec->control_data = davinci_vc; |
160 | 158 | ||
161 | /* Set controls */ | 159 | /* Set controls */ |
162 | snd_soc_add_controls(codec, cq93vc_snd_controls, | 160 | snd_soc_add_codec_controls(codec, cq93vc_snd_controls, |
163 | ARRAY_SIZE(cq93vc_snd_controls)); | 161 | ARRAY_SIZE(cq93vc_snd_controls)); |
164 | 162 | ||
165 | /* Off, with power on */ | 163 | /* Off, with power on */ |
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 055536645da9..1d672f528662 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
@@ -521,7 +521,7 @@ static int cs4270_probe(struct snd_soc_codec *codec) | |||
521 | } | 521 | } |
522 | 522 | ||
523 | /* Add the non-DAPM controls */ | 523 | /* Add the non-DAPM controls */ |
524 | ret = snd_soc_add_controls(codec, cs4270_snd_controls, | 524 | ret = snd_soc_add_codec_controls(codec, cs4270_snd_controls, |
525 | ARRAY_SIZE(cs4270_snd_controls)); | 525 | ARRAY_SIZE(cs4270_snd_controls)); |
526 | if (ret < 0) { | 526 | if (ret < 0) { |
527 | dev_err(codec->dev, "failed to add controls\n"); | 527 | dev_err(codec->dev, "failed to add controls\n"); |
@@ -715,7 +715,7 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id); | |||
715 | */ | 715 | */ |
716 | static struct i2c_driver cs4270_i2c_driver = { | 716 | static struct i2c_driver cs4270_i2c_driver = { |
717 | .driver = { | 717 | .driver = { |
718 | .name = "cs4270-codec", | 718 | .name = "cs4270", |
719 | .owner = THIS_MODULE, | 719 | .owner = THIS_MODULE, |
720 | }, | 720 | }, |
721 | .id_table = cs4270_id, | 721 | .id_table = cs4270_id, |
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index f6fe846b6a6c..bf7141280a74 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c | |||
@@ -513,7 +513,7 @@ static int cs4271_probe(struct snd_soc_codec *codec) | |||
513 | /* Power-up sequence requires 85 uS */ | 513 | /* Power-up sequence requires 85 uS */ |
514 | udelay(85); | 514 | udelay(85); |
515 | 515 | ||
516 | return snd_soc_add_controls(codec, cs4271_snd_controls, | 516 | return snd_soc_add_codec_controls(codec, cs4271_snd_controls, |
517 | ARRAY_SIZE(cs4271_snd_controls)); | 517 | ARRAY_SIZE(cs4271_snd_controls)); |
518 | } | 518 | } |
519 | 519 | ||
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 9d38db8f1919..78979b3e0e95 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -1113,7 +1113,7 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream, | |||
1113 | priv->config[id].mmcc &= 0xC0; | 1113 | priv->config[id].mmcc &= 0xC0; |
1114 | priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc; | 1114 | priv->config[id].mmcc |= cs42l73_mclk_coeffs[mclk_coeff].mmcc; |
1115 | priv->config[id].spc &= 0xFC; | 1115 | priv->config[id].spc &= 0xFC; |
1116 | priv->config[id].spc &= MCK_SCLK_64FS; | 1116 | priv->config[id].spc |= MCK_SCLK_MCLK; |
1117 | } else { | 1117 | } else { |
1118 | /* CS42L73 Slave */ | 1118 | /* CS42L73 Slave */ |
1119 | priv->config[id].spc &= 0xFC; | 1119 | priv->config[id].spc &= 0xFC; |
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index ab38e93c3543..7843711729bc 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
20 | #include <linux/regmap.h> | ||
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
21 | #include <linux/module.h> | 22 | #include <linux/module.h> |
22 | #include <sound/pcm.h> | 23 | #include <sound/pcm.h> |
@@ -626,41 +627,82 @@ static const struct snd_soc_dapm_route da7210_audio_map[] = { | |||
626 | 627 | ||
627 | /* Codec private data */ | 628 | /* Codec private data */ |
628 | struct da7210_priv { | 629 | struct da7210_priv { |
629 | enum snd_soc_control_type control_type; | 630 | struct regmap *regmap; |
630 | }; | 631 | }; |
631 | 632 | ||
632 | /* | 633 | static struct reg_default da7210_reg_defaults[] = { |
633 | * Register cache | 634 | { 0x01, 0x11 }, |
634 | */ | 635 | { 0x03, 0x00 }, |
635 | static const u8 da7210_reg[] = { | 636 | { 0x04, 0x00 }, |
636 | 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R0 - R7 */ | 637 | { 0x05, 0x00 }, |
637 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* R8 - RF */ | 638 | { 0x06, 0x00 }, |
638 | 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x54, /* R10 - R17 */ | 639 | { 0x07, 0x00 }, |
639 | 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R18 - R1F */ | 640 | { 0x08, 0x00 }, |
640 | 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, /* R20 - R27 */ | 641 | { 0x09, 0x00 }, |
641 | 0x04, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x40, 0x00, /* R28 - R2F */ | 642 | { 0x0a, 0x00 }, |
642 | 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, /* R30 - R37 */ | 643 | { 0x0b, 0x00 }, |
643 | 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, /* R38 - R3F */ | 644 | { 0x0c, 0x00 }, |
644 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R40 - R4F */ | 645 | { 0x0d, 0x00 }, |
645 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R48 - R4F */ | 646 | { 0x0e, 0x00 }, |
646 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R50 - R57 */ | 647 | { 0x0f, 0x08 }, |
647 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R58 - R5F */ | 648 | { 0x10, 0x00 }, |
648 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R60 - R67 */ | 649 | { 0x11, 0x00 }, |
649 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R68 - R6F */ | 650 | { 0x12, 0x00 }, |
650 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R70 - R77 */ | 651 | { 0x13, 0x00 }, |
651 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, /* R78 - R7F */ | 652 | { 0x14, 0x08 }, |
652 | 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, /* R80 - R87 */ | 653 | { 0x15, 0x10 }, |
653 | 0x00, /* R88 */ | 654 | { 0x16, 0x10 }, |
655 | { 0x17, 0x54 }, | ||
656 | { 0x18, 0x40 }, | ||
657 | { 0x19, 0x00 }, | ||
658 | { 0x1a, 0x00 }, | ||
659 | { 0x1b, 0x00 }, | ||
660 | { 0x1c, 0x00 }, | ||
661 | { 0x1d, 0x00 }, | ||
662 | { 0x1e, 0x00 }, | ||
663 | { 0x1f, 0x00 }, | ||
664 | { 0x20, 0x00 }, | ||
665 | { 0x21, 0x00 }, | ||
666 | { 0x22, 0x00 }, | ||
667 | { 0x23, 0x02 }, | ||
668 | { 0x24, 0x00 }, | ||
669 | { 0x25, 0x76 }, | ||
670 | { 0x26, 0x00 }, | ||
671 | { 0x27, 0x00 }, | ||
672 | { 0x28, 0x04 }, | ||
673 | { 0x29, 0x00 }, | ||
674 | { 0x2a, 0x00 }, | ||
675 | { 0x2b, 0x30 }, | ||
676 | { 0x2c, 0x2A }, | ||
677 | { 0x83, 0x00 }, | ||
678 | { 0x84, 0x00 }, | ||
679 | { 0x85, 0x00 }, | ||
680 | { 0x86, 0x00 }, | ||
681 | { 0x87, 0x00 }, | ||
682 | { 0x88, 0x00 }, | ||
654 | }; | 683 | }; |
655 | 684 | ||
656 | static int da7210_volatile_register(struct snd_soc_codec *codec, | 685 | static bool da7210_readable_register(struct device *dev, unsigned int reg) |
686 | { | ||
687 | switch (reg) { | ||
688 | case DA7210_A_HID_UNLOCK: | ||
689 | case DA7210_A_TEST_UNLOCK: | ||
690 | case DA7210_A_PLL1: | ||
691 | case DA7210_A_CP_MODE: | ||
692 | return false; | ||
693 | default: | ||
694 | return true; | ||
695 | } | ||
696 | } | ||
697 | |||
698 | static bool da7210_volatile_register(struct device *dev, | ||
657 | unsigned int reg) | 699 | unsigned int reg) |
658 | { | 700 | { |
659 | switch (reg) { | 701 | switch (reg) { |
660 | case DA7210_STATUS: | 702 | case DA7210_STATUS: |
661 | return 1; | 703 | return true; |
662 | default: | 704 | default: |
663 | return 0; | 705 | return false; |
664 | } | 706 | } |
665 | } | 707 | } |
666 | 708 | ||
@@ -866,7 +908,8 @@ static int da7210_probe(struct snd_soc_codec *codec) | |||
866 | 908 | ||
867 | dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); | 909 | dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); |
868 | 910 | ||
869 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, da7210->control_type); | 911 | codec->control_data = da7210->regmap; |
912 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); | ||
870 | if (ret < 0) { | 913 | if (ret < 0) { |
871 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 914 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
872 | return ret; | 915 | return ret; |
@@ -983,12 +1026,14 @@ static int da7210_probe(struct snd_soc_codec *codec) | |||
983 | snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN); | 1026 | snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN); |
984 | 1027 | ||
985 | /* As suggested by Dialog */ | 1028 | /* As suggested by Dialog */ |
986 | snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */ | 1029 | /* unlock */ |
987 | snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0xB4); | 1030 | regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x8B); |
988 | snd_soc_write(codec, DA7210_A_PLL1, 0x01); | 1031 | regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0xB4); |
989 | snd_soc_write(codec, DA7210_A_CP_MODE, 0x7C); | 1032 | regmap_write(da7210->regmap, DA7210_A_PLL1, 0x01); |
990 | snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */ | 1033 | regmap_write(da7210->regmap, DA7210_A_CP_MODE, 0x7C); |
991 | snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0x00); | 1034 | /* re-lock */ |
1035 | regmap_write(da7210->regmap, DA7210_A_HID_UNLOCK, 0x00); | ||
1036 | regmap_write(da7210->regmap, DA7210_A_TEST_UNLOCK, 0x00); | ||
992 | 1037 | ||
993 | /* Activate all enabled subsystem */ | 1038 | /* Activate all enabled subsystem */ |
994 | snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); | 1039 | snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); |
@@ -1000,10 +1045,6 @@ static int da7210_probe(struct snd_soc_codec *codec) | |||
1000 | 1045 | ||
1001 | static struct snd_soc_codec_driver soc_codec_dev_da7210 = { | 1046 | static struct snd_soc_codec_driver soc_codec_dev_da7210 = { |
1002 | .probe = da7210_probe, | 1047 | .probe = da7210_probe, |
1003 | .reg_cache_size = ARRAY_SIZE(da7210_reg), | ||
1004 | .reg_word_size = sizeof(u8), | ||
1005 | .reg_cache_default = da7210_reg, | ||
1006 | .volatile_register = da7210_volatile_register, | ||
1007 | 1048 | ||
1008 | .controls = da7210_snd_controls, | 1049 | .controls = da7210_snd_controls, |
1009 | .num_controls = ARRAY_SIZE(da7210_snd_controls), | 1050 | .num_controls = ARRAY_SIZE(da7210_snd_controls), |
@@ -1014,6 +1055,17 @@ static struct snd_soc_codec_driver soc_codec_dev_da7210 = { | |||
1014 | .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), | 1055 | .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), |
1015 | }; | 1056 | }; |
1016 | 1057 | ||
1058 | static struct regmap_config da7210_regmap = { | ||
1059 | .reg_bits = 8, | ||
1060 | .val_bits = 8, | ||
1061 | |||
1062 | .reg_defaults = da7210_reg_defaults, | ||
1063 | .num_reg_defaults = ARRAY_SIZE(da7210_reg_defaults), | ||
1064 | .volatile_reg = da7210_volatile_register, | ||
1065 | .readable_reg = da7210_readable_register, | ||
1066 | .cache_type = REGCACHE_RBTREE, | ||
1067 | }; | ||
1068 | |||
1017 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1069 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
1018 | static int __devinit da7210_i2c_probe(struct i2c_client *i2c, | 1070 | static int __devinit da7210_i2c_probe(struct i2c_client *i2c, |
1019 | const struct i2c_device_id *id) | 1071 | const struct i2c_device_id *id) |
@@ -1027,16 +1079,34 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c, | |||
1027 | return -ENOMEM; | 1079 | return -ENOMEM; |
1028 | 1080 | ||
1029 | i2c_set_clientdata(i2c, da7210); | 1081 | i2c_set_clientdata(i2c, da7210); |
1030 | da7210->control_type = SND_SOC_I2C; | 1082 | |
1083 | da7210->regmap = regmap_init_i2c(i2c, &da7210_regmap); | ||
1084 | if (IS_ERR(da7210->regmap)) { | ||
1085 | ret = PTR_ERR(da7210->regmap); | ||
1086 | dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); | ||
1087 | return ret; | ||
1088 | } | ||
1031 | 1089 | ||
1032 | ret = snd_soc_register_codec(&i2c->dev, | 1090 | ret = snd_soc_register_codec(&i2c->dev, |
1033 | &soc_codec_dev_da7210, &da7210_dai, 1); | 1091 | &soc_codec_dev_da7210, &da7210_dai, 1); |
1092 | if (ret < 0) { | ||
1093 | dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); | ||
1094 | goto err_regmap; | ||
1095 | } | ||
1096 | return ret; | ||
1097 | |||
1098 | err_regmap: | ||
1099 | regmap_exit(da7210->regmap); | ||
1100 | |||
1034 | return ret; | 1101 | return ret; |
1035 | } | 1102 | } |
1036 | 1103 | ||
1037 | static int __devexit da7210_i2c_remove(struct i2c_client *client) | 1104 | static int __devexit da7210_i2c_remove(struct i2c_client *client) |
1038 | { | 1105 | { |
1106 | struct da7210_priv *da7210 = i2c_get_clientdata(client); | ||
1107 | |||
1039 | snd_soc_unregister_codec(&client->dev); | 1108 | snd_soc_unregister_codec(&client->dev); |
1109 | regmap_exit(da7210->regmap); | ||
1040 | return 0; | 1110 | return 0; |
1041 | } | 1111 | } |
1042 | 1112 | ||
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c index 319039240e0f..ba4fafb93e56 100644 --- a/sound/soc/codecs/lm4857.c +++ b/sound/soc/codecs/lm4857.c | |||
@@ -179,7 +179,7 @@ static int lm4857_probe(struct snd_soc_codec *codec) | |||
179 | 179 | ||
180 | codec->control_data = lm4857->i2c; | 180 | codec->control_data = lm4857->i2c; |
181 | 181 | ||
182 | ret = snd_soc_add_controls(codec, lm4857_controls, | 182 | ret = snd_soc_add_codec_controls(codec, lm4857_controls, |
183 | ARRAY_SIZE(lm4857_controls)); | 183 | ARRAY_SIZE(lm4857_controls)); |
184 | if (ret) | 184 | if (ret) |
185 | return ret; | 185 | return ret; |
diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c new file mode 100644 index 000000000000..17b3ec2d05cb --- /dev/null +++ b/sound/soc/codecs/max9768.c | |||
@@ -0,0 +1,247 @@ | |||
1 | /* | ||
2 | * MAX9768 AMP driver | ||
3 | * | ||
4 | * Copyright (C) 2011, 2012 by Wolfram Sang, Pengutronix e.K. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; version 2 of the License. | ||
9 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/gpio.h> | ||
16 | #include <linux/regmap.h> | ||
17 | |||
18 | #include <sound/core.h> | ||
19 | #include <sound/soc.h> | ||
20 | #include <sound/tlv.h> | ||
21 | #include <sound/max9768.h> | ||
22 | |||
23 | /* "Registers" */ | ||
24 | #define MAX9768_VOL 0 | ||
25 | #define MAX9768_CTRL 3 | ||
26 | |||
27 | /* Commands */ | ||
28 | #define MAX9768_CTRL_PWM 0x15 | ||
29 | #define MAX9768_CTRL_FILTERLESS 0x16 | ||
30 | |||
31 | struct max9768 { | ||
32 | struct regmap *regmap; | ||
33 | int mute_gpio; | ||
34 | int shdn_gpio; | ||
35 | u32 flags; | ||
36 | }; | ||
37 | |||
38 | static struct reg_default max9768_default_regs[] = { | ||
39 | { 0, 0 }, | ||
40 | { 3, MAX9768_CTRL_FILTERLESS}, | ||
41 | }; | ||
42 | |||
43 | static int max9768_get_gpio(struct snd_kcontrol *kcontrol, | ||
44 | struct snd_ctl_elem_value *ucontrol) | ||
45 | { | ||
46 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
47 | struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); | ||
48 | int val = gpio_get_value_cansleep(max9768->mute_gpio); | ||
49 | |||
50 | ucontrol->value.integer.value[0] = !val; | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static int max9768_set_gpio(struct snd_kcontrol *kcontrol, | ||
56 | struct snd_ctl_elem_value *ucontrol) | ||
57 | { | ||
58 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
59 | struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); | ||
60 | |||
61 | gpio_set_value_cansleep(max9768->mute_gpio, !ucontrol->value.integer.value[0]); | ||
62 | |||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static const unsigned int volume_tlv[] = { | ||
67 | TLV_DB_RANGE_HEAD(43), | ||
68 | 0, 0, TLV_DB_SCALE_ITEM(-16150, 0, 0), | ||
69 | 1, 1, TLV_DB_SCALE_ITEM(-9280, 0, 0), | ||
70 | 2, 2, TLV_DB_SCALE_ITEM(-9030, 0, 0), | ||
71 | 3, 3, TLV_DB_SCALE_ITEM(-8680, 0, 0), | ||
72 | 4, 4, TLV_DB_SCALE_ITEM(-8430, 0, 0), | ||
73 | 5, 5, TLV_DB_SCALE_ITEM(-8080, 0, 0), | ||
74 | 6, 6, TLV_DB_SCALE_ITEM(-7830, 0, 0), | ||
75 | 7, 7, TLV_DB_SCALE_ITEM(-7470, 0, 0), | ||
76 | 8, 8, TLV_DB_SCALE_ITEM(-7220, 0, 0), | ||
77 | 9, 9, TLV_DB_SCALE_ITEM(-6870, 0, 0), | ||
78 | 10, 10, TLV_DB_SCALE_ITEM(-6620, 0, 0), | ||
79 | 11, 11, TLV_DB_SCALE_ITEM(-6270, 0, 0), | ||
80 | 12, 12, TLV_DB_SCALE_ITEM(-6020, 0, 0), | ||
81 | 13, 13, TLV_DB_SCALE_ITEM(-5670, 0, 0), | ||
82 | 14, 14, TLV_DB_SCALE_ITEM(-5420, 0, 0), | ||
83 | 15, 17, TLV_DB_SCALE_ITEM(-5060, 250, 0), | ||
84 | 18, 18, TLV_DB_SCALE_ITEM(-4370, 0, 0), | ||
85 | 19, 19, TLV_DB_SCALE_ITEM(-4210, 0, 0), | ||
86 | 20, 20, TLV_DB_SCALE_ITEM(-3960, 0, 0), | ||
87 | 21, 21, TLV_DB_SCALE_ITEM(-3760, 0, 0), | ||
88 | 22, 22, TLV_DB_SCALE_ITEM(-3600, 0, 0), | ||
89 | 23, 23, TLV_DB_SCALE_ITEM(-3340, 0, 0), | ||
90 | 24, 24, TLV_DB_SCALE_ITEM(-3150, 0, 0), | ||
91 | 25, 25, TLV_DB_SCALE_ITEM(-2980, 0, 0), | ||
92 | 26, 26, TLV_DB_SCALE_ITEM(-2720, 0, 0), | ||
93 | 27, 27, TLV_DB_SCALE_ITEM(-2520, 0, 0), | ||
94 | 28, 30, TLV_DB_SCALE_ITEM(-2350, 190, 0), | ||
95 | 31, 31, TLV_DB_SCALE_ITEM(-1750, 0, 0), | ||
96 | 32, 34, TLV_DB_SCALE_ITEM(-1640, 100, 0), | ||
97 | 35, 37, TLV_DB_SCALE_ITEM(-1310, 110, 0), | ||
98 | 38, 39, TLV_DB_SCALE_ITEM(-990, 100, 0), | ||
99 | 40, 40, TLV_DB_SCALE_ITEM(-710, 0, 0), | ||
100 | 41, 41, TLV_DB_SCALE_ITEM(-600, 0, 0), | ||
101 | 42, 42, TLV_DB_SCALE_ITEM(-500, 0, 0), | ||
102 | 43, 43, TLV_DB_SCALE_ITEM(-340, 0, 0), | ||
103 | 44, 44, TLV_DB_SCALE_ITEM(-190, 0, 0), | ||
104 | 45, 45, TLV_DB_SCALE_ITEM(-50, 0, 0), | ||
105 | 46, 46, TLV_DB_SCALE_ITEM(50, 0, 0), | ||
106 | 47, 50, TLV_DB_SCALE_ITEM(120, 40, 0), | ||
107 | 51, 57, TLV_DB_SCALE_ITEM(290, 50, 0), | ||
108 | 58, 58, TLV_DB_SCALE_ITEM(650, 0, 0), | ||
109 | 59, 62, TLV_DB_SCALE_ITEM(700, 60, 0), | ||
110 | 63, 63, TLV_DB_SCALE_ITEM(950, 0, 0), | ||
111 | }; | ||
112 | |||
113 | static const struct snd_kcontrol_new max9768_volume[] = { | ||
114 | SOC_SINGLE_TLV("Playback Volume", MAX9768_VOL, 0, 63, 0, volume_tlv), | ||
115 | }; | ||
116 | |||
117 | static const struct snd_kcontrol_new max9768_mute[] = { | ||
118 | SOC_SINGLE_BOOL_EXT("Playback Switch", 0, max9768_get_gpio, max9768_set_gpio), | ||
119 | }; | ||
120 | |||
121 | static int max9768_probe(struct snd_soc_codec *codec) | ||
122 | { | ||
123 | struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); | ||
124 | int ret; | ||
125 | |||
126 | codec->control_data = max9768->regmap; | ||
127 | ret = snd_soc_codec_set_cache_io(codec, 2, 6, SND_SOC_REGMAP); | ||
128 | if (ret) | ||
129 | return ret; | ||
130 | |||
131 | if (max9768->flags & MAX9768_FLAG_CLASSIC_PWM) { | ||
132 | ret = snd_soc_write(codec, MAX9768_CTRL, MAX9768_CTRL_PWM); | ||
133 | if (ret) | ||
134 | return ret; | ||
135 | } | ||
136 | |||
137 | if (gpio_is_valid(max9768->mute_gpio)) { | ||
138 | ret = snd_soc_add_codec_controls(codec, max9768_mute, | ||
139 | ARRAY_SIZE(max9768_mute)); | ||
140 | if (ret) | ||
141 | return ret; | ||
142 | } | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static struct snd_soc_codec_driver max9768_codec_driver = { | ||
148 | .probe = max9768_probe, | ||
149 | .controls = max9768_volume, | ||
150 | .num_controls = ARRAY_SIZE(max9768_volume), | ||
151 | }; | ||
152 | |||
153 | static const struct regmap_config max9768_i2c_regmap_config = { | ||
154 | .reg_bits = 2, | ||
155 | .val_bits = 6, | ||
156 | .max_register = 3, | ||
157 | .reg_defaults = max9768_default_regs, | ||
158 | .num_reg_defaults = ARRAY_SIZE(max9768_default_regs), | ||
159 | .cache_type = REGCACHE_RBTREE, | ||
160 | }; | ||
161 | |||
162 | static int __devinit max9768_i2c_probe(struct i2c_client *client, | ||
163 | const struct i2c_device_id *id) | ||
164 | { | ||
165 | struct max9768 *max9768; | ||
166 | struct max9768_pdata *pdata = client->dev.platform_data; | ||
167 | int err; | ||
168 | |||
169 | max9768 = devm_kzalloc(&client->dev, sizeof(*max9768), GFP_KERNEL); | ||
170 | if (!max9768) | ||
171 | return -ENOMEM; | ||
172 | |||
173 | if (pdata) { | ||
174 | /* Mute on powerup to avoid clicks */ | ||
175 | err = gpio_request_one(pdata->mute_gpio, GPIOF_INIT_HIGH, "MAX9768 Mute"); | ||
176 | max9768->mute_gpio = err ?: pdata->mute_gpio; | ||
177 | |||
178 | /* Activate chip by releasing shutdown, enables I2C */ | ||
179 | err = gpio_request_one(pdata->shdn_gpio, GPIOF_INIT_HIGH, "MAX9768 Shutdown"); | ||
180 | max9768->shdn_gpio = err ?: pdata->shdn_gpio; | ||
181 | |||
182 | max9768->flags = pdata->flags; | ||
183 | } else { | ||
184 | max9768->shdn_gpio = -EINVAL; | ||
185 | max9768->mute_gpio = -EINVAL; | ||
186 | } | ||
187 | |||
188 | i2c_set_clientdata(client, max9768); | ||
189 | |||
190 | max9768->regmap = regmap_init_i2c(client, &max9768_i2c_regmap_config); | ||
191 | if (IS_ERR(max9768->regmap)) { | ||
192 | err = PTR_ERR(max9768->regmap); | ||
193 | goto err_gpio_free; | ||
194 | } | ||
195 | |||
196 | err = snd_soc_register_codec(&client->dev, &max9768_codec_driver, NULL, 0); | ||
197 | if (err) | ||
198 | goto err_regmap_free; | ||
199 | |||
200 | return 0; | ||
201 | |||
202 | err_regmap_free: | ||
203 | regmap_exit(max9768->regmap); | ||
204 | err_gpio_free: | ||
205 | if (gpio_is_valid(max9768->shdn_gpio)) | ||
206 | gpio_free(max9768->shdn_gpio); | ||
207 | if (gpio_is_valid(max9768->mute_gpio)) | ||
208 | gpio_free(max9768->mute_gpio); | ||
209 | |||
210 | return err; | ||
211 | } | ||
212 | |||
213 | static int __devexit max9768_i2c_remove(struct i2c_client *client) | ||
214 | { | ||
215 | struct max9768 *max9768 = i2c_get_clientdata(client); | ||
216 | |||
217 | snd_soc_unregister_codec(&client->dev); | ||
218 | regmap_exit(max9768->regmap); | ||
219 | |||
220 | if (gpio_is_valid(max9768->shdn_gpio)) | ||
221 | gpio_free(max9768->shdn_gpio); | ||
222 | if (gpio_is_valid(max9768->mute_gpio)) | ||
223 | gpio_free(max9768->mute_gpio); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | static const struct i2c_device_id max9768_i2c_id[] = { | ||
229 | { "max9768", 0 }, | ||
230 | { } | ||
231 | }; | ||
232 | MODULE_DEVICE_TABLE(i2c, max9768_i2c_id); | ||
233 | |||
234 | static struct i2c_driver max9768_i2c_driver = { | ||
235 | .driver = { | ||
236 | .name = "max9768", | ||
237 | .owner = THIS_MODULE, | ||
238 | }, | ||
239 | .probe = max9768_i2c_probe, | ||
240 | .remove = __devexit_p(max9768_i2c_remove), | ||
241 | .id_table = max9768_i2c_id, | ||
242 | }; | ||
243 | module_i2c_driver(max9768_i2c_driver); | ||
244 | |||
245 | MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>"); | ||
246 | MODULE_DESCRIPTION("ASoC MAX9768 amplifier driver"); | ||
247 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 006efcfe6dda..af7324b79dd0 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c | |||
@@ -1908,7 +1908,7 @@ static void max98088_handle_eq_pdata(struct snd_soc_codec *codec) | |||
1908 | max98088->eq_enum.texts = max98088->eq_texts; | 1908 | max98088->eq_enum.texts = max98088->eq_texts; |
1909 | max98088->eq_enum.max = max98088->eq_textcnt; | 1909 | max98088->eq_enum.max = max98088->eq_textcnt; |
1910 | 1910 | ||
1911 | ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); | 1911 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); |
1912 | if (ret != 0) | 1912 | if (ret != 0) |
1913 | dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); | 1913 | dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); |
1914 | } | 1914 | } |
@@ -2030,7 +2030,7 @@ static int max98088_probe(struct snd_soc_codec *codec) | |||
2030 | 2030 | ||
2031 | max98088_handle_pdata(codec); | 2031 | max98088_handle_pdata(codec); |
2032 | 2032 | ||
2033 | snd_soc_add_controls(codec, max98088_snd_controls, | 2033 | snd_soc_add_codec_controls(codec, max98088_snd_controls, |
2034 | ARRAY_SIZE(max98088_snd_controls)); | 2034 | ARRAY_SIZE(max98088_snd_controls)); |
2035 | 2035 | ||
2036 | err_access: | 2036 | err_access: |
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index fcfa7497d7b7..0bb511a0388d 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c | |||
@@ -1284,7 +1284,7 @@ static const struct snd_soc_dapm_route max98095_audio_map[] = { | |||
1284 | 1284 | ||
1285 | static int max98095_add_widgets(struct snd_soc_codec *codec) | 1285 | static int max98095_add_widgets(struct snd_soc_codec *codec) |
1286 | { | 1286 | { |
1287 | snd_soc_add_controls(codec, max98095_snd_controls, | 1287 | snd_soc_add_codec_controls(codec, max98095_snd_controls, |
1288 | ARRAY_SIZE(max98095_snd_controls)); | 1288 | ARRAY_SIZE(max98095_snd_controls)); |
1289 | 1289 | ||
1290 | return 0; | 1290 | return 0; |
@@ -1984,7 +1984,7 @@ static void max98095_handle_eq_pdata(struct snd_soc_codec *codec) | |||
1984 | max98095->eq_enum.texts = max98095->eq_texts; | 1984 | max98095->eq_enum.texts = max98095->eq_texts; |
1985 | max98095->eq_enum.max = max98095->eq_textcnt; | 1985 | max98095->eq_enum.max = max98095->eq_textcnt; |
1986 | 1986 | ||
1987 | ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); | 1987 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); |
1988 | if (ret != 0) | 1988 | if (ret != 0) |
1989 | dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); | 1989 | dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); |
1990 | } | 1990 | } |
@@ -2139,7 +2139,7 @@ static void max98095_handle_bq_pdata(struct snd_soc_codec *codec) | |||
2139 | max98095->bq_enum.texts = max98095->bq_texts; | 2139 | max98095->bq_enum.texts = max98095->bq_texts; |
2140 | max98095->bq_enum.max = max98095->bq_textcnt; | 2140 | max98095->bq_enum.max = max98095->bq_textcnt; |
2141 | 2141 | ||
2142 | ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); | 2142 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); |
2143 | if (ret != 0) | 2143 | if (ret != 0) |
2144 | dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret); | 2144 | dev_err(codec->dev, "Failed to add Biquad control: %d\n", ret); |
2145 | } | 2145 | } |
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c index dcf6f2a1600a..3a2ba3d8fd6d 100644 --- a/sound/soc/codecs/max9877.c +++ b/sound/soc/codecs/max9877.c | |||
@@ -253,7 +253,7 @@ static const struct snd_kcontrol_new max9877_controls[] = { | |||
253 | /* This function is called from ASoC machine driver */ | 253 | /* This function is called from ASoC machine driver */ |
254 | int max9877_add_controls(struct snd_soc_codec *codec) | 254 | int max9877_add_controls(struct snd_soc_codec *codec) |
255 | { | 255 | { |
256 | return snd_soc_add_controls(codec, max9877_controls, | 256 | return snd_soc_add_codec_controls(codec, max9877_controls, |
257 | ARRAY_SIZE(max9877_controls)); | 257 | ARRAY_SIZE(max9877_controls)); |
258 | } | 258 | } |
259 | EXPORT_SYMBOL_GPL(max9877_add_controls); | 259 | EXPORT_SYMBOL_GPL(max9877_add_controls); |
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index f8863ebb4304..d1926266fe00 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c | |||
@@ -227,7 +227,7 @@ static const struct snd_soc_dapm_widget sgtl5000_dapm_widgets[] = { | |||
227 | }; | 227 | }; |
228 | 228 | ||
229 | /* routes for sgtl5000 */ | 229 | /* routes for sgtl5000 */ |
230 | static const struct snd_soc_dapm_route audio_map[] = { | 230 | static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = { |
231 | {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */ | 231 | {"Capture Mux", "LINE_IN", "LINE_IN"}, /* line_in --> adc_mux */ |
232 | {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */ | 232 | {"Capture Mux", "MIC_IN", "MIC_IN"}, /* mic_in --> adc_mux */ |
233 | 233 | ||
@@ -987,12 +987,12 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec) | |||
987 | /* restore regular registers */ | 987 | /* restore regular registers */ |
988 | for (reg = 0; reg <= SGTL5000_CHIP_SHORT_CTRL; reg += 2) { | 988 | for (reg = 0; reg <= SGTL5000_CHIP_SHORT_CTRL; reg += 2) { |
989 | 989 | ||
990 | /* this regs depends on the others */ | 990 | /* These regs should restore in particular order */ |
991 | if (reg == SGTL5000_CHIP_ANA_POWER || | 991 | if (reg == SGTL5000_CHIP_ANA_POWER || |
992 | reg == SGTL5000_CHIP_CLK_CTRL || | 992 | reg == SGTL5000_CHIP_CLK_CTRL || |
993 | reg == SGTL5000_CHIP_LINREG_CTRL || | 993 | reg == SGTL5000_CHIP_LINREG_CTRL || |
994 | reg == SGTL5000_CHIP_LINE_OUT_CTRL || | 994 | reg == SGTL5000_CHIP_LINE_OUT_CTRL || |
995 | reg == SGTL5000_CHIP_CLK_CTRL) | 995 | reg == SGTL5000_CHIP_REF_CTRL) |
996 | continue; | 996 | continue; |
997 | 997 | ||
998 | snd_soc_write(codec, reg, cache[reg]); | 998 | snd_soc_write(codec, reg, cache[reg]); |
@@ -1003,8 +1003,17 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec) | |||
1003 | snd_soc_write(codec, reg, cache[reg]); | 1003 | snd_soc_write(codec, reg, cache[reg]); |
1004 | 1004 | ||
1005 | /* | 1005 | /* |
1006 | * restore power and other regs according | 1006 | * restore these regs according to the power setting sequence in |
1007 | * to set_power() and set_clock() | 1007 | * sgtl5000_set_power_regs() and clock setting sequence in |
1008 | * sgtl5000_set_clock(). | ||
1009 | * | ||
1010 | * The order of restore is: | ||
1011 | * 1. SGTL5000_CHIP_CLK_CTRL MCLK_FREQ bits (1:0) should be restore after | ||
1012 | * SGTL5000_CHIP_ANA_POWER PLL bits set | ||
1013 | * 2. SGTL5000_CHIP_LINREG_CTRL should be set before | ||
1014 | * SGTL5000_CHIP_ANA_POWER LINREG_D restored | ||
1015 | * 3. SGTL5000_CHIP_REF_CTRL controls Analog Ground Voltage, | ||
1016 | * prefer to resotre it after SGTL5000_CHIP_ANA_POWER restored | ||
1008 | */ | 1017 | */ |
1009 | snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, | 1018 | snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, |
1010 | cache[SGTL5000_CHIP_LINREG_CTRL]); | 1019 | cache[SGTL5000_CHIP_LINREG_CTRL]); |
@@ -1239,7 +1248,7 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) | |||
1239 | } | 1248 | } |
1240 | 1249 | ||
1241 | rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT; | 1250 | rev = (reg & SGTL5000_REVID_MASK) >> SGTL5000_REVID_SHIFT; |
1242 | dev_info(codec->dev, "sgtl5000 revision %d\n", rev); | 1251 | dev_info(codec->dev, "sgtl5000 revision 0x%x\n", rev); |
1243 | 1252 | ||
1244 | /* | 1253 | /* |
1245 | * workaround for revision 0x11 and later, | 1254 | * workaround for revision 0x11 and later, |
@@ -1344,15 +1353,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec) | |||
1344 | if (ret) | 1353 | if (ret) |
1345 | goto err; | 1354 | goto err; |
1346 | 1355 | ||
1347 | snd_soc_add_controls(codec, sgtl5000_snd_controls, | ||
1348 | ARRAY_SIZE(sgtl5000_snd_controls)); | ||
1349 | |||
1350 | snd_soc_dapm_new_controls(&codec->dapm, sgtl5000_dapm_widgets, | ||
1351 | ARRAY_SIZE(sgtl5000_dapm_widgets)); | ||
1352 | |||
1353 | snd_soc_dapm_add_routes(&codec->dapm, audio_map, | ||
1354 | ARRAY_SIZE(audio_map)); | ||
1355 | |||
1356 | snd_soc_dapm_new_widgets(&codec->dapm); | 1356 | snd_soc_dapm_new_widgets(&codec->dapm); |
1357 | 1357 | ||
1358 | return 0; | 1358 | return 0; |
@@ -1393,6 +1393,12 @@ static struct snd_soc_codec_driver sgtl5000_driver = { | |||
1393 | .reg_cache_step = 2, | 1393 | .reg_cache_step = 2, |
1394 | .reg_cache_default = sgtl5000_regs, | 1394 | .reg_cache_default = sgtl5000_regs, |
1395 | .volatile_register = sgtl5000_volatile_register, | 1395 | .volatile_register = sgtl5000_volatile_register, |
1396 | .controls = sgtl5000_snd_controls, | ||
1397 | .num_controls = ARRAY_SIZE(sgtl5000_snd_controls), | ||
1398 | .dapm_widgets = sgtl5000_dapm_widgets, | ||
1399 | .num_dapm_widgets = ARRAY_SIZE(sgtl5000_dapm_widgets), | ||
1400 | .dapm_routes = sgtl5000_dapm_routes, | ||
1401 | .num_dapm_routes = ARRAY_SIZE(sgtl5000_dapm_routes), | ||
1396 | }; | 1402 | }; |
1397 | 1403 | ||
1398 | static __devinit int sgtl5000_i2c_probe(struct i2c_client *client, | 1404 | static __devinit int sgtl5000_i2c_probe(struct i2c_client *client, |
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index f99baa0b8c39..50dbdb9357ea 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c | |||
@@ -827,8 +827,6 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec) | |||
827 | { | 827 | { |
828 | pr_debug("codec_probe called\n"); | 828 | pr_debug("codec_probe called\n"); |
829 | 829 | ||
830 | codec->dapm.idle_bias_off = 1; | ||
831 | |||
832 | /* PCM interface config | 830 | /* PCM interface config |
833 | * This sets the pcm rx slot conguration to max 6 slots | 831 | * This sets the pcm rx slot conguration to max 6 slots |
834 | * for max 4 dais (2 stereo and 2 mono) | 832 | * for max 4 dais (2 stereo and 2 mono) |
@@ -871,7 +869,7 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec) | |||
871 | snd_soc_write(codec, SN95031_SSR2, 0x10); | 869 | snd_soc_write(codec, SN95031_SSR2, 0x10); |
872 | snd_soc_write(codec, SN95031_SSR3, 0x40); | 870 | snd_soc_write(codec, SN95031_SSR3, 0x40); |
873 | 871 | ||
874 | snd_soc_add_controls(codec, sn95031_snd_controls, | 872 | snd_soc_add_codec_controls(codec, sn95031_snd_controls, |
875 | ARRAY_SIZE(sn95031_snd_controls)); | 873 | ARRAY_SIZE(sn95031_snd_controls)); |
876 | 874 | ||
877 | return 0; | 875 | return 0; |
@@ -891,6 +889,7 @@ struct snd_soc_codec_driver sn95031_codec = { | |||
891 | .read = sn95031_read, | 889 | .read = sn95031_read, |
892 | .write = sn95031_write, | 890 | .write = sn95031_write, |
893 | .set_bias_level = sn95031_set_vaud_bias, | 891 | .set_bias_level = sn95031_set_vaud_bias, |
892 | .idle_bias_off = true, | ||
894 | .dapm_widgets = sn95031_dapm_widgets, | 893 | .dapm_widgets = sn95031_dapm_widgets, |
895 | .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets), | 894 | .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets), |
896 | .dapm_routes = sn95031_audio_map, | 895 | .dapm_routes = sn95031_audio_map, |
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 333dd98af39c..de2b20544ceb 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c | |||
@@ -548,7 +548,7 @@ static int ssm2602_probe(struct snd_soc_codec *codec) | |||
548 | snd_soc_update_bits(codec, SSM2602_ROUT1V, | 548 | snd_soc_update_bits(codec, SSM2602_ROUT1V, |
549 | ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH); | 549 | ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH); |
550 | 550 | ||
551 | ret = snd_soc_add_controls(codec, ssm2602_snd_controls, | 551 | ret = snd_soc_add_codec_controls(codec, ssm2602_snd_controls, |
552 | ARRAY_SIZE(ssm2602_snd_controls)); | 552 | ARRAY_SIZE(ssm2602_snd_controls)); |
553 | if (ret) | 553 | if (ret) |
554 | return ret; | 554 | return ret; |
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index cc0566c22ec1..982e437799a8 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c | |||
@@ -355,7 +355,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec) | |||
355 | 355 | ||
356 | stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 356 | stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
357 | 357 | ||
358 | snd_soc_add_controls(codec, stac9766_snd_ac97_controls, | 358 | snd_soc_add_codec_controls(codec, stac9766_snd_ac97_controls, |
359 | ARRAY_SIZE(stac9766_snd_ac97_controls)); | 359 | ARRAY_SIZE(stac9766_snd_ac97_controls)); |
360 | 360 | ||
361 | return 0; | 361 | return 0; |
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index dfa41a96599b..16d55f91a653 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c | |||
@@ -593,7 +593,7 @@ static int tlv320aic23_probe(struct snd_soc_codec *codec) | |||
593 | 593 | ||
594 | snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1); | 594 | snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1); |
595 | 595 | ||
596 | snd_soc_add_controls(codec, tlv320aic23_snd_controls, | 596 | snd_soc_add_codec_controls(codec, tlv320aic23_snd_controls, |
597 | ARRAY_SIZE(tlv320aic23_snd_controls)); | 597 | ARRAY_SIZE(tlv320aic23_snd_controls)); |
598 | 598 | ||
599 | return 0; | 599 | return 0; |
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index a038daec682b..802064b5030d 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c | |||
@@ -389,7 +389,7 @@ static int aic26_probe(struct snd_soc_codec *codec) | |||
389 | 389 | ||
390 | /* register controls */ | 390 | /* register controls */ |
391 | dev_dbg(codec->dev, "Registering controls\n"); | 391 | dev_dbg(codec->dev, "Registering controls\n"); |
392 | err = snd_soc_add_controls(codec, aic26_snd_controls, | 392 | err = snd_soc_add_codec_controls(codec, aic26_snd_controls, |
393 | ARRAY_SIZE(aic26_snd_controls)); | 393 | ARRAY_SIZE(aic26_snd_controls)); |
394 | WARN_ON(err < 0); | 394 | WARN_ON(err < 0); |
395 | 395 | ||
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index eb401ef021fb..b0a73d37ed52 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
@@ -60,7 +60,6 @@ struct aic32x4_rate_divs { | |||
60 | 60 | ||
61 | struct aic32x4_priv { | 61 | struct aic32x4_priv { |
62 | u32 sysclk; | 62 | u32 sysclk; |
63 | s32 master; | ||
64 | u8 page_no; | 63 | u8 page_no; |
65 | void *control_data; | 64 | void *control_data; |
66 | u32 power_cfg; | 65 | u32 power_cfg; |
@@ -369,7 +368,6 @@ static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
369 | static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | 368 | static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) |
370 | { | 369 | { |
371 | struct snd_soc_codec *codec = codec_dai->codec; | 370 | struct snd_soc_codec *codec = codec_dai->codec; |
372 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | ||
373 | u8 iface_reg_1; | 371 | u8 iface_reg_1; |
374 | u8 iface_reg_2; | 372 | u8 iface_reg_2; |
375 | u8 iface_reg_3; | 373 | u8 iface_reg_3; |
@@ -384,11 +382,9 @@ static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | |||
384 | /* set master/slave audio interface */ | 382 | /* set master/slave audio interface */ |
385 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 383 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
386 | case SND_SOC_DAIFMT_CBM_CFM: | 384 | case SND_SOC_DAIFMT_CBM_CFM: |
387 | aic32x4->master = 1; | ||
388 | iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER; | 385 | iface_reg_1 |= AIC32X4_BCLKMASTER | AIC32X4_WCLKMASTER; |
389 | break; | 386 | break; |
390 | case SND_SOC_DAIFMT_CBS_CFS: | 387 | case SND_SOC_DAIFMT_CBS_CFS: |
391 | aic32x4->master = 0; | ||
392 | break; | 388 | break; |
393 | default: | 389 | default: |
394 | printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n"); | 390 | printk(KERN_ERR "aic32x4: invalid DAI master/slave interface\n"); |
@@ -526,64 +522,58 @@ static int aic32x4_mute(struct snd_soc_dai *dai, int mute) | |||
526 | static int aic32x4_set_bias_level(struct snd_soc_codec *codec, | 522 | static int aic32x4_set_bias_level(struct snd_soc_codec *codec, |
527 | enum snd_soc_bias_level level) | 523 | enum snd_soc_bias_level level) |
528 | { | 524 | { |
529 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | ||
530 | |||
531 | switch (level) { | 525 | switch (level) { |
532 | case SND_SOC_BIAS_ON: | 526 | case SND_SOC_BIAS_ON: |
533 | if (aic32x4->master) { | 527 | /* Switch on PLL */ |
534 | /* Switch on PLL */ | 528 | snd_soc_update_bits(codec, AIC32X4_PLLPR, |
535 | snd_soc_update_bits(codec, AIC32X4_PLLPR, | 529 | AIC32X4_PLLEN, AIC32X4_PLLEN); |
536 | AIC32X4_PLLEN, AIC32X4_PLLEN); | 530 | |
537 | 531 | /* Switch on NDAC Divider */ | |
538 | /* Switch on NDAC Divider */ | 532 | snd_soc_update_bits(codec, AIC32X4_NDAC, |
539 | snd_soc_update_bits(codec, AIC32X4_NDAC, | 533 | AIC32X4_NDACEN, AIC32X4_NDACEN); |
540 | AIC32X4_NDACEN, AIC32X4_NDACEN); | 534 | |
541 | 535 | /* Switch on MDAC Divider */ | |
542 | /* Switch on MDAC Divider */ | 536 | snd_soc_update_bits(codec, AIC32X4_MDAC, |
543 | snd_soc_update_bits(codec, AIC32X4_MDAC, | 537 | AIC32X4_MDACEN, AIC32X4_MDACEN); |
544 | AIC32X4_MDACEN, AIC32X4_MDACEN); | 538 | |
545 | 539 | /* Switch on NADC Divider */ | |
546 | /* Switch on NADC Divider */ | 540 | snd_soc_update_bits(codec, AIC32X4_NADC, |
547 | snd_soc_update_bits(codec, AIC32X4_NADC, | 541 | AIC32X4_NADCEN, AIC32X4_NADCEN); |
548 | AIC32X4_NADCEN, AIC32X4_NADCEN); | 542 | |
549 | 543 | /* Switch on MADC Divider */ | |
550 | /* Switch on MADC Divider */ | 544 | snd_soc_update_bits(codec, AIC32X4_MADC, |
551 | snd_soc_update_bits(codec, AIC32X4_MADC, | 545 | AIC32X4_MADCEN, AIC32X4_MADCEN); |
552 | AIC32X4_MADCEN, AIC32X4_MADCEN); | 546 | |
553 | 547 | /* Switch on BCLK_N Divider */ | |
554 | /* Switch on BCLK_N Divider */ | 548 | snd_soc_update_bits(codec, AIC32X4_BCLKN, |
555 | snd_soc_update_bits(codec, AIC32X4_BCLKN, | 549 | AIC32X4_BCLKEN, AIC32X4_BCLKEN); |
556 | AIC32X4_BCLKEN, AIC32X4_BCLKEN); | ||
557 | } | ||
558 | break; | 550 | break; |
559 | case SND_SOC_BIAS_PREPARE: | 551 | case SND_SOC_BIAS_PREPARE: |
560 | break; | 552 | break; |
561 | case SND_SOC_BIAS_STANDBY: | 553 | case SND_SOC_BIAS_STANDBY: |
562 | if (aic32x4->master) { | 554 | /* Switch off PLL */ |
563 | /* Switch off PLL */ | 555 | snd_soc_update_bits(codec, AIC32X4_PLLPR, |
564 | snd_soc_update_bits(codec, AIC32X4_PLLPR, | 556 | AIC32X4_PLLEN, 0); |
565 | AIC32X4_PLLEN, 0); | 557 | |
566 | 558 | /* Switch off NDAC Divider */ | |
567 | /* Switch off NDAC Divider */ | 559 | snd_soc_update_bits(codec, AIC32X4_NDAC, |
568 | snd_soc_update_bits(codec, AIC32X4_NDAC, | 560 | AIC32X4_NDACEN, 0); |
569 | AIC32X4_NDACEN, 0); | 561 | |
570 | 562 | /* Switch off MDAC Divider */ | |
571 | /* Switch off MDAC Divider */ | 563 | snd_soc_update_bits(codec, AIC32X4_MDAC, |
572 | snd_soc_update_bits(codec, AIC32X4_MDAC, | 564 | AIC32X4_MDACEN, 0); |
573 | AIC32X4_MDACEN, 0); | 565 | |
574 | 566 | /* Switch off NADC Divider */ | |
575 | /* Switch off NADC Divider */ | 567 | snd_soc_update_bits(codec, AIC32X4_NADC, |
576 | snd_soc_update_bits(codec, AIC32X4_NADC, | 568 | AIC32X4_NADCEN, 0); |
577 | AIC32X4_NADCEN, 0); | 569 | |
578 | 570 | /* Switch off MADC Divider */ | |
579 | /* Switch off MADC Divider */ | 571 | snd_soc_update_bits(codec, AIC32X4_MADC, |
580 | snd_soc_update_bits(codec, AIC32X4_MADC, | 572 | AIC32X4_MADCEN, 0); |
581 | AIC32X4_MADCEN, 0); | 573 | |
582 | 574 | /* Switch off BCLK_N Divider */ | |
583 | /* Switch off BCLK_N Divider */ | 575 | snd_soc_update_bits(codec, AIC32X4_BCLKN, |
584 | snd_soc_update_bits(codec, AIC32X4_BCLKN, | 576 | AIC32X4_BCLKEN, 0); |
585 | AIC32X4_BCLKEN, 0); | ||
586 | } | ||
587 | break; | 577 | break; |
588 | case SND_SOC_BIAS_OFF: | 578 | case SND_SOC_BIAS_OFF: |
589 | break; | 579 | break; |
@@ -651,9 +641,11 @@ static int aic32x4_probe(struct snd_soc_codec *codec) | |||
651 | if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) { | 641 | if (aic32x4->power_cfg & AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE) { |
652 | snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE); | 642 | snd_soc_write(codec, AIC32X4_PWRCFG, AIC32X4_AVDDWEAKDISABLE); |
653 | } | 643 | } |
654 | if (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) { | 644 | |
655 | snd_soc_write(codec, AIC32X4_LDOCTL, AIC32X4_LDOCTLEN); | 645 | tmp_reg = (aic32x4->power_cfg & AIC32X4_PWR_AIC32X4_LDO_ENABLE) ? |
656 | } | 646 | AIC32X4_LDOCTLEN : 0; |
647 | snd_soc_write(codec, AIC32X4_LDOCTL, tmp_reg); | ||
648 | |||
657 | tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE); | 649 | tmp_reg = snd_soc_read(codec, AIC32X4_CMMODE); |
658 | if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36) { | 650 | if (aic32x4->power_cfg & AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36) { |
659 | tmp_reg |= AIC32X4_LDOIN_18_36; | 651 | tmp_reg |= AIC32X4_LDOIN_18_36; |
@@ -679,7 +671,7 @@ static int aic32x4_probe(struct snd_soc_codec *codec) | |||
679 | } | 671 | } |
680 | 672 | ||
681 | aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 673 | aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
682 | snd_soc_add_controls(codec, aic32x4_snd_controls, | 674 | snd_soc_add_codec_controls(codec, aic32x4_snd_controls, |
683 | ARRAY_SIZE(aic32x4_snd_controls)); | 675 | ARRAY_SIZE(aic32x4_snd_controls)); |
684 | aic32x4_add_widgets(codec); | 676 | aic32x4_add_widgets(codec); |
685 | 677 | ||
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 492f22f8a4d7..8d20f6ec20f3 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -121,30 +121,6 @@ static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = { | |||
121 | 0x00, 0x00, 0x02, /* 100 */ | 121 | 0x00, 0x00, 0x02, /* 100 */ |
122 | }; | 122 | }; |
123 | 123 | ||
124 | /* | ||
125 | * read from the aic3x register space. Only use for this function is if | ||
126 | * wanting to read volatile bits from those registers that has both read-only | ||
127 | * and read/write bits. All other cases should use snd_soc_read. | ||
128 | */ | ||
129 | static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg, | ||
130 | u8 *value) | ||
131 | { | ||
132 | u8 *cache = codec->reg_cache; | ||
133 | |||
134 | if (codec->cache_only) | ||
135 | return -EINVAL; | ||
136 | if (reg >= AIC3X_CACHEREGNUM) | ||
137 | return -1; | ||
138 | |||
139 | codec->cache_bypass = 1; | ||
140 | *value = snd_soc_read(codec, reg); | ||
141 | codec->cache_bypass = 0; | ||
142 | |||
143 | cache[reg] = *value; | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | #define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \ | 124 | #define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \ |
149 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 125 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
150 | .info = snd_soc_info_volsw, \ | 126 | .info = snd_soc_info_volsw, \ |
@@ -1185,25 +1161,6 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec, | |||
1185 | return 0; | 1161 | return 0; |
1186 | } | 1162 | } |
1187 | 1163 | ||
1188 | void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state) | ||
1189 | { | ||
1190 | u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG; | ||
1191 | u8 bit = gpio ? 3: 0; | ||
1192 | u8 val = snd_soc_read(codec, reg) & ~(1 << bit); | ||
1193 | snd_soc_write(codec, reg, val | (!!state << bit)); | ||
1194 | } | ||
1195 | EXPORT_SYMBOL_GPL(aic3x_set_gpio); | ||
1196 | |||
1197 | int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio) | ||
1198 | { | ||
1199 | u8 reg = gpio ? AIC3X_GPIO2_REG : AIC3X_GPIO1_REG; | ||
1200 | u8 val = 0, bit = gpio ? 2 : 1; | ||
1201 | |||
1202 | aic3x_read(codec, reg, &val); | ||
1203 | return (val >> bit) & 1; | ||
1204 | } | ||
1205 | EXPORT_SYMBOL_GPL(aic3x_get_gpio); | ||
1206 | |||
1207 | void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect, | 1164 | void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect, |
1208 | int headset_debounce, int button_debounce) | 1165 | int headset_debounce, int button_debounce) |
1209 | { | 1166 | { |
@@ -1221,23 +1178,6 @@ void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect, | |||
1221 | 1178 | ||
1222 | snd_soc_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val); | 1179 | snd_soc_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val); |
1223 | } | 1180 | } |
1224 | EXPORT_SYMBOL_GPL(aic3x_set_headset_detection); | ||
1225 | |||
1226 | int aic3x_headset_detected(struct snd_soc_codec *codec) | ||
1227 | { | ||
1228 | u8 val = 0; | ||
1229 | aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val); | ||
1230 | return (val >> 4) & 1; | ||
1231 | } | ||
1232 | EXPORT_SYMBOL_GPL(aic3x_headset_detected); | ||
1233 | |||
1234 | int aic3x_button_pressed(struct snd_soc_codec *codec) | ||
1235 | { | ||
1236 | u8 val = 0; | ||
1237 | aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val); | ||
1238 | return (val >> 5) & 1; | ||
1239 | } | ||
1240 | EXPORT_SYMBOL_GPL(aic3x_button_pressed); | ||
1241 | 1181 | ||
1242 | #define AIC3X_RATES SNDRV_PCM_RATE_8000_96000 | 1182 | #define AIC3X_RATES SNDRV_PCM_RATE_8000_96000 |
1243 | #define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | 1183 | #define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ |
@@ -1377,7 +1317,6 @@ static int aic3x_probe(struct snd_soc_codec *codec) | |||
1377 | 1317 | ||
1378 | INIT_LIST_HEAD(&aic3x->list); | 1318 | INIT_LIST_HEAD(&aic3x->list); |
1379 | aic3x->codec = codec; | 1319 | aic3x->codec = codec; |
1380 | codec->dapm.idle_bias_off = 1; | ||
1381 | 1320 | ||
1382 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type); | 1321 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type); |
1383 | if (ret != 0) { | 1322 | if (ret != 0) { |
@@ -1426,10 +1365,10 @@ static int aic3x_probe(struct snd_soc_codec *codec) | |||
1426 | (aic3x->setup->gpio_func[1] & 0xf) << 4); | 1365 | (aic3x->setup->gpio_func[1] & 0xf) << 4); |
1427 | } | 1366 | } |
1428 | 1367 | ||
1429 | snd_soc_add_controls(codec, aic3x_snd_controls, | 1368 | snd_soc_add_codec_controls(codec, aic3x_snd_controls, |
1430 | ARRAY_SIZE(aic3x_snd_controls)); | 1369 | ARRAY_SIZE(aic3x_snd_controls)); |
1431 | if (aic3x->model == AIC3X_MODEL_3007) | 1370 | if (aic3x->model == AIC3X_MODEL_3007) |
1432 | snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); | 1371 | snd_soc_add_codec_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); |
1433 | 1372 | ||
1434 | aic3x_add_widgets(codec); | 1373 | aic3x_add_widgets(codec); |
1435 | list_add(&aic3x->list, &reset_list); | 1374 | list_add(&aic3x->list, &reset_list); |
@@ -1471,6 +1410,7 @@ static int aic3x_remove(struct snd_soc_codec *codec) | |||
1471 | 1410 | ||
1472 | static struct snd_soc_codec_driver soc_codec_dev_aic3x = { | 1411 | static struct snd_soc_codec_driver soc_codec_dev_aic3x = { |
1473 | .set_bias_level = aic3x_set_bias_level, | 1412 | .set_bias_level = aic3x_set_bias_level, |
1413 | .idle_bias_off = true, | ||
1474 | .reg_cache_size = ARRAY_SIZE(aic3x_reg), | 1414 | .reg_cache_size = ARRAY_SIZE(aic3x_reg), |
1475 | .reg_word_size = sizeof(u8), | 1415 | .reg_word_size = sizeof(u8), |
1476 | .reg_cache_default = aic3x_reg, | 1416 | .reg_cache_default = aic3x_reg, |
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h index 06a19784b162..6f097fb60683 100644 --- a/sound/soc/codecs/tlv320aic3x.h +++ b/sound/soc/codecs/tlv320aic3x.h | |||
@@ -212,9 +212,6 @@ | |||
212 | /* Default input volume */ | 212 | /* Default input volume */ |
213 | #define DEFAULT_GAIN 0x20 | 213 | #define DEFAULT_GAIN 0x20 |
214 | 214 | ||
215 | void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state); | ||
216 | int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio); | ||
217 | |||
218 | /* headset detection / button API */ | 215 | /* headset detection / button API */ |
219 | 216 | ||
220 | /* The AIC3x supports detection of stereo headsets (GND + left + right signal) | 217 | /* The AIC3x supports detection of stereo headsets (GND + left + right signal) |
@@ -252,10 +249,4 @@ enum { | |||
252 | #define AIC3X_BUTTON_DEBOUNCE_SHIFT 0 | 249 | #define AIC3X_BUTTON_DEBOUNCE_SHIFT 0 |
253 | #define AIC3X_BUTTON_DEBOUNCE_MASK 3 | 250 | #define AIC3X_BUTTON_DEBOUNCE_MASK 3 |
254 | 251 | ||
255 | /* see the enums above for valid parameters to this function */ | ||
256 | void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect, | ||
257 | int headset_debounce, int button_debounce); | ||
258 | int aic3x_headset_detected(struct snd_soc_codec *codec); | ||
259 | int aic3x_button_pressed(struct snd_soc_codec *codec); | ||
260 | |||
261 | #endif /* _AIC3X_H */ | 252 | #endif /* _AIC3X_H */ |
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index f0aad26cdb31..4587ddd0fbf8 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c | |||
@@ -806,8 +806,6 @@ static int dac33_startup(struct snd_pcm_substream *substream, | |||
806 | /* Stream started, save the substream pointer */ | 806 | /* Stream started, save the substream pointer */ |
807 | dac33->substream = substream; | 807 | dac33->substream = substream; |
808 | 808 | ||
809 | snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24); | ||
810 | |||
811 | return 0; | 809 | return 0; |
812 | } | 810 | } |
813 | 811 | ||
@@ -1397,7 +1395,6 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) | |||
1397 | 1395 | ||
1398 | codec->control_data = dac33->control_data; | 1396 | codec->control_data = dac33->control_data; |
1399 | codec->hw_write = (hw_write_t) i2c_master_send; | 1397 | codec->hw_write = (hw_write_t) i2c_master_send; |
1400 | codec->dapm.idle_bias_off = 1; | ||
1401 | dac33->codec = codec; | 1398 | dac33->codec = codec; |
1402 | 1399 | ||
1403 | /* Read the tlv320dac33 ID registers */ | 1400 | /* Read the tlv320dac33 ID registers */ |
@@ -1440,7 +1437,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) | |||
1440 | 1437 | ||
1441 | /* Only add the FIFO controls, if we have valid IRQ number */ | 1438 | /* Only add the FIFO controls, if we have valid IRQ number */ |
1442 | if (dac33->irq >= 0) | 1439 | if (dac33->irq >= 0) |
1443 | snd_soc_add_controls(codec, dac33_mode_snd_controls, | 1440 | snd_soc_add_codec_controls(codec, dac33_mode_snd_controls, |
1444 | ARRAY_SIZE(dac33_mode_snd_controls)); | 1441 | ARRAY_SIZE(dac33_mode_snd_controls)); |
1445 | 1442 | ||
1446 | err_power: | 1443 | err_power: |
@@ -1478,6 +1475,7 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { | |||
1478 | .read = dac33_read_reg_cache, | 1475 | .read = dac33_read_reg_cache, |
1479 | .write = dac33_write_locked, | 1476 | .write = dac33_write_locked, |
1480 | .set_bias_level = dac33_set_bias_level, | 1477 | .set_bias_level = dac33_set_bias_level, |
1478 | .idle_bias_off = true, | ||
1481 | .reg_cache_size = ARRAY_SIZE(dac33_reg), | 1479 | .reg_cache_size = ARRAY_SIZE(dac33_reg), |
1482 | .reg_word_size = sizeof(u8), | 1480 | .reg_word_size = sizeof(u8), |
1483 | .reg_cache_default = dac33_reg, | 1481 | .reg_cache_default = dac33_reg, |
@@ -1515,7 +1513,9 @@ static struct snd_soc_dai_driver dac33_dai = { | |||
1515 | .channels_min = 2, | 1513 | .channels_min = 2, |
1516 | .channels_max = 2, | 1514 | .channels_max = 2, |
1517 | .rates = DAC33_RATES, | 1515 | .rates = DAC33_RATES, |
1518 | .formats = DAC33_FORMATS,}, | 1516 | .formats = DAC33_FORMATS, |
1517 | .sig_bits = 24, | ||
1518 | }, | ||
1519 | .ops = &dac33_dai_ops, | 1519 | .ops = &dac33_dai_ops, |
1520 | }; | 1520 | }; |
1521 | 1521 | ||
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 363b99dad8e9..6fe4aa3ac544 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c | |||
@@ -351,10 +351,10 @@ int tpa6130a2_add_controls(struct snd_soc_codec *codec) | |||
351 | data = i2c_get_clientdata(tpa6130a2_client); | 351 | data = i2c_get_clientdata(tpa6130a2_client); |
352 | 352 | ||
353 | if (data->id == TPA6140A2) | 353 | if (data->id == TPA6140A2) |
354 | return snd_soc_add_controls(codec, tpa6140a2_controls, | 354 | return snd_soc_add_codec_controls(codec, tpa6140a2_controls, |
355 | ARRAY_SIZE(tpa6140a2_controls)); | 355 | ARRAY_SIZE(tpa6140a2_controls)); |
356 | else | 356 | else |
357 | return snd_soc_add_controls(codec, tpa6130a2_controls, | 357 | return snd_soc_add_codec_controls(codec, tpa6130a2_controls, |
358 | ARRAY_SIZE(tpa6130a2_controls)); | 358 | ARRAY_SIZE(tpa6130a2_controls)); |
359 | } | 359 | } |
360 | EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); | 360 | EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); |
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 18e71014cc2e..170cf9a8fc79 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -1002,8 +1002,8 @@ static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, | |||
1002 | unsigned short mask, bitmask; | 1002 | unsigned short mask, bitmask; |
1003 | 1003 | ||
1004 | if (twl4030->configured) { | 1004 | if (twl4030->configured) { |
1005 | printk(KERN_ERR "twl4030 operation mode cannot be " | 1005 | dev_err(codec->dev, |
1006 | "changed on-the-fly\n"); | 1006 | "operation mode cannot be changed on-the-fly\n"); |
1007 | return -EBUSY; | 1007 | return -EBUSY; |
1008 | } | 1008 | } |
1009 | 1009 | ||
@@ -1689,7 +1689,6 @@ static int twl4030_startup(struct snd_pcm_substream *substream, | |||
1689 | struct snd_soc_codec *codec = rtd->codec; | 1689 | struct snd_soc_codec *codec = rtd->codec; |
1690 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 1690 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
1691 | 1691 | ||
1692 | snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24); | ||
1693 | if (twl4030->master_substream) { | 1692 | if (twl4030->master_substream) { |
1694 | twl4030->slave_substream = substream; | 1693 | twl4030->slave_substream = substream; |
1695 | /* The DAI has one configuration for playback and capture, so | 1694 | /* The DAI has one configuration for playback and capture, so |
@@ -1801,7 +1800,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, | |||
1801 | mode |= TWL4030_APLL_RATE_96000; | 1800 | mode |= TWL4030_APLL_RATE_96000; |
1802 | break; | 1801 | break; |
1803 | default: | 1802 | default: |
1804 | printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n", | 1803 | dev_err(codec->dev, "%s: unknown rate %d\n", __func__, |
1805 | params_rate(params)); | 1804 | params_rate(params)); |
1806 | return -EINVAL; | 1805 | return -EINVAL; |
1807 | } | 1806 | } |
@@ -1818,7 +1817,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, | |||
1818 | format |= TWL4030_DATA_WIDTH_32S_24W; | 1817 | format |= TWL4030_DATA_WIDTH_32S_24W; |
1819 | break; | 1818 | break; |
1820 | default: | 1819 | default: |
1821 | printk(KERN_ERR "TWL4030 hw params: unknown format %d\n", | 1820 | dev_err(codec->dev, "%s: unknown format %d\n", __func__, |
1822 | params_format(params)); | 1821 | params_format(params)); |
1823 | return -EINVAL; | 1822 | return -EINVAL; |
1824 | } | 1823 | } |
@@ -1868,13 +1867,13 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
1868 | case 38400000: | 1867 | case 38400000: |
1869 | break; | 1868 | break; |
1870 | default: | 1869 | default: |
1871 | dev_err(codec->dev, "Unsupported APLL mclk: %u\n", freq); | 1870 | dev_err(codec->dev, "Unsupported HFCLKIN: %u\n", freq); |
1872 | return -EINVAL; | 1871 | return -EINVAL; |
1873 | } | 1872 | } |
1874 | 1873 | ||
1875 | if ((freq / 1000) != twl4030->sysclk) { | 1874 | if ((freq / 1000) != twl4030->sysclk) { |
1876 | dev_err(codec->dev, | 1875 | dev_err(codec->dev, |
1877 | "Mismatch in APLL mclk: %u (configured: %u)\n", | 1876 | "Mismatch in HFCLKIN: %u (configured: %u)\n", |
1878 | freq, twl4030->sysclk * 1000); | 1877 | freq, twl4030->sysclk * 1000); |
1879 | return -EINVAL; | 1878 | return -EINVAL; |
1880 | } | 1879 | } |
@@ -1984,9 +1983,9 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream, | |||
1984 | * not available. | 1983 | * not available. |
1985 | */ | 1984 | */ |
1986 | if (twl4030->sysclk != 26000) { | 1985 | if (twl4030->sysclk != 26000) { |
1987 | dev_err(codec->dev, "The board is configured for %u Hz, while" | 1986 | dev_err(codec->dev, |
1988 | "the Voice interface needs 26MHz APLL mclk\n", | 1987 | "%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n", |
1989 | twl4030->sysclk * 1000); | 1988 | __func__, twl4030->sysclk); |
1990 | return -EINVAL; | 1989 | return -EINVAL; |
1991 | } | 1990 | } |
1992 | 1991 | ||
@@ -1997,8 +1996,8 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream, | |||
1997 | & TWL4030_OPT_MODE; | 1996 | & TWL4030_OPT_MODE; |
1998 | 1997 | ||
1999 | if (mode != TWL4030_OPTION_2) { | 1998 | if (mode != TWL4030_OPTION_2) { |
2000 | printk(KERN_ERR "TWL4030 voice startup: " | 1999 | dev_err(codec->dev, "%s: the codec mode is not option2\n", |
2001 | "the codec mode is not option2\n"); | 2000 | __func__); |
2002 | return -EINVAL; | 2001 | return -EINVAL; |
2003 | } | 2002 | } |
2004 | 2003 | ||
@@ -2039,7 +2038,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, | |||
2039 | mode |= TWL4030_SEL_16K; | 2038 | mode |= TWL4030_SEL_16K; |
2040 | break; | 2039 | break; |
2041 | default: | 2040 | default: |
2042 | printk(KERN_ERR "TWL4030 voice hw params: unknown rate %d\n", | 2041 | dev_err(codec->dev, "%s: unknown rate %d\n", __func__, |
2043 | params_rate(params)); | 2042 | params_rate(params)); |
2044 | return -EINVAL; | 2043 | return -EINVAL; |
2045 | } | 2044 | } |
@@ -2068,13 +2067,14 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
2068 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 2067 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
2069 | 2068 | ||
2070 | if (freq != 26000000) { | 2069 | if (freq != 26000000) { |
2071 | dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice" | 2070 | dev_err(codec->dev, |
2072 | "interface needs 26MHz APLL mclk\n", freq); | 2071 | "%s: HFCLKIN is %u KHz, voice interface needs 26MHz\n", |
2072 | __func__, freq / 1000); | ||
2073 | return -EINVAL; | 2073 | return -EINVAL; |
2074 | } | 2074 | } |
2075 | if ((freq / 1000) != twl4030->sysclk) { | 2075 | if ((freq / 1000) != twl4030->sysclk) { |
2076 | dev_err(codec->dev, | 2076 | dev_err(codec->dev, |
2077 | "Mismatch in APLL mclk: %u (configured: %u)\n", | 2077 | "Mismatch in HFCLKIN: %u (configured: %u)\n", |
2078 | freq, twl4030->sysclk * 1000); | 2078 | freq, twl4030->sysclk * 1000); |
2079 | return -EINVAL; | 2079 | return -EINVAL; |
2080 | } | 2080 | } |
@@ -2175,13 +2175,15 @@ static struct snd_soc_dai_driver twl4030_dai[] = { | |||
2175 | .channels_min = 2, | 2175 | .channels_min = 2, |
2176 | .channels_max = 4, | 2176 | .channels_max = 4, |
2177 | .rates = TWL4030_RATES | SNDRV_PCM_RATE_96000, | 2177 | .rates = TWL4030_RATES | SNDRV_PCM_RATE_96000, |
2178 | .formats = TWL4030_FORMATS,}, | 2178 | .formats = TWL4030_FORMATS, |
2179 | .sig_bits = 24,}, | ||
2179 | .capture = { | 2180 | .capture = { |
2180 | .stream_name = "Capture", | 2181 | .stream_name = "Capture", |
2181 | .channels_min = 2, | 2182 | .channels_min = 2, |
2182 | .channels_max = 4, | 2183 | .channels_max = 4, |
2183 | .rates = TWL4030_RATES, | 2184 | .rates = TWL4030_RATES, |
2184 | .formats = TWL4030_FORMATS,}, | 2185 | .formats = TWL4030_FORMATS, |
2186 | .sig_bits = 24,}, | ||
2185 | .ops = &twl4030_dai_hifi_ops, | 2187 | .ops = &twl4030_dai_hifi_ops, |
2186 | }, | 2188 | }, |
2187 | { | 2189 | { |
@@ -2220,13 +2222,12 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec) | |||
2220 | 2222 | ||
2221 | twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); | 2223 | twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); |
2222 | if (twl4030 == NULL) { | 2224 | if (twl4030 == NULL) { |
2223 | printk("Can not allocate memroy\n"); | 2225 | dev_err(codec->dev, "Can not allocate memory\n"); |
2224 | return -ENOMEM; | 2226 | return -ENOMEM; |
2225 | } | 2227 | } |
2226 | snd_soc_codec_set_drvdata(codec, twl4030); | 2228 | snd_soc_codec_set_drvdata(codec, twl4030); |
2227 | /* Set the defaults, and power up the codec */ | 2229 | /* Set the defaults, and power up the codec */ |
2228 | twl4030->sysclk = twl4030_audio_get_mclk() / 1000; | 2230 | twl4030->sysclk = twl4030_audio_get_mclk() / 1000; |
2229 | codec->dapm.idle_bias_off = 1; | ||
2230 | 2231 | ||
2231 | twl4030_init_chip(codec); | 2232 | twl4030_init_chip(codec); |
2232 | 2233 | ||
@@ -2252,6 +2253,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { | |||
2252 | .read = twl4030_read_reg_cache, | 2253 | .read = twl4030_read_reg_cache, |
2253 | .write = twl4030_write, | 2254 | .write = twl4030_write, |
2254 | .set_bias_level = twl4030_set_bias_level, | 2255 | .set_bias_level = twl4030_set_bias_level, |
2256 | .idle_bias_off = true, | ||
2255 | .reg_cache_size = sizeof(twl4030_reg), | 2257 | .reg_cache_size = sizeof(twl4030_reg), |
2256 | .reg_word_size = sizeof(u8), | 2258 | .reg_word_size = sizeof(u8), |
2257 | .reg_cache_default = twl4030_reg, | 2259 | .reg_cache_default = twl4030_reg, |
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 5b9c79b6f65e..2d8c6b825e57 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c | |||
@@ -1052,6 +1052,19 @@ int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim) | |||
1052 | } | 1052 | } |
1053 | EXPORT_SYMBOL_GPL(twl6040_get_trim_value); | 1053 | EXPORT_SYMBOL_GPL(twl6040_get_trim_value); |
1054 | 1054 | ||
1055 | int twl6040_get_hs_step_size(struct snd_soc_codec *codec) | ||
1056 | { | ||
1057 | struct twl6040 *twl6040 = codec->control_data; | ||
1058 | |||
1059 | if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_2) | ||
1060 | /* For ES under ES_1.3 HS step is 2 mV */ | ||
1061 | return 2; | ||
1062 | else | ||
1063 | /* For ES_1.3 HS step is 1 mV */ | ||
1064 | return 1; | ||
1065 | } | ||
1066 | EXPORT_SYMBOL_GPL(twl6040_get_hs_step_size); | ||
1067 | |||
1055 | static const struct snd_kcontrol_new twl6040_snd_controls[] = { | 1068 | static const struct snd_kcontrol_new twl6040_snd_controls[] = { |
1056 | /* Capture gains */ | 1069 | /* Capture gains */ |
1057 | SOC_DOUBLE_TLV("Capture Preamplifier Volume", | 1070 | SOC_DOUBLE_TLV("Capture Preamplifier Volume", |
@@ -1125,14 +1138,14 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { | |||
1125 | TWL6040_REG_MICRCTL, 2, 0), | 1138 | TWL6040_REG_MICRCTL, 2, 0), |
1126 | 1139 | ||
1127 | /* Microphone bias */ | 1140 | /* Microphone bias */ |
1128 | SND_SOC_DAPM_MICBIAS("Headset Mic Bias", | 1141 | SND_SOC_DAPM_SUPPLY("Headset Mic Bias", |
1129 | TWL6040_REG_AMICBCTL, 0, 0), | 1142 | TWL6040_REG_AMICBCTL, 0, 0, NULL, 0), |
1130 | SND_SOC_DAPM_MICBIAS("Main Mic Bias", | 1143 | SND_SOC_DAPM_SUPPLY("Main Mic Bias", |
1131 | TWL6040_REG_AMICBCTL, 4, 0), | 1144 | TWL6040_REG_AMICBCTL, 4, 0, NULL, 0), |
1132 | SND_SOC_DAPM_MICBIAS("Digital Mic1 Bias", | 1145 | SND_SOC_DAPM_SUPPLY("Digital Mic1 Bias", |
1133 | TWL6040_REG_DMICBCTL, 0, 0), | 1146 | TWL6040_REG_DMICBCTL, 0, 0, NULL, 0), |
1134 | SND_SOC_DAPM_MICBIAS("Digital Mic2 Bias", | 1147 | SND_SOC_DAPM_SUPPLY("Digital Mic2 Bias", |
1135 | TWL6040_REG_DMICBCTL, 4, 0), | 1148 | TWL6040_REG_DMICBCTL, 4, 0, NULL, 0), |
1136 | 1149 | ||
1137 | /* DACs */ | 1150 | /* DACs */ |
1138 | SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", SND_SOC_NOPM, 0, 0), | 1151 | SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", SND_SOC_NOPM, 0, 0), |
@@ -1527,7 +1540,6 @@ static int twl6040_probe(struct snd_soc_codec *codec) | |||
1527 | 1540 | ||
1528 | priv->codec = codec; | 1541 | priv->codec = codec; |
1529 | codec->control_data = dev_get_drvdata(codec->dev->parent); | 1542 | codec->control_data = dev_get_drvdata(codec->dev->parent); |
1530 | codec->ignore_pmdown_time = 1; | ||
1531 | 1543 | ||
1532 | if (pdata && pdata->hs_left_step && pdata->hs_right_step) { | 1544 | if (pdata && pdata->hs_left_step && pdata->hs_right_step) { |
1533 | priv->hs_left_step = pdata->hs_left_step; | 1545 | priv->hs_left_step = pdata->hs_left_step; |
@@ -1613,6 +1625,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = { | |||
1613 | .reg_cache_size = ARRAY_SIZE(twl6040_reg), | 1625 | .reg_cache_size = ARRAY_SIZE(twl6040_reg), |
1614 | .reg_word_size = sizeof(u8), | 1626 | .reg_word_size = sizeof(u8), |
1615 | .reg_cache_default = twl6040_reg, | 1627 | .reg_cache_default = twl6040_reg, |
1628 | .ignore_pmdown_time = true, | ||
1616 | 1629 | ||
1617 | .controls = twl6040_snd_controls, | 1630 | .controls = twl6040_snd_controls, |
1618 | .num_controls = ARRAY_SIZE(twl6040_snd_controls), | 1631 | .num_controls = ARRAY_SIZE(twl6040_snd_controls), |
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h index ef273f1fac2f..0611406ca7c0 100644 --- a/sound/soc/codecs/twl6040.h +++ b/sound/soc/codecs/twl6040.h | |||
@@ -39,5 +39,6 @@ void twl6040_hs_jack_detect(struct snd_soc_codec *codec, | |||
39 | struct snd_soc_jack *jack, int report); | 39 | struct snd_soc_jack *jack, int report); |
40 | int twl6040_get_clk_id(struct snd_soc_codec *codec); | 40 | int twl6040_get_clk_id(struct snd_soc_codec *codec); |
41 | int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim); | 41 | int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim); |
42 | int twl6040_get_hs_step_size(struct snd_soc_codec *codec); | ||
42 | 43 | ||
43 | #endif /* End of __TWL6040_H__ */ | 44 | #endif /* End of __TWL6040_H__ */ |
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 8f4f469d6411..797b0dde2c68 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c | |||
@@ -531,15 +531,15 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) | |||
531 | switch (pd->model) { | 531 | switch (pd->model) { |
532 | case UDA134X_UDA1340: | 532 | case UDA134X_UDA1340: |
533 | case UDA134X_UDA1344: | 533 | case UDA134X_UDA1344: |
534 | ret = snd_soc_add_controls(codec, uda1340_snd_controls, | 534 | ret = snd_soc_add_codec_controls(codec, uda1340_snd_controls, |
535 | ARRAY_SIZE(uda1340_snd_controls)); | 535 | ARRAY_SIZE(uda1340_snd_controls)); |
536 | break; | 536 | break; |
537 | case UDA134X_UDA1341: | 537 | case UDA134X_UDA1341: |
538 | ret = snd_soc_add_controls(codec, uda1341_snd_controls, | 538 | ret = snd_soc_add_codec_controls(codec, uda1341_snd_controls, |
539 | ARRAY_SIZE(uda1341_snd_controls)); | 539 | ARRAY_SIZE(uda1341_snd_controls)); |
540 | break; | 540 | break; |
541 | case UDA134X_UDA1345: | 541 | case UDA134X_UDA1345: |
542 | ret = snd_soc_add_controls(codec, uda1345_snd_controls, | 542 | ret = snd_soc_add_codec_controls(codec, uda1345_snd_controls, |
543 | ARRAY_SIZE(uda1345_snd_controls)); | 543 | ARRAY_SIZE(uda1345_snd_controls)); |
544 | break; | 544 | break; |
545 | default: | 545 | default: |
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index 44aacf927ba9..3d868dc40092 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c | |||
@@ -464,7 +464,7 @@ static int wl1273_probe(struct snd_soc_codec *codec) | |||
464 | 464 | ||
465 | snd_soc_codec_set_drvdata(codec, wl1273); | 465 | snd_soc_codec_set_drvdata(codec, wl1273); |
466 | 466 | ||
467 | r = snd_soc_add_controls(codec, wl1273_controls, | 467 | r = snd_soc_add_codec_controls(codec, wl1273_controls, |
468 | ARRAY_SIZE(wl1273_controls)); | 468 | ARRAY_SIZE(wl1273_controls)); |
469 | if (r) | 469 | if (r) |
470 | kfree(wl1273); | 470 | kfree(wl1273); |
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index c2880907fced..a75c3766aede 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -733,8 +733,9 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
733 | struct wm2000_priv *wm2000; | 733 | struct wm2000_priv *wm2000; |
734 | struct wm2000_platform_data *pdata; | 734 | struct wm2000_platform_data *pdata; |
735 | const char *filename; | 735 | const char *filename; |
736 | const struct firmware *fw; | 736 | const struct firmware *fw = NULL; |
737 | int reg, ret; | 737 | int ret; |
738 | int reg; | ||
738 | u16 id; | 739 | u16 id; |
739 | 740 | ||
740 | wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv), | 741 | wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv), |
@@ -751,7 +752,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
751 | ret = PTR_ERR(wm2000->regmap); | 752 | ret = PTR_ERR(wm2000->regmap); |
752 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 753 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
753 | ret); | 754 | ret); |
754 | goto err; | 755 | goto out; |
755 | } | 756 | } |
756 | 757 | ||
757 | /* Verify that this is a WM2000 */ | 758 | /* Verify that this is a WM2000 */ |
@@ -763,7 +764,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
763 | if (id != 0x2000) { | 764 | if (id != 0x2000) { |
764 | dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); | 765 | dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id); |
765 | ret = -ENODEV; | 766 | ret = -ENODEV; |
766 | goto err_regmap; | 767 | goto out_regmap_exit; |
767 | } | 768 | } |
768 | 769 | ||
769 | reg = wm2000_read(i2c, WM2000_REG_REVISON); | 770 | reg = wm2000_read(i2c, WM2000_REG_REVISON); |
@@ -782,7 +783,7 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
782 | ret = request_firmware(&fw, filename, &i2c->dev); | 783 | ret = request_firmware(&fw, filename, &i2c->dev); |
783 | if (ret != 0) { | 784 | if (ret != 0) { |
784 | dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); | 785 | dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); |
785 | goto err_regmap; | 786 | goto out_regmap_exit; |
786 | } | 787 | } |
787 | 788 | ||
788 | /* Pre-cook the concatenation of the register address onto the image */ | 789 | /* Pre-cook the concatenation of the register address onto the image */ |
@@ -793,15 +794,13 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
793 | if (wm2000->anc_download == NULL) { | 794 | if (wm2000->anc_download == NULL) { |
794 | dev_err(&i2c->dev, "Out of memory\n"); | 795 | dev_err(&i2c->dev, "Out of memory\n"); |
795 | ret = -ENOMEM; | 796 | ret = -ENOMEM; |
796 | goto err_fw; | 797 | goto out_regmap_exit; |
797 | } | 798 | } |
798 | 799 | ||
799 | wm2000->anc_download[0] = 0x80; | 800 | wm2000->anc_download[0] = 0x80; |
800 | wm2000->anc_download[1] = 0x00; | 801 | wm2000->anc_download[1] = 0x00; |
801 | memcpy(wm2000->anc_download + 2, fw->data, fw->size); | 802 | memcpy(wm2000->anc_download + 2, fw->data, fw->size); |
802 | 803 | ||
803 | release_firmware(fw); | ||
804 | |||
805 | wm2000->anc_eng_ena = 1; | 804 | wm2000->anc_eng_ena = 1; |
806 | wm2000->anc_active = 1; | 805 | wm2000->anc_active = 1; |
807 | wm2000->spk_ena = 1; | 806 | wm2000->spk_ena = 1; |
@@ -809,18 +808,14 @@ static int __devinit wm2000_i2c_probe(struct i2c_client *i2c, | |||
809 | 808 | ||
810 | wm2000_reset(wm2000); | 809 | wm2000_reset(wm2000); |
811 | 810 | ||
812 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, | 811 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm2000, NULL, 0); |
813 | NULL, 0); | 812 | if (!ret) |
814 | if (ret != 0) | 813 | goto out; |
815 | goto err_fw; | ||
816 | 814 | ||
817 | return 0; | 815 | out_regmap_exit: |
818 | |||
819 | err_fw: | ||
820 | release_firmware(fw); | ||
821 | err_regmap: | ||
822 | regmap_exit(wm2000->regmap); | 816 | regmap_exit(wm2000->regmap); |
823 | err: | 817 | out: |
818 | release_firmware(fw); | ||
824 | return ret; | 819 | return ret; |
825 | } | 820 | } |
826 | 821 | ||
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c new file mode 100644 index 000000000000..acbdc5fde923 --- /dev/null +++ b/sound/soc/codecs/wm2200.c | |||
@@ -0,0 +1,2286 @@ | |||
1 | /* | ||
2 | * wm2200.c -- WM2200 ALSA SoC Audio driver | ||
3 | * | ||
4 | * Copyright 2012 Wolfson Microelectronics plc | ||
5 | * | ||
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/moduleparam.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/pm.h> | ||
18 | #include <linux/gcd.h> | ||
19 | #include <linux/gpio.h> | ||
20 | #include <linux/i2c.h> | ||
21 | #include <linux/pm_runtime.h> | ||
22 | #include <linux/regulator/consumer.h> | ||
23 | #include <linux/regulator/fixed.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <sound/core.h> | ||
26 | #include <sound/pcm.h> | ||
27 | #include <sound/pcm_params.h> | ||
28 | #include <sound/soc.h> | ||
29 | #include <sound/jack.h> | ||
30 | #include <sound/initval.h> | ||
31 | #include <sound/tlv.h> | ||
32 | #include <sound/wm2200.h> | ||
33 | |||
34 | #include "wm2200.h" | ||
35 | |||
36 | /* The code assumes DCVDD is generated internally */ | ||
37 | #define WM2200_NUM_CORE_SUPPLIES 2 | ||
38 | static const char *wm2200_core_supply_names[WM2200_NUM_CORE_SUPPLIES] = { | ||
39 | "DBVDD", | ||
40 | "LDOVDD", | ||
41 | }; | ||
42 | |||
43 | struct wm2200_fll { | ||
44 | int fref; | ||
45 | int fout; | ||
46 | int src; | ||
47 | struct completion lock; | ||
48 | }; | ||
49 | |||
50 | /* codec private data */ | ||
51 | struct wm2200_priv { | ||
52 | struct regmap *regmap; | ||
53 | struct device *dev; | ||
54 | struct snd_soc_codec *codec; | ||
55 | struct wm2200_pdata pdata; | ||
56 | struct regulator_bulk_data core_supplies[WM2200_NUM_CORE_SUPPLIES]; | ||
57 | |||
58 | struct completion fll_lock; | ||
59 | int fll_fout; | ||
60 | int fll_fref; | ||
61 | int fll_src; | ||
62 | |||
63 | int rev; | ||
64 | int sysclk; | ||
65 | }; | ||
66 | |||
67 | static struct reg_default wm2200_reg_defaults[] = { | ||
68 | { 0x000B, 0x0000 }, /* R11 - Tone Generator 1 */ | ||
69 | { 0x0102, 0x0000 }, /* R258 - Clocking 3 */ | ||
70 | { 0x0103, 0x0011 }, /* R259 - Clocking 4 */ | ||
71 | { 0x0111, 0x0000 }, /* R273 - FLL Control 1 */ | ||
72 | { 0x0112, 0x0000 }, /* R274 - FLL Control 2 */ | ||
73 | { 0x0113, 0x0000 }, /* R275 - FLL Control 3 */ | ||
74 | { 0x0114, 0x0000 }, /* R276 - FLL Control 4 */ | ||
75 | { 0x0116, 0x0177 }, /* R278 - FLL Control 6 */ | ||
76 | { 0x0117, 0x0004 }, /* R279 - FLL Control 7 */ | ||
77 | { 0x0119, 0x0000 }, /* R281 - FLL EFS 1 */ | ||
78 | { 0x011A, 0x0002 }, /* R282 - FLL EFS 2 */ | ||
79 | { 0x0200, 0x0000 }, /* R512 - Mic Charge Pump 1 */ | ||
80 | { 0x0201, 0x03FF }, /* R513 - Mic Charge Pump 2 */ | ||
81 | { 0x0202, 0x9BDE }, /* R514 - DM Charge Pump 1 */ | ||
82 | { 0x020C, 0x0000 }, /* R524 - Mic Bias Ctrl 1 */ | ||
83 | { 0x020D, 0x0000 }, /* R525 - Mic Bias Ctrl 2 */ | ||
84 | { 0x020F, 0x0000 }, /* R527 - Ear Piece Ctrl 1 */ | ||
85 | { 0x0210, 0x0000 }, /* R528 - Ear Piece Ctrl 2 */ | ||
86 | { 0x0301, 0x0000 }, /* R769 - Input Enables */ | ||
87 | { 0x0302, 0x2240 }, /* R770 - IN1L Control */ | ||
88 | { 0x0303, 0x0040 }, /* R771 - IN1R Control */ | ||
89 | { 0x0304, 0x2240 }, /* R772 - IN2L Control */ | ||
90 | { 0x0305, 0x0040 }, /* R773 - IN2R Control */ | ||
91 | { 0x0306, 0x2240 }, /* R774 - IN3L Control */ | ||
92 | { 0x0307, 0x0040 }, /* R775 - IN3R Control */ | ||
93 | { 0x030A, 0x0000 }, /* R778 - RXANC_SRC */ | ||
94 | { 0x030B, 0x0022 }, /* R779 - Input Volume Ramp */ | ||
95 | { 0x030C, 0x0180 }, /* R780 - ADC Digital Volume 1L */ | ||
96 | { 0x030D, 0x0180 }, /* R781 - ADC Digital Volume 1R */ | ||
97 | { 0x030E, 0x0180 }, /* R782 - ADC Digital Volume 2L */ | ||
98 | { 0x030F, 0x0180 }, /* R783 - ADC Digital Volume 2R */ | ||
99 | { 0x0310, 0x0180 }, /* R784 - ADC Digital Volume 3L */ | ||
100 | { 0x0311, 0x0180 }, /* R785 - ADC Digital Volume 3R */ | ||
101 | { 0x0400, 0x0000 }, /* R1024 - Output Enables */ | ||
102 | { 0x0401, 0x0000 }, /* R1025 - DAC Volume Limit 1L */ | ||
103 | { 0x0402, 0x0000 }, /* R1026 - DAC Volume Limit 1R */ | ||
104 | { 0x0403, 0x0000 }, /* R1027 - DAC Volume Limit 2L */ | ||
105 | { 0x0404, 0x0000 }, /* R1028 - DAC Volume Limit 2R */ | ||
106 | { 0x0409, 0x0000 }, /* R1033 - DAC AEC Control 1 */ | ||
107 | { 0x040A, 0x0022 }, /* R1034 - Output Volume Ramp */ | ||
108 | { 0x040B, 0x0180 }, /* R1035 - DAC Digital Volume 1L */ | ||
109 | { 0x040C, 0x0180 }, /* R1036 - DAC Digital Volume 1R */ | ||
110 | { 0x040D, 0x0180 }, /* R1037 - DAC Digital Volume 2L */ | ||
111 | { 0x040E, 0x0180 }, /* R1038 - DAC Digital Volume 2R */ | ||
112 | { 0x0417, 0x0069 }, /* R1047 - PDM 1 */ | ||
113 | { 0x0418, 0x0000 }, /* R1048 - PDM 2 */ | ||
114 | { 0x0500, 0x0000 }, /* R1280 - Audio IF 1_1 */ | ||
115 | { 0x0501, 0x0008 }, /* R1281 - Audio IF 1_2 */ | ||
116 | { 0x0502, 0x0000 }, /* R1282 - Audio IF 1_3 */ | ||
117 | { 0x0503, 0x0000 }, /* R1283 - Audio IF 1_4 */ | ||
118 | { 0x0504, 0x0000 }, /* R1284 - Audio IF 1_5 */ | ||
119 | { 0x0505, 0x0001 }, /* R1285 - Audio IF 1_6 */ | ||
120 | { 0x0506, 0x0001 }, /* R1286 - Audio IF 1_7 */ | ||
121 | { 0x0507, 0x0000 }, /* R1287 - Audio IF 1_8 */ | ||
122 | { 0x0508, 0x0000 }, /* R1288 - Audio IF 1_9 */ | ||
123 | { 0x0509, 0x0000 }, /* R1289 - Audio IF 1_10 */ | ||
124 | { 0x050A, 0x0000 }, /* R1290 - Audio IF 1_11 */ | ||
125 | { 0x050B, 0x0000 }, /* R1291 - Audio IF 1_12 */ | ||
126 | { 0x050C, 0x0000 }, /* R1292 - Audio IF 1_13 */ | ||
127 | { 0x050D, 0x0000 }, /* R1293 - Audio IF 1_14 */ | ||
128 | { 0x050E, 0x0000 }, /* R1294 - Audio IF 1_15 */ | ||
129 | { 0x050F, 0x0000 }, /* R1295 - Audio IF 1_16 */ | ||
130 | { 0x0510, 0x0000 }, /* R1296 - Audio IF 1_17 */ | ||
131 | { 0x0511, 0x0000 }, /* R1297 - Audio IF 1_18 */ | ||
132 | { 0x0512, 0x0000 }, /* R1298 - Audio IF 1_19 */ | ||
133 | { 0x0513, 0x0000 }, /* R1299 - Audio IF 1_20 */ | ||
134 | { 0x0514, 0x0000 }, /* R1300 - Audio IF 1_21 */ | ||
135 | { 0x0515, 0x0001 }, /* R1301 - Audio IF 1_22 */ | ||
136 | { 0x0600, 0x0000 }, /* R1536 - OUT1LMIX Input 1 Source */ | ||
137 | { 0x0601, 0x0080 }, /* R1537 - OUT1LMIX Input 1 Volume */ | ||
138 | { 0x0602, 0x0000 }, /* R1538 - OUT1LMIX Input 2 Source */ | ||
139 | { 0x0603, 0x0080 }, /* R1539 - OUT1LMIX Input 2 Volume */ | ||
140 | { 0x0604, 0x0000 }, /* R1540 - OUT1LMIX Input 3 Source */ | ||
141 | { 0x0605, 0x0080 }, /* R1541 - OUT1LMIX Input 3 Volume */ | ||
142 | { 0x0606, 0x0000 }, /* R1542 - OUT1LMIX Input 4 Source */ | ||
143 | { 0x0607, 0x0080 }, /* R1543 - OUT1LMIX Input 4 Volume */ | ||
144 | { 0x0608, 0x0000 }, /* R1544 - OUT1RMIX Input 1 Source */ | ||
145 | { 0x0609, 0x0080 }, /* R1545 - OUT1RMIX Input 1 Volume */ | ||
146 | { 0x060A, 0x0000 }, /* R1546 - OUT1RMIX Input 2 Source */ | ||
147 | { 0x060B, 0x0080 }, /* R1547 - OUT1RMIX Input 2 Volume */ | ||
148 | { 0x060C, 0x0000 }, /* R1548 - OUT1RMIX Input 3 Source */ | ||
149 | { 0x060D, 0x0080 }, /* R1549 - OUT1RMIX Input 3 Volume */ | ||
150 | { 0x060E, 0x0000 }, /* R1550 - OUT1RMIX Input 4 Source */ | ||
151 | { 0x060F, 0x0080 }, /* R1551 - OUT1RMIX Input 4 Volume */ | ||
152 | { 0x0610, 0x0000 }, /* R1552 - OUT2LMIX Input 1 Source */ | ||
153 | { 0x0611, 0x0080 }, /* R1553 - OUT2LMIX Input 1 Volume */ | ||
154 | { 0x0612, 0x0000 }, /* R1554 - OUT2LMIX Input 2 Source */ | ||
155 | { 0x0613, 0x0080 }, /* R1555 - OUT2LMIX Input 2 Volume */ | ||
156 | { 0x0614, 0x0000 }, /* R1556 - OUT2LMIX Input 3 Source */ | ||
157 | { 0x0615, 0x0080 }, /* R1557 - OUT2LMIX Input 3 Volume */ | ||
158 | { 0x0616, 0x0000 }, /* R1558 - OUT2LMIX Input 4 Source */ | ||
159 | { 0x0617, 0x0080 }, /* R1559 - OUT2LMIX Input 4 Volume */ | ||
160 | { 0x0618, 0x0000 }, /* R1560 - OUT2RMIX Input 1 Source */ | ||
161 | { 0x0619, 0x0080 }, /* R1561 - OUT2RMIX Input 1 Volume */ | ||
162 | { 0x061A, 0x0000 }, /* R1562 - OUT2RMIX Input 2 Source */ | ||
163 | { 0x061B, 0x0080 }, /* R1563 - OUT2RMIX Input 2 Volume */ | ||
164 | { 0x061C, 0x0000 }, /* R1564 - OUT2RMIX Input 3 Source */ | ||
165 | { 0x061D, 0x0080 }, /* R1565 - OUT2RMIX Input 3 Volume */ | ||
166 | { 0x061E, 0x0000 }, /* R1566 - OUT2RMIX Input 4 Source */ | ||
167 | { 0x061F, 0x0080 }, /* R1567 - OUT2RMIX Input 4 Volume */ | ||
168 | { 0x0620, 0x0000 }, /* R1568 - AIF1TX1MIX Input 1 Source */ | ||
169 | { 0x0621, 0x0080 }, /* R1569 - AIF1TX1MIX Input 1 Volume */ | ||
170 | { 0x0622, 0x0000 }, /* R1570 - AIF1TX1MIX Input 2 Source */ | ||
171 | { 0x0623, 0x0080 }, /* R1571 - AIF1TX1MIX Input 2 Volume */ | ||
172 | { 0x0624, 0x0000 }, /* R1572 - AIF1TX1MIX Input 3 Source */ | ||
173 | { 0x0625, 0x0080 }, /* R1573 - AIF1TX1MIX Input 3 Volume */ | ||
174 | { 0x0626, 0x0000 }, /* R1574 - AIF1TX1MIX Input 4 Source */ | ||
175 | { 0x0627, 0x0080 }, /* R1575 - AIF1TX1MIX Input 4 Volume */ | ||
176 | { 0x0628, 0x0000 }, /* R1576 - AIF1TX2MIX Input 1 Source */ | ||
177 | { 0x0629, 0x0080 }, /* R1577 - AIF1TX2MIX Input 1 Volume */ | ||
178 | { 0x062A, 0x0000 }, /* R1578 - AIF1TX2MIX Input 2 Source */ | ||
179 | { 0x062B, 0x0080 }, /* R1579 - AIF1TX2MIX Input 2 Volume */ | ||
180 | { 0x062C, 0x0000 }, /* R1580 - AIF1TX2MIX Input 3 Source */ | ||
181 | { 0x062D, 0x0080 }, /* R1581 - AIF1TX2MIX Input 3 Volume */ | ||
182 | { 0x062E, 0x0000 }, /* R1582 - AIF1TX2MIX Input 4 Source */ | ||
183 | { 0x062F, 0x0080 }, /* R1583 - AIF1TX2MIX Input 4 Volume */ | ||
184 | { 0x0630, 0x0000 }, /* R1584 - AIF1TX3MIX Input 1 Source */ | ||
185 | { 0x0631, 0x0080 }, /* R1585 - AIF1TX3MIX Input 1 Volume */ | ||
186 | { 0x0632, 0x0000 }, /* R1586 - AIF1TX3MIX Input 2 Source */ | ||
187 | { 0x0633, 0x0080 }, /* R1587 - AIF1TX3MIX Input 2 Volume */ | ||
188 | { 0x0634, 0x0000 }, /* R1588 - AIF1TX3MIX Input 3 Source */ | ||
189 | { 0x0635, 0x0080 }, /* R1589 - AIF1TX3MIX Input 3 Volume */ | ||
190 | { 0x0636, 0x0000 }, /* R1590 - AIF1TX3MIX Input 4 Source */ | ||
191 | { 0x0637, 0x0080 }, /* R1591 - AIF1TX3MIX Input 4 Volume */ | ||
192 | { 0x0638, 0x0000 }, /* R1592 - AIF1TX4MIX Input 1 Source */ | ||
193 | { 0x0639, 0x0080 }, /* R1593 - AIF1TX4MIX Input 1 Volume */ | ||
194 | { 0x063A, 0x0000 }, /* R1594 - AIF1TX4MIX Input 2 Source */ | ||
195 | { 0x063B, 0x0080 }, /* R1595 - AIF1TX4MIX Input 2 Volume */ | ||
196 | { 0x063C, 0x0000 }, /* R1596 - AIF1TX4MIX Input 3 Source */ | ||
197 | { 0x063D, 0x0080 }, /* R1597 - AIF1TX4MIX Input 3 Volume */ | ||
198 | { 0x063E, 0x0000 }, /* R1598 - AIF1TX4MIX Input 4 Source */ | ||
199 | { 0x063F, 0x0080 }, /* R1599 - AIF1TX4MIX Input 4 Volume */ | ||
200 | { 0x0640, 0x0000 }, /* R1600 - AIF1TX5MIX Input 1 Source */ | ||
201 | { 0x0641, 0x0080 }, /* R1601 - AIF1TX5MIX Input 1 Volume */ | ||
202 | { 0x0642, 0x0000 }, /* R1602 - AIF1TX5MIX Input 2 Source */ | ||
203 | { 0x0643, 0x0080 }, /* R1603 - AIF1TX5MIX Input 2 Volume */ | ||
204 | { 0x0644, 0x0000 }, /* R1604 - AIF1TX5MIX Input 3 Source */ | ||
205 | { 0x0645, 0x0080 }, /* R1605 - AIF1TX5MIX Input 3 Volume */ | ||
206 | { 0x0646, 0x0000 }, /* R1606 - AIF1TX5MIX Input 4 Source */ | ||
207 | { 0x0647, 0x0080 }, /* R1607 - AIF1TX5MIX Input 4 Volume */ | ||
208 | { 0x0648, 0x0000 }, /* R1608 - AIF1TX6MIX Input 1 Source */ | ||
209 | { 0x0649, 0x0080 }, /* R1609 - AIF1TX6MIX Input 1 Volume */ | ||
210 | { 0x064A, 0x0000 }, /* R1610 - AIF1TX6MIX Input 2 Source */ | ||
211 | { 0x064B, 0x0080 }, /* R1611 - AIF1TX6MIX Input 2 Volume */ | ||
212 | { 0x064C, 0x0000 }, /* R1612 - AIF1TX6MIX Input 3 Source */ | ||
213 | { 0x064D, 0x0080 }, /* R1613 - AIF1TX6MIX Input 3 Volume */ | ||
214 | { 0x064E, 0x0000 }, /* R1614 - AIF1TX6MIX Input 4 Source */ | ||
215 | { 0x064F, 0x0080 }, /* R1615 - AIF1TX6MIX Input 4 Volume */ | ||
216 | { 0x0650, 0x0000 }, /* R1616 - EQLMIX Input 1 Source */ | ||
217 | { 0x0651, 0x0080 }, /* R1617 - EQLMIX Input 1 Volume */ | ||
218 | { 0x0652, 0x0000 }, /* R1618 - EQLMIX Input 2 Source */ | ||
219 | { 0x0653, 0x0080 }, /* R1619 - EQLMIX Input 2 Volume */ | ||
220 | { 0x0654, 0x0000 }, /* R1620 - EQLMIX Input 3 Source */ | ||
221 | { 0x0655, 0x0080 }, /* R1621 - EQLMIX Input 3 Volume */ | ||
222 | { 0x0656, 0x0000 }, /* R1622 - EQLMIX Input 4 Source */ | ||
223 | { 0x0657, 0x0080 }, /* R1623 - EQLMIX Input 4 Volume */ | ||
224 | { 0x0658, 0x0000 }, /* R1624 - EQRMIX Input 1 Source */ | ||
225 | { 0x0659, 0x0080 }, /* R1625 - EQRMIX Input 1 Volume */ | ||
226 | { 0x065A, 0x0000 }, /* R1626 - EQRMIX Input 2 Source */ | ||
227 | { 0x065B, 0x0080 }, /* R1627 - EQRMIX Input 2 Volume */ | ||
228 | { 0x065C, 0x0000 }, /* R1628 - EQRMIX Input 3 Source */ | ||
229 | { 0x065D, 0x0080 }, /* R1629 - EQRMIX Input 3 Volume */ | ||
230 | { 0x065E, 0x0000 }, /* R1630 - EQRMIX Input 4 Source */ | ||
231 | { 0x065F, 0x0080 }, /* R1631 - EQRMIX Input 4 Volume */ | ||
232 | { 0x0660, 0x0000 }, /* R1632 - LHPF1MIX Input 1 Source */ | ||
233 | { 0x0661, 0x0080 }, /* R1633 - LHPF1MIX Input 1 Volume */ | ||
234 | { 0x0662, 0x0000 }, /* R1634 - LHPF1MIX Input 2 Source */ | ||
235 | { 0x0663, 0x0080 }, /* R1635 - LHPF1MIX Input 2 Volume */ | ||
236 | { 0x0664, 0x0000 }, /* R1636 - LHPF1MIX Input 3 Source */ | ||
237 | { 0x0665, 0x0080 }, /* R1637 - LHPF1MIX Input 3 Volume */ | ||
238 | { 0x0666, 0x0000 }, /* R1638 - LHPF1MIX Input 4 Source */ | ||
239 | { 0x0667, 0x0080 }, /* R1639 - LHPF1MIX Input 4 Volume */ | ||
240 | { 0x0668, 0x0000 }, /* R1640 - LHPF2MIX Input 1 Source */ | ||
241 | { 0x0669, 0x0080 }, /* R1641 - LHPF2MIX Input 1 Volume */ | ||
242 | { 0x066A, 0x0000 }, /* R1642 - LHPF2MIX Input 2 Source */ | ||
243 | { 0x066B, 0x0080 }, /* R1643 - LHPF2MIX Input 2 Volume */ | ||
244 | { 0x066C, 0x0000 }, /* R1644 - LHPF2MIX Input 3 Source */ | ||
245 | { 0x066D, 0x0080 }, /* R1645 - LHPF2MIX Input 3 Volume */ | ||
246 | { 0x066E, 0x0000 }, /* R1646 - LHPF2MIX Input 4 Source */ | ||
247 | { 0x066F, 0x0080 }, /* R1647 - LHPF2MIX Input 4 Volume */ | ||
248 | { 0x0670, 0x0000 }, /* R1648 - DSP1LMIX Input 1 Source */ | ||
249 | { 0x0671, 0x0080 }, /* R1649 - DSP1LMIX Input 1 Volume */ | ||
250 | { 0x0672, 0x0000 }, /* R1650 - DSP1LMIX Input 2 Source */ | ||
251 | { 0x0673, 0x0080 }, /* R1651 - DSP1LMIX Input 2 Volume */ | ||
252 | { 0x0674, 0x0000 }, /* R1652 - DSP1LMIX Input 3 Source */ | ||
253 | { 0x0675, 0x0080 }, /* R1653 - DSP1LMIX Input 3 Volume */ | ||
254 | { 0x0676, 0x0000 }, /* R1654 - DSP1LMIX Input 4 Source */ | ||
255 | { 0x0677, 0x0080 }, /* R1655 - DSP1LMIX Input 4 Volume */ | ||
256 | { 0x0678, 0x0000 }, /* R1656 - DSP1RMIX Input 1 Source */ | ||
257 | { 0x0679, 0x0080 }, /* R1657 - DSP1RMIX Input 1 Volume */ | ||
258 | { 0x067A, 0x0000 }, /* R1658 - DSP1RMIX Input 2 Source */ | ||
259 | { 0x067B, 0x0080 }, /* R1659 - DSP1RMIX Input 2 Volume */ | ||
260 | { 0x067C, 0x0000 }, /* R1660 - DSP1RMIX Input 3 Source */ | ||
261 | { 0x067D, 0x0080 }, /* R1661 - DSP1RMIX Input 3 Volume */ | ||
262 | { 0x067E, 0x0000 }, /* R1662 - DSP1RMIX Input 4 Source */ | ||
263 | { 0x067F, 0x0080 }, /* R1663 - DSP1RMIX Input 4 Volume */ | ||
264 | { 0x0680, 0x0000 }, /* R1664 - DSP1AUX1MIX Input 1 Source */ | ||
265 | { 0x0681, 0x0000 }, /* R1665 - DSP1AUX2MIX Input 1 Source */ | ||
266 | { 0x0682, 0x0000 }, /* R1666 - DSP1AUX3MIX Input 1 Source */ | ||
267 | { 0x0683, 0x0000 }, /* R1667 - DSP1AUX4MIX Input 1 Source */ | ||
268 | { 0x0684, 0x0000 }, /* R1668 - DSP1AUX5MIX Input 1 Source */ | ||
269 | { 0x0685, 0x0000 }, /* R1669 - DSP1AUX6MIX Input 1 Source */ | ||
270 | { 0x0686, 0x0000 }, /* R1670 - DSP2LMIX Input 1 Source */ | ||
271 | { 0x0687, 0x0080 }, /* R1671 - DSP2LMIX Input 1 Volume */ | ||
272 | { 0x0688, 0x0000 }, /* R1672 - DSP2LMIX Input 2 Source */ | ||
273 | { 0x0689, 0x0080 }, /* R1673 - DSP2LMIX Input 2 Volume */ | ||
274 | { 0x068A, 0x0000 }, /* R1674 - DSP2LMIX Input 3 Source */ | ||
275 | { 0x068B, 0x0080 }, /* R1675 - DSP2LMIX Input 3 Volume */ | ||
276 | { 0x068C, 0x0000 }, /* R1676 - DSP2LMIX Input 4 Source */ | ||
277 | { 0x068D, 0x0080 }, /* R1677 - DSP2LMIX Input 4 Volume */ | ||
278 | { 0x068E, 0x0000 }, /* R1678 - DSP2RMIX Input 1 Source */ | ||
279 | { 0x068F, 0x0080 }, /* R1679 - DSP2RMIX Input 1 Volume */ | ||
280 | { 0x0690, 0x0000 }, /* R1680 - DSP2RMIX Input 2 Source */ | ||
281 | { 0x0691, 0x0080 }, /* R1681 - DSP2RMIX Input 2 Volume */ | ||
282 | { 0x0692, 0x0000 }, /* R1682 - DSP2RMIX Input 3 Source */ | ||
283 | { 0x0693, 0x0080 }, /* R1683 - DSP2RMIX Input 3 Volume */ | ||
284 | { 0x0694, 0x0000 }, /* R1684 - DSP2RMIX Input 4 Source */ | ||
285 | { 0x0695, 0x0080 }, /* R1685 - DSP2RMIX Input 4 Volume */ | ||
286 | { 0x0696, 0x0000 }, /* R1686 - DSP2AUX1MIX Input 1 Source */ | ||
287 | { 0x0697, 0x0000 }, /* R1687 - DSP2AUX2MIX Input 1 Source */ | ||
288 | { 0x0698, 0x0000 }, /* R1688 - DSP2AUX3MIX Input 1 Source */ | ||
289 | { 0x0699, 0x0000 }, /* R1689 - DSP2AUX4MIX Input 1 Source */ | ||
290 | { 0x069A, 0x0000 }, /* R1690 - DSP2AUX5MIX Input 1 Source */ | ||
291 | { 0x069B, 0x0000 }, /* R1691 - DSP2AUX6MIX Input 1 Source */ | ||
292 | { 0x0700, 0xA101 }, /* R1792 - GPIO CTRL 1 */ | ||
293 | { 0x0701, 0xA101 }, /* R1793 - GPIO CTRL 2 */ | ||
294 | { 0x0702, 0xA101 }, /* R1794 - GPIO CTRL 3 */ | ||
295 | { 0x0703, 0xA101 }, /* R1795 - GPIO CTRL 4 */ | ||
296 | { 0x0709, 0x0000 }, /* R1801 - Misc Pad Ctrl 1 */ | ||
297 | { 0x0801, 0x00FF }, /* R2049 - Interrupt Status 1 Mask */ | ||
298 | { 0x0804, 0xFFFF }, /* R2052 - Interrupt Status 2 Mask */ | ||
299 | { 0x0808, 0x0000 }, /* R2056 - Interrupt Control */ | ||
300 | { 0x0900, 0x0000 }, /* R2304 - EQL_1 */ | ||
301 | { 0x0901, 0x0000 }, /* R2305 - EQL_2 */ | ||
302 | { 0x0902, 0x0000 }, /* R2306 - EQL_3 */ | ||
303 | { 0x0903, 0x0000 }, /* R2307 - EQL_4 */ | ||
304 | { 0x0904, 0x0000 }, /* R2308 - EQL_5 */ | ||
305 | { 0x0905, 0x0000 }, /* R2309 - EQL_6 */ | ||
306 | { 0x0906, 0x0000 }, /* R2310 - EQL_7 */ | ||
307 | { 0x0907, 0x0000 }, /* R2311 - EQL_8 */ | ||
308 | { 0x0908, 0x0000 }, /* R2312 - EQL_9 */ | ||
309 | { 0x0909, 0x0000 }, /* R2313 - EQL_10 */ | ||
310 | { 0x090A, 0x0000 }, /* R2314 - EQL_11 */ | ||
311 | { 0x090B, 0x0000 }, /* R2315 - EQL_12 */ | ||
312 | { 0x090C, 0x0000 }, /* R2316 - EQL_13 */ | ||
313 | { 0x090D, 0x0000 }, /* R2317 - EQL_14 */ | ||
314 | { 0x090E, 0x0000 }, /* R2318 - EQL_15 */ | ||
315 | { 0x090F, 0x0000 }, /* R2319 - EQL_16 */ | ||
316 | { 0x0910, 0x0000 }, /* R2320 - EQL_17 */ | ||
317 | { 0x0911, 0x0000 }, /* R2321 - EQL_18 */ | ||
318 | { 0x0912, 0x0000 }, /* R2322 - EQL_19 */ | ||
319 | { 0x0913, 0x0000 }, /* R2323 - EQL_20 */ | ||
320 | { 0x0916, 0x0000 }, /* R2326 - EQR_1 */ | ||
321 | { 0x0917, 0x0000 }, /* R2327 - EQR_2 */ | ||
322 | { 0x0918, 0x0000 }, /* R2328 - EQR_3 */ | ||
323 | { 0x0919, 0x0000 }, /* R2329 - EQR_4 */ | ||
324 | { 0x091A, 0x0000 }, /* R2330 - EQR_5 */ | ||
325 | { 0x091B, 0x0000 }, /* R2331 - EQR_6 */ | ||
326 | { 0x091C, 0x0000 }, /* R2332 - EQR_7 */ | ||
327 | { 0x091D, 0x0000 }, /* R2333 - EQR_8 */ | ||
328 | { 0x091E, 0x0000 }, /* R2334 - EQR_9 */ | ||
329 | { 0x091F, 0x0000 }, /* R2335 - EQR_10 */ | ||
330 | { 0x0920, 0x0000 }, /* R2336 - EQR_11 */ | ||
331 | { 0x0921, 0x0000 }, /* R2337 - EQR_12 */ | ||
332 | { 0x0922, 0x0000 }, /* R2338 - EQR_13 */ | ||
333 | { 0x0923, 0x0000 }, /* R2339 - EQR_14 */ | ||
334 | { 0x0924, 0x0000 }, /* R2340 - EQR_15 */ | ||
335 | { 0x0925, 0x0000 }, /* R2341 - EQR_16 */ | ||
336 | { 0x0926, 0x0000 }, /* R2342 - EQR_17 */ | ||
337 | { 0x0927, 0x0000 }, /* R2343 - EQR_18 */ | ||
338 | { 0x0928, 0x0000 }, /* R2344 - EQR_19 */ | ||
339 | { 0x0929, 0x0000 }, /* R2345 - EQR_20 */ | ||
340 | { 0x093E, 0x0000 }, /* R2366 - HPLPF1_1 */ | ||
341 | { 0x093F, 0x0000 }, /* R2367 - HPLPF1_2 */ | ||
342 | { 0x0942, 0x0000 }, /* R2370 - HPLPF2_1 */ | ||
343 | { 0x0943, 0x0000 }, /* R2371 - HPLPF2_2 */ | ||
344 | { 0x0A00, 0x0000 }, /* R2560 - DSP1 Control 1 */ | ||
345 | { 0x0A02, 0x0000 }, /* R2562 - DSP1 Control 2 */ | ||
346 | { 0x0A03, 0x0000 }, /* R2563 - DSP1 Control 3 */ | ||
347 | { 0x0A04, 0x0000 }, /* R2564 - DSP1 Control 4 */ | ||
348 | { 0x0A06, 0x0000 }, /* R2566 - DSP1 Control 5 */ | ||
349 | { 0x0A07, 0x0000 }, /* R2567 - DSP1 Control 6 */ | ||
350 | { 0x0A08, 0x0000 }, /* R2568 - DSP1 Control 7 */ | ||
351 | { 0x0A09, 0x0000 }, /* R2569 - DSP1 Control 8 */ | ||
352 | { 0x0A0A, 0x0000 }, /* R2570 - DSP1 Control 9 */ | ||
353 | { 0x0A0B, 0x0000 }, /* R2571 - DSP1 Control 10 */ | ||
354 | { 0x0A0C, 0x0000 }, /* R2572 - DSP1 Control 11 */ | ||
355 | { 0x0A0D, 0x0000 }, /* R2573 - DSP1 Control 12 */ | ||
356 | { 0x0A0F, 0x0000 }, /* R2575 - DSP1 Control 13 */ | ||
357 | { 0x0A10, 0x0000 }, /* R2576 - DSP1 Control 14 */ | ||
358 | { 0x0A11, 0x0000 }, /* R2577 - DSP1 Control 15 */ | ||
359 | { 0x0A12, 0x0000 }, /* R2578 - DSP1 Control 16 */ | ||
360 | { 0x0A13, 0x0000 }, /* R2579 - DSP1 Control 17 */ | ||
361 | { 0x0A14, 0x0000 }, /* R2580 - DSP1 Control 18 */ | ||
362 | { 0x0A16, 0x0000 }, /* R2582 - DSP1 Control 19 */ | ||
363 | { 0x0A17, 0x0000 }, /* R2583 - DSP1 Control 20 */ | ||
364 | { 0x0A18, 0x0000 }, /* R2584 - DSP1 Control 21 */ | ||
365 | { 0x0A1A, 0x1800 }, /* R2586 - DSP1 Control 22 */ | ||
366 | { 0x0A1B, 0x1000 }, /* R2587 - DSP1 Control 23 */ | ||
367 | { 0x0A1C, 0x0400 }, /* R2588 - DSP1 Control 24 */ | ||
368 | { 0x0A1E, 0x0000 }, /* R2590 - DSP1 Control 25 */ | ||
369 | { 0x0A20, 0x0000 }, /* R2592 - DSP1 Control 26 */ | ||
370 | { 0x0A21, 0x0000 }, /* R2593 - DSP1 Control 27 */ | ||
371 | { 0x0A22, 0x0000 }, /* R2594 - DSP1 Control 28 */ | ||
372 | { 0x0A23, 0x0000 }, /* R2595 - DSP1 Control 29 */ | ||
373 | { 0x0A24, 0x0000 }, /* R2596 - DSP1 Control 30 */ | ||
374 | { 0x0A26, 0x0000 }, /* R2598 - DSP1 Control 31 */ | ||
375 | { 0x0B00, 0x0000 }, /* R2816 - DSP2 Control 1 */ | ||
376 | { 0x0B02, 0x0000 }, /* R2818 - DSP2 Control 2 */ | ||
377 | { 0x0B03, 0x0000 }, /* R2819 - DSP2 Control 3 */ | ||
378 | { 0x0B04, 0x0000 }, /* R2820 - DSP2 Control 4 */ | ||
379 | { 0x0B06, 0x0000 }, /* R2822 - DSP2 Control 5 */ | ||
380 | { 0x0B07, 0x0000 }, /* R2823 - DSP2 Control 6 */ | ||
381 | { 0x0B08, 0x0000 }, /* R2824 - DSP2 Control 7 */ | ||
382 | { 0x0B09, 0x0000 }, /* R2825 - DSP2 Control 8 */ | ||
383 | { 0x0B0A, 0x0000 }, /* R2826 - DSP2 Control 9 */ | ||
384 | { 0x0B0B, 0x0000 }, /* R2827 - DSP2 Control 10 */ | ||
385 | { 0x0B0C, 0x0000 }, /* R2828 - DSP2 Control 11 */ | ||
386 | { 0x0B0D, 0x0000 }, /* R2829 - DSP2 Control 12 */ | ||
387 | { 0x0B0F, 0x0000 }, /* R2831 - DSP2 Control 13 */ | ||
388 | { 0x0B10, 0x0000 }, /* R2832 - DSP2 Control 14 */ | ||
389 | { 0x0B11, 0x0000 }, /* R2833 - DSP2 Control 15 */ | ||
390 | { 0x0B12, 0x0000 }, /* R2834 - DSP2 Control 16 */ | ||
391 | { 0x0B13, 0x0000 }, /* R2835 - DSP2 Control 17 */ | ||
392 | { 0x0B14, 0x0000 }, /* R2836 - DSP2 Control 18 */ | ||
393 | { 0x0B16, 0x0000 }, /* R2838 - DSP2 Control 19 */ | ||
394 | { 0x0B17, 0x0000 }, /* R2839 - DSP2 Control 20 */ | ||
395 | { 0x0B18, 0x0000 }, /* R2840 - DSP2 Control 21 */ | ||
396 | { 0x0B1A, 0x0800 }, /* R2842 - DSP2 Control 22 */ | ||
397 | { 0x0B1B, 0x1000 }, /* R2843 - DSP2 Control 23 */ | ||
398 | { 0x0B1C, 0x0400 }, /* R2844 - DSP2 Control 24 */ | ||
399 | { 0x0B1E, 0x0000 }, /* R2846 - DSP2 Control 25 */ | ||
400 | { 0x0B20, 0x0000 }, /* R2848 - DSP2 Control 26 */ | ||
401 | { 0x0B21, 0x0000 }, /* R2849 - DSP2 Control 27 */ | ||
402 | { 0x0B22, 0x0000 }, /* R2850 - DSP2 Control 28 */ | ||
403 | { 0x0B23, 0x0000 }, /* R2851 - DSP2 Control 29 */ | ||
404 | { 0x0B24, 0x0000 }, /* R2852 - DSP2 Control 30 */ | ||
405 | { 0x0B26, 0x0000 }, /* R2854 - DSP2 Control 31 */ | ||
406 | }; | ||
407 | |||
408 | static bool wm2200_volatile_register(struct device *dev, unsigned int reg) | ||
409 | { | ||
410 | switch (reg) { | ||
411 | case WM2200_SOFTWARE_RESET: | ||
412 | case WM2200_DEVICE_REVISION: | ||
413 | case WM2200_ADPS1_IRQ0: | ||
414 | case WM2200_ADPS1_IRQ1: | ||
415 | case WM2200_INTERRUPT_STATUS_1: | ||
416 | case WM2200_INTERRUPT_STATUS_2: | ||
417 | case WM2200_INTERRUPT_RAW_STATUS_2: | ||
418 | return true; | ||
419 | default: | ||
420 | return false; | ||
421 | } | ||
422 | } | ||
423 | |||
424 | static bool wm2200_readable_register(struct device *dev, unsigned int reg) | ||
425 | { | ||
426 | switch (reg) { | ||
427 | case WM2200_SOFTWARE_RESET: | ||
428 | case WM2200_DEVICE_REVISION: | ||
429 | case WM2200_TONE_GENERATOR_1: | ||
430 | case WM2200_CLOCKING_3: | ||
431 | case WM2200_CLOCKING_4: | ||
432 | case WM2200_FLL_CONTROL_1: | ||
433 | case WM2200_FLL_CONTROL_2: | ||
434 | case WM2200_FLL_CONTROL_3: | ||
435 | case WM2200_FLL_CONTROL_4: | ||
436 | case WM2200_FLL_CONTROL_6: | ||
437 | case WM2200_FLL_CONTROL_7: | ||
438 | case WM2200_FLL_EFS_1: | ||
439 | case WM2200_FLL_EFS_2: | ||
440 | case WM2200_MIC_CHARGE_PUMP_1: | ||
441 | case WM2200_MIC_CHARGE_PUMP_2: | ||
442 | case WM2200_DM_CHARGE_PUMP_1: | ||
443 | case WM2200_MIC_BIAS_CTRL_1: | ||
444 | case WM2200_MIC_BIAS_CTRL_2: | ||
445 | case WM2200_EAR_PIECE_CTRL_1: | ||
446 | case WM2200_EAR_PIECE_CTRL_2: | ||
447 | case WM2200_INPUT_ENABLES: | ||
448 | case WM2200_IN1L_CONTROL: | ||
449 | case WM2200_IN1R_CONTROL: | ||
450 | case WM2200_IN2L_CONTROL: | ||
451 | case WM2200_IN2R_CONTROL: | ||
452 | case WM2200_IN3L_CONTROL: | ||
453 | case WM2200_IN3R_CONTROL: | ||
454 | case WM2200_RXANC_SRC: | ||
455 | case WM2200_INPUT_VOLUME_RAMP: | ||
456 | case WM2200_ADC_DIGITAL_VOLUME_1L: | ||
457 | case WM2200_ADC_DIGITAL_VOLUME_1R: | ||
458 | case WM2200_ADC_DIGITAL_VOLUME_2L: | ||
459 | case WM2200_ADC_DIGITAL_VOLUME_2R: | ||
460 | case WM2200_ADC_DIGITAL_VOLUME_3L: | ||
461 | case WM2200_ADC_DIGITAL_VOLUME_3R: | ||
462 | case WM2200_OUTPUT_ENABLES: | ||
463 | case WM2200_DAC_VOLUME_LIMIT_1L: | ||
464 | case WM2200_DAC_VOLUME_LIMIT_1R: | ||
465 | case WM2200_DAC_VOLUME_LIMIT_2L: | ||
466 | case WM2200_DAC_VOLUME_LIMIT_2R: | ||
467 | case WM2200_DAC_AEC_CONTROL_1: | ||
468 | case WM2200_OUTPUT_VOLUME_RAMP: | ||
469 | case WM2200_DAC_DIGITAL_VOLUME_1L: | ||
470 | case WM2200_DAC_DIGITAL_VOLUME_1R: | ||
471 | case WM2200_DAC_DIGITAL_VOLUME_2L: | ||
472 | case WM2200_DAC_DIGITAL_VOLUME_2R: | ||
473 | case WM2200_PDM_1: | ||
474 | case WM2200_PDM_2: | ||
475 | case WM2200_AUDIO_IF_1_1: | ||
476 | case WM2200_AUDIO_IF_1_2: | ||
477 | case WM2200_AUDIO_IF_1_3: | ||
478 | case WM2200_AUDIO_IF_1_4: | ||
479 | case WM2200_AUDIO_IF_1_5: | ||
480 | case WM2200_AUDIO_IF_1_6: | ||
481 | case WM2200_AUDIO_IF_1_7: | ||
482 | case WM2200_AUDIO_IF_1_8: | ||
483 | case WM2200_AUDIO_IF_1_9: | ||
484 | case WM2200_AUDIO_IF_1_10: | ||
485 | case WM2200_AUDIO_IF_1_11: | ||
486 | case WM2200_AUDIO_IF_1_12: | ||
487 | case WM2200_AUDIO_IF_1_13: | ||
488 | case WM2200_AUDIO_IF_1_14: | ||
489 | case WM2200_AUDIO_IF_1_15: | ||
490 | case WM2200_AUDIO_IF_1_16: | ||
491 | case WM2200_AUDIO_IF_1_17: | ||
492 | case WM2200_AUDIO_IF_1_18: | ||
493 | case WM2200_AUDIO_IF_1_19: | ||
494 | case WM2200_AUDIO_IF_1_20: | ||
495 | case WM2200_AUDIO_IF_1_21: | ||
496 | case WM2200_AUDIO_IF_1_22: | ||
497 | case WM2200_OUT1LMIX_INPUT_1_SOURCE: | ||
498 | case WM2200_OUT1LMIX_INPUT_1_VOLUME: | ||
499 | case WM2200_OUT1LMIX_INPUT_2_SOURCE: | ||
500 | case WM2200_OUT1LMIX_INPUT_2_VOLUME: | ||
501 | case WM2200_OUT1LMIX_INPUT_3_SOURCE: | ||
502 | case WM2200_OUT1LMIX_INPUT_3_VOLUME: | ||
503 | case WM2200_OUT1LMIX_INPUT_4_SOURCE: | ||
504 | case WM2200_OUT1LMIX_INPUT_4_VOLUME: | ||
505 | case WM2200_OUT1RMIX_INPUT_1_SOURCE: | ||
506 | case WM2200_OUT1RMIX_INPUT_1_VOLUME: | ||
507 | case WM2200_OUT1RMIX_INPUT_2_SOURCE: | ||
508 | case WM2200_OUT1RMIX_INPUT_2_VOLUME: | ||
509 | case WM2200_OUT1RMIX_INPUT_3_SOURCE: | ||
510 | case WM2200_OUT1RMIX_INPUT_3_VOLUME: | ||
511 | case WM2200_OUT1RMIX_INPUT_4_SOURCE: | ||
512 | case WM2200_OUT1RMIX_INPUT_4_VOLUME: | ||
513 | case WM2200_OUT2LMIX_INPUT_1_SOURCE: | ||
514 | case WM2200_OUT2LMIX_INPUT_1_VOLUME: | ||
515 | case WM2200_OUT2LMIX_INPUT_2_SOURCE: | ||
516 | case WM2200_OUT2LMIX_INPUT_2_VOLUME: | ||
517 | case WM2200_OUT2LMIX_INPUT_3_SOURCE: | ||
518 | case WM2200_OUT2LMIX_INPUT_3_VOLUME: | ||
519 | case WM2200_OUT2LMIX_INPUT_4_SOURCE: | ||
520 | case WM2200_OUT2LMIX_INPUT_4_VOLUME: | ||
521 | case WM2200_OUT2RMIX_INPUT_1_SOURCE: | ||
522 | case WM2200_OUT2RMIX_INPUT_1_VOLUME: | ||
523 | case WM2200_OUT2RMIX_INPUT_2_SOURCE: | ||
524 | case WM2200_OUT2RMIX_INPUT_2_VOLUME: | ||
525 | case WM2200_OUT2RMIX_INPUT_3_SOURCE: | ||
526 | case WM2200_OUT2RMIX_INPUT_3_VOLUME: | ||
527 | case WM2200_OUT2RMIX_INPUT_4_SOURCE: | ||
528 | case WM2200_OUT2RMIX_INPUT_4_VOLUME: | ||
529 | case WM2200_AIF1TX1MIX_INPUT_1_SOURCE: | ||
530 | case WM2200_AIF1TX1MIX_INPUT_1_VOLUME: | ||
531 | case WM2200_AIF1TX1MIX_INPUT_2_SOURCE: | ||
532 | case WM2200_AIF1TX1MIX_INPUT_2_VOLUME: | ||
533 | case WM2200_AIF1TX1MIX_INPUT_3_SOURCE: | ||
534 | case WM2200_AIF1TX1MIX_INPUT_3_VOLUME: | ||
535 | case WM2200_AIF1TX1MIX_INPUT_4_SOURCE: | ||
536 | case WM2200_AIF1TX1MIX_INPUT_4_VOLUME: | ||
537 | case WM2200_AIF1TX2MIX_INPUT_1_SOURCE: | ||
538 | case WM2200_AIF1TX2MIX_INPUT_1_VOLUME: | ||
539 | case WM2200_AIF1TX2MIX_INPUT_2_SOURCE: | ||
540 | case WM2200_AIF1TX2MIX_INPUT_2_VOLUME: | ||
541 | case WM2200_AIF1TX2MIX_INPUT_3_SOURCE: | ||
542 | case WM2200_AIF1TX2MIX_INPUT_3_VOLUME: | ||
543 | case WM2200_AIF1TX2MIX_INPUT_4_SOURCE: | ||
544 | case WM2200_AIF1TX2MIX_INPUT_4_VOLUME: | ||
545 | case WM2200_AIF1TX3MIX_INPUT_1_SOURCE: | ||
546 | case WM2200_AIF1TX3MIX_INPUT_1_VOLUME: | ||
547 | case WM2200_AIF1TX3MIX_INPUT_2_SOURCE: | ||
548 | case WM2200_AIF1TX3MIX_INPUT_2_VOLUME: | ||
549 | case WM2200_AIF1TX3MIX_INPUT_3_SOURCE: | ||
550 | case WM2200_AIF1TX3MIX_INPUT_3_VOLUME: | ||
551 | case WM2200_AIF1TX3MIX_INPUT_4_SOURCE: | ||
552 | case WM2200_AIF1TX3MIX_INPUT_4_VOLUME: | ||
553 | case WM2200_AIF1TX4MIX_INPUT_1_SOURCE: | ||
554 | case WM2200_AIF1TX4MIX_INPUT_1_VOLUME: | ||
555 | case WM2200_AIF1TX4MIX_INPUT_2_SOURCE: | ||
556 | case WM2200_AIF1TX4MIX_INPUT_2_VOLUME: | ||
557 | case WM2200_AIF1TX4MIX_INPUT_3_SOURCE: | ||
558 | case WM2200_AIF1TX4MIX_INPUT_3_VOLUME: | ||
559 | case WM2200_AIF1TX4MIX_INPUT_4_SOURCE: | ||
560 | case WM2200_AIF1TX4MIX_INPUT_4_VOLUME: | ||
561 | case WM2200_AIF1TX5MIX_INPUT_1_SOURCE: | ||
562 | case WM2200_AIF1TX5MIX_INPUT_1_VOLUME: | ||
563 | case WM2200_AIF1TX5MIX_INPUT_2_SOURCE: | ||
564 | case WM2200_AIF1TX5MIX_INPUT_2_VOLUME: | ||
565 | case WM2200_AIF1TX5MIX_INPUT_3_SOURCE: | ||
566 | case WM2200_AIF1TX5MIX_INPUT_3_VOLUME: | ||
567 | case WM2200_AIF1TX5MIX_INPUT_4_SOURCE: | ||
568 | case WM2200_AIF1TX5MIX_INPUT_4_VOLUME: | ||
569 | case WM2200_AIF1TX6MIX_INPUT_1_SOURCE: | ||
570 | case WM2200_AIF1TX6MIX_INPUT_1_VOLUME: | ||
571 | case WM2200_AIF1TX6MIX_INPUT_2_SOURCE: | ||
572 | case WM2200_AIF1TX6MIX_INPUT_2_VOLUME: | ||
573 | case WM2200_AIF1TX6MIX_INPUT_3_SOURCE: | ||
574 | case WM2200_AIF1TX6MIX_INPUT_3_VOLUME: | ||
575 | case WM2200_AIF1TX6MIX_INPUT_4_SOURCE: | ||
576 | case WM2200_AIF1TX6MIX_INPUT_4_VOLUME: | ||
577 | case WM2200_EQLMIX_INPUT_1_SOURCE: | ||
578 | case WM2200_EQLMIX_INPUT_1_VOLUME: | ||
579 | case WM2200_EQLMIX_INPUT_2_SOURCE: | ||
580 | case WM2200_EQLMIX_INPUT_2_VOLUME: | ||
581 | case WM2200_EQLMIX_INPUT_3_SOURCE: | ||
582 | case WM2200_EQLMIX_INPUT_3_VOLUME: | ||
583 | case WM2200_EQLMIX_INPUT_4_SOURCE: | ||
584 | case WM2200_EQLMIX_INPUT_4_VOLUME: | ||
585 | case WM2200_EQRMIX_INPUT_1_SOURCE: | ||
586 | case WM2200_EQRMIX_INPUT_1_VOLUME: | ||
587 | case WM2200_EQRMIX_INPUT_2_SOURCE: | ||
588 | case WM2200_EQRMIX_INPUT_2_VOLUME: | ||
589 | case WM2200_EQRMIX_INPUT_3_SOURCE: | ||
590 | case WM2200_EQRMIX_INPUT_3_VOLUME: | ||
591 | case WM2200_EQRMIX_INPUT_4_SOURCE: | ||
592 | case WM2200_EQRMIX_INPUT_4_VOLUME: | ||
593 | case WM2200_LHPF1MIX_INPUT_1_SOURCE: | ||
594 | case WM2200_LHPF1MIX_INPUT_1_VOLUME: | ||
595 | case WM2200_LHPF1MIX_INPUT_2_SOURCE: | ||
596 | case WM2200_LHPF1MIX_INPUT_2_VOLUME: | ||
597 | case WM2200_LHPF1MIX_INPUT_3_SOURCE: | ||
598 | case WM2200_LHPF1MIX_INPUT_3_VOLUME: | ||
599 | case WM2200_LHPF1MIX_INPUT_4_SOURCE: | ||
600 | case WM2200_LHPF1MIX_INPUT_4_VOLUME: | ||
601 | case WM2200_LHPF2MIX_INPUT_1_SOURCE: | ||
602 | case WM2200_LHPF2MIX_INPUT_1_VOLUME: | ||
603 | case WM2200_LHPF2MIX_INPUT_2_SOURCE: | ||
604 | case WM2200_LHPF2MIX_INPUT_2_VOLUME: | ||
605 | case WM2200_LHPF2MIX_INPUT_3_SOURCE: | ||
606 | case WM2200_LHPF2MIX_INPUT_3_VOLUME: | ||
607 | case WM2200_LHPF2MIX_INPUT_4_SOURCE: | ||
608 | case WM2200_LHPF2MIX_INPUT_4_VOLUME: | ||
609 | case WM2200_DSP1LMIX_INPUT_1_SOURCE: | ||
610 | case WM2200_DSP1LMIX_INPUT_1_VOLUME: | ||
611 | case WM2200_DSP1LMIX_INPUT_2_SOURCE: | ||
612 | case WM2200_DSP1LMIX_INPUT_2_VOLUME: | ||
613 | case WM2200_DSP1LMIX_INPUT_3_SOURCE: | ||
614 | case WM2200_DSP1LMIX_INPUT_3_VOLUME: | ||
615 | case WM2200_DSP1LMIX_INPUT_4_SOURCE: | ||
616 | case WM2200_DSP1LMIX_INPUT_4_VOLUME: | ||
617 | case WM2200_DSP1RMIX_INPUT_1_SOURCE: | ||
618 | case WM2200_DSP1RMIX_INPUT_1_VOLUME: | ||
619 | case WM2200_DSP1RMIX_INPUT_2_SOURCE: | ||
620 | case WM2200_DSP1RMIX_INPUT_2_VOLUME: | ||
621 | case WM2200_DSP1RMIX_INPUT_3_SOURCE: | ||
622 | case WM2200_DSP1RMIX_INPUT_3_VOLUME: | ||
623 | case WM2200_DSP1RMIX_INPUT_4_SOURCE: | ||
624 | case WM2200_DSP1RMIX_INPUT_4_VOLUME: | ||
625 | case WM2200_DSP1AUX1MIX_INPUT_1_SOURCE: | ||
626 | case WM2200_DSP1AUX2MIX_INPUT_1_SOURCE: | ||
627 | case WM2200_DSP1AUX3MIX_INPUT_1_SOURCE: | ||
628 | case WM2200_DSP1AUX4MIX_INPUT_1_SOURCE: | ||
629 | case WM2200_DSP1AUX5MIX_INPUT_1_SOURCE: | ||
630 | case WM2200_DSP1AUX6MIX_INPUT_1_SOURCE: | ||
631 | case WM2200_DSP2LMIX_INPUT_1_SOURCE: | ||
632 | case WM2200_DSP2LMIX_INPUT_1_VOLUME: | ||
633 | case WM2200_DSP2LMIX_INPUT_2_SOURCE: | ||
634 | case WM2200_DSP2LMIX_INPUT_2_VOLUME: | ||
635 | case WM2200_DSP2LMIX_INPUT_3_SOURCE: | ||
636 | case WM2200_DSP2LMIX_INPUT_3_VOLUME: | ||
637 | case WM2200_DSP2LMIX_INPUT_4_SOURCE: | ||
638 | case WM2200_DSP2LMIX_INPUT_4_VOLUME: | ||
639 | case WM2200_DSP2RMIX_INPUT_1_SOURCE: | ||
640 | case WM2200_DSP2RMIX_INPUT_1_VOLUME: | ||
641 | case WM2200_DSP2RMIX_INPUT_2_SOURCE: | ||
642 | case WM2200_DSP2RMIX_INPUT_2_VOLUME: | ||
643 | case WM2200_DSP2RMIX_INPUT_3_SOURCE: | ||
644 | case WM2200_DSP2RMIX_INPUT_3_VOLUME: | ||
645 | case WM2200_DSP2RMIX_INPUT_4_SOURCE: | ||
646 | case WM2200_DSP2RMIX_INPUT_4_VOLUME: | ||
647 | case WM2200_DSP2AUX1MIX_INPUT_1_SOURCE: | ||
648 | case WM2200_DSP2AUX2MIX_INPUT_1_SOURCE: | ||
649 | case WM2200_DSP2AUX3MIX_INPUT_1_SOURCE: | ||
650 | case WM2200_DSP2AUX4MIX_INPUT_1_SOURCE: | ||
651 | case WM2200_DSP2AUX5MIX_INPUT_1_SOURCE: | ||
652 | case WM2200_DSP2AUX6MIX_INPUT_1_SOURCE: | ||
653 | case WM2200_GPIO_CTRL_1: | ||
654 | case WM2200_GPIO_CTRL_2: | ||
655 | case WM2200_GPIO_CTRL_3: | ||
656 | case WM2200_GPIO_CTRL_4: | ||
657 | case WM2200_ADPS1_IRQ0: | ||
658 | case WM2200_ADPS1_IRQ1: | ||
659 | case WM2200_MISC_PAD_CTRL_1: | ||
660 | case WM2200_INTERRUPT_STATUS_1: | ||
661 | case WM2200_INTERRUPT_STATUS_1_MASK: | ||
662 | case WM2200_INTERRUPT_STATUS_2: | ||
663 | case WM2200_INTERRUPT_RAW_STATUS_2: | ||
664 | case WM2200_INTERRUPT_STATUS_2_MASK: | ||
665 | case WM2200_INTERRUPT_CONTROL: | ||
666 | case WM2200_EQL_1: | ||
667 | case WM2200_EQL_2: | ||
668 | case WM2200_EQL_3: | ||
669 | case WM2200_EQL_4: | ||
670 | case WM2200_EQL_5: | ||
671 | case WM2200_EQL_6: | ||
672 | case WM2200_EQL_7: | ||
673 | case WM2200_EQL_8: | ||
674 | case WM2200_EQL_9: | ||
675 | case WM2200_EQL_10: | ||
676 | case WM2200_EQL_11: | ||
677 | case WM2200_EQL_12: | ||
678 | case WM2200_EQL_13: | ||
679 | case WM2200_EQL_14: | ||
680 | case WM2200_EQL_15: | ||
681 | case WM2200_EQL_16: | ||
682 | case WM2200_EQL_17: | ||
683 | case WM2200_EQL_18: | ||
684 | case WM2200_EQL_19: | ||
685 | case WM2200_EQL_20: | ||
686 | case WM2200_EQR_1: | ||
687 | case WM2200_EQR_2: | ||
688 | case WM2200_EQR_3: | ||
689 | case WM2200_EQR_4: | ||
690 | case WM2200_EQR_5: | ||
691 | case WM2200_EQR_6: | ||
692 | case WM2200_EQR_7: | ||
693 | case WM2200_EQR_8: | ||
694 | case WM2200_EQR_9: | ||
695 | case WM2200_EQR_10: | ||
696 | case WM2200_EQR_11: | ||
697 | case WM2200_EQR_12: | ||
698 | case WM2200_EQR_13: | ||
699 | case WM2200_EQR_14: | ||
700 | case WM2200_EQR_15: | ||
701 | case WM2200_EQR_16: | ||
702 | case WM2200_EQR_17: | ||
703 | case WM2200_EQR_18: | ||
704 | case WM2200_EQR_19: | ||
705 | case WM2200_EQR_20: | ||
706 | case WM2200_HPLPF1_1: | ||
707 | case WM2200_HPLPF1_2: | ||
708 | case WM2200_HPLPF2_1: | ||
709 | case WM2200_HPLPF2_2: | ||
710 | case WM2200_DSP1_CONTROL_1: | ||
711 | case WM2200_DSP1_CONTROL_2: | ||
712 | case WM2200_DSP1_CONTROL_3: | ||
713 | case WM2200_DSP1_CONTROL_4: | ||
714 | case WM2200_DSP1_CONTROL_5: | ||
715 | case WM2200_DSP1_CONTROL_6: | ||
716 | case WM2200_DSP1_CONTROL_7: | ||
717 | case WM2200_DSP1_CONTROL_8: | ||
718 | case WM2200_DSP1_CONTROL_9: | ||
719 | case WM2200_DSP1_CONTROL_10: | ||
720 | case WM2200_DSP1_CONTROL_11: | ||
721 | case WM2200_DSP1_CONTROL_12: | ||
722 | case WM2200_DSP1_CONTROL_13: | ||
723 | case WM2200_DSP1_CONTROL_14: | ||
724 | case WM2200_DSP1_CONTROL_15: | ||
725 | case WM2200_DSP1_CONTROL_16: | ||
726 | case WM2200_DSP1_CONTROL_17: | ||
727 | case WM2200_DSP1_CONTROL_18: | ||
728 | case WM2200_DSP1_CONTROL_19: | ||
729 | case WM2200_DSP1_CONTROL_20: | ||
730 | case WM2200_DSP1_CONTROL_21: | ||
731 | case WM2200_DSP1_CONTROL_22: | ||
732 | case WM2200_DSP1_CONTROL_23: | ||
733 | case WM2200_DSP1_CONTROL_24: | ||
734 | case WM2200_DSP1_CONTROL_25: | ||
735 | case WM2200_DSP1_CONTROL_26: | ||
736 | case WM2200_DSP1_CONTROL_27: | ||
737 | case WM2200_DSP1_CONTROL_28: | ||
738 | case WM2200_DSP1_CONTROL_29: | ||
739 | case WM2200_DSP1_CONTROL_30: | ||
740 | case WM2200_DSP1_CONTROL_31: | ||
741 | case WM2200_DSP2_CONTROL_1: | ||
742 | case WM2200_DSP2_CONTROL_2: | ||
743 | case WM2200_DSP2_CONTROL_3: | ||
744 | case WM2200_DSP2_CONTROL_4: | ||
745 | case WM2200_DSP2_CONTROL_5: | ||
746 | case WM2200_DSP2_CONTROL_6: | ||
747 | case WM2200_DSP2_CONTROL_7: | ||
748 | case WM2200_DSP2_CONTROL_8: | ||
749 | case WM2200_DSP2_CONTROL_9: | ||
750 | case WM2200_DSP2_CONTROL_10: | ||
751 | case WM2200_DSP2_CONTROL_11: | ||
752 | case WM2200_DSP2_CONTROL_12: | ||
753 | case WM2200_DSP2_CONTROL_13: | ||
754 | case WM2200_DSP2_CONTROL_14: | ||
755 | case WM2200_DSP2_CONTROL_15: | ||
756 | case WM2200_DSP2_CONTROL_16: | ||
757 | case WM2200_DSP2_CONTROL_17: | ||
758 | case WM2200_DSP2_CONTROL_18: | ||
759 | case WM2200_DSP2_CONTROL_19: | ||
760 | case WM2200_DSP2_CONTROL_20: | ||
761 | case WM2200_DSP2_CONTROL_21: | ||
762 | case WM2200_DSP2_CONTROL_22: | ||
763 | case WM2200_DSP2_CONTROL_23: | ||
764 | case WM2200_DSP2_CONTROL_24: | ||
765 | case WM2200_DSP2_CONTROL_25: | ||
766 | case WM2200_DSP2_CONTROL_26: | ||
767 | case WM2200_DSP2_CONTROL_27: | ||
768 | case WM2200_DSP2_CONTROL_28: | ||
769 | case WM2200_DSP2_CONTROL_29: | ||
770 | case WM2200_DSP2_CONTROL_30: | ||
771 | case WM2200_DSP2_CONTROL_31: | ||
772 | return true; | ||
773 | default: | ||
774 | return false; | ||
775 | } | ||
776 | } | ||
777 | |||
778 | static const struct reg_default wm2200_reva_patch[] = { | ||
779 | { 0x07, 0x0003 }, | ||
780 | { 0x102, 0x0200 }, | ||
781 | { 0x203, 0x0084 }, | ||
782 | { 0x201, 0x83FF }, | ||
783 | { 0x20C, 0x0062 }, | ||
784 | { 0x20D, 0x0062 }, | ||
785 | { 0x207, 0x2002 }, | ||
786 | { 0x208, 0x20C0 }, | ||
787 | { 0x21D, 0x01C0 }, | ||
788 | { 0x50A, 0x0001 }, | ||
789 | { 0x50B, 0x0002 }, | ||
790 | { 0x50C, 0x0003 }, | ||
791 | { 0x50D, 0x0004 }, | ||
792 | { 0x50E, 0x0005 }, | ||
793 | { 0x510, 0x0001 }, | ||
794 | { 0x511, 0x0002 }, | ||
795 | { 0x512, 0x0003 }, | ||
796 | { 0x513, 0x0004 }, | ||
797 | { 0x514, 0x0005 }, | ||
798 | { 0x515, 0x0000 }, | ||
799 | { 0x201, 0x8084 }, | ||
800 | { 0x202, 0xBBDE }, | ||
801 | { 0x203, 0x00EC }, | ||
802 | { 0x500, 0x8000 }, | ||
803 | { 0x507, 0x1820 }, | ||
804 | { 0x508, 0x1820 }, | ||
805 | { 0x505, 0x0300 }, | ||
806 | { 0x506, 0x0300 }, | ||
807 | { 0x302, 0x2280 }, | ||
808 | { 0x303, 0x0080 }, | ||
809 | { 0x304, 0x2280 }, | ||
810 | { 0x305, 0x0080 }, | ||
811 | { 0x306, 0x2280 }, | ||
812 | { 0x307, 0x0080 }, | ||
813 | { 0x401, 0x0080 }, | ||
814 | { 0x402, 0x0080 }, | ||
815 | { 0x417, 0x3069 }, | ||
816 | { 0x900, 0x6318 }, | ||
817 | { 0x901, 0x6300 }, | ||
818 | { 0x902, 0x0FC8 }, | ||
819 | { 0x903, 0x03FE }, | ||
820 | { 0x904, 0x00E0 }, | ||
821 | { 0x905, 0x1EC4 }, | ||
822 | { 0x906, 0xF136 }, | ||
823 | { 0x907, 0x0409 }, | ||
824 | { 0x908, 0x04CC }, | ||
825 | { 0x909, 0x1C9B }, | ||
826 | { 0x90A, 0xF337 }, | ||
827 | { 0x90B, 0x040B }, | ||
828 | { 0x90C, 0x0CBB }, | ||
829 | { 0x90D, 0x16F8 }, | ||
830 | { 0x90E, 0xF7D9 }, | ||
831 | { 0x90F, 0x040A }, | ||
832 | { 0x910, 0x1F14 }, | ||
833 | { 0x911, 0x058C }, | ||
834 | { 0x912, 0x0563 }, | ||
835 | { 0x913, 0x4000 }, | ||
836 | { 0x916, 0x6318 }, | ||
837 | { 0x917, 0x6300 }, | ||
838 | { 0x918, 0x0FC8 }, | ||
839 | { 0x919, 0x03FE }, | ||
840 | { 0x91A, 0x00E0 }, | ||
841 | { 0x91B, 0x1EC4 }, | ||
842 | { 0x91C, 0xF136 }, | ||
843 | { 0x91D, 0x0409 }, | ||
844 | { 0x91E, 0x04CC }, | ||
845 | { 0x91F, 0x1C9B }, | ||
846 | { 0x920, 0xF337 }, | ||
847 | { 0x921, 0x040B }, | ||
848 | { 0x922, 0x0CBB }, | ||
849 | { 0x923, 0x16F8 }, | ||
850 | { 0x924, 0xF7D9 }, | ||
851 | { 0x925, 0x040A }, | ||
852 | { 0x926, 0x1F14 }, | ||
853 | { 0x927, 0x058C }, | ||
854 | { 0x928, 0x0563 }, | ||
855 | { 0x929, 0x4000 }, | ||
856 | { 0x709, 0x2000 }, | ||
857 | { 0x207, 0x200E }, | ||
858 | { 0x208, 0x20D4 }, | ||
859 | { 0x20A, 0x0080 }, | ||
860 | { 0x07, 0x0000 }, | ||
861 | }; | ||
862 | |||
863 | static int wm2200_reset(struct wm2200_priv *wm2200) | ||
864 | { | ||
865 | if (wm2200->pdata.reset) { | ||
866 | gpio_set_value_cansleep(wm2200->pdata.reset, 0); | ||
867 | gpio_set_value_cansleep(wm2200->pdata.reset, 1); | ||
868 | |||
869 | return 0; | ||
870 | } else { | ||
871 | return regmap_write(wm2200->regmap, WM2200_SOFTWARE_RESET, | ||
872 | 0x2200); | ||
873 | } | ||
874 | } | ||
875 | |||
876 | static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0); | ||
877 | static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); | ||
878 | static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0); | ||
879 | |||
880 | static const char *wm2200_mixer_texts[] = { | ||
881 | "None", | ||
882 | "Tone Generator", | ||
883 | "AEC loopback", | ||
884 | "IN1L", | ||
885 | "IN1R", | ||
886 | "IN2L", | ||
887 | "IN2R", | ||
888 | "IN3L", | ||
889 | "IN3R", | ||
890 | "AIF1RX1", | ||
891 | "AIF1RX2", | ||
892 | "AIF1RX3", | ||
893 | "AIF1RX4", | ||
894 | "AIF1RX5", | ||
895 | "AIF1RX6", | ||
896 | "EQL", | ||
897 | "EQR", | ||
898 | "LHPF1", | ||
899 | "LHPF2", | ||
900 | "LHPF3", | ||
901 | "LHPF4", | ||
902 | "DSP1.1", | ||
903 | "DSP1.2", | ||
904 | "DSP1.3", | ||
905 | "DSP1.4", | ||
906 | "DSP1.5", | ||
907 | "DSP1.6", | ||
908 | "DSP2.1", | ||
909 | "DSP2.2", | ||
910 | "DSP2.3", | ||
911 | "DSP2.4", | ||
912 | "DSP2.5", | ||
913 | "DSP2.6", | ||
914 | }; | ||
915 | |||
916 | static int wm2200_mixer_values[] = { | ||
917 | 0x00, | ||
918 | 0x04, /* Tone */ | ||
919 | 0x08, /* AEC */ | ||
920 | 0x10, /* Input */ | ||
921 | 0x11, | ||
922 | 0x12, | ||
923 | 0x13, | ||
924 | 0x14, | ||
925 | 0x15, | ||
926 | 0x20, /* AIF */ | ||
927 | 0x21, | ||
928 | 0x22, | ||
929 | 0x23, | ||
930 | 0x24, | ||
931 | 0x25, | ||
932 | 0x50, /* EQ */ | ||
933 | 0x51, | ||
934 | 0x52, | ||
935 | 0x60, /* LHPF1 */ | ||
936 | 0x61, /* LHPF2 */ | ||
937 | 0x68, /* DSP1 */ | ||
938 | 0x69, | ||
939 | 0x6a, | ||
940 | 0x6b, | ||
941 | 0x6c, | ||
942 | 0x6d, | ||
943 | 0x70, /* DSP2 */ | ||
944 | 0x71, | ||
945 | 0x72, | ||
946 | 0x73, | ||
947 | 0x74, | ||
948 | 0x75, | ||
949 | }; | ||
950 | |||
951 | #define WM2200_MIXER_CONTROLS(name, base) \ | ||
952 | SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \ | ||
953 | WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \ | ||
954 | SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \ | ||
955 | WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \ | ||
956 | SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \ | ||
957 | WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \ | ||
958 | SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \ | ||
959 | WM2200_MIXER_VOL_SHIFT, 80, 0, mixer_tlv) | ||
960 | |||
961 | #define WM2200_MUX_ENUM_DECL(name, reg) \ | ||
962 | SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \ | ||
963 | wm2200_mixer_texts, wm2200_mixer_values) | ||
964 | |||
965 | #define WM2200_MUX_CTL_DECL(name) \ | ||
966 | const struct snd_kcontrol_new name##_mux = \ | ||
967 | SOC_DAPM_VALUE_ENUM("Route", name##_enum) | ||
968 | |||
969 | #define WM2200_MIXER_ENUMS(name, base_reg) \ | ||
970 | static WM2200_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ | ||
971 | static WM2200_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \ | ||
972 | static WM2200_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \ | ||
973 | static WM2200_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \ | ||
974 | static WM2200_MUX_CTL_DECL(name##_in1); \ | ||
975 | static WM2200_MUX_CTL_DECL(name##_in2); \ | ||
976 | static WM2200_MUX_CTL_DECL(name##_in3); \ | ||
977 | static WM2200_MUX_CTL_DECL(name##_in4) | ||
978 | |||
979 | static const struct snd_kcontrol_new wm2200_snd_controls[] = { | ||
980 | SOC_SINGLE("IN1 High Performance Switch", WM2200_IN1L_CONTROL, | ||
981 | WM2200_IN1_OSR_SHIFT, 1, 0), | ||
982 | SOC_SINGLE("IN2 High Performance Switch", WM2200_IN2L_CONTROL, | ||
983 | WM2200_IN2_OSR_SHIFT, 1, 0), | ||
984 | SOC_SINGLE("IN3 High Performance Switch", WM2200_IN3L_CONTROL, | ||
985 | WM2200_IN3_OSR_SHIFT, 1, 0), | ||
986 | |||
987 | SOC_DOUBLE_R_TLV("IN1 Volume", WM2200_IN1L_CONTROL, WM2200_IN1R_CONTROL, | ||
988 | WM2200_IN1L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv), | ||
989 | SOC_DOUBLE_R_TLV("IN2 Volume", WM2200_IN2L_CONTROL, WM2200_IN2R_CONTROL, | ||
990 | WM2200_IN2L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv), | ||
991 | SOC_DOUBLE_R_TLV("IN3 Volume", WM2200_IN3L_CONTROL, WM2200_IN3R_CONTROL, | ||
992 | WM2200_IN3L_PGA_VOL_SHIFT, 0x5f, 0, in_tlv), | ||
993 | |||
994 | SOC_DOUBLE_R("IN1 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L, | ||
995 | WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_MUTE_SHIFT, 1, 1), | ||
996 | SOC_DOUBLE_R("IN2 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L, | ||
997 | WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_MUTE_SHIFT, 1, 1), | ||
998 | SOC_DOUBLE_R("IN3 Digital Switch", WM2200_ADC_DIGITAL_VOLUME_1L, | ||
999 | WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_MUTE_SHIFT, 1, 1), | ||
1000 | |||
1001 | SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_1L, | ||
1002 | WM2200_ADC_DIGITAL_VOLUME_1R, WM2200_IN1L_DIG_VOL_SHIFT, | ||
1003 | 0xbf, 0, digital_tlv), | ||
1004 | SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_2L, | ||
1005 | WM2200_ADC_DIGITAL_VOLUME_2R, WM2200_IN2L_DIG_VOL_SHIFT, | ||
1006 | 0xbf, 0, digital_tlv), | ||
1007 | SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM2200_ADC_DIGITAL_VOLUME_3L, | ||
1008 | WM2200_ADC_DIGITAL_VOLUME_3R, WM2200_IN3L_DIG_VOL_SHIFT, | ||
1009 | 0xbf, 0, digital_tlv), | ||
1010 | |||
1011 | SOC_SINGLE("OUT1 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_1L, | ||
1012 | WM2200_OUT1_OSR_SHIFT, 1, 0), | ||
1013 | SOC_SINGLE("OUT2 High Performance Switch", WM2200_DAC_DIGITAL_VOLUME_2L, | ||
1014 | WM2200_OUT2_OSR_SHIFT, 1, 0), | ||
1015 | |||
1016 | SOC_DOUBLE_R("OUT1 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_1L, | ||
1017 | WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_MUTE_SHIFT, 1, 1), | ||
1018 | SOC_DOUBLE_R_TLV("OUT1 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_1L, | ||
1019 | WM2200_DAC_DIGITAL_VOLUME_1R, WM2200_OUT1L_VOL_SHIFT, 0x9f, 0, | ||
1020 | digital_tlv), | ||
1021 | SOC_DOUBLE_R_TLV("OUT1 Volume", WM2200_DAC_VOLUME_LIMIT_1L, | ||
1022 | WM2200_DAC_VOLUME_LIMIT_1R, WM2200_OUT1L_PGA_VOL_SHIFT, | ||
1023 | 0x46, 0, out_tlv), | ||
1024 | |||
1025 | SOC_DOUBLE_R("OUT2 Digital Switch", WM2200_DAC_DIGITAL_VOLUME_2L, | ||
1026 | WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_MUTE_SHIFT, 1, 1), | ||
1027 | SOC_DOUBLE_R_TLV("OUT2 Digital Volume", WM2200_DAC_DIGITAL_VOLUME_2L, | ||
1028 | WM2200_DAC_DIGITAL_VOLUME_2R, WM2200_OUT2L_VOL_SHIFT, 0x9f, 0, | ||
1029 | digital_tlv), | ||
1030 | SOC_DOUBLE("OUT2 Switch", WM2200_PDM_1, WM2200_SPK1L_MUTE_SHIFT, | ||
1031 | WM2200_SPK1R_MUTE_SHIFT, 1, 0), | ||
1032 | }; | ||
1033 | |||
1034 | WM2200_MIXER_ENUMS(OUT1L, WM2200_OUT1LMIX_INPUT_1_SOURCE); | ||
1035 | WM2200_MIXER_ENUMS(OUT1R, WM2200_OUT1RMIX_INPUT_1_SOURCE); | ||
1036 | WM2200_MIXER_ENUMS(OUT2L, WM2200_OUT2LMIX_INPUT_1_SOURCE); | ||
1037 | WM2200_MIXER_ENUMS(OUT2R, WM2200_OUT2RMIX_INPUT_1_SOURCE); | ||
1038 | |||
1039 | WM2200_MIXER_ENUMS(AIF1TX1, WM2200_AIF1TX1MIX_INPUT_1_SOURCE); | ||
1040 | WM2200_MIXER_ENUMS(AIF1TX2, WM2200_AIF1TX2MIX_INPUT_1_SOURCE); | ||
1041 | WM2200_MIXER_ENUMS(AIF1TX3, WM2200_AIF1TX3MIX_INPUT_1_SOURCE); | ||
1042 | WM2200_MIXER_ENUMS(AIF1TX4, WM2200_AIF1TX4MIX_INPUT_1_SOURCE); | ||
1043 | WM2200_MIXER_ENUMS(AIF1TX5, WM2200_AIF1TX5MIX_INPUT_1_SOURCE); | ||
1044 | WM2200_MIXER_ENUMS(AIF1TX6, WM2200_AIF1TX6MIX_INPUT_1_SOURCE); | ||
1045 | |||
1046 | WM2200_MIXER_ENUMS(EQL, WM2200_EQLMIX_INPUT_1_SOURCE); | ||
1047 | WM2200_MIXER_ENUMS(EQR, WM2200_EQRMIX_INPUT_1_SOURCE); | ||
1048 | |||
1049 | WM2200_MIXER_ENUMS(DSP1L, WM2200_DSP1LMIX_INPUT_1_SOURCE); | ||
1050 | WM2200_MIXER_ENUMS(DSP1R, WM2200_DSP1RMIX_INPUT_1_SOURCE); | ||
1051 | WM2200_MIXER_ENUMS(DSP2L, WM2200_DSP2LMIX_INPUT_1_SOURCE); | ||
1052 | WM2200_MIXER_ENUMS(DSP2R, WM2200_DSP2RMIX_INPUT_1_SOURCE); | ||
1053 | |||
1054 | WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE); | ||
1055 | WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); | ||
1056 | |||
1057 | #define WM2200_MUX(name, ctrl) \ | ||
1058 | SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) | ||
1059 | |||
1060 | #define WM2200_MIXER_WIDGETS(name, name_str) \ | ||
1061 | WM2200_MUX(name_str " Input 1", &name##_in1_mux), \ | ||
1062 | WM2200_MUX(name_str " Input 2", &name##_in2_mux), \ | ||
1063 | WM2200_MUX(name_str " Input 3", &name##_in3_mux), \ | ||
1064 | WM2200_MUX(name_str " Input 4", &name##_in4_mux), \ | ||
1065 | SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) | ||
1066 | |||
1067 | #define WM2200_MIXER_INPUT_ROUTES(name) \ | ||
1068 | { name, "Tone Generator", "Tone Generator" }, \ | ||
1069 | { name, "IN1L", "IN1L PGA" }, \ | ||
1070 | { name, "IN1R", "IN1R PGA" }, \ | ||
1071 | { name, "IN2L", "IN2L PGA" }, \ | ||
1072 | { name, "IN2R", "IN2R PGA" }, \ | ||
1073 | { name, "IN3L", "IN3L PGA" }, \ | ||
1074 | { name, "IN3R", "IN3R PGA" }, \ | ||
1075 | { name, "DSP1.1", "DSP1" }, \ | ||
1076 | { name, "DSP1.2", "DSP1" }, \ | ||
1077 | { name, "DSP1.3", "DSP1" }, \ | ||
1078 | { name, "DSP1.4", "DSP1" }, \ | ||
1079 | { name, "DSP1.5", "DSP1" }, \ | ||
1080 | { name, "DSP1.6", "DSP1" }, \ | ||
1081 | { name, "DSP2.1", "DSP2" }, \ | ||
1082 | { name, "DSP2.2", "DSP2" }, \ | ||
1083 | { name, "DSP2.3", "DSP2" }, \ | ||
1084 | { name, "DSP2.4", "DSP2" }, \ | ||
1085 | { name, "DSP2.5", "DSP2" }, \ | ||
1086 | { name, "DSP2.6", "DSP2" }, \ | ||
1087 | { name, "AIF1RX1", "AIF1RX1" }, \ | ||
1088 | { name, "AIF1RX2", "AIF1RX2" }, \ | ||
1089 | { name, "AIF1RX3", "AIF1RX3" }, \ | ||
1090 | { name, "AIF1RX4", "AIF1RX4" }, \ | ||
1091 | { name, "AIF1RX5", "AIF1RX5" }, \ | ||
1092 | { name, "AIF1RX6", "AIF1RX6" }, \ | ||
1093 | { name, "EQL", "EQL" }, \ | ||
1094 | { name, "EQR", "EQR" }, \ | ||
1095 | { name, "LHPF1", "LHPF1" }, \ | ||
1096 | { name, "LHPF2", "LHPF2" } | ||
1097 | |||
1098 | #define WM2200_MIXER_ROUTES(widget, name) \ | ||
1099 | { widget, NULL, name " Mixer" }, \ | ||
1100 | { name " Mixer", NULL, name " Input 1" }, \ | ||
1101 | { name " Mixer", NULL, name " Input 2" }, \ | ||
1102 | { name " Mixer", NULL, name " Input 3" }, \ | ||
1103 | { name " Mixer", NULL, name " Input 4" }, \ | ||
1104 | WM2200_MIXER_INPUT_ROUTES(name " Input 1"), \ | ||
1105 | WM2200_MIXER_INPUT_ROUTES(name " Input 2"), \ | ||
1106 | WM2200_MIXER_INPUT_ROUTES(name " Input 3"), \ | ||
1107 | WM2200_MIXER_INPUT_ROUTES(name " Input 4") | ||
1108 | |||
1109 | static const struct snd_soc_dapm_widget wm2200_dapm_widgets[] = { | ||
1110 | SND_SOC_DAPM_SUPPLY("SYSCLK", WM2200_CLOCKING_3, WM2200_SYSCLK_ENA_SHIFT, 0, | ||
1111 | NULL, 0), | ||
1112 | SND_SOC_DAPM_SUPPLY("CP1", WM2200_DM_CHARGE_PUMP_1, WM2200_CPDM_ENA_SHIFT, 0, | ||
1113 | NULL, 0), | ||
1114 | SND_SOC_DAPM_SUPPLY("CP2", WM2200_MIC_CHARGE_PUMP_1, WM2200_CPMIC_ENA_SHIFT, 0, | ||
1115 | NULL, 0), | ||
1116 | SND_SOC_DAPM_SUPPLY("MICBIAS1", WM2200_MIC_BIAS_CTRL_1, WM2200_MICB1_ENA_SHIFT, | ||
1117 | 0, NULL, 0), | ||
1118 | SND_SOC_DAPM_SUPPLY("MICBIAS2", WM2200_MIC_BIAS_CTRL_2, WM2200_MICB2_ENA_SHIFT, | ||
1119 | 0, NULL, 0), | ||
1120 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20), | ||
1121 | SND_SOC_DAPM_REGULATOR_SUPPLY("AVDD", 20), | ||
1122 | |||
1123 | SND_SOC_DAPM_INPUT("IN1L"), | ||
1124 | SND_SOC_DAPM_INPUT("IN1R"), | ||
1125 | SND_SOC_DAPM_INPUT("IN2L"), | ||
1126 | SND_SOC_DAPM_INPUT("IN2R"), | ||
1127 | SND_SOC_DAPM_INPUT("IN3L"), | ||
1128 | SND_SOC_DAPM_INPUT("IN3R"), | ||
1129 | |||
1130 | SND_SOC_DAPM_SIGGEN("TONE"), | ||
1131 | SND_SOC_DAPM_PGA("Tone Generator", WM2200_TONE_GENERATOR_1, | ||
1132 | WM2200_TONE_ENA_SHIFT, 0, NULL, 0), | ||
1133 | |||
1134 | SND_SOC_DAPM_PGA("IN1L PGA", WM2200_INPUT_ENABLES, WM2200_IN1L_ENA_SHIFT, 0, | ||
1135 | NULL, 0), | ||
1136 | SND_SOC_DAPM_PGA("IN1R PGA", WM2200_INPUT_ENABLES, WM2200_IN1R_ENA_SHIFT, 0, | ||
1137 | NULL, 0), | ||
1138 | SND_SOC_DAPM_PGA("IN2L PGA", WM2200_INPUT_ENABLES, WM2200_IN2L_ENA_SHIFT, 0, | ||
1139 | NULL, 0), | ||
1140 | SND_SOC_DAPM_PGA("IN2R PGA", WM2200_INPUT_ENABLES, WM2200_IN2R_ENA_SHIFT, 0, | ||
1141 | NULL, 0), | ||
1142 | SND_SOC_DAPM_PGA("IN3L PGA", WM2200_INPUT_ENABLES, WM2200_IN3L_ENA_SHIFT, 0, | ||
1143 | NULL, 0), | ||
1144 | SND_SOC_DAPM_PGA("IN3R PGA", WM2200_INPUT_ENABLES, WM2200_IN3R_ENA_SHIFT, 0, | ||
1145 | NULL, 0), | ||
1146 | |||
1147 | SND_SOC_DAPM_AIF_IN("AIF1RX1", "Playback", 0, | ||
1148 | WM2200_AUDIO_IF_1_22, WM2200_AIF1RX1_ENA_SHIFT, 0), | ||
1149 | SND_SOC_DAPM_AIF_IN("AIF1RX2", "Playback", 1, | ||
1150 | WM2200_AUDIO_IF_1_22, WM2200_AIF1RX2_ENA_SHIFT, 0), | ||
1151 | SND_SOC_DAPM_AIF_IN("AIF1RX3", "Playback", 2, | ||
1152 | WM2200_AUDIO_IF_1_22, WM2200_AIF1RX3_ENA_SHIFT, 0), | ||
1153 | SND_SOC_DAPM_AIF_IN("AIF1RX4", "Playback", 3, | ||
1154 | WM2200_AUDIO_IF_1_22, WM2200_AIF1RX4_ENA_SHIFT, 0), | ||
1155 | SND_SOC_DAPM_AIF_IN("AIF1RX5", "Playback", 4, | ||
1156 | WM2200_AUDIO_IF_1_22, WM2200_AIF1RX5_ENA_SHIFT, 0), | ||
1157 | SND_SOC_DAPM_AIF_IN("AIF1RX6", "Playback", 5, | ||
1158 | WM2200_AUDIO_IF_1_22, WM2200_AIF1RX6_ENA_SHIFT, 0), | ||
1159 | |||
1160 | SND_SOC_DAPM_PGA("EQL", WM2200_EQL_1, WM2200_EQL_ENA_SHIFT, 0, NULL, 0), | ||
1161 | SND_SOC_DAPM_PGA("EQR", WM2200_EQR_1, WM2200_EQR_ENA_SHIFT, 0, NULL, 0), | ||
1162 | |||
1163 | SND_SOC_DAPM_PGA("LHPF1", WM2200_HPLPF1_1, WM2200_LHPF1_ENA_SHIFT, 0, | ||
1164 | NULL, 0), | ||
1165 | SND_SOC_DAPM_PGA("LHPF2", WM2200_HPLPF2_1, WM2200_LHPF2_ENA_SHIFT, 0, | ||
1166 | NULL, 0), | ||
1167 | |||
1168 | SND_SOC_DAPM_PGA_E("DSP1", SND_SOC_NOPM, 0, 0, NULL, 0, NULL, 0), | ||
1169 | SND_SOC_DAPM_PGA_E("DSP2", SND_SOC_NOPM, 1, 0, NULL, 0, NULL, 0), | ||
1170 | |||
1171 | SND_SOC_DAPM_AIF_OUT("AIF1TX1", "Capture", 0, | ||
1172 | WM2200_AUDIO_IF_1_22, WM2200_AIF1TX1_ENA_SHIFT, 0), | ||
1173 | SND_SOC_DAPM_AIF_OUT("AIF1TX2", "Capture", 1, | ||
1174 | WM2200_AUDIO_IF_1_22, WM2200_AIF1TX2_ENA_SHIFT, 0), | ||
1175 | SND_SOC_DAPM_AIF_OUT("AIF1TX3", "Capture", 2, | ||
1176 | WM2200_AUDIO_IF_1_22, WM2200_AIF1TX3_ENA_SHIFT, 0), | ||
1177 | SND_SOC_DAPM_AIF_OUT("AIF1TX4", "Capture", 3, | ||
1178 | WM2200_AUDIO_IF_1_22, WM2200_AIF1TX4_ENA_SHIFT, 0), | ||
1179 | SND_SOC_DAPM_AIF_OUT("AIF1TX5", "Capture", 4, | ||
1180 | WM2200_AUDIO_IF_1_22, WM2200_AIF1TX5_ENA_SHIFT, 0), | ||
1181 | SND_SOC_DAPM_AIF_OUT("AIF1TX6", "Capture", 5, | ||
1182 | WM2200_AUDIO_IF_1_22, WM2200_AIF1TX6_ENA_SHIFT, 0), | ||
1183 | |||
1184 | SND_SOC_DAPM_PGA_S("OUT1L", 0, WM2200_OUTPUT_ENABLES, | ||
1185 | WM2200_OUT1L_ENA_SHIFT, 0, NULL, 0), | ||
1186 | SND_SOC_DAPM_PGA_S("OUT1R", 0, WM2200_OUTPUT_ENABLES, | ||
1187 | WM2200_OUT1R_ENA_SHIFT, 0, NULL, 0), | ||
1188 | |||
1189 | SND_SOC_DAPM_PGA_S("EPD_LP", 1, WM2200_EAR_PIECE_CTRL_1, | ||
1190 | WM2200_EPD_LP_ENA_SHIFT, 0, NULL, 0), | ||
1191 | SND_SOC_DAPM_PGA_S("EPD_OUTP_LP", 1, WM2200_EAR_PIECE_CTRL_1, | ||
1192 | WM2200_EPD_OUTP_LP_ENA_SHIFT, 0, NULL, 0), | ||
1193 | SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LP", 1, WM2200_EAR_PIECE_CTRL_1, | ||
1194 | WM2200_EPD_RMV_SHRT_LP_SHIFT, 0, NULL, 0), | ||
1195 | |||
1196 | SND_SOC_DAPM_PGA_S("EPD_LN", 1, WM2200_EAR_PIECE_CTRL_1, | ||
1197 | WM2200_EPD_LN_ENA_SHIFT, 0, NULL, 0), | ||
1198 | SND_SOC_DAPM_PGA_S("EPD_OUTP_LN", 1, WM2200_EAR_PIECE_CTRL_1, | ||
1199 | WM2200_EPD_OUTP_LN_ENA_SHIFT, 0, NULL, 0), | ||
1200 | SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_LN", 1, WM2200_EAR_PIECE_CTRL_1, | ||
1201 | WM2200_EPD_RMV_SHRT_LN_SHIFT, 0, NULL, 0), | ||
1202 | |||
1203 | SND_SOC_DAPM_PGA_S("EPD_RP", 1, WM2200_EAR_PIECE_CTRL_2, | ||
1204 | WM2200_EPD_RP_ENA_SHIFT, 0, NULL, 0), | ||
1205 | SND_SOC_DAPM_PGA_S("EPD_OUTP_RP", 1, WM2200_EAR_PIECE_CTRL_2, | ||
1206 | WM2200_EPD_OUTP_RP_ENA_SHIFT, 0, NULL, 0), | ||
1207 | SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RP", 1, WM2200_EAR_PIECE_CTRL_2, | ||
1208 | WM2200_EPD_RMV_SHRT_RP_SHIFT, 0, NULL, 0), | ||
1209 | |||
1210 | SND_SOC_DAPM_PGA_S("EPD_RN", 1, WM2200_EAR_PIECE_CTRL_2, | ||
1211 | WM2200_EPD_RN_ENA_SHIFT, 0, NULL, 0), | ||
1212 | SND_SOC_DAPM_PGA_S("EPD_OUTP_RN", 1, WM2200_EAR_PIECE_CTRL_2, | ||
1213 | WM2200_EPD_OUTP_RN_ENA_SHIFT, 0, NULL, 0), | ||
1214 | SND_SOC_DAPM_PGA_S("EPD_RMV_SHRT_RN", 1, WM2200_EAR_PIECE_CTRL_2, | ||
1215 | WM2200_EPD_RMV_SHRT_RN_SHIFT, 0, NULL, 0), | ||
1216 | |||
1217 | SND_SOC_DAPM_PGA("OUT2L", WM2200_OUTPUT_ENABLES, WM2200_OUT2L_ENA_SHIFT, | ||
1218 | 0, NULL, 0), | ||
1219 | SND_SOC_DAPM_PGA("OUT2R", WM2200_OUTPUT_ENABLES, WM2200_OUT2R_ENA_SHIFT, | ||
1220 | 0, NULL, 0), | ||
1221 | |||
1222 | SND_SOC_DAPM_OUTPUT("EPOUTLN"), | ||
1223 | SND_SOC_DAPM_OUTPUT("EPOUTLP"), | ||
1224 | SND_SOC_DAPM_OUTPUT("EPOUTRN"), | ||
1225 | SND_SOC_DAPM_OUTPUT("EPOUTRP"), | ||
1226 | SND_SOC_DAPM_OUTPUT("SPK"), | ||
1227 | |||
1228 | WM2200_MIXER_WIDGETS(EQL, "EQL"), | ||
1229 | WM2200_MIXER_WIDGETS(EQR, "EQR"), | ||
1230 | |||
1231 | WM2200_MIXER_WIDGETS(LHPF1, "LHPF1"), | ||
1232 | WM2200_MIXER_WIDGETS(LHPF2, "LHPF2"), | ||
1233 | |||
1234 | WM2200_MIXER_WIDGETS(DSP1L, "DSP1L"), | ||
1235 | WM2200_MIXER_WIDGETS(DSP1R, "DSP1R"), | ||
1236 | WM2200_MIXER_WIDGETS(DSP2L, "DSP2L"), | ||
1237 | WM2200_MIXER_WIDGETS(DSP2R, "DSP2R"), | ||
1238 | |||
1239 | WM2200_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"), | ||
1240 | WM2200_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"), | ||
1241 | WM2200_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"), | ||
1242 | WM2200_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"), | ||
1243 | WM2200_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"), | ||
1244 | WM2200_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"), | ||
1245 | |||
1246 | WM2200_MIXER_WIDGETS(OUT1L, "OUT1L"), | ||
1247 | WM2200_MIXER_WIDGETS(OUT1R, "OUT1R"), | ||
1248 | WM2200_MIXER_WIDGETS(OUT2L, "OUT2L"), | ||
1249 | WM2200_MIXER_WIDGETS(OUT2R, "OUT2R"), | ||
1250 | }; | ||
1251 | |||
1252 | static const struct snd_soc_dapm_route wm2200_dapm_routes[] = { | ||
1253 | /* Everything needs SYSCLK but only hook up things on the edge | ||
1254 | * of the chip */ | ||
1255 | { "IN1L", NULL, "SYSCLK" }, | ||
1256 | { "IN1R", NULL, "SYSCLK" }, | ||
1257 | { "IN2L", NULL, "SYSCLK" }, | ||
1258 | { "IN2R", NULL, "SYSCLK" }, | ||
1259 | { "IN3L", NULL, "SYSCLK" }, | ||
1260 | { "IN3R", NULL, "SYSCLK" }, | ||
1261 | { "OUT1L", NULL, "SYSCLK" }, | ||
1262 | { "OUT1R", NULL, "SYSCLK" }, | ||
1263 | { "OUT2L", NULL, "SYSCLK" }, | ||
1264 | { "OUT2R", NULL, "SYSCLK" }, | ||
1265 | { "AIF1RX1", NULL, "SYSCLK" }, | ||
1266 | { "AIF1RX2", NULL, "SYSCLK" }, | ||
1267 | { "AIF1RX3", NULL, "SYSCLK" }, | ||
1268 | { "AIF1RX4", NULL, "SYSCLK" }, | ||
1269 | { "AIF1RX5", NULL, "SYSCLK" }, | ||
1270 | { "AIF1RX6", NULL, "SYSCLK" }, | ||
1271 | { "AIF1TX1", NULL, "SYSCLK" }, | ||
1272 | { "AIF1TX2", NULL, "SYSCLK" }, | ||
1273 | { "AIF1TX3", NULL, "SYSCLK" }, | ||
1274 | { "AIF1TX4", NULL, "SYSCLK" }, | ||
1275 | { "AIF1TX5", NULL, "SYSCLK" }, | ||
1276 | { "AIF1TX6", NULL, "SYSCLK" }, | ||
1277 | |||
1278 | { "IN1L", NULL, "AVDD" }, | ||
1279 | { "IN1R", NULL, "AVDD" }, | ||
1280 | { "IN2L", NULL, "AVDD" }, | ||
1281 | { "IN2R", NULL, "AVDD" }, | ||
1282 | { "IN3L", NULL, "AVDD" }, | ||
1283 | { "IN3R", NULL, "AVDD" }, | ||
1284 | { "OUT1L", NULL, "AVDD" }, | ||
1285 | { "OUT1R", NULL, "AVDD" }, | ||
1286 | |||
1287 | { "IN1L PGA", NULL, "IN1L" }, | ||
1288 | { "IN1R PGA", NULL, "IN1R" }, | ||
1289 | { "IN2L PGA", NULL, "IN2L" }, | ||
1290 | { "IN2R PGA", NULL, "IN2R" }, | ||
1291 | { "IN3L PGA", NULL, "IN3L" }, | ||
1292 | { "IN3R PGA", NULL, "IN3R" }, | ||
1293 | |||
1294 | { "Tone Generator", NULL, "TONE" }, | ||
1295 | |||
1296 | { "CP2", NULL, "CPVDD" }, | ||
1297 | { "MICBIAS1", NULL, "CP2" }, | ||
1298 | { "MICBIAS2", NULL, "CP2" }, | ||
1299 | |||
1300 | { "CP1", NULL, "CPVDD" }, | ||
1301 | { "EPD_LN", NULL, "CP1" }, | ||
1302 | { "EPD_LP", NULL, "CP1" }, | ||
1303 | { "EPD_RN", NULL, "CP1" }, | ||
1304 | { "EPD_RP", NULL, "CP1" }, | ||
1305 | |||
1306 | { "EPD_LP", NULL, "OUT1L" }, | ||
1307 | { "EPD_OUTP_LP", NULL, "EPD_LP" }, | ||
1308 | { "EPD_RMV_SHRT_LP", NULL, "EPD_OUTP_LP" }, | ||
1309 | { "EPOUTLP", NULL, "EPD_RMV_SHRT_LP" }, | ||
1310 | |||
1311 | { "EPD_LN", NULL, "OUT1L" }, | ||
1312 | { "EPD_OUTP_LN", NULL, "EPD_LN" }, | ||
1313 | { "EPD_RMV_SHRT_LN", NULL, "EPD_OUTP_LN" }, | ||
1314 | { "EPOUTLN", NULL, "EPD_RMV_SHRT_LN" }, | ||
1315 | |||
1316 | { "EPD_RP", NULL, "OUT1R" }, | ||
1317 | { "EPD_OUTP_RP", NULL, "EPD_RP" }, | ||
1318 | { "EPD_RMV_SHRT_RP", NULL, "EPD_OUTP_RP" }, | ||
1319 | { "EPOUTRP", NULL, "EPD_RMV_SHRT_RP" }, | ||
1320 | |||
1321 | { "EPD_RN", NULL, "OUT1R" }, | ||
1322 | { "EPD_OUTP_RN", NULL, "EPD_RN" }, | ||
1323 | { "EPD_RMV_SHRT_RN", NULL, "EPD_OUTP_RN" }, | ||
1324 | { "EPOUTRN", NULL, "EPD_RMV_SHRT_RN" }, | ||
1325 | |||
1326 | { "SPK", NULL, "OUT2L" }, | ||
1327 | { "SPK", NULL, "OUT2R" }, | ||
1328 | |||
1329 | WM2200_MIXER_ROUTES("DSP1", "DSP1L"), | ||
1330 | WM2200_MIXER_ROUTES("DSP1", "DSP1R"), | ||
1331 | WM2200_MIXER_ROUTES("DSP2", "DSP2L"), | ||
1332 | WM2200_MIXER_ROUTES("DSP2", "DSP2R"), | ||
1333 | |||
1334 | WM2200_MIXER_ROUTES("OUT1L", "OUT1L"), | ||
1335 | WM2200_MIXER_ROUTES("OUT1R", "OUT1R"), | ||
1336 | WM2200_MIXER_ROUTES("OUT2L", "OUT2L"), | ||
1337 | WM2200_MIXER_ROUTES("OUT2R", "OUT2R"), | ||
1338 | |||
1339 | WM2200_MIXER_ROUTES("AIF1TX1", "AIF1TX1"), | ||
1340 | WM2200_MIXER_ROUTES("AIF1TX2", "AIF1TX2"), | ||
1341 | WM2200_MIXER_ROUTES("AIF1TX3", "AIF1TX3"), | ||
1342 | WM2200_MIXER_ROUTES("AIF1TX4", "AIF1TX4"), | ||
1343 | WM2200_MIXER_ROUTES("AIF1TX5", "AIF1TX5"), | ||
1344 | WM2200_MIXER_ROUTES("AIF1TX6", "AIF1TX6"), | ||
1345 | |||
1346 | WM2200_MIXER_ROUTES("EQL", "EQL"), | ||
1347 | WM2200_MIXER_ROUTES("EQR", "EQR"), | ||
1348 | |||
1349 | WM2200_MIXER_ROUTES("LHPF1", "LHPF1"), | ||
1350 | WM2200_MIXER_ROUTES("LHPF2", "LHPF2"), | ||
1351 | }; | ||
1352 | |||
1353 | static int wm2200_probe(struct snd_soc_codec *codec) | ||
1354 | { | ||
1355 | struct wm2200_priv *wm2200 = dev_get_drvdata(codec->dev); | ||
1356 | int ret; | ||
1357 | |||
1358 | wm2200->codec = codec; | ||
1359 | codec->control_data = wm2200->regmap; | ||
1360 | codec->dapm.bias_level = SND_SOC_BIAS_OFF; | ||
1361 | |||
1362 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | ||
1363 | if (ret != 0) { | ||
1364 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
1365 | return ret; | ||
1366 | } | ||
1367 | |||
1368 | return ret; | ||
1369 | } | ||
1370 | |||
1371 | static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
1372 | { | ||
1373 | struct snd_soc_codec *codec = dai->codec; | ||
1374 | int lrclk, bclk, fmt_val; | ||
1375 | |||
1376 | lrclk = 0; | ||
1377 | bclk = 0; | ||
1378 | |||
1379 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
1380 | case SND_SOC_DAIFMT_DSP_A: | ||
1381 | fmt_val = 0; | ||
1382 | break; | ||
1383 | case SND_SOC_DAIFMT_DSP_B: | ||
1384 | fmt_val = 1; | ||
1385 | break; | ||
1386 | case SND_SOC_DAIFMT_I2S: | ||
1387 | fmt_val = 2; | ||
1388 | break; | ||
1389 | case SND_SOC_DAIFMT_LEFT_J: | ||
1390 | fmt_val = 3; | ||
1391 | break; | ||
1392 | default: | ||
1393 | dev_err(codec->dev, "Unsupported DAI format %d\n", | ||
1394 | fmt & SND_SOC_DAIFMT_FORMAT_MASK); | ||
1395 | return -EINVAL; | ||
1396 | } | ||
1397 | |||
1398 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
1399 | case SND_SOC_DAIFMT_CBS_CFS: | ||
1400 | break; | ||
1401 | case SND_SOC_DAIFMT_CBS_CFM: | ||
1402 | lrclk |= WM2200_AIF1TX_LRCLK_MSTR; | ||
1403 | break; | ||
1404 | case SND_SOC_DAIFMT_CBM_CFS: | ||
1405 | bclk |= WM2200_AIF1_BCLK_MSTR; | ||
1406 | break; | ||
1407 | case SND_SOC_DAIFMT_CBM_CFM: | ||
1408 | lrclk |= WM2200_AIF1TX_LRCLK_MSTR; | ||
1409 | bclk |= WM2200_AIF1_BCLK_MSTR; | ||
1410 | break; | ||
1411 | default: | ||
1412 | dev_err(codec->dev, "Unsupported master mode %d\n", | ||
1413 | fmt & SND_SOC_DAIFMT_MASTER_MASK); | ||
1414 | return -EINVAL; | ||
1415 | } | ||
1416 | |||
1417 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
1418 | case SND_SOC_DAIFMT_NB_NF: | ||
1419 | break; | ||
1420 | case SND_SOC_DAIFMT_IB_IF: | ||
1421 | bclk |= WM2200_AIF1_BCLK_INV; | ||
1422 | lrclk |= WM2200_AIF1TX_LRCLK_INV; | ||
1423 | break; | ||
1424 | case SND_SOC_DAIFMT_IB_NF: | ||
1425 | bclk |= WM2200_AIF1_BCLK_INV; | ||
1426 | break; | ||
1427 | case SND_SOC_DAIFMT_NB_IF: | ||
1428 | lrclk |= WM2200_AIF1TX_LRCLK_INV; | ||
1429 | break; | ||
1430 | default: | ||
1431 | return -EINVAL; | ||
1432 | } | ||
1433 | |||
1434 | snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1, WM2200_AIF1_BCLK_MSTR | | ||
1435 | WM2200_AIF1_BCLK_INV, bclk); | ||
1436 | snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2, | ||
1437 | WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV, | ||
1438 | lrclk); | ||
1439 | snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_3, | ||
1440 | WM2200_AIF1TX_LRCLK_MSTR | WM2200_AIF1TX_LRCLK_INV, | ||
1441 | lrclk); | ||
1442 | snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_5, | ||
1443 | WM2200_AIF1_FMT_MASK << 1, fmt_val << 1); | ||
1444 | |||
1445 | return 0; | ||
1446 | } | ||
1447 | |||
1448 | static int wm2200_sr_code[] = { | ||
1449 | 0, | ||
1450 | 12000, | ||
1451 | 24000, | ||
1452 | 48000, | ||
1453 | 96000, | ||
1454 | 192000, | ||
1455 | 384000, | ||
1456 | 768000, | ||
1457 | 0, | ||
1458 | 11025, | ||
1459 | 22050, | ||
1460 | 44100, | ||
1461 | 88200, | ||
1462 | 176400, | ||
1463 | 352800, | ||
1464 | 705600, | ||
1465 | 4000, | ||
1466 | 8000, | ||
1467 | 16000, | ||
1468 | 32000, | ||
1469 | 64000, | ||
1470 | 128000, | ||
1471 | 256000, | ||
1472 | 512000, | ||
1473 | }; | ||
1474 | |||
1475 | #define WM2200_NUM_BCLK_RATES 12 | ||
1476 | |||
1477 | static int wm2200_bclk_rates_dat[WM2200_NUM_BCLK_RATES] = { | ||
1478 | 6144000, | ||
1479 | 3072000, | ||
1480 | 2048000, | ||
1481 | 1536000, | ||
1482 | 768000, | ||
1483 | 512000, | ||
1484 | 384000, | ||
1485 | 256000, | ||
1486 | 192000, | ||
1487 | 128000, | ||
1488 | 96000, | ||
1489 | 64000, | ||
1490 | }; | ||
1491 | |||
1492 | static int wm2200_bclk_rates_cd[WM2200_NUM_BCLK_RATES] = { | ||
1493 | 5644800, | ||
1494 | 2882400, | ||
1495 | 1881600, | ||
1496 | 1411200, | ||
1497 | 705600, | ||
1498 | 470400, | ||
1499 | 352800, | ||
1500 | 176400, | ||
1501 | 117600, | ||
1502 | 88200, | ||
1503 | 58800, | ||
1504 | }; | ||
1505 | |||
1506 | static int wm2200_hw_params(struct snd_pcm_substream *substream, | ||
1507 | struct snd_pcm_hw_params *params, | ||
1508 | struct snd_soc_dai *dai) | ||
1509 | { | ||
1510 | struct snd_soc_codec *codec = dai->codec; | ||
1511 | struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec); | ||
1512 | int i, bclk, lrclk, wl, fl, sr_code; | ||
1513 | int *bclk_rates; | ||
1514 | |||
1515 | /* Data sizes if not using TDM */ | ||
1516 | wl = snd_pcm_format_width(params_format(params)); | ||
1517 | if (wl < 0) | ||
1518 | return wl; | ||
1519 | fl = snd_soc_params_to_frame_size(params); | ||
1520 | if (fl < 0) | ||
1521 | return fl; | ||
1522 | |||
1523 | dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n", | ||
1524 | wl, fl); | ||
1525 | |||
1526 | /* Target BCLK rate */ | ||
1527 | bclk = snd_soc_params_to_bclk(params); | ||
1528 | if (bclk < 0) | ||
1529 | return bclk; | ||
1530 | |||
1531 | if (!wm2200->sysclk) { | ||
1532 | dev_err(codec->dev, "SYSCLK has no rate set\n"); | ||
1533 | return -EINVAL; | ||
1534 | } | ||
1535 | |||
1536 | for (i = 0; i < ARRAY_SIZE(wm2200_sr_code); i++) | ||
1537 | if (wm2200_sr_code[i] == params_rate(params)) | ||
1538 | break; | ||
1539 | if (i == ARRAY_SIZE(wm2200_sr_code)) { | ||
1540 | dev_err(codec->dev, "Unsupported sample rate: %dHz\n", | ||
1541 | params_rate(params)); | ||
1542 | return -EINVAL; | ||
1543 | } | ||
1544 | sr_code = i; | ||
1545 | |||
1546 | dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz SYSCLK\n", | ||
1547 | bclk, wm2200->sysclk); | ||
1548 | |||
1549 | if (wm2200->sysclk % 4000) | ||
1550 | bclk_rates = wm2200_bclk_rates_cd; | ||
1551 | else | ||
1552 | bclk_rates = wm2200_bclk_rates_dat; | ||
1553 | |||
1554 | for (i = 0; i < WM2200_NUM_BCLK_RATES; i++) | ||
1555 | if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0)) | ||
1556 | break; | ||
1557 | if (i == WM2200_NUM_BCLK_RATES) { | ||
1558 | dev_err(codec->dev, | ||
1559 | "No valid BCLK for %dHz found from %dHz SYSCLK\n", | ||
1560 | bclk, wm2200->sysclk); | ||
1561 | return -EINVAL; | ||
1562 | } | ||
1563 | |||
1564 | bclk = i; | ||
1565 | dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]); | ||
1566 | snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_1, | ||
1567 | WM2200_AIF1_BCLK_DIV_MASK, bclk); | ||
1568 | |||
1569 | lrclk = bclk_rates[bclk] / params_rate(params); | ||
1570 | dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk); | ||
1571 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || | ||
1572 | dai->symmetric_rates) | ||
1573 | snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_7, | ||
1574 | WM2200_AIF1RX_BCPF_MASK, lrclk); | ||
1575 | else | ||
1576 | snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_6, | ||
1577 | WM2200_AIF1TX_BCPF_MASK, lrclk); | ||
1578 | |||
1579 | i = (wl << WM2200_AIF1TX_WL_SHIFT) | wl; | ||
1580 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
1581 | snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_9, | ||
1582 | WM2200_AIF1RX_WL_MASK | | ||
1583 | WM2200_AIF1RX_SLOT_LEN_MASK, i); | ||
1584 | else | ||
1585 | snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_8, | ||
1586 | WM2200_AIF1TX_WL_MASK | | ||
1587 | WM2200_AIF1TX_SLOT_LEN_MASK, i); | ||
1588 | |||
1589 | snd_soc_update_bits(codec, WM2200_CLOCKING_4, | ||
1590 | WM2200_SAMPLE_RATE_1_MASK, sr_code); | ||
1591 | |||
1592 | return 0; | ||
1593 | } | ||
1594 | |||
1595 | static const struct snd_soc_dai_ops wm2200_dai_ops = { | ||
1596 | .set_fmt = wm2200_set_fmt, | ||
1597 | .hw_params = wm2200_hw_params, | ||
1598 | }; | ||
1599 | |||
1600 | static int wm2200_set_sysclk(struct snd_soc_codec *codec, int clk_id, | ||
1601 | int source, unsigned int freq, int dir) | ||
1602 | { | ||
1603 | struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec); | ||
1604 | int fval; | ||
1605 | |||
1606 | switch (clk_id) { | ||
1607 | case WM2200_CLK_SYSCLK: | ||
1608 | break; | ||
1609 | |||
1610 | default: | ||
1611 | dev_err(codec->dev, "Unknown clock %d\n", clk_id); | ||
1612 | return -EINVAL; | ||
1613 | } | ||
1614 | |||
1615 | switch (source) { | ||
1616 | case WM2200_CLKSRC_MCLK1: | ||
1617 | case WM2200_CLKSRC_MCLK2: | ||
1618 | case WM2200_CLKSRC_FLL: | ||
1619 | case WM2200_CLKSRC_BCLK1: | ||
1620 | break; | ||
1621 | default: | ||
1622 | dev_err(codec->dev, "Invalid source %d\n", source); | ||
1623 | return -EINVAL; | ||
1624 | } | ||
1625 | |||
1626 | switch (freq) { | ||
1627 | case 22579200: | ||
1628 | case 24576000: | ||
1629 | fval = 2; | ||
1630 | break; | ||
1631 | default: | ||
1632 | dev_err(codec->dev, "Invalid clock rate: %d\n", freq); | ||
1633 | return -EINVAL; | ||
1634 | } | ||
1635 | |||
1636 | /* TODO: Check if MCLKs are in use and enable/disable pulls to | ||
1637 | * match. | ||
1638 | */ | ||
1639 | |||
1640 | snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_FREQ_MASK | | ||
1641 | WM2200_SYSCLK_SRC_MASK, | ||
1642 | fval << WM2200_SYSCLK_FREQ_SHIFT | source); | ||
1643 | |||
1644 | wm2200->sysclk = freq; | ||
1645 | |||
1646 | return 0; | ||
1647 | } | ||
1648 | |||
1649 | struct _fll_div { | ||
1650 | u16 fll_fratio; | ||
1651 | u16 fll_outdiv; | ||
1652 | u16 fll_refclk_div; | ||
1653 | u16 n; | ||
1654 | u16 theta; | ||
1655 | u16 lambda; | ||
1656 | }; | ||
1657 | |||
1658 | static struct { | ||
1659 | unsigned int min; | ||
1660 | unsigned int max; | ||
1661 | u16 fll_fratio; | ||
1662 | int ratio; | ||
1663 | } fll_fratios[] = { | ||
1664 | { 0, 64000, 4, 16 }, | ||
1665 | { 64000, 128000, 3, 8 }, | ||
1666 | { 128000, 256000, 2, 4 }, | ||
1667 | { 256000, 1000000, 1, 2 }, | ||
1668 | { 1000000, 13500000, 0, 1 }, | ||
1669 | }; | ||
1670 | |||
1671 | static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, | ||
1672 | unsigned int Fout) | ||
1673 | { | ||
1674 | unsigned int target; | ||
1675 | unsigned int div; | ||
1676 | unsigned int fratio, gcd_fll; | ||
1677 | int i; | ||
1678 | |||
1679 | /* Fref must be <=13.5MHz */ | ||
1680 | div = 1; | ||
1681 | fll_div->fll_refclk_div = 0; | ||
1682 | while ((Fref / div) > 13500000) { | ||
1683 | div *= 2; | ||
1684 | fll_div->fll_refclk_div++; | ||
1685 | |||
1686 | if (div > 8) { | ||
1687 | pr_err("Can't scale %dMHz input down to <=13.5MHz\n", | ||
1688 | Fref); | ||
1689 | return -EINVAL; | ||
1690 | } | ||
1691 | } | ||
1692 | |||
1693 | pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout); | ||
1694 | |||
1695 | /* Apply the division for our remaining calculations */ | ||
1696 | Fref /= div; | ||
1697 | |||
1698 | /* Fvco should be 90-100MHz; don't check the upper bound */ | ||
1699 | div = 2; | ||
1700 | while (Fout * div < 90000000) { | ||
1701 | div++; | ||
1702 | if (div > 64) { | ||
1703 | pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n", | ||
1704 | Fout); | ||
1705 | return -EINVAL; | ||
1706 | } | ||
1707 | } | ||
1708 | target = Fout * div; | ||
1709 | fll_div->fll_outdiv = div - 1; | ||
1710 | |||
1711 | pr_debug("FLL Fvco=%dHz\n", target); | ||
1712 | |||
1713 | /* Find an appropraite FLL_FRATIO and factor it out of the target */ | ||
1714 | for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { | ||
1715 | if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { | ||
1716 | fll_div->fll_fratio = fll_fratios[i].fll_fratio; | ||
1717 | fratio = fll_fratios[i].ratio; | ||
1718 | break; | ||
1719 | } | ||
1720 | } | ||
1721 | if (i == ARRAY_SIZE(fll_fratios)) { | ||
1722 | pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref); | ||
1723 | return -EINVAL; | ||
1724 | } | ||
1725 | |||
1726 | fll_div->n = target / (fratio * Fref); | ||
1727 | |||
1728 | if (target % Fref == 0) { | ||
1729 | fll_div->theta = 0; | ||
1730 | fll_div->lambda = 0; | ||
1731 | } else { | ||
1732 | gcd_fll = gcd(target, fratio * Fref); | ||
1733 | |||
1734 | fll_div->theta = (target - (fll_div->n * fratio * Fref)) | ||
1735 | / gcd_fll; | ||
1736 | fll_div->lambda = (fratio * Fref) / gcd_fll; | ||
1737 | } | ||
1738 | |||
1739 | pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n", | ||
1740 | fll_div->n, fll_div->theta, fll_div->lambda); | ||
1741 | pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n", | ||
1742 | fll_div->fll_fratio, fratio, fll_div->fll_outdiv, | ||
1743 | fll_div->fll_refclk_div); | ||
1744 | |||
1745 | return 0; | ||
1746 | } | ||
1747 | |||
1748 | static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | ||
1749 | unsigned int Fref, unsigned int Fout) | ||
1750 | { | ||
1751 | struct i2c_client *i2c = to_i2c_client(codec->dev); | ||
1752 | struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec); | ||
1753 | struct _fll_div factors; | ||
1754 | int ret, i, timeout; | ||
1755 | |||
1756 | if (!Fout) { | ||
1757 | dev_dbg(codec->dev, "FLL disabled"); | ||
1758 | |||
1759 | if (wm2200->fll_fout) | ||
1760 | pm_runtime_put(codec->dev); | ||
1761 | |||
1762 | wm2200->fll_fout = 0; | ||
1763 | snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1, | ||
1764 | WM2200_FLL_ENA, 0); | ||
1765 | return 0; | ||
1766 | } | ||
1767 | |||
1768 | switch (source) { | ||
1769 | case WM2200_FLL_SRC_MCLK1: | ||
1770 | case WM2200_FLL_SRC_MCLK2: | ||
1771 | case WM2200_FLL_SRC_BCLK: | ||
1772 | break; | ||
1773 | default: | ||
1774 | dev_err(codec->dev, "Invalid FLL source %d\n", source); | ||
1775 | return -EINVAL; | ||
1776 | } | ||
1777 | |||
1778 | ret = fll_factors(&factors, Fref, Fout); | ||
1779 | if (ret < 0) | ||
1780 | return ret; | ||
1781 | |||
1782 | /* Disable the FLL while we reconfigure */ | ||
1783 | snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1, WM2200_FLL_ENA, 0); | ||
1784 | |||
1785 | snd_soc_update_bits(codec, WM2200_FLL_CONTROL_2, | ||
1786 | WM2200_FLL_OUTDIV_MASK | WM2200_FLL_FRATIO_MASK, | ||
1787 | (factors.fll_outdiv << WM2200_FLL_OUTDIV_SHIFT) | | ||
1788 | factors.fll_fratio); | ||
1789 | if (factors.theta) { | ||
1790 | snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3, | ||
1791 | WM2200_FLL_FRACN_ENA, | ||
1792 | WM2200_FLL_FRACN_ENA); | ||
1793 | snd_soc_update_bits(codec, WM2200_FLL_EFS_2, | ||
1794 | WM2200_FLL_EFS_ENA, | ||
1795 | WM2200_FLL_EFS_ENA); | ||
1796 | } else { | ||
1797 | snd_soc_update_bits(codec, WM2200_FLL_CONTROL_3, | ||
1798 | WM2200_FLL_FRACN_ENA, 0); | ||
1799 | snd_soc_update_bits(codec, WM2200_FLL_EFS_2, | ||
1800 | WM2200_FLL_EFS_ENA, 0); | ||
1801 | } | ||
1802 | |||
1803 | snd_soc_update_bits(codec, WM2200_FLL_CONTROL_4, WM2200_FLL_THETA_MASK, | ||
1804 | factors.theta); | ||
1805 | snd_soc_update_bits(codec, WM2200_FLL_CONTROL_6, WM2200_FLL_N_MASK, | ||
1806 | factors.n); | ||
1807 | snd_soc_update_bits(codec, WM2200_FLL_CONTROL_7, | ||
1808 | WM2200_FLL_CLK_REF_DIV_MASK | | ||
1809 | WM2200_FLL_CLK_REF_SRC_MASK, | ||
1810 | (factors.fll_refclk_div | ||
1811 | << WM2200_FLL_CLK_REF_DIV_SHIFT) | source); | ||
1812 | snd_soc_update_bits(codec, WM2200_FLL_EFS_1, | ||
1813 | WM2200_FLL_LAMBDA_MASK, factors.lambda); | ||
1814 | |||
1815 | /* Clear any pending completions */ | ||
1816 | try_wait_for_completion(&wm2200->fll_lock); | ||
1817 | |||
1818 | pm_runtime_get_sync(codec->dev); | ||
1819 | |||
1820 | snd_soc_update_bits(codec, WM2200_FLL_CONTROL_1, | ||
1821 | WM2200_FLL_ENA, WM2200_FLL_ENA); | ||
1822 | |||
1823 | if (i2c->irq) | ||
1824 | timeout = 2; | ||
1825 | else | ||
1826 | timeout = 50; | ||
1827 | |||
1828 | snd_soc_update_bits(codec, WM2200_CLOCKING_3, WM2200_SYSCLK_ENA, | ||
1829 | WM2200_SYSCLK_ENA); | ||
1830 | |||
1831 | /* Poll for the lock; will use the interrupt to exit quickly */ | ||
1832 | for (i = 0; i < timeout; i++) { | ||
1833 | if (i2c->irq) { | ||
1834 | ret = wait_for_completion_timeout(&wm2200->fll_lock, | ||
1835 | msecs_to_jiffies(25)); | ||
1836 | if (ret > 0) | ||
1837 | break; | ||
1838 | } else { | ||
1839 | msleep(1); | ||
1840 | } | ||
1841 | |||
1842 | ret = snd_soc_read(codec, | ||
1843 | WM2200_INTERRUPT_RAW_STATUS_2); | ||
1844 | if (ret < 0) { | ||
1845 | dev_err(codec->dev, | ||
1846 | "Failed to read FLL status: %d\n", | ||
1847 | ret); | ||
1848 | continue; | ||
1849 | } | ||
1850 | if (ret & WM2200_FLL_LOCK_STS) | ||
1851 | break; | ||
1852 | } | ||
1853 | if (i == timeout) { | ||
1854 | dev_err(codec->dev, "FLL lock timed out\n"); | ||
1855 | pm_runtime_put(codec->dev); | ||
1856 | return -ETIMEDOUT; | ||
1857 | } | ||
1858 | |||
1859 | wm2200->fll_src = source; | ||
1860 | wm2200->fll_fref = Fref; | ||
1861 | wm2200->fll_fout = Fout; | ||
1862 | |||
1863 | dev_dbg(codec->dev, "FLL running %dHz->%dHz\n", Fref, Fout); | ||
1864 | |||
1865 | return 0; | ||
1866 | } | ||
1867 | |||
1868 | static int wm2200_dai_probe(struct snd_soc_dai *dai) | ||
1869 | { | ||
1870 | struct snd_soc_codec *codec = dai->codec; | ||
1871 | unsigned int val = 0; | ||
1872 | int ret; | ||
1873 | |||
1874 | ret = snd_soc_read(codec, WM2200_GPIO_CTRL_1); | ||
1875 | if (ret >= 0) { | ||
1876 | if ((ret & WM2200_GP1_FN_MASK) != 0) { | ||
1877 | dai->symmetric_rates = true; | ||
1878 | val = WM2200_AIF1TX_LRCLK_SRC; | ||
1879 | } | ||
1880 | } else { | ||
1881 | dev_err(codec->dev, "Failed to read GPIO 1 config: %d\n", ret); | ||
1882 | } | ||
1883 | |||
1884 | snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_2, | ||
1885 | WM2200_AIF1TX_LRCLK_SRC, val); | ||
1886 | |||
1887 | return 0; | ||
1888 | } | ||
1889 | |||
1890 | #define WM2200_RATES SNDRV_PCM_RATE_8000_48000 | ||
1891 | |||
1892 | #define WM2200_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ | ||
1893 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | ||
1894 | |||
1895 | static struct snd_soc_dai_driver wm2200_dai = { | ||
1896 | .name = "wm2200", | ||
1897 | .probe = wm2200_dai_probe, | ||
1898 | .playback = { | ||
1899 | .stream_name = "Playback", | ||
1900 | .channels_min = 2, | ||
1901 | .channels_max = 2, | ||
1902 | .rates = WM2200_RATES, | ||
1903 | .formats = WM2200_FORMATS, | ||
1904 | }, | ||
1905 | .capture = { | ||
1906 | .stream_name = "Capture", | ||
1907 | .channels_min = 2, | ||
1908 | .channels_max = 2, | ||
1909 | .rates = WM2200_RATES, | ||
1910 | .formats = WM2200_FORMATS, | ||
1911 | }, | ||
1912 | .ops = &wm2200_dai_ops, | ||
1913 | }; | ||
1914 | |||
1915 | static struct snd_soc_codec_driver soc_codec_wm2200 = { | ||
1916 | .probe = wm2200_probe, | ||
1917 | |||
1918 | .idle_bias_off = true, | ||
1919 | .ignore_pmdown_time = true, | ||
1920 | .set_sysclk = wm2200_set_sysclk, | ||
1921 | .set_pll = wm2200_set_fll, | ||
1922 | |||
1923 | .controls = wm2200_snd_controls, | ||
1924 | .num_controls = ARRAY_SIZE(wm2200_snd_controls), | ||
1925 | .dapm_widgets = wm2200_dapm_widgets, | ||
1926 | .num_dapm_widgets = ARRAY_SIZE(wm2200_dapm_widgets), | ||
1927 | .dapm_routes = wm2200_dapm_routes, | ||
1928 | .num_dapm_routes = ARRAY_SIZE(wm2200_dapm_routes), | ||
1929 | }; | ||
1930 | |||
1931 | static irqreturn_t wm2200_irq(int irq, void *data) | ||
1932 | { | ||
1933 | struct wm2200_priv *wm2200 = data; | ||
1934 | unsigned int val, mask; | ||
1935 | int ret; | ||
1936 | |||
1937 | ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, &val); | ||
1938 | if (ret != 0) { | ||
1939 | dev_err(wm2200->dev, "Failed to read IRQ status: %d\n", ret); | ||
1940 | return IRQ_NONE; | ||
1941 | } | ||
1942 | |||
1943 | ret = regmap_read(wm2200->regmap, WM2200_INTERRUPT_STATUS_2_MASK, | ||
1944 | &mask); | ||
1945 | if (ret != 0) { | ||
1946 | dev_warn(wm2200->dev, "Failed to read IRQ mask: %d\n", ret); | ||
1947 | mask = 0; | ||
1948 | } | ||
1949 | |||
1950 | val &= ~mask; | ||
1951 | |||
1952 | if (val & WM2200_FLL_LOCK_EINT) { | ||
1953 | dev_dbg(wm2200->dev, "FLL locked\n"); | ||
1954 | complete(&wm2200->fll_lock); | ||
1955 | } | ||
1956 | |||
1957 | if (val) { | ||
1958 | regmap_write(wm2200->regmap, WM2200_INTERRUPT_STATUS_2, val); | ||
1959 | |||
1960 | return IRQ_HANDLED; | ||
1961 | } else { | ||
1962 | return IRQ_NONE; | ||
1963 | } | ||
1964 | } | ||
1965 | |||
1966 | static const struct regmap_config wm2200_regmap = { | ||
1967 | .reg_bits = 16, | ||
1968 | .val_bits = 16, | ||
1969 | |||
1970 | .max_register = WM2200_MAX_REGISTER, | ||
1971 | .reg_defaults = wm2200_reg_defaults, | ||
1972 | .num_reg_defaults = ARRAY_SIZE(wm2200_reg_defaults), | ||
1973 | .volatile_reg = wm2200_volatile_register, | ||
1974 | .readable_reg = wm2200_readable_register, | ||
1975 | .cache_type = REGCACHE_RBTREE, | ||
1976 | }; | ||
1977 | |||
1978 | static const unsigned int wm2200_dig_vu[] = { | ||
1979 | WM2200_DAC_DIGITAL_VOLUME_1L, | ||
1980 | WM2200_DAC_DIGITAL_VOLUME_1R, | ||
1981 | WM2200_DAC_DIGITAL_VOLUME_2L, | ||
1982 | WM2200_DAC_DIGITAL_VOLUME_2R, | ||
1983 | WM2200_ADC_DIGITAL_VOLUME_1L, | ||
1984 | WM2200_ADC_DIGITAL_VOLUME_1R, | ||
1985 | WM2200_ADC_DIGITAL_VOLUME_2L, | ||
1986 | WM2200_ADC_DIGITAL_VOLUME_2R, | ||
1987 | WM2200_ADC_DIGITAL_VOLUME_3L, | ||
1988 | WM2200_ADC_DIGITAL_VOLUME_3R, | ||
1989 | }; | ||
1990 | |||
1991 | static const unsigned int wm2200_mic_ctrl_reg[] = { | ||
1992 | WM2200_IN1L_CONTROL, | ||
1993 | WM2200_IN2L_CONTROL, | ||
1994 | WM2200_IN3L_CONTROL, | ||
1995 | }; | ||
1996 | |||
1997 | static __devinit int wm2200_i2c_probe(struct i2c_client *i2c, | ||
1998 | const struct i2c_device_id *id) | ||
1999 | { | ||
2000 | struct wm2200_pdata *pdata = dev_get_platdata(&i2c->dev); | ||
2001 | struct wm2200_priv *wm2200; | ||
2002 | unsigned int reg; | ||
2003 | int ret, i; | ||
2004 | |||
2005 | wm2200 = devm_kzalloc(&i2c->dev, sizeof(struct wm2200_priv), | ||
2006 | GFP_KERNEL); | ||
2007 | if (wm2200 == NULL) | ||
2008 | return -ENOMEM; | ||
2009 | |||
2010 | wm2200->dev = &i2c->dev; | ||
2011 | init_completion(&wm2200->fll_lock); | ||
2012 | |||
2013 | wm2200->regmap = regmap_init_i2c(i2c, &wm2200_regmap); | ||
2014 | if (IS_ERR(wm2200->regmap)) { | ||
2015 | ret = PTR_ERR(wm2200->regmap); | ||
2016 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
2017 | ret); | ||
2018 | goto err; | ||
2019 | } | ||
2020 | |||
2021 | if (pdata) | ||
2022 | wm2200->pdata = *pdata; | ||
2023 | |||
2024 | i2c_set_clientdata(i2c, wm2200); | ||
2025 | |||
2026 | for (i = 0; i < ARRAY_SIZE(wm2200->core_supplies); i++) | ||
2027 | wm2200->core_supplies[i].supply = wm2200_core_supply_names[i]; | ||
2028 | |||
2029 | ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm2200->core_supplies), | ||
2030 | wm2200->core_supplies); | ||
2031 | if (ret != 0) { | ||
2032 | dev_err(&i2c->dev, "Failed to request core supplies: %d\n", | ||
2033 | ret); | ||
2034 | goto err_regmap; | ||
2035 | } | ||
2036 | |||
2037 | ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies), | ||
2038 | wm2200->core_supplies); | ||
2039 | if (ret != 0) { | ||
2040 | dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", | ||
2041 | ret); | ||
2042 | goto err_core; | ||
2043 | } | ||
2044 | |||
2045 | if (wm2200->pdata.ldo_ena) { | ||
2046 | ret = gpio_request_one(wm2200->pdata.ldo_ena, | ||
2047 | GPIOF_OUT_INIT_HIGH, "WM2200 LDOENA"); | ||
2048 | if (ret < 0) { | ||
2049 | dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n", | ||
2050 | wm2200->pdata.ldo_ena, ret); | ||
2051 | goto err_enable; | ||
2052 | } | ||
2053 | msleep(2); | ||
2054 | } | ||
2055 | |||
2056 | if (wm2200->pdata.reset) { | ||
2057 | ret = gpio_request_one(wm2200->pdata.reset, | ||
2058 | GPIOF_OUT_INIT_HIGH, "WM2200 /RESET"); | ||
2059 | if (ret < 0) { | ||
2060 | dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n", | ||
2061 | wm2200->pdata.reset, ret); | ||
2062 | goto err_ldo; | ||
2063 | } | ||
2064 | } | ||
2065 | |||
2066 | ret = regmap_read(wm2200->regmap, WM2200_SOFTWARE_RESET, ®); | ||
2067 | if (ret < 0) { | ||
2068 | dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret); | ||
2069 | goto err_reset; | ||
2070 | } | ||
2071 | switch (reg) { | ||
2072 | case 0x2200: | ||
2073 | break; | ||
2074 | |||
2075 | default: | ||
2076 | dev_err(&i2c->dev, "Device is not a WM2200, ID is %x\n", reg); | ||
2077 | ret = -EINVAL; | ||
2078 | goto err_reset; | ||
2079 | } | ||
2080 | |||
2081 | ret = regmap_read(wm2200->regmap, WM2200_DEVICE_REVISION, ®); | ||
2082 | if (ret < 0) { | ||
2083 | dev_err(&i2c->dev, "Failed to read revision register\n"); | ||
2084 | goto err_reset; | ||
2085 | } | ||
2086 | |||
2087 | wm2200->rev = reg & WM2200_DEVICE_REVISION_MASK; | ||
2088 | |||
2089 | dev_info(&i2c->dev, "revision %c\n", wm2200->rev + 'A'); | ||
2090 | |||
2091 | switch (wm2200->rev) { | ||
2092 | case 0: | ||
2093 | ret = regmap_register_patch(wm2200->regmap, wm2200_reva_patch, | ||
2094 | ARRAY_SIZE(wm2200_reva_patch)); | ||
2095 | if (ret != 0) { | ||
2096 | dev_err(&i2c->dev, "Failed to register patch: %d\n", | ||
2097 | ret); | ||
2098 | } | ||
2099 | break; | ||
2100 | default: | ||
2101 | break; | ||
2102 | } | ||
2103 | |||
2104 | ret = wm2200_reset(wm2200); | ||
2105 | if (ret < 0) { | ||
2106 | dev_err(&i2c->dev, "Failed to issue reset\n"); | ||
2107 | goto err_reset; | ||
2108 | } | ||
2109 | |||
2110 | for (i = 0; i < ARRAY_SIZE(wm2200->pdata.gpio_defaults); i++) { | ||
2111 | if (!wm2200->pdata.gpio_defaults[i]) | ||
2112 | continue; | ||
2113 | |||
2114 | regmap_write(wm2200->regmap, WM2200_GPIO_CTRL_1 + i, | ||
2115 | wm2200->pdata.gpio_defaults[i]); | ||
2116 | } | ||
2117 | |||
2118 | for (i = 0; i < ARRAY_SIZE(wm2200_dig_vu); i++) | ||
2119 | regmap_update_bits(wm2200->regmap, wm2200_dig_vu[i], | ||
2120 | WM2200_OUT_VU, WM2200_OUT_VU); | ||
2121 | |||
2122 | /* Assign slots 1-6 to channels 1-6 for both TX and RX */ | ||
2123 | for (i = 0; i < 6; i++) { | ||
2124 | regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_10 + i, i); | ||
2125 | regmap_write(wm2200->regmap, WM2200_AUDIO_IF_1_16 + i, i); | ||
2126 | } | ||
2127 | |||
2128 | for (i = 0; i < ARRAY_SIZE(wm2200->pdata.in_mode); i++) { | ||
2129 | regmap_update_bits(wm2200->regmap, wm2200_mic_ctrl_reg[i], | ||
2130 | WM2200_IN1_MODE_MASK | | ||
2131 | WM2200_IN1_DMIC_SUP_MASK, | ||
2132 | (wm2200->pdata.in_mode[i] << | ||
2133 | WM2200_IN1_MODE_SHIFT) | | ||
2134 | (wm2200->pdata.dmic_sup[i] << | ||
2135 | WM2200_IN1_DMIC_SUP_SHIFT)); | ||
2136 | } | ||
2137 | |||
2138 | if (i2c->irq) { | ||
2139 | ret = request_threaded_irq(i2c->irq, NULL, wm2200_irq, | ||
2140 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | ||
2141 | "wm2200", wm2200); | ||
2142 | if (ret == 0) | ||
2143 | regmap_update_bits(wm2200->regmap, | ||
2144 | WM2200_INTERRUPT_STATUS_2_MASK, | ||
2145 | WM2200_FLL_LOCK_EINT, 0); | ||
2146 | else | ||
2147 | dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n", | ||
2148 | i2c->irq, ret); | ||
2149 | } | ||
2150 | |||
2151 | pm_runtime_set_active(&i2c->dev); | ||
2152 | pm_runtime_enable(&i2c->dev); | ||
2153 | pm_request_idle(&i2c->dev); | ||
2154 | |||
2155 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_wm2200, | ||
2156 | &wm2200_dai, 1); | ||
2157 | if (ret != 0) { | ||
2158 | dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); | ||
2159 | goto err_pm_runtime; | ||
2160 | } | ||
2161 | |||
2162 | return 0; | ||
2163 | |||
2164 | err_pm_runtime: | ||
2165 | pm_runtime_disable(&i2c->dev); | ||
2166 | err_reset: | ||
2167 | if (wm2200->pdata.reset) { | ||
2168 | gpio_set_value_cansleep(wm2200->pdata.reset, 0); | ||
2169 | gpio_free(wm2200->pdata.reset); | ||
2170 | } | ||
2171 | err_ldo: | ||
2172 | if (wm2200->pdata.ldo_ena) { | ||
2173 | gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); | ||
2174 | gpio_free(wm2200->pdata.ldo_ena); | ||
2175 | } | ||
2176 | err_enable: | ||
2177 | regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies), | ||
2178 | wm2200->core_supplies); | ||
2179 | err_core: | ||
2180 | regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies), | ||
2181 | wm2200->core_supplies); | ||
2182 | err_regmap: | ||
2183 | regmap_exit(wm2200->regmap); | ||
2184 | err: | ||
2185 | return ret; | ||
2186 | } | ||
2187 | |||
2188 | static __devexit int wm2200_i2c_remove(struct i2c_client *i2c) | ||
2189 | { | ||
2190 | struct wm2200_priv *wm2200 = i2c_get_clientdata(i2c); | ||
2191 | |||
2192 | snd_soc_unregister_codec(&i2c->dev); | ||
2193 | if (i2c->irq) | ||
2194 | free_irq(i2c->irq, wm2200); | ||
2195 | if (wm2200->pdata.reset) { | ||
2196 | gpio_set_value_cansleep(wm2200->pdata.reset, 0); | ||
2197 | gpio_free(wm2200->pdata.reset); | ||
2198 | } | ||
2199 | if (wm2200->pdata.ldo_ena) { | ||
2200 | gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); | ||
2201 | gpio_free(wm2200->pdata.ldo_ena); | ||
2202 | } | ||
2203 | regulator_bulk_free(ARRAY_SIZE(wm2200->core_supplies), | ||
2204 | wm2200->core_supplies); | ||
2205 | regmap_exit(wm2200->regmap); | ||
2206 | |||
2207 | return 0; | ||
2208 | } | ||
2209 | |||
2210 | #ifdef CONFIG_PM_RUNTIME | ||
2211 | static int wm2200_runtime_suspend(struct device *dev) | ||
2212 | { | ||
2213 | struct wm2200_priv *wm2200 = dev_get_drvdata(dev); | ||
2214 | |||
2215 | regcache_cache_only(wm2200->regmap, true); | ||
2216 | regcache_mark_dirty(wm2200->regmap); | ||
2217 | if (wm2200->pdata.ldo_ena) | ||
2218 | gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 0); | ||
2219 | regulator_bulk_disable(ARRAY_SIZE(wm2200->core_supplies), | ||
2220 | wm2200->core_supplies); | ||
2221 | |||
2222 | return 0; | ||
2223 | } | ||
2224 | |||
2225 | static int wm2200_runtime_resume(struct device *dev) | ||
2226 | { | ||
2227 | struct wm2200_priv *wm2200 = dev_get_drvdata(dev); | ||
2228 | int ret; | ||
2229 | |||
2230 | ret = regulator_bulk_enable(ARRAY_SIZE(wm2200->core_supplies), | ||
2231 | wm2200->core_supplies); | ||
2232 | if (ret != 0) { | ||
2233 | dev_err(dev, "Failed to enable supplies: %d\n", | ||
2234 | ret); | ||
2235 | return ret; | ||
2236 | } | ||
2237 | |||
2238 | if (wm2200->pdata.ldo_ena) { | ||
2239 | gpio_set_value_cansleep(wm2200->pdata.ldo_ena, 1); | ||
2240 | msleep(2); | ||
2241 | } | ||
2242 | |||
2243 | regcache_cache_only(wm2200->regmap, false); | ||
2244 | regcache_sync(wm2200->regmap); | ||
2245 | |||
2246 | return 0; | ||
2247 | } | ||
2248 | #endif | ||
2249 | |||
2250 | static struct dev_pm_ops wm2200_pm = { | ||
2251 | SET_RUNTIME_PM_OPS(wm2200_runtime_suspend, wm2200_runtime_resume, | ||
2252 | NULL) | ||
2253 | }; | ||
2254 | |||
2255 | static const struct i2c_device_id wm2200_i2c_id[] = { | ||
2256 | { "wm2200", 0 }, | ||
2257 | { } | ||
2258 | }; | ||
2259 | MODULE_DEVICE_TABLE(i2c, wm2200_i2c_id); | ||
2260 | |||
2261 | static struct i2c_driver wm2200_i2c_driver = { | ||
2262 | .driver = { | ||
2263 | .name = "wm2200", | ||
2264 | .owner = THIS_MODULE, | ||
2265 | .pm = &wm2200_pm, | ||
2266 | }, | ||
2267 | .probe = wm2200_i2c_probe, | ||
2268 | .remove = __devexit_p(wm2200_i2c_remove), | ||
2269 | .id_table = wm2200_i2c_id, | ||
2270 | }; | ||
2271 | |||
2272 | static int __init wm2200_modinit(void) | ||
2273 | { | ||
2274 | return i2c_add_driver(&wm2200_i2c_driver); | ||
2275 | } | ||
2276 | module_init(wm2200_modinit); | ||
2277 | |||
2278 | static void __exit wm2200_exit(void) | ||
2279 | { | ||
2280 | i2c_del_driver(&wm2200_i2c_driver); | ||
2281 | } | ||
2282 | module_exit(wm2200_exit); | ||
2283 | |||
2284 | MODULE_DESCRIPTION("ASoC WM2200 driver"); | ||
2285 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
2286 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/wm2200.h b/sound/soc/codecs/wm2200.h new file mode 100644 index 000000000000..5d719d6b4a8d --- /dev/null +++ b/sound/soc/codecs/wm2200.h | |||
@@ -0,0 +1,3674 @@ | |||
1 | /* | ||
2 | * wm2200.h - WM2200 audio codec interface | ||
3 | * | ||
4 | * Copyright 2012 Wolfson Microelectronics PLC. | ||
5 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | |||
13 | #ifndef _WM2200_H | ||
14 | #define _WM2200_H | ||
15 | |||
16 | #define WM2200_CLK_SYSCLK 1 | ||
17 | |||
18 | #define WM2200_CLKSRC_MCLK1 0 | ||
19 | #define WM2200_CLKSRC_MCLK2 1 | ||
20 | #define WM2200_CLKSRC_FLL 4 | ||
21 | #define WM2200_CLKSRC_BCLK1 8 | ||
22 | |||
23 | #define WM2200_FLL_SRC_MCLK1 0 | ||
24 | #define WM2200_FLL_SRC_MCLK2 1 | ||
25 | #define WM2200_FLL_SRC_BCLK 2 | ||
26 | |||
27 | /* | ||
28 | * Register values. | ||
29 | */ | ||
30 | #define WM2200_SOFTWARE_RESET 0x00 | ||
31 | #define WM2200_DEVICE_REVISION 0x01 | ||
32 | #define WM2200_TONE_GENERATOR_1 0x0B | ||
33 | #define WM2200_CLOCKING_3 0x102 | ||
34 | #define WM2200_CLOCKING_4 0x103 | ||
35 | #define WM2200_FLL_CONTROL_1 0x111 | ||
36 | #define WM2200_FLL_CONTROL_2 0x112 | ||
37 | #define WM2200_FLL_CONTROL_3 0x113 | ||
38 | #define WM2200_FLL_CONTROL_4 0x114 | ||
39 | #define WM2200_FLL_CONTROL_6 0x116 | ||
40 | #define WM2200_FLL_CONTROL_7 0x117 | ||
41 | #define WM2200_FLL_EFS_1 0x119 | ||
42 | #define WM2200_FLL_EFS_2 0x11A | ||
43 | #define WM2200_MIC_CHARGE_PUMP_1 0x200 | ||
44 | #define WM2200_MIC_CHARGE_PUMP_2 0x201 | ||
45 | #define WM2200_DM_CHARGE_PUMP_1 0x202 | ||
46 | #define WM2200_MIC_BIAS_CTRL_1 0x20C | ||
47 | #define WM2200_MIC_BIAS_CTRL_2 0x20D | ||
48 | #define WM2200_EAR_PIECE_CTRL_1 0x20F | ||
49 | #define WM2200_EAR_PIECE_CTRL_2 0x210 | ||
50 | #define WM2200_INPUT_ENABLES 0x301 | ||
51 | #define WM2200_IN1L_CONTROL 0x302 | ||
52 | #define WM2200_IN1R_CONTROL 0x303 | ||
53 | #define WM2200_IN2L_CONTROL 0x304 | ||
54 | #define WM2200_IN2R_CONTROL 0x305 | ||
55 | #define WM2200_IN3L_CONTROL 0x306 | ||
56 | #define WM2200_IN3R_CONTROL 0x307 | ||
57 | #define WM2200_RXANC_SRC 0x30A | ||
58 | #define WM2200_INPUT_VOLUME_RAMP 0x30B | ||
59 | #define WM2200_ADC_DIGITAL_VOLUME_1L 0x30C | ||
60 | #define WM2200_ADC_DIGITAL_VOLUME_1R 0x30D | ||
61 | #define WM2200_ADC_DIGITAL_VOLUME_2L 0x30E | ||
62 | #define WM2200_ADC_DIGITAL_VOLUME_2R 0x30F | ||
63 | #define WM2200_ADC_DIGITAL_VOLUME_3L 0x310 | ||
64 | #define WM2200_ADC_DIGITAL_VOLUME_3R 0x311 | ||
65 | #define WM2200_OUTPUT_ENABLES 0x400 | ||
66 | #define WM2200_DAC_VOLUME_LIMIT_1L 0x401 | ||
67 | #define WM2200_DAC_VOLUME_LIMIT_1R 0x402 | ||
68 | #define WM2200_DAC_VOLUME_LIMIT_2L 0x403 | ||
69 | #define WM2200_DAC_VOLUME_LIMIT_2R 0x404 | ||
70 | #define WM2200_DAC_AEC_CONTROL_1 0x409 | ||
71 | #define WM2200_OUTPUT_VOLUME_RAMP 0x40A | ||
72 | #define WM2200_DAC_DIGITAL_VOLUME_1L 0x40B | ||
73 | #define WM2200_DAC_DIGITAL_VOLUME_1R 0x40C | ||
74 | #define WM2200_DAC_DIGITAL_VOLUME_2L 0x40D | ||
75 | #define WM2200_DAC_DIGITAL_VOLUME_2R 0x40E | ||
76 | #define WM2200_PDM_1 0x417 | ||
77 | #define WM2200_PDM_2 0x418 | ||
78 | #define WM2200_AUDIO_IF_1_1 0x500 | ||
79 | #define WM2200_AUDIO_IF_1_2 0x501 | ||
80 | #define WM2200_AUDIO_IF_1_3 0x502 | ||
81 | #define WM2200_AUDIO_IF_1_4 0x503 | ||
82 | #define WM2200_AUDIO_IF_1_5 0x504 | ||
83 | #define WM2200_AUDIO_IF_1_6 0x505 | ||
84 | #define WM2200_AUDIO_IF_1_7 0x506 | ||
85 | #define WM2200_AUDIO_IF_1_8 0x507 | ||
86 | #define WM2200_AUDIO_IF_1_9 0x508 | ||
87 | #define WM2200_AUDIO_IF_1_10 0x509 | ||
88 | #define WM2200_AUDIO_IF_1_11 0x50A | ||
89 | #define WM2200_AUDIO_IF_1_12 0x50B | ||
90 | #define WM2200_AUDIO_IF_1_13 0x50C | ||
91 | #define WM2200_AUDIO_IF_1_14 0x50D | ||
92 | #define WM2200_AUDIO_IF_1_15 0x50E | ||
93 | #define WM2200_AUDIO_IF_1_16 0x50F | ||
94 | #define WM2200_AUDIO_IF_1_17 0x510 | ||
95 | #define WM2200_AUDIO_IF_1_18 0x511 | ||
96 | #define WM2200_AUDIO_IF_1_19 0x512 | ||
97 | #define WM2200_AUDIO_IF_1_20 0x513 | ||
98 | #define WM2200_AUDIO_IF_1_21 0x514 | ||
99 | #define WM2200_AUDIO_IF_1_22 0x515 | ||
100 | #define WM2200_OUT1LMIX_INPUT_1_SOURCE 0x600 | ||
101 | #define WM2200_OUT1LMIX_INPUT_1_VOLUME 0x601 | ||
102 | #define WM2200_OUT1LMIX_INPUT_2_SOURCE 0x602 | ||
103 | #define WM2200_OUT1LMIX_INPUT_2_VOLUME 0x603 | ||
104 | #define WM2200_OUT1LMIX_INPUT_3_SOURCE 0x604 | ||
105 | #define WM2200_OUT1LMIX_INPUT_3_VOLUME 0x605 | ||
106 | #define WM2200_OUT1LMIX_INPUT_4_SOURCE 0x606 | ||
107 | #define WM2200_OUT1LMIX_INPUT_4_VOLUME 0x607 | ||
108 | #define WM2200_OUT1RMIX_INPUT_1_SOURCE 0x608 | ||
109 | #define WM2200_OUT1RMIX_INPUT_1_VOLUME 0x609 | ||
110 | #define WM2200_OUT1RMIX_INPUT_2_SOURCE 0x60A | ||
111 | #define WM2200_OUT1RMIX_INPUT_2_VOLUME 0x60B | ||
112 | #define WM2200_OUT1RMIX_INPUT_3_SOURCE 0x60C | ||
113 | #define WM2200_OUT1RMIX_INPUT_3_VOLUME 0x60D | ||
114 | #define WM2200_OUT1RMIX_INPUT_4_SOURCE 0x60E | ||
115 | #define WM2200_OUT1RMIX_INPUT_4_VOLUME 0x60F | ||
116 | #define WM2200_OUT2LMIX_INPUT_1_SOURCE 0x610 | ||
117 | #define WM2200_OUT2LMIX_INPUT_1_VOLUME 0x611 | ||
118 | #define WM2200_OUT2LMIX_INPUT_2_SOURCE 0x612 | ||
119 | #define WM2200_OUT2LMIX_INPUT_2_VOLUME 0x613 | ||
120 | #define WM2200_OUT2LMIX_INPUT_3_SOURCE 0x614 | ||
121 | #define WM2200_OUT2LMIX_INPUT_3_VOLUME 0x615 | ||
122 | #define WM2200_OUT2LMIX_INPUT_4_SOURCE 0x616 | ||
123 | #define WM2200_OUT2LMIX_INPUT_4_VOLUME 0x617 | ||
124 | #define WM2200_OUT2RMIX_INPUT_1_SOURCE 0x618 | ||
125 | #define WM2200_OUT2RMIX_INPUT_1_VOLUME 0x619 | ||
126 | #define WM2200_OUT2RMIX_INPUT_2_SOURCE 0x61A | ||
127 | #define WM2200_OUT2RMIX_INPUT_2_VOLUME 0x61B | ||
128 | #define WM2200_OUT2RMIX_INPUT_3_SOURCE 0x61C | ||
129 | #define WM2200_OUT2RMIX_INPUT_3_VOLUME 0x61D | ||
130 | #define WM2200_OUT2RMIX_INPUT_4_SOURCE 0x61E | ||
131 | #define WM2200_OUT2RMIX_INPUT_4_VOLUME 0x61F | ||
132 | #define WM2200_AIF1TX1MIX_INPUT_1_SOURCE 0x620 | ||
133 | #define WM2200_AIF1TX1MIX_INPUT_1_VOLUME 0x621 | ||
134 | #define WM2200_AIF1TX1MIX_INPUT_2_SOURCE 0x622 | ||
135 | #define WM2200_AIF1TX1MIX_INPUT_2_VOLUME 0x623 | ||
136 | #define WM2200_AIF1TX1MIX_INPUT_3_SOURCE 0x624 | ||
137 | #define WM2200_AIF1TX1MIX_INPUT_3_VOLUME 0x625 | ||
138 | #define WM2200_AIF1TX1MIX_INPUT_4_SOURCE 0x626 | ||
139 | #define WM2200_AIF1TX1MIX_INPUT_4_VOLUME 0x627 | ||
140 | #define WM2200_AIF1TX2MIX_INPUT_1_SOURCE 0x628 | ||
141 | #define WM2200_AIF1TX2MIX_INPUT_1_VOLUME 0x629 | ||
142 | #define WM2200_AIF1TX2MIX_INPUT_2_SOURCE 0x62A | ||
143 | #define WM2200_AIF1TX2MIX_INPUT_2_VOLUME 0x62B | ||
144 | #define WM2200_AIF1TX2MIX_INPUT_3_SOURCE 0x62C | ||
145 | #define WM2200_AIF1TX2MIX_INPUT_3_VOLUME 0x62D | ||
146 | #define WM2200_AIF1TX2MIX_INPUT_4_SOURCE 0x62E | ||
147 | #define WM2200_AIF1TX2MIX_INPUT_4_VOLUME 0x62F | ||
148 | #define WM2200_AIF1TX3MIX_INPUT_1_SOURCE 0x630 | ||
149 | #define WM2200_AIF1TX3MIX_INPUT_1_VOLUME 0x631 | ||
150 | #define WM2200_AIF1TX3MIX_INPUT_2_SOURCE 0x632 | ||
151 | #define WM2200_AIF1TX3MIX_INPUT_2_VOLUME 0x633 | ||
152 | #define WM2200_AIF1TX3MIX_INPUT_3_SOURCE 0x634 | ||
153 | #define WM2200_AIF1TX3MIX_INPUT_3_VOLUME 0x635 | ||
154 | #define WM2200_AIF1TX3MIX_INPUT_4_SOURCE 0x636 | ||
155 | #define WM2200_AIF1TX3MIX_INPUT_4_VOLUME 0x637 | ||
156 | #define WM2200_AIF1TX4MIX_INPUT_1_SOURCE 0x638 | ||
157 | #define WM2200_AIF1TX4MIX_INPUT_1_VOLUME 0x639 | ||
158 | #define WM2200_AIF1TX4MIX_INPUT_2_SOURCE 0x63A | ||
159 | #define WM2200_AIF1TX4MIX_INPUT_2_VOLUME 0x63B | ||
160 | #define WM2200_AIF1TX4MIX_INPUT_3_SOURCE 0x63C | ||
161 | #define WM2200_AIF1TX4MIX_INPUT_3_VOLUME 0x63D | ||
162 | #define WM2200_AIF1TX4MIX_INPUT_4_SOURCE 0x63E | ||
163 | #define WM2200_AIF1TX4MIX_INPUT_4_VOLUME 0x63F | ||
164 | #define WM2200_AIF1TX5MIX_INPUT_1_SOURCE 0x640 | ||
165 | #define WM2200_AIF1TX5MIX_INPUT_1_VOLUME 0x641 | ||
166 | #define WM2200_AIF1TX5MIX_INPUT_2_SOURCE 0x642 | ||
167 | #define WM2200_AIF1TX5MIX_INPUT_2_VOLUME 0x643 | ||
168 | #define WM2200_AIF1TX5MIX_INPUT_3_SOURCE 0x644 | ||
169 | #define WM2200_AIF1TX5MIX_INPUT_3_VOLUME 0x645 | ||
170 | #define WM2200_AIF1TX5MIX_INPUT_4_SOURCE 0x646 | ||
171 | #define WM2200_AIF1TX5MIX_INPUT_4_VOLUME 0x647 | ||
172 | #define WM2200_AIF1TX6MIX_INPUT_1_SOURCE 0x648 | ||
173 | #define WM2200_AIF1TX6MIX_INPUT_1_VOLUME 0x649 | ||
174 | #define WM2200_AIF1TX6MIX_INPUT_2_SOURCE 0x64A | ||
175 | #define WM2200_AIF1TX6MIX_INPUT_2_VOLUME 0x64B | ||
176 | #define WM2200_AIF1TX6MIX_INPUT_3_SOURCE 0x64C | ||
177 | #define WM2200_AIF1TX6MIX_INPUT_3_VOLUME 0x64D | ||
178 | #define WM2200_AIF1TX6MIX_INPUT_4_SOURCE 0x64E | ||
179 | #define WM2200_AIF1TX6MIX_INPUT_4_VOLUME 0x64F | ||
180 | #define WM2200_EQLMIX_INPUT_1_SOURCE 0x650 | ||
181 | #define WM2200_EQLMIX_INPUT_1_VOLUME 0x651 | ||
182 | #define WM2200_EQLMIX_INPUT_2_SOURCE 0x652 | ||
183 | #define WM2200_EQLMIX_INPUT_2_VOLUME 0x653 | ||
184 | #define WM2200_EQLMIX_INPUT_3_SOURCE 0x654 | ||
185 | #define WM2200_EQLMIX_INPUT_3_VOLUME 0x655 | ||
186 | #define WM2200_EQLMIX_INPUT_4_SOURCE 0x656 | ||
187 | #define WM2200_EQLMIX_INPUT_4_VOLUME 0x657 | ||
188 | #define WM2200_EQRMIX_INPUT_1_SOURCE 0x658 | ||
189 | #define WM2200_EQRMIX_INPUT_1_VOLUME 0x659 | ||
190 | #define WM2200_EQRMIX_INPUT_2_SOURCE 0x65A | ||
191 | #define WM2200_EQRMIX_INPUT_2_VOLUME 0x65B | ||
192 | #define WM2200_EQRMIX_INPUT_3_SOURCE 0x65C | ||
193 | #define WM2200_EQRMIX_INPUT_3_VOLUME 0x65D | ||
194 | #define WM2200_EQRMIX_INPUT_4_SOURCE 0x65E | ||
195 | #define WM2200_EQRMIX_INPUT_4_VOLUME 0x65F | ||
196 | #define WM2200_LHPF1MIX_INPUT_1_SOURCE 0x660 | ||
197 | #define WM2200_LHPF1MIX_INPUT_1_VOLUME 0x661 | ||
198 | #define WM2200_LHPF1MIX_INPUT_2_SOURCE 0x662 | ||
199 | #define WM2200_LHPF1MIX_INPUT_2_VOLUME 0x663 | ||
200 | #define WM2200_LHPF1MIX_INPUT_3_SOURCE 0x664 | ||
201 | #define WM2200_LHPF1MIX_INPUT_3_VOLUME 0x665 | ||
202 | #define WM2200_LHPF1MIX_INPUT_4_SOURCE 0x666 | ||
203 | #define WM2200_LHPF1MIX_INPUT_4_VOLUME 0x667 | ||
204 | #define WM2200_LHPF2MIX_INPUT_1_SOURCE 0x668 | ||
205 | #define WM2200_LHPF2MIX_INPUT_1_VOLUME 0x669 | ||
206 | #define WM2200_LHPF2MIX_INPUT_2_SOURCE 0x66A | ||
207 | #define WM2200_LHPF2MIX_INPUT_2_VOLUME 0x66B | ||
208 | #define WM2200_LHPF2MIX_INPUT_3_SOURCE 0x66C | ||
209 | #define WM2200_LHPF2MIX_INPUT_3_VOLUME 0x66D | ||
210 | #define WM2200_LHPF2MIX_INPUT_4_SOURCE 0x66E | ||
211 | #define WM2200_LHPF2MIX_INPUT_4_VOLUME 0x66F | ||
212 | #define WM2200_DSP1LMIX_INPUT_1_SOURCE 0x670 | ||
213 | #define WM2200_DSP1LMIX_INPUT_1_VOLUME 0x671 | ||
214 | #define WM2200_DSP1LMIX_INPUT_2_SOURCE 0x672 | ||
215 | #define WM2200_DSP1LMIX_INPUT_2_VOLUME 0x673 | ||
216 | #define WM2200_DSP1LMIX_INPUT_3_SOURCE 0x674 | ||
217 | #define WM2200_DSP1LMIX_INPUT_3_VOLUME 0x675 | ||
218 | #define WM2200_DSP1LMIX_INPUT_4_SOURCE 0x676 | ||
219 | #define WM2200_DSP1LMIX_INPUT_4_VOLUME 0x677 | ||
220 | #define WM2200_DSP1RMIX_INPUT_1_SOURCE 0x678 | ||
221 | #define WM2200_DSP1RMIX_INPUT_1_VOLUME 0x679 | ||
222 | #define WM2200_DSP1RMIX_INPUT_2_SOURCE 0x67A | ||
223 | #define WM2200_DSP1RMIX_INPUT_2_VOLUME 0x67B | ||
224 | #define WM2200_DSP1RMIX_INPUT_3_SOURCE 0x67C | ||
225 | #define WM2200_DSP1RMIX_INPUT_3_VOLUME 0x67D | ||
226 | #define WM2200_DSP1RMIX_INPUT_4_SOURCE 0x67E | ||
227 | #define WM2200_DSP1RMIX_INPUT_4_VOLUME 0x67F | ||
228 | #define WM2200_DSP1AUX1MIX_INPUT_1_SOURCE 0x680 | ||
229 | #define WM2200_DSP1AUX2MIX_INPUT_1_SOURCE 0x681 | ||
230 | #define WM2200_DSP1AUX3MIX_INPUT_1_SOURCE 0x682 | ||
231 | #define WM2200_DSP1AUX4MIX_INPUT_1_SOURCE 0x683 | ||
232 | #define WM2200_DSP1AUX5MIX_INPUT_1_SOURCE 0x684 | ||
233 | #define WM2200_DSP1AUX6MIX_INPUT_1_SOURCE 0x685 | ||
234 | #define WM2200_DSP2LMIX_INPUT_1_SOURCE 0x686 | ||
235 | #define WM2200_DSP2LMIX_INPUT_1_VOLUME 0x687 | ||
236 | #define WM2200_DSP2LMIX_INPUT_2_SOURCE 0x688 | ||
237 | #define WM2200_DSP2LMIX_INPUT_2_VOLUME 0x689 | ||
238 | #define WM2200_DSP2LMIX_INPUT_3_SOURCE 0x68A | ||
239 | #define WM2200_DSP2LMIX_INPUT_3_VOLUME 0x68B | ||
240 | #define WM2200_DSP2LMIX_INPUT_4_SOURCE 0x68C | ||
241 | #define WM2200_DSP2LMIX_INPUT_4_VOLUME 0x68D | ||
242 | #define WM2200_DSP2RMIX_INPUT_1_SOURCE 0x68E | ||
243 | #define WM2200_DSP2RMIX_INPUT_1_VOLUME 0x68F | ||
244 | #define WM2200_DSP2RMIX_INPUT_2_SOURCE 0x690 | ||
245 | #define WM2200_DSP2RMIX_INPUT_2_VOLUME 0x691 | ||
246 | #define WM2200_DSP2RMIX_INPUT_3_SOURCE 0x692 | ||
247 | #define WM2200_DSP2RMIX_INPUT_3_VOLUME 0x693 | ||
248 | #define WM2200_DSP2RMIX_INPUT_4_SOURCE 0x694 | ||
249 | #define WM2200_DSP2RMIX_INPUT_4_VOLUME 0x695 | ||
250 | #define WM2200_DSP2AUX1MIX_INPUT_1_SOURCE 0x696 | ||
251 | #define WM2200_DSP2AUX2MIX_INPUT_1_SOURCE 0x697 | ||
252 | #define WM2200_DSP2AUX3MIX_INPUT_1_SOURCE 0x698 | ||
253 | #define WM2200_DSP2AUX4MIX_INPUT_1_SOURCE 0x699 | ||
254 | #define WM2200_DSP2AUX5MIX_INPUT_1_SOURCE 0x69A | ||
255 | #define WM2200_DSP2AUX6MIX_INPUT_1_SOURCE 0x69B | ||
256 | #define WM2200_GPIO_CTRL_1 0x700 | ||
257 | #define WM2200_GPIO_CTRL_2 0x701 | ||
258 | #define WM2200_GPIO_CTRL_3 0x702 | ||
259 | #define WM2200_GPIO_CTRL_4 0x703 | ||
260 | #define WM2200_ADPS1_IRQ0 0x707 | ||
261 | #define WM2200_ADPS1_IRQ1 0x708 | ||
262 | #define WM2200_MISC_PAD_CTRL_1 0x709 | ||
263 | #define WM2200_INTERRUPT_STATUS_1 0x800 | ||
264 | #define WM2200_INTERRUPT_STATUS_1_MASK 0x801 | ||
265 | #define WM2200_INTERRUPT_STATUS_2 0x802 | ||
266 | #define WM2200_INTERRUPT_RAW_STATUS_2 0x803 | ||
267 | #define WM2200_INTERRUPT_STATUS_2_MASK 0x804 | ||
268 | #define WM2200_INTERRUPT_CONTROL 0x808 | ||
269 | #define WM2200_EQL_1 0x900 | ||
270 | #define WM2200_EQL_2 0x901 | ||
271 | #define WM2200_EQL_3 0x902 | ||
272 | #define WM2200_EQL_4 0x903 | ||
273 | #define WM2200_EQL_5 0x904 | ||
274 | #define WM2200_EQL_6 0x905 | ||
275 | #define WM2200_EQL_7 0x906 | ||
276 | #define WM2200_EQL_8 0x907 | ||
277 | #define WM2200_EQL_9 0x908 | ||
278 | #define WM2200_EQL_10 0x909 | ||
279 | #define WM2200_EQL_11 0x90A | ||
280 | #define WM2200_EQL_12 0x90B | ||
281 | #define WM2200_EQL_13 0x90C | ||
282 | #define WM2200_EQL_14 0x90D | ||
283 | #define WM2200_EQL_15 0x90E | ||
284 | #define WM2200_EQL_16 0x90F | ||
285 | #define WM2200_EQL_17 0x910 | ||
286 | #define WM2200_EQL_18 0x911 | ||
287 | #define WM2200_EQL_19 0x912 | ||
288 | #define WM2200_EQL_20 0x913 | ||
289 | #define WM2200_EQR_1 0x916 | ||
290 | #define WM2200_EQR_2 0x917 | ||
291 | #define WM2200_EQR_3 0x918 | ||
292 | #define WM2200_EQR_4 0x919 | ||
293 | #define WM2200_EQR_5 0x91A | ||
294 | #define WM2200_EQR_6 0x91B | ||
295 | #define WM2200_EQR_7 0x91C | ||
296 | #define WM2200_EQR_8 0x91D | ||
297 | #define WM2200_EQR_9 0x91E | ||
298 | #define WM2200_EQR_10 0x91F | ||
299 | #define WM2200_EQR_11 0x920 | ||
300 | #define WM2200_EQR_12 0x921 | ||
301 | #define WM2200_EQR_13 0x922 | ||
302 | #define WM2200_EQR_14 0x923 | ||
303 | #define WM2200_EQR_15 0x924 | ||
304 | #define WM2200_EQR_16 0x925 | ||
305 | #define WM2200_EQR_17 0x926 | ||
306 | #define WM2200_EQR_18 0x927 | ||
307 | #define WM2200_EQR_19 0x928 | ||
308 | #define WM2200_EQR_20 0x929 | ||
309 | #define WM2200_HPLPF1_1 0x93E | ||
310 | #define WM2200_HPLPF1_2 0x93F | ||
311 | #define WM2200_HPLPF2_1 0x942 | ||
312 | #define WM2200_HPLPF2_2 0x943 | ||
313 | #define WM2200_DSP1_CONTROL_1 0xA00 | ||
314 | #define WM2200_DSP1_CONTROL_2 0xA02 | ||
315 | #define WM2200_DSP1_CONTROL_3 0xA03 | ||
316 | #define WM2200_DSP1_CONTROL_4 0xA04 | ||
317 | #define WM2200_DSP1_CONTROL_5 0xA06 | ||
318 | #define WM2200_DSP1_CONTROL_6 0xA07 | ||
319 | #define WM2200_DSP1_CONTROL_7 0xA08 | ||
320 | #define WM2200_DSP1_CONTROL_8 0xA09 | ||
321 | #define WM2200_DSP1_CONTROL_9 0xA0A | ||
322 | #define WM2200_DSP1_CONTROL_10 0xA0B | ||
323 | #define WM2200_DSP1_CONTROL_11 0xA0C | ||
324 | #define WM2200_DSP1_CONTROL_12 0xA0D | ||
325 | #define WM2200_DSP1_CONTROL_13 0xA0F | ||
326 | #define WM2200_DSP1_CONTROL_14 0xA10 | ||
327 | #define WM2200_DSP1_CONTROL_15 0xA11 | ||
328 | #define WM2200_DSP1_CONTROL_16 0xA12 | ||
329 | #define WM2200_DSP1_CONTROL_17 0xA13 | ||
330 | #define WM2200_DSP1_CONTROL_18 0xA14 | ||
331 | #define WM2200_DSP1_CONTROL_19 0xA16 | ||
332 | #define WM2200_DSP1_CONTROL_20 0xA17 | ||
333 | #define WM2200_DSP1_CONTROL_21 0xA18 | ||
334 | #define WM2200_DSP1_CONTROL_22 0xA1A | ||
335 | #define WM2200_DSP1_CONTROL_23 0xA1B | ||
336 | #define WM2200_DSP1_CONTROL_24 0xA1C | ||
337 | #define WM2200_DSP1_CONTROL_25 0xA1E | ||
338 | #define WM2200_DSP1_CONTROL_26 0xA20 | ||
339 | #define WM2200_DSP1_CONTROL_27 0xA21 | ||
340 | #define WM2200_DSP1_CONTROL_28 0xA22 | ||
341 | #define WM2200_DSP1_CONTROL_29 0xA23 | ||
342 | #define WM2200_DSP1_CONTROL_30 0xA24 | ||
343 | #define WM2200_DSP1_CONTROL_31 0xA26 | ||
344 | #define WM2200_DSP2_CONTROL_1 0xB00 | ||
345 | #define WM2200_DSP2_CONTROL_2 0xB02 | ||
346 | #define WM2200_DSP2_CONTROL_3 0xB03 | ||
347 | #define WM2200_DSP2_CONTROL_4 0xB04 | ||
348 | #define WM2200_DSP2_CONTROL_5 0xB06 | ||
349 | #define WM2200_DSP2_CONTROL_6 0xB07 | ||
350 | #define WM2200_DSP2_CONTROL_7 0xB08 | ||
351 | #define WM2200_DSP2_CONTROL_8 0xB09 | ||
352 | #define WM2200_DSP2_CONTROL_9 0xB0A | ||
353 | #define WM2200_DSP2_CONTROL_10 0xB0B | ||
354 | #define WM2200_DSP2_CONTROL_11 0xB0C | ||
355 | #define WM2200_DSP2_CONTROL_12 0xB0D | ||
356 | #define WM2200_DSP2_CONTROL_13 0xB0F | ||
357 | #define WM2200_DSP2_CONTROL_14 0xB10 | ||
358 | #define WM2200_DSP2_CONTROL_15 0xB11 | ||
359 | #define WM2200_DSP2_CONTROL_16 0xB12 | ||
360 | #define WM2200_DSP2_CONTROL_17 0xB13 | ||
361 | #define WM2200_DSP2_CONTROL_18 0xB14 | ||
362 | #define WM2200_DSP2_CONTROL_19 0xB16 | ||
363 | #define WM2200_DSP2_CONTROL_20 0xB17 | ||
364 | #define WM2200_DSP2_CONTROL_21 0xB18 | ||
365 | #define WM2200_DSP2_CONTROL_22 0xB1A | ||
366 | #define WM2200_DSP2_CONTROL_23 0xB1B | ||
367 | #define WM2200_DSP2_CONTROL_24 0xB1C | ||
368 | #define WM2200_DSP2_CONTROL_25 0xB1E | ||
369 | #define WM2200_DSP2_CONTROL_26 0xB20 | ||
370 | #define WM2200_DSP2_CONTROL_27 0xB21 | ||
371 | #define WM2200_DSP2_CONTROL_28 0xB22 | ||
372 | #define WM2200_DSP2_CONTROL_29 0xB23 | ||
373 | #define WM2200_DSP2_CONTROL_30 0xB24 | ||
374 | #define WM2200_DSP2_CONTROL_31 0xB26 | ||
375 | #define WM2200_ANC_CTRL1 0xD00 | ||
376 | #define WM2200_ANC_CTRL2 0xD01 | ||
377 | #define WM2200_ANC_CTRL3 0xD02 | ||
378 | #define WM2200_ANC_CTRL7 0xD08 | ||
379 | #define WM2200_ANC_CTRL8 0xD09 | ||
380 | #define WM2200_ANC_CTRL9 0xD0A | ||
381 | #define WM2200_ANC_CTRL10 0xD0B | ||
382 | #define WM2200_ANC_CTRL11 0xD0C | ||
383 | #define WM2200_ANC_CTRL12 0xD0D | ||
384 | #define WM2200_ANC_CTRL13 0xD0E | ||
385 | #define WM2200_ANC_CTRL14 0xD0F | ||
386 | #define WM2200_ANC_CTRL15 0xD10 | ||
387 | #define WM2200_ANC_CTRL16 0xD11 | ||
388 | #define WM2200_ANC_CTRL17 0xD12 | ||
389 | #define WM2200_ANC_CTRL18 0xD15 | ||
390 | #define WM2200_ANC_CTRL19 0xD16 | ||
391 | #define WM2200_ANC_CTRL20 0xD17 | ||
392 | #define WM2200_ANC_CTRL21 0xD18 | ||
393 | #define WM2200_ANC_CTRL22 0xD19 | ||
394 | #define WM2200_ANC_CTRL23 0xD1A | ||
395 | #define WM2200_ANC_CTRL24 0xD1B | ||
396 | #define WM2200_ANC_CTRL25 0xD1C | ||
397 | #define WM2200_ANC_CTRL26 0xD1D | ||
398 | #define WM2200_ANC_CTRL27 0xD1E | ||
399 | #define WM2200_ANC_CTRL28 0xD1F | ||
400 | #define WM2200_ANC_CTRL29 0xD20 | ||
401 | #define WM2200_ANC_CTRL30 0xD21 | ||
402 | #define WM2200_ANC_CTRL31 0xD23 | ||
403 | #define WM2200_ANC_CTRL32 0xD24 | ||
404 | #define WM2200_ANC_CTRL33 0xD25 | ||
405 | #define WM2200_ANC_CTRL34 0xD27 | ||
406 | #define WM2200_ANC_CTRL35 0xD28 | ||
407 | #define WM2200_ANC_CTRL36 0xD29 | ||
408 | #define WM2200_ANC_CTRL37 0xD2A | ||
409 | #define WM2200_ANC_CTRL38 0xD2B | ||
410 | #define WM2200_ANC_CTRL39 0xD2C | ||
411 | #define WM2200_ANC_CTRL40 0xD2D | ||
412 | #define WM2200_ANC_CTRL41 0xD2E | ||
413 | #define WM2200_ANC_CTRL42 0xD2F | ||
414 | #define WM2200_ANC_CTRL43 0xD30 | ||
415 | #define WM2200_ANC_CTRL44 0xD31 | ||
416 | #define WM2200_ANC_CTRL45 0xD32 | ||
417 | #define WM2200_ANC_CTRL46 0xD33 | ||
418 | #define WM2200_ANC_CTRL47 0xD34 | ||
419 | #define WM2200_ANC_CTRL48 0xD35 | ||
420 | #define WM2200_ANC_CTRL49 0xD36 | ||
421 | #define WM2200_ANC_CTRL50 0xD37 | ||
422 | #define WM2200_ANC_CTRL51 0xD38 | ||
423 | #define WM2200_ANC_CTRL52 0xD39 | ||
424 | #define WM2200_ANC_CTRL53 0xD3A | ||
425 | #define WM2200_ANC_CTRL54 0xD3B | ||
426 | #define WM2200_ANC_CTRL55 0xD3C | ||
427 | #define WM2200_ANC_CTRL56 0xD3D | ||
428 | #define WM2200_ANC_CTRL57 0xD3E | ||
429 | #define WM2200_ANC_CTRL58 0xD3F | ||
430 | #define WM2200_ANC_CTRL59 0xD40 | ||
431 | #define WM2200_ANC_CTRL60 0xD41 | ||
432 | #define WM2200_ANC_CTRL61 0xD42 | ||
433 | #define WM2200_ANC_CTRL62 0xD43 | ||
434 | #define WM2200_ANC_CTRL63 0xD44 | ||
435 | #define WM2200_ANC_CTRL64 0xD45 | ||
436 | #define WM2200_ANC_CTRL65 0xD46 | ||
437 | #define WM2200_ANC_CTRL66 0xD47 | ||
438 | #define WM2200_ANC_CTRL67 0xD48 | ||
439 | #define WM2200_ANC_CTRL68 0xD49 | ||
440 | #define WM2200_ANC_CTRL69 0xD4A | ||
441 | #define WM2200_ANC_CTRL70 0xD4B | ||
442 | #define WM2200_ANC_CTRL71 0xD4C | ||
443 | #define WM2200_ANC_CTRL72 0xD4D | ||
444 | #define WM2200_ANC_CTRL73 0xD4E | ||
445 | #define WM2200_ANC_CTRL74 0xD4F | ||
446 | #define WM2200_ANC_CTRL75 0xD50 | ||
447 | #define WM2200_ANC_CTRL76 0xD51 | ||
448 | #define WM2200_ANC_CTRL77 0xD52 | ||
449 | #define WM2200_ANC_CTRL78 0xD53 | ||
450 | #define WM2200_ANC_CTRL79 0xD54 | ||
451 | #define WM2200_ANC_CTRL80 0xD55 | ||
452 | #define WM2200_ANC_CTRL81 0xD56 | ||
453 | #define WM2200_ANC_CTRL82 0xD57 | ||
454 | #define WM2200_ANC_CTRL83 0xD58 | ||
455 | #define WM2200_ANC_CTRL84 0xD5B | ||
456 | #define WM2200_ANC_CTRL85 0xD5C | ||
457 | #define WM2200_ANC_CTRL86 0xD5F | ||
458 | #define WM2200_ANC_CTRL87 0xD60 | ||
459 | #define WM2200_ANC_CTRL88 0xD61 | ||
460 | #define WM2200_ANC_CTRL89 0xD62 | ||
461 | #define WM2200_ANC_CTRL90 0xD63 | ||
462 | #define WM2200_ANC_CTRL91 0xD64 | ||
463 | #define WM2200_ANC_CTRL92 0xD65 | ||
464 | #define WM2200_ANC_CTRL93 0xD66 | ||
465 | #define WM2200_ANC_CTRL94 0xD67 | ||
466 | #define WM2200_ANC_CTRL95 0xD68 | ||
467 | #define WM2200_ANC_CTRL96 0xD69 | ||
468 | #define WM2200_DSP1_DM_0 0x3000 | ||
469 | #define WM2200_DSP1_DM_1 0x3001 | ||
470 | #define WM2200_DSP1_DM_2 0x3002 | ||
471 | #define WM2200_DSP1_DM_3 0x3003 | ||
472 | #define WM2200_DSP1_DM_2044 0x37FC | ||
473 | #define WM2200_DSP1_DM_2045 0x37FD | ||
474 | #define WM2200_DSP1_DM_2046 0x37FE | ||
475 | #define WM2200_DSP1_DM_2047 0x37FF | ||
476 | #define WM2200_DSP1_PM_0 0x3800 | ||
477 | #define WM2200_DSP1_PM_1 0x3801 | ||
478 | #define WM2200_DSP1_PM_2 0x3802 | ||
479 | #define WM2200_DSP1_PM_3 0x3803 | ||
480 | #define WM2200_DSP1_PM_4 0x3804 | ||
481 | #define WM2200_DSP1_PM_5 0x3805 | ||
482 | #define WM2200_DSP1_PM_762 0x3AFA | ||
483 | #define WM2200_DSP1_PM_763 0x3AFB | ||
484 | #define WM2200_DSP1_PM_764 0x3AFC | ||
485 | #define WM2200_DSP1_PM_765 0x3AFD | ||
486 | #define WM2200_DSP1_PM_766 0x3AFE | ||
487 | #define WM2200_DSP1_PM_767 0x3AFF | ||
488 | #define WM2200_DSP1_ZM_0 0x3C00 | ||
489 | #define WM2200_DSP1_ZM_1 0x3C01 | ||
490 | #define WM2200_DSP1_ZM_2 0x3C02 | ||
491 | #define WM2200_DSP1_ZM_3 0x3C03 | ||
492 | #define WM2200_DSP1_ZM_1020 0x3FFC | ||
493 | #define WM2200_DSP1_ZM_1021 0x3FFD | ||
494 | #define WM2200_DSP1_ZM_1022 0x3FFE | ||
495 | #define WM2200_DSP1_ZM_1023 0x3FFF | ||
496 | #define WM2200_DSP2_DM_0 0x4000 | ||
497 | #define WM2200_DSP2_DM_1 0x4001 | ||
498 | #define WM2200_DSP2_DM_2 0x4002 | ||
499 | #define WM2200_DSP2_DM_3 0x4003 | ||
500 | #define WM2200_DSP2_DM_2044 0x47FC | ||
501 | #define WM2200_DSP2_DM_2045 0x47FD | ||
502 | #define WM2200_DSP2_DM_2046 0x47FE | ||
503 | #define WM2200_DSP2_DM_2047 0x47FF | ||
504 | #define WM2200_DSP2_PM_0 0x4800 | ||
505 | #define WM2200_DSP2_PM_1 0x4801 | ||
506 | #define WM2200_DSP2_PM_2 0x4802 | ||
507 | #define WM2200_DSP2_PM_3 0x4803 | ||
508 | #define WM2200_DSP2_PM_4 0x4804 | ||
509 | #define WM2200_DSP2_PM_5 0x4805 | ||
510 | #define WM2200_DSP2_PM_762 0x4AFA | ||
511 | #define WM2200_DSP2_PM_763 0x4AFB | ||
512 | #define WM2200_DSP2_PM_764 0x4AFC | ||
513 | #define WM2200_DSP2_PM_765 0x4AFD | ||
514 | #define WM2200_DSP2_PM_766 0x4AFE | ||
515 | #define WM2200_DSP2_PM_767 0x4AFF | ||
516 | #define WM2200_DSP2_ZM_0 0x4C00 | ||
517 | #define WM2200_DSP2_ZM_1 0x4C01 | ||
518 | #define WM2200_DSP2_ZM_2 0x4C02 | ||
519 | #define WM2200_DSP2_ZM_3 0x4C03 | ||
520 | #define WM2200_DSP2_ZM_1020 0x4FFC | ||
521 | #define WM2200_DSP2_ZM_1021 0x4FFD | ||
522 | #define WM2200_DSP2_ZM_1022 0x4FFE | ||
523 | #define WM2200_DSP2_ZM_1023 0x4FFF | ||
524 | |||
525 | #define WM2200_REGISTER_COUNT 494 | ||
526 | #define WM2200_MAX_REGISTER 0x4FFF | ||
527 | |||
528 | /* | ||
529 | * Field Definitions. | ||
530 | */ | ||
531 | |||
532 | /* | ||
533 | * R0 (0x00) - software reset | ||
534 | */ | ||
535 | #define WM2200_SW_RESET_CHIP_ID1_MASK 0xFFFF /* SW_RESET_CHIP_ID1 - [15:0] */ | ||
536 | #define WM2200_SW_RESET_CHIP_ID1_SHIFT 0 /* SW_RESET_CHIP_ID1 - [15:0] */ | ||
537 | #define WM2200_SW_RESET_CHIP_ID1_WIDTH 16 /* SW_RESET_CHIP_ID1 - [15:0] */ | ||
538 | |||
539 | /* | ||
540 | * R1 (0x01) - Device Revision | ||
541 | */ | ||
542 | #define WM2200_DEVICE_REVISION_MASK 0x000F /* DEVICE_REVISION - [3:0] */ | ||
543 | #define WM2200_DEVICE_REVISION_SHIFT 0 /* DEVICE_REVISION - [3:0] */ | ||
544 | #define WM2200_DEVICE_REVISION_WIDTH 4 /* DEVICE_REVISION - [3:0] */ | ||
545 | |||
546 | /* | ||
547 | * R11 (0x0B) - Tone Generator 1 | ||
548 | */ | ||
549 | #define WM2200_TONE_ENA 0x0001 /* TONE_ENA */ | ||
550 | #define WM2200_TONE_ENA_MASK 0x0001 /* TONE_ENA */ | ||
551 | #define WM2200_TONE_ENA_SHIFT 0 /* TONE_ENA */ | ||
552 | #define WM2200_TONE_ENA_WIDTH 1 /* TONE_ENA */ | ||
553 | |||
554 | /* | ||
555 | * R258 (0x102) - Clocking 3 | ||
556 | */ | ||
557 | #define WM2200_SYSCLK_FREQ_MASK 0x0700 /* SYSCLK_FREQ - [10:8] */ | ||
558 | #define WM2200_SYSCLK_FREQ_SHIFT 8 /* SYSCLK_FREQ - [10:8] */ | ||
559 | #define WM2200_SYSCLK_FREQ_WIDTH 3 /* SYSCLK_FREQ - [10:8] */ | ||
560 | #define WM2200_SYSCLK_ENA 0x0040 /* SYSCLK_ENA */ | ||
561 | #define WM2200_SYSCLK_ENA_MASK 0x0040 /* SYSCLK_ENA */ | ||
562 | #define WM2200_SYSCLK_ENA_SHIFT 6 /* SYSCLK_ENA */ | ||
563 | #define WM2200_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */ | ||
564 | #define WM2200_SYSCLK_SRC_MASK 0x000F /* SYSCLK_SRC - [3:0] */ | ||
565 | #define WM2200_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC - [3:0] */ | ||
566 | #define WM2200_SYSCLK_SRC_WIDTH 4 /* SYSCLK_SRC - [3:0] */ | ||
567 | |||
568 | /* | ||
569 | * R259 (0x103) - Clocking 4 | ||
570 | */ | ||
571 | #define WM2200_SAMPLE_RATE_1_MASK 0x001F /* SAMPLE_RATE_1 - [4:0] */ | ||
572 | #define WM2200_SAMPLE_RATE_1_SHIFT 0 /* SAMPLE_RATE_1 - [4:0] */ | ||
573 | #define WM2200_SAMPLE_RATE_1_WIDTH 5 /* SAMPLE_RATE_1 - [4:0] */ | ||
574 | |||
575 | /* | ||
576 | * R273 (0x111) - FLL Control 1 | ||
577 | */ | ||
578 | #define WM2200_FLL_ENA 0x0001 /* FLL_ENA */ | ||
579 | #define WM2200_FLL_ENA_MASK 0x0001 /* FLL_ENA */ | ||
580 | #define WM2200_FLL_ENA_SHIFT 0 /* FLL_ENA */ | ||
581 | #define WM2200_FLL_ENA_WIDTH 1 /* FLL_ENA */ | ||
582 | |||
583 | /* | ||
584 | * R274 (0x112) - FLL Control 2 | ||
585 | */ | ||
586 | #define WM2200_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */ | ||
587 | #define WM2200_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */ | ||
588 | #define WM2200_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */ | ||
589 | #define WM2200_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */ | ||
590 | #define WM2200_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */ | ||
591 | #define WM2200_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */ | ||
592 | |||
593 | /* | ||
594 | * R275 (0x113) - FLL Control 3 | ||
595 | */ | ||
596 | #define WM2200_FLL_FRACN_ENA 0x0001 /* FLL_FRACN_ENA */ | ||
597 | #define WM2200_FLL_FRACN_ENA_MASK 0x0001 /* FLL_FRACN_ENA */ | ||
598 | #define WM2200_FLL_FRACN_ENA_SHIFT 0 /* FLL_FRACN_ENA */ | ||
599 | #define WM2200_FLL_FRACN_ENA_WIDTH 1 /* FLL_FRACN_ENA */ | ||
600 | |||
601 | /* | ||
602 | * R276 (0x114) - FLL Control 4 | ||
603 | */ | ||
604 | #define WM2200_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */ | ||
605 | #define WM2200_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */ | ||
606 | #define WM2200_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */ | ||
607 | |||
608 | /* | ||
609 | * R278 (0x116) - FLL Control 6 | ||
610 | */ | ||
611 | #define WM2200_FLL_N_MASK 0x03FF /* FLL_N - [9:0] */ | ||
612 | #define WM2200_FLL_N_SHIFT 0 /* FLL_N - [9:0] */ | ||
613 | #define WM2200_FLL_N_WIDTH 10 /* FLL_N - [9:0] */ | ||
614 | |||
615 | /* | ||
616 | * R279 (0x117) - FLL Control 7 | ||
617 | */ | ||
618 | #define WM2200_FLL_CLK_REF_DIV_MASK 0x0030 /* FLL_CLK_REF_DIV - [5:4] */ | ||
619 | #define WM2200_FLL_CLK_REF_DIV_SHIFT 4 /* FLL_CLK_REF_DIV - [5:4] */ | ||
620 | #define WM2200_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [5:4] */ | ||
621 | #define WM2200_FLL_CLK_REF_SRC_MASK 0x0003 /* FLL_CLK_REF_SRC - [1:0] */ | ||
622 | #define WM2200_FLL_CLK_REF_SRC_SHIFT 0 /* FLL_CLK_REF_SRC - [1:0] */ | ||
623 | #define WM2200_FLL_CLK_REF_SRC_WIDTH 2 /* FLL_CLK_REF_SRC - [1:0] */ | ||
624 | |||
625 | /* | ||
626 | * R281 (0x119) - FLL EFS 1 | ||
627 | */ | ||
628 | #define WM2200_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */ | ||
629 | #define WM2200_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */ | ||
630 | #define WM2200_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */ | ||
631 | |||
632 | /* | ||
633 | * R282 (0x11A) - FLL EFS 2 | ||
634 | */ | ||
635 | #define WM2200_FLL_EFS_ENA 0x0001 /* FLL_EFS_ENA */ | ||
636 | #define WM2200_FLL_EFS_ENA_MASK 0x0001 /* FLL_EFS_ENA */ | ||
637 | #define WM2200_FLL_EFS_ENA_SHIFT 0 /* FLL_EFS_ENA */ | ||
638 | #define WM2200_FLL_EFS_ENA_WIDTH 1 /* FLL_EFS_ENA */ | ||
639 | |||
640 | /* | ||
641 | * R512 (0x200) - Mic Charge Pump 1 | ||
642 | */ | ||
643 | #define WM2200_CPMIC_BYPASS_MODE 0x0020 /* CPMIC_BYPASS_MODE */ | ||
644 | #define WM2200_CPMIC_BYPASS_MODE_MASK 0x0020 /* CPMIC_BYPASS_MODE */ | ||
645 | #define WM2200_CPMIC_BYPASS_MODE_SHIFT 5 /* CPMIC_BYPASS_MODE */ | ||
646 | #define WM2200_CPMIC_BYPASS_MODE_WIDTH 1 /* CPMIC_BYPASS_MODE */ | ||
647 | #define WM2200_CPMIC_ENA 0x0001 /* CPMIC_ENA */ | ||
648 | #define WM2200_CPMIC_ENA_MASK 0x0001 /* CPMIC_ENA */ | ||
649 | #define WM2200_CPMIC_ENA_SHIFT 0 /* CPMIC_ENA */ | ||
650 | #define WM2200_CPMIC_ENA_WIDTH 1 /* CPMIC_ENA */ | ||
651 | |||
652 | /* | ||
653 | * R513 (0x201) - Mic Charge Pump 2 | ||
654 | */ | ||
655 | #define WM2200_CPMIC_LDO_VSEL_OVERRIDE_MASK 0xF800 /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */ | ||
656 | #define WM2200_CPMIC_LDO_VSEL_OVERRIDE_SHIFT 11 /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */ | ||
657 | #define WM2200_CPMIC_LDO_VSEL_OVERRIDE_WIDTH 5 /* CPMIC_LDO_VSEL_OVERRIDE - [15:11] */ | ||
658 | |||
659 | /* | ||
660 | * R514 (0x202) - DM Charge Pump 1 | ||
661 | */ | ||
662 | #define WM2200_CPDM_ENA 0x0001 /* CPDM_ENA */ | ||
663 | #define WM2200_CPDM_ENA_MASK 0x0001 /* CPDM_ENA */ | ||
664 | #define WM2200_CPDM_ENA_SHIFT 0 /* CPDM_ENA */ | ||
665 | #define WM2200_CPDM_ENA_WIDTH 1 /* CPDM_ENA */ | ||
666 | |||
667 | /* | ||
668 | * R524 (0x20C) - Mic Bias Ctrl 1 | ||
669 | */ | ||
670 | #define WM2200_MICB1_DISCH 0x0040 /* MICB1_DISCH */ | ||
671 | #define WM2200_MICB1_DISCH_MASK 0x0040 /* MICB1_DISCH */ | ||
672 | #define WM2200_MICB1_DISCH_SHIFT 6 /* MICB1_DISCH */ | ||
673 | #define WM2200_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */ | ||
674 | #define WM2200_MICB1_RATE 0x0020 /* MICB1_RATE */ | ||
675 | #define WM2200_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */ | ||
676 | #define WM2200_MICB1_RATE_SHIFT 5 /* MICB1_RATE */ | ||
677 | #define WM2200_MICB1_RATE_WIDTH 1 /* MICB1_RATE */ | ||
678 | #define WM2200_MICB1_LVL_MASK 0x001C /* MICB1_LVL - [4:2] */ | ||
679 | #define WM2200_MICB1_LVL_SHIFT 2 /* MICB1_LVL - [4:2] */ | ||
680 | #define WM2200_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [4:2] */ | ||
681 | #define WM2200_MICB1_MODE 0x0002 /* MICB1_MODE */ | ||
682 | #define WM2200_MICB1_MODE_MASK 0x0002 /* MICB1_MODE */ | ||
683 | #define WM2200_MICB1_MODE_SHIFT 1 /* MICB1_MODE */ | ||
684 | #define WM2200_MICB1_MODE_WIDTH 1 /* MICB1_MODE */ | ||
685 | #define WM2200_MICB1_ENA 0x0001 /* MICB1_ENA */ | ||
686 | #define WM2200_MICB1_ENA_MASK 0x0001 /* MICB1_ENA */ | ||
687 | #define WM2200_MICB1_ENA_SHIFT 0 /* MICB1_ENA */ | ||
688 | #define WM2200_MICB1_ENA_WIDTH 1 /* MICB1_ENA */ | ||
689 | |||
690 | /* | ||
691 | * R525 (0x20D) - Mic Bias Ctrl 2 | ||
692 | */ | ||
693 | #define WM2200_MICB2_DISCH 0x0040 /* MICB2_DISCH */ | ||
694 | #define WM2200_MICB2_DISCH_MASK 0x0040 /* MICB2_DISCH */ | ||
695 | #define WM2200_MICB2_DISCH_SHIFT 6 /* MICB2_DISCH */ | ||
696 | #define WM2200_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */ | ||
697 | #define WM2200_MICB2_RATE 0x0020 /* MICB2_RATE */ | ||
698 | #define WM2200_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */ | ||
699 | #define WM2200_MICB2_RATE_SHIFT 5 /* MICB2_RATE */ | ||
700 | #define WM2200_MICB2_RATE_WIDTH 1 /* MICB2_RATE */ | ||
701 | #define WM2200_MICB2_LVL_MASK 0x001C /* MICB2_LVL - [4:2] */ | ||
702 | #define WM2200_MICB2_LVL_SHIFT 2 /* MICB2_LVL - [4:2] */ | ||
703 | #define WM2200_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [4:2] */ | ||
704 | #define WM2200_MICB2_MODE 0x0002 /* MICB2_MODE */ | ||
705 | #define WM2200_MICB2_MODE_MASK 0x0002 /* MICB2_MODE */ | ||
706 | #define WM2200_MICB2_MODE_SHIFT 1 /* MICB2_MODE */ | ||
707 | #define WM2200_MICB2_MODE_WIDTH 1 /* MICB2_MODE */ | ||
708 | #define WM2200_MICB2_ENA 0x0001 /* MICB2_ENA */ | ||
709 | #define WM2200_MICB2_ENA_MASK 0x0001 /* MICB2_ENA */ | ||
710 | #define WM2200_MICB2_ENA_SHIFT 0 /* MICB2_ENA */ | ||
711 | #define WM2200_MICB2_ENA_WIDTH 1 /* MICB2_ENA */ | ||
712 | |||
713 | /* | ||
714 | * R527 (0x20F) - Ear Piece Ctrl 1 | ||
715 | */ | ||
716 | #define WM2200_EPD_LP_ENA 0x4000 /* EPD_LP_ENA */ | ||
717 | #define WM2200_EPD_LP_ENA_MASK 0x4000 /* EPD_LP_ENA */ | ||
718 | #define WM2200_EPD_LP_ENA_SHIFT 14 /* EPD_LP_ENA */ | ||
719 | #define WM2200_EPD_LP_ENA_WIDTH 1 /* EPD_LP_ENA */ | ||
720 | #define WM2200_EPD_OUTP_LP_ENA 0x2000 /* EPD_OUTP_LP_ENA */ | ||
721 | #define WM2200_EPD_OUTP_LP_ENA_MASK 0x2000 /* EPD_OUTP_LP_ENA */ | ||
722 | #define WM2200_EPD_OUTP_LP_ENA_SHIFT 13 /* EPD_OUTP_LP_ENA */ | ||
723 | #define WM2200_EPD_OUTP_LP_ENA_WIDTH 1 /* EPD_OUTP_LP_ENA */ | ||
724 | #define WM2200_EPD_RMV_SHRT_LP 0x1000 /* EPD_RMV_SHRT_LP */ | ||
725 | #define WM2200_EPD_RMV_SHRT_LP_MASK 0x1000 /* EPD_RMV_SHRT_LP */ | ||
726 | #define WM2200_EPD_RMV_SHRT_LP_SHIFT 12 /* EPD_RMV_SHRT_LP */ | ||
727 | #define WM2200_EPD_RMV_SHRT_LP_WIDTH 1 /* EPD_RMV_SHRT_LP */ | ||
728 | #define WM2200_EPD_LN_ENA 0x0800 /* EPD_LN_ENA */ | ||
729 | #define WM2200_EPD_LN_ENA_MASK 0x0800 /* EPD_LN_ENA */ | ||
730 | #define WM2200_EPD_LN_ENA_SHIFT 11 /* EPD_LN_ENA */ | ||
731 | #define WM2200_EPD_LN_ENA_WIDTH 1 /* EPD_LN_ENA */ | ||
732 | #define WM2200_EPD_OUTP_LN_ENA 0x0400 /* EPD_OUTP_LN_ENA */ | ||
733 | #define WM2200_EPD_OUTP_LN_ENA_MASK 0x0400 /* EPD_OUTP_LN_ENA */ | ||
734 | #define WM2200_EPD_OUTP_LN_ENA_SHIFT 10 /* EPD_OUTP_LN_ENA */ | ||
735 | #define WM2200_EPD_OUTP_LN_ENA_WIDTH 1 /* EPD_OUTP_LN_ENA */ | ||
736 | #define WM2200_EPD_RMV_SHRT_LN 0x0200 /* EPD_RMV_SHRT_LN */ | ||
737 | #define WM2200_EPD_RMV_SHRT_LN_MASK 0x0200 /* EPD_RMV_SHRT_LN */ | ||
738 | #define WM2200_EPD_RMV_SHRT_LN_SHIFT 9 /* EPD_RMV_SHRT_LN */ | ||
739 | #define WM2200_EPD_RMV_SHRT_LN_WIDTH 1 /* EPD_RMV_SHRT_LN */ | ||
740 | |||
741 | /* | ||
742 | * R528 (0x210) - Ear Piece Ctrl 2 | ||
743 | */ | ||
744 | #define WM2200_EPD_RP_ENA 0x4000 /* EPD_RP_ENA */ | ||
745 | #define WM2200_EPD_RP_ENA_MASK 0x4000 /* EPD_RP_ENA */ | ||
746 | #define WM2200_EPD_RP_ENA_SHIFT 14 /* EPD_RP_ENA */ | ||
747 | #define WM2200_EPD_RP_ENA_WIDTH 1 /* EPD_RP_ENA */ | ||
748 | #define WM2200_EPD_OUTP_RP_ENA 0x2000 /* EPD_OUTP_RP_ENA */ | ||
749 | #define WM2200_EPD_OUTP_RP_ENA_MASK 0x2000 /* EPD_OUTP_RP_ENA */ | ||
750 | #define WM2200_EPD_OUTP_RP_ENA_SHIFT 13 /* EPD_OUTP_RP_ENA */ | ||
751 | #define WM2200_EPD_OUTP_RP_ENA_WIDTH 1 /* EPD_OUTP_RP_ENA */ | ||
752 | #define WM2200_EPD_RMV_SHRT_RP 0x1000 /* EPD_RMV_SHRT_RP */ | ||
753 | #define WM2200_EPD_RMV_SHRT_RP_MASK 0x1000 /* EPD_RMV_SHRT_RP */ | ||
754 | #define WM2200_EPD_RMV_SHRT_RP_SHIFT 12 /* EPD_RMV_SHRT_RP */ | ||
755 | #define WM2200_EPD_RMV_SHRT_RP_WIDTH 1 /* EPD_RMV_SHRT_RP */ | ||
756 | #define WM2200_EPD_RN_ENA 0x0800 /* EPD_RN_ENA */ | ||
757 | #define WM2200_EPD_RN_ENA_MASK 0x0800 /* EPD_RN_ENA */ | ||
758 | #define WM2200_EPD_RN_ENA_SHIFT 11 /* EPD_RN_ENA */ | ||
759 | #define WM2200_EPD_RN_ENA_WIDTH 1 /* EPD_RN_ENA */ | ||
760 | #define WM2200_EPD_OUTP_RN_ENA 0x0400 /* EPD_OUTP_RN_ENA */ | ||
761 | #define WM2200_EPD_OUTP_RN_ENA_MASK 0x0400 /* EPD_OUTP_RN_ENA */ | ||
762 | #define WM2200_EPD_OUTP_RN_ENA_SHIFT 10 /* EPD_OUTP_RN_ENA */ | ||
763 | #define WM2200_EPD_OUTP_RN_ENA_WIDTH 1 /* EPD_OUTP_RN_ENA */ | ||
764 | #define WM2200_EPD_RMV_SHRT_RN 0x0200 /* EPD_RMV_SHRT_RN */ | ||
765 | #define WM2200_EPD_RMV_SHRT_RN_MASK 0x0200 /* EPD_RMV_SHRT_RN */ | ||
766 | #define WM2200_EPD_RMV_SHRT_RN_SHIFT 9 /* EPD_RMV_SHRT_RN */ | ||
767 | #define WM2200_EPD_RMV_SHRT_RN_WIDTH 1 /* EPD_RMV_SHRT_RN */ | ||
768 | |||
769 | /* | ||
770 | * R769 (0x301) - Input Enables | ||
771 | */ | ||
772 | #define WM2200_IN3L_ENA 0x0020 /* IN3L_ENA */ | ||
773 | #define WM2200_IN3L_ENA_MASK 0x0020 /* IN3L_ENA */ | ||
774 | #define WM2200_IN3L_ENA_SHIFT 5 /* IN3L_ENA */ | ||
775 | #define WM2200_IN3L_ENA_WIDTH 1 /* IN3L_ENA */ | ||
776 | #define WM2200_IN3R_ENA 0x0010 /* IN3R_ENA */ | ||
777 | #define WM2200_IN3R_ENA_MASK 0x0010 /* IN3R_ENA */ | ||
778 | #define WM2200_IN3R_ENA_SHIFT 4 /* IN3R_ENA */ | ||
779 | #define WM2200_IN3R_ENA_WIDTH 1 /* IN3R_ENA */ | ||
780 | #define WM2200_IN2L_ENA 0x0008 /* IN2L_ENA */ | ||
781 | #define WM2200_IN2L_ENA_MASK 0x0008 /* IN2L_ENA */ | ||
782 | #define WM2200_IN2L_ENA_SHIFT 3 /* IN2L_ENA */ | ||
783 | #define WM2200_IN2L_ENA_WIDTH 1 /* IN2L_ENA */ | ||
784 | #define WM2200_IN2R_ENA 0x0004 /* IN2R_ENA */ | ||
785 | #define WM2200_IN2R_ENA_MASK 0x0004 /* IN2R_ENA */ | ||
786 | #define WM2200_IN2R_ENA_SHIFT 2 /* IN2R_ENA */ | ||
787 | #define WM2200_IN2R_ENA_WIDTH 1 /* IN2R_ENA */ | ||
788 | #define WM2200_IN1L_ENA 0x0002 /* IN1L_ENA */ | ||
789 | #define WM2200_IN1L_ENA_MASK 0x0002 /* IN1L_ENA */ | ||
790 | #define WM2200_IN1L_ENA_SHIFT 1 /* IN1L_ENA */ | ||
791 | #define WM2200_IN1L_ENA_WIDTH 1 /* IN1L_ENA */ | ||
792 | #define WM2200_IN1R_ENA 0x0001 /* IN1R_ENA */ | ||
793 | #define WM2200_IN1R_ENA_MASK 0x0001 /* IN1R_ENA */ | ||
794 | #define WM2200_IN1R_ENA_SHIFT 0 /* IN1R_ENA */ | ||
795 | #define WM2200_IN1R_ENA_WIDTH 1 /* IN1R_ENA */ | ||
796 | |||
797 | /* | ||
798 | * R770 (0x302) - IN1L Control | ||
799 | */ | ||
800 | #define WM2200_IN1_OSR 0x2000 /* IN1_OSR */ | ||
801 | #define WM2200_IN1_OSR_MASK 0x2000 /* IN1_OSR */ | ||
802 | #define WM2200_IN1_OSR_SHIFT 13 /* IN1_OSR */ | ||
803 | #define WM2200_IN1_OSR_WIDTH 1 /* IN1_OSR */ | ||
804 | #define WM2200_IN1_DMIC_SUP_MASK 0x1800 /* IN1_DMIC_SUP - [12:11] */ | ||
805 | #define WM2200_IN1_DMIC_SUP_SHIFT 11 /* IN1_DMIC_SUP - [12:11] */ | ||
806 | #define WM2200_IN1_DMIC_SUP_WIDTH 2 /* IN1_DMIC_SUP - [12:11] */ | ||
807 | #define WM2200_IN1_MODE_MASK 0x0600 /* IN1_MODE - [10:9] */ | ||
808 | #define WM2200_IN1_MODE_SHIFT 9 /* IN1_MODE - [10:9] */ | ||
809 | #define WM2200_IN1_MODE_WIDTH 2 /* IN1_MODE - [10:9] */ | ||
810 | #define WM2200_IN1L_PGA_VOL_MASK 0x00FE /* IN1L_PGA_VOL - [7:1] */ | ||
811 | #define WM2200_IN1L_PGA_VOL_SHIFT 1 /* IN1L_PGA_VOL - [7:1] */ | ||
812 | #define WM2200_IN1L_PGA_VOL_WIDTH 7 /* IN1L_PGA_VOL - [7:1] */ | ||
813 | |||
814 | /* | ||
815 | * R771 (0x303) - IN1R Control | ||
816 | */ | ||
817 | #define WM2200_IN1R_PGA_VOL_MASK 0x00FE /* IN1R_PGA_VOL - [7:1] */ | ||
818 | #define WM2200_IN1R_PGA_VOL_SHIFT 1 /* IN1R_PGA_VOL - [7:1] */ | ||
819 | #define WM2200_IN1R_PGA_VOL_WIDTH 7 /* IN1R_PGA_VOL - [7:1] */ | ||
820 | |||
821 | /* | ||
822 | * R772 (0x304) - IN2L Control | ||
823 | */ | ||
824 | #define WM2200_IN2_OSR 0x2000 /* IN2_OSR */ | ||
825 | #define WM2200_IN2_OSR_MASK 0x2000 /* IN2_OSR */ | ||
826 | #define WM2200_IN2_OSR_SHIFT 13 /* IN2_OSR */ | ||
827 | #define WM2200_IN2_OSR_WIDTH 1 /* IN2_OSR */ | ||
828 | #define WM2200_IN2_DMIC_SUP_MASK 0x1800 /* IN2_DMIC_SUP - [12:11] */ | ||
829 | #define WM2200_IN2_DMIC_SUP_SHIFT 11 /* IN2_DMIC_SUP - [12:11] */ | ||
830 | #define WM2200_IN2_DMIC_SUP_WIDTH 2 /* IN2_DMIC_SUP - [12:11] */ | ||
831 | #define WM2200_IN2_MODE_MASK 0x0600 /* IN2_MODE - [10:9] */ | ||
832 | #define WM2200_IN2_MODE_SHIFT 9 /* IN2_MODE - [10:9] */ | ||
833 | #define WM2200_IN2_MODE_WIDTH 2 /* IN2_MODE - [10:9] */ | ||
834 | #define WM2200_IN2L_PGA_VOL_MASK 0x00FE /* IN2L_PGA_VOL - [7:1] */ | ||
835 | #define WM2200_IN2L_PGA_VOL_SHIFT 1 /* IN2L_PGA_VOL - [7:1] */ | ||
836 | #define WM2200_IN2L_PGA_VOL_WIDTH 7 /* IN2L_PGA_VOL - [7:1] */ | ||
837 | |||
838 | /* | ||
839 | * R773 (0x305) - IN2R Control | ||
840 | */ | ||
841 | #define WM2200_IN2R_PGA_VOL_MASK 0x00FE /* IN2R_PGA_VOL - [7:1] */ | ||
842 | #define WM2200_IN2R_PGA_VOL_SHIFT 1 /* IN2R_PGA_VOL - [7:1] */ | ||
843 | #define WM2200_IN2R_PGA_VOL_WIDTH 7 /* IN2R_PGA_VOL - [7:1] */ | ||
844 | |||
845 | /* | ||
846 | * R774 (0x306) - IN3L Control | ||
847 | */ | ||
848 | #define WM2200_IN3_OSR 0x2000 /* IN3_OSR */ | ||
849 | #define WM2200_IN3_OSR_MASK 0x2000 /* IN3_OSR */ | ||
850 | #define WM2200_IN3_OSR_SHIFT 13 /* IN3_OSR */ | ||
851 | #define WM2200_IN3_OSR_WIDTH 1 /* IN3_OSR */ | ||
852 | #define WM2200_IN3_DMIC_SUP_MASK 0x1800 /* IN3_DMIC_SUP - [12:11] */ | ||
853 | #define WM2200_IN3_DMIC_SUP_SHIFT 11 /* IN3_DMIC_SUP - [12:11] */ | ||
854 | #define WM2200_IN3_DMIC_SUP_WIDTH 2 /* IN3_DMIC_SUP - [12:11] */ | ||
855 | #define WM2200_IN3_MODE_MASK 0x0600 /* IN3_MODE - [10:9] */ | ||
856 | #define WM2200_IN3_MODE_SHIFT 9 /* IN3_MODE - [10:9] */ | ||
857 | #define WM2200_IN3_MODE_WIDTH 2 /* IN3_MODE - [10:9] */ | ||
858 | #define WM2200_IN3L_PGA_VOL_MASK 0x00FE /* IN3L_PGA_VOL - [7:1] */ | ||
859 | #define WM2200_IN3L_PGA_VOL_SHIFT 1 /* IN3L_PGA_VOL - [7:1] */ | ||
860 | #define WM2200_IN3L_PGA_VOL_WIDTH 7 /* IN3L_PGA_VOL - [7:1] */ | ||
861 | |||
862 | /* | ||
863 | * R775 (0x307) - IN3R Control | ||
864 | */ | ||
865 | #define WM2200_IN3R_PGA_VOL_MASK 0x00FE /* IN3R_PGA_VOL - [7:1] */ | ||
866 | #define WM2200_IN3R_PGA_VOL_SHIFT 1 /* IN3R_PGA_VOL - [7:1] */ | ||
867 | #define WM2200_IN3R_PGA_VOL_WIDTH 7 /* IN3R_PGA_VOL - [7:1] */ | ||
868 | |||
869 | /* | ||
870 | * R778 (0x30A) - RXANC_SRC | ||
871 | */ | ||
872 | #define WM2200_IN_RXANC_SEL_MASK 0x0007 /* IN_RXANC_SEL - [2:0] */ | ||
873 | #define WM2200_IN_RXANC_SEL_SHIFT 0 /* IN_RXANC_SEL - [2:0] */ | ||
874 | #define WM2200_IN_RXANC_SEL_WIDTH 3 /* IN_RXANC_SEL - [2:0] */ | ||
875 | |||
876 | /* | ||
877 | * R779 (0x30B) - Input Volume Ramp | ||
878 | */ | ||
879 | #define WM2200_IN_VD_RAMP_MASK 0x0070 /* IN_VD_RAMP - [6:4] */ | ||
880 | #define WM2200_IN_VD_RAMP_SHIFT 4 /* IN_VD_RAMP - [6:4] */ | ||
881 | #define WM2200_IN_VD_RAMP_WIDTH 3 /* IN_VD_RAMP - [6:4] */ | ||
882 | #define WM2200_IN_VI_RAMP_MASK 0x0007 /* IN_VI_RAMP - [2:0] */ | ||
883 | #define WM2200_IN_VI_RAMP_SHIFT 0 /* IN_VI_RAMP - [2:0] */ | ||
884 | #define WM2200_IN_VI_RAMP_WIDTH 3 /* IN_VI_RAMP - [2:0] */ | ||
885 | |||
886 | /* | ||
887 | * R780 (0x30C) - ADC Digital Volume 1L | ||
888 | */ | ||
889 | #define WM2200_IN_VU 0x0200 /* IN_VU */ | ||
890 | #define WM2200_IN_VU_MASK 0x0200 /* IN_VU */ | ||
891 | #define WM2200_IN_VU_SHIFT 9 /* IN_VU */ | ||
892 | #define WM2200_IN_VU_WIDTH 1 /* IN_VU */ | ||
893 | #define WM2200_IN1L_MUTE 0x0100 /* IN1L_MUTE */ | ||
894 | #define WM2200_IN1L_MUTE_MASK 0x0100 /* IN1L_MUTE */ | ||
895 | #define WM2200_IN1L_MUTE_SHIFT 8 /* IN1L_MUTE */ | ||
896 | #define WM2200_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */ | ||
897 | #define WM2200_IN1L_DIG_VOL_MASK 0x00FF /* IN1L_DIG_VOL - [7:0] */ | ||
898 | #define WM2200_IN1L_DIG_VOL_SHIFT 0 /* IN1L_DIG_VOL - [7:0] */ | ||
899 | #define WM2200_IN1L_DIG_VOL_WIDTH 8 /* IN1L_DIG_VOL - [7:0] */ | ||
900 | |||
901 | /* | ||
902 | * R781 (0x30D) - ADC Digital Volume 1R | ||
903 | */ | ||
904 | #define WM2200_IN_VU 0x0200 /* IN_VU */ | ||
905 | #define WM2200_IN_VU_MASK 0x0200 /* IN_VU */ | ||
906 | #define WM2200_IN_VU_SHIFT 9 /* IN_VU */ | ||
907 | #define WM2200_IN_VU_WIDTH 1 /* IN_VU */ | ||
908 | #define WM2200_IN1R_MUTE 0x0100 /* IN1R_MUTE */ | ||
909 | #define WM2200_IN1R_MUTE_MASK 0x0100 /* IN1R_MUTE */ | ||
910 | #define WM2200_IN1R_MUTE_SHIFT 8 /* IN1R_MUTE */ | ||
911 | #define WM2200_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */ | ||
912 | #define WM2200_IN1R_DIG_VOL_MASK 0x00FF /* IN1R_DIG_VOL - [7:0] */ | ||
913 | #define WM2200_IN1R_DIG_VOL_SHIFT 0 /* IN1R_DIG_VOL - [7:0] */ | ||
914 | #define WM2200_IN1R_DIG_VOL_WIDTH 8 /* IN1R_DIG_VOL - [7:0] */ | ||
915 | |||
916 | /* | ||
917 | * R782 (0x30E) - ADC Digital Volume 2L | ||
918 | */ | ||
919 | #define WM2200_IN_VU 0x0200 /* IN_VU */ | ||
920 | #define WM2200_IN_VU_MASK 0x0200 /* IN_VU */ | ||
921 | #define WM2200_IN_VU_SHIFT 9 /* IN_VU */ | ||
922 | #define WM2200_IN_VU_WIDTH 1 /* IN_VU */ | ||
923 | #define WM2200_IN2L_MUTE 0x0100 /* IN2L_MUTE */ | ||
924 | #define WM2200_IN2L_MUTE_MASK 0x0100 /* IN2L_MUTE */ | ||
925 | #define WM2200_IN2L_MUTE_SHIFT 8 /* IN2L_MUTE */ | ||
926 | #define WM2200_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */ | ||
927 | #define WM2200_IN2L_DIG_VOL_MASK 0x00FF /* IN2L_DIG_VOL - [7:0] */ | ||
928 | #define WM2200_IN2L_DIG_VOL_SHIFT 0 /* IN2L_DIG_VOL - [7:0] */ | ||
929 | #define WM2200_IN2L_DIG_VOL_WIDTH 8 /* IN2L_DIG_VOL - [7:0] */ | ||
930 | |||
931 | /* | ||
932 | * R783 (0x30F) - ADC Digital Volume 2R | ||
933 | */ | ||
934 | #define WM2200_IN_VU 0x0200 /* IN_VU */ | ||
935 | #define WM2200_IN_VU_MASK 0x0200 /* IN_VU */ | ||
936 | #define WM2200_IN_VU_SHIFT 9 /* IN_VU */ | ||
937 | #define WM2200_IN_VU_WIDTH 1 /* IN_VU */ | ||
938 | #define WM2200_IN2R_MUTE 0x0100 /* IN2R_MUTE */ | ||
939 | #define WM2200_IN2R_MUTE_MASK 0x0100 /* IN2R_MUTE */ | ||
940 | #define WM2200_IN2R_MUTE_SHIFT 8 /* IN2R_MUTE */ | ||
941 | #define WM2200_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */ | ||
942 | #define WM2200_IN2R_DIG_VOL_MASK 0x00FF /* IN2R_DIG_VOL - [7:0] */ | ||
943 | #define WM2200_IN2R_DIG_VOL_SHIFT 0 /* IN2R_DIG_VOL - [7:0] */ | ||
944 | #define WM2200_IN2R_DIG_VOL_WIDTH 8 /* IN2R_DIG_VOL - [7:0] */ | ||
945 | |||
946 | /* | ||
947 | * R784 (0x310) - ADC Digital Volume 3L | ||
948 | */ | ||
949 | #define WM2200_IN_VU 0x0200 /* IN_VU */ | ||
950 | #define WM2200_IN_VU_MASK 0x0200 /* IN_VU */ | ||
951 | #define WM2200_IN_VU_SHIFT 9 /* IN_VU */ | ||
952 | #define WM2200_IN_VU_WIDTH 1 /* IN_VU */ | ||
953 | #define WM2200_IN3L_MUTE 0x0100 /* IN3L_MUTE */ | ||
954 | #define WM2200_IN3L_MUTE_MASK 0x0100 /* IN3L_MUTE */ | ||
955 | #define WM2200_IN3L_MUTE_SHIFT 8 /* IN3L_MUTE */ | ||
956 | #define WM2200_IN3L_MUTE_WIDTH 1 /* IN3L_MUTE */ | ||
957 | #define WM2200_IN3L_DIG_VOL_MASK 0x00FF /* IN3L_DIG_VOL - [7:0] */ | ||
958 | #define WM2200_IN3L_DIG_VOL_SHIFT 0 /* IN3L_DIG_VOL - [7:0] */ | ||
959 | #define WM2200_IN3L_DIG_VOL_WIDTH 8 /* IN3L_DIG_VOL - [7:0] */ | ||
960 | |||
961 | /* | ||
962 | * R785 (0x311) - ADC Digital Volume 3R | ||
963 | */ | ||
964 | #define WM2200_IN_VU 0x0200 /* IN_VU */ | ||
965 | #define WM2200_IN_VU_MASK 0x0200 /* IN_VU */ | ||
966 | #define WM2200_IN_VU_SHIFT 9 /* IN_VU */ | ||
967 | #define WM2200_IN_VU_WIDTH 1 /* IN_VU */ | ||
968 | #define WM2200_IN3R_MUTE 0x0100 /* IN3R_MUTE */ | ||
969 | #define WM2200_IN3R_MUTE_MASK 0x0100 /* IN3R_MUTE */ | ||
970 | #define WM2200_IN3R_MUTE_SHIFT 8 /* IN3R_MUTE */ | ||
971 | #define WM2200_IN3R_MUTE_WIDTH 1 /* IN3R_MUTE */ | ||
972 | #define WM2200_IN3R_DIG_VOL_MASK 0x00FF /* IN3R_DIG_VOL - [7:0] */ | ||
973 | #define WM2200_IN3R_DIG_VOL_SHIFT 0 /* IN3R_DIG_VOL - [7:0] */ | ||
974 | #define WM2200_IN3R_DIG_VOL_WIDTH 8 /* IN3R_DIG_VOL - [7:0] */ | ||
975 | |||
976 | /* | ||
977 | * R1024 (0x400) - Output Enables | ||
978 | */ | ||
979 | #define WM2200_OUT2L_ENA 0x0008 /* OUT2L_ENA */ | ||
980 | #define WM2200_OUT2L_ENA_MASK 0x0008 /* OUT2L_ENA */ | ||
981 | #define WM2200_OUT2L_ENA_SHIFT 3 /* OUT2L_ENA */ | ||
982 | #define WM2200_OUT2L_ENA_WIDTH 1 /* OUT2L_ENA */ | ||
983 | #define WM2200_OUT2R_ENA 0x0004 /* OUT2R_ENA */ | ||
984 | #define WM2200_OUT2R_ENA_MASK 0x0004 /* OUT2R_ENA */ | ||
985 | #define WM2200_OUT2R_ENA_SHIFT 2 /* OUT2R_ENA */ | ||
986 | #define WM2200_OUT2R_ENA_WIDTH 1 /* OUT2R_ENA */ | ||
987 | #define WM2200_OUT1L_ENA 0x0002 /* OUT1L_ENA */ | ||
988 | #define WM2200_OUT1L_ENA_MASK 0x0002 /* OUT1L_ENA */ | ||
989 | #define WM2200_OUT1L_ENA_SHIFT 1 /* OUT1L_ENA */ | ||
990 | #define WM2200_OUT1L_ENA_WIDTH 1 /* OUT1L_ENA */ | ||
991 | #define WM2200_OUT1R_ENA 0x0001 /* OUT1R_ENA */ | ||
992 | #define WM2200_OUT1R_ENA_MASK 0x0001 /* OUT1R_ENA */ | ||
993 | #define WM2200_OUT1R_ENA_SHIFT 0 /* OUT1R_ENA */ | ||
994 | #define WM2200_OUT1R_ENA_WIDTH 1 /* OUT1R_ENA */ | ||
995 | |||
996 | /* | ||
997 | * R1025 (0x401) - DAC Volume Limit 1L | ||
998 | */ | ||
999 | #define WM2200_OUT1_OSR 0x2000 /* OUT1_OSR */ | ||
1000 | #define WM2200_OUT1_OSR_MASK 0x2000 /* OUT1_OSR */ | ||
1001 | #define WM2200_OUT1_OSR_SHIFT 13 /* OUT1_OSR */ | ||
1002 | #define WM2200_OUT1_OSR_WIDTH 1 /* OUT1_OSR */ | ||
1003 | #define WM2200_OUT1L_ANC_SRC 0x0800 /* OUT1L_ANC_SRC */ | ||
1004 | #define WM2200_OUT1L_ANC_SRC_MASK 0x0800 /* OUT1L_ANC_SRC */ | ||
1005 | #define WM2200_OUT1L_ANC_SRC_SHIFT 11 /* OUT1L_ANC_SRC */ | ||
1006 | #define WM2200_OUT1L_ANC_SRC_WIDTH 1 /* OUT1L_ANC_SRC */ | ||
1007 | #define WM2200_OUT1L_PGA_VOL_MASK 0x00FE /* OUT1L_PGA_VOL - [7:1] */ | ||
1008 | #define WM2200_OUT1L_PGA_VOL_SHIFT 1 /* OUT1L_PGA_VOL - [7:1] */ | ||
1009 | #define WM2200_OUT1L_PGA_VOL_WIDTH 7 /* OUT1L_PGA_VOL - [7:1] */ | ||
1010 | |||
1011 | /* | ||
1012 | * R1026 (0x402) - DAC Volume Limit 1R | ||
1013 | */ | ||
1014 | #define WM2200_OUT1R_ANC_SRC 0x0800 /* OUT1R_ANC_SRC */ | ||
1015 | #define WM2200_OUT1R_ANC_SRC_MASK 0x0800 /* OUT1R_ANC_SRC */ | ||
1016 | #define WM2200_OUT1R_ANC_SRC_SHIFT 11 /* OUT1R_ANC_SRC */ | ||
1017 | #define WM2200_OUT1R_ANC_SRC_WIDTH 1 /* OUT1R_ANC_SRC */ | ||
1018 | #define WM2200_OUT1R_PGA_VOL_MASK 0x00FE /* OUT1R_PGA_VOL - [7:1] */ | ||
1019 | #define WM2200_OUT1R_PGA_VOL_SHIFT 1 /* OUT1R_PGA_VOL - [7:1] */ | ||
1020 | #define WM2200_OUT1R_PGA_VOL_WIDTH 7 /* OUT1R_PGA_VOL - [7:1] */ | ||
1021 | |||
1022 | /* | ||
1023 | * R1027 (0x403) - DAC Volume Limit 2L | ||
1024 | */ | ||
1025 | #define WM2200_OUT2_OSR 0x2000 /* OUT2_OSR */ | ||
1026 | #define WM2200_OUT2_OSR_MASK 0x2000 /* OUT2_OSR */ | ||
1027 | #define WM2200_OUT2_OSR_SHIFT 13 /* OUT2_OSR */ | ||
1028 | #define WM2200_OUT2_OSR_WIDTH 1 /* OUT2_OSR */ | ||
1029 | #define WM2200_OUT2L_ANC_SRC 0x0800 /* OUT2L_ANC_SRC */ | ||
1030 | #define WM2200_OUT2L_ANC_SRC_MASK 0x0800 /* OUT2L_ANC_SRC */ | ||
1031 | #define WM2200_OUT2L_ANC_SRC_SHIFT 11 /* OUT2L_ANC_SRC */ | ||
1032 | #define WM2200_OUT2L_ANC_SRC_WIDTH 1 /* OUT2L_ANC_SRC */ | ||
1033 | |||
1034 | /* | ||
1035 | * R1028 (0x404) - DAC Volume Limit 2R | ||
1036 | */ | ||
1037 | #define WM2200_OUT2R_ANC_SRC 0x0800 /* OUT2R_ANC_SRC */ | ||
1038 | #define WM2200_OUT2R_ANC_SRC_MASK 0x0800 /* OUT2R_ANC_SRC */ | ||
1039 | #define WM2200_OUT2R_ANC_SRC_SHIFT 11 /* OUT2R_ANC_SRC */ | ||
1040 | #define WM2200_OUT2R_ANC_SRC_WIDTH 1 /* OUT2R_ANC_SRC */ | ||
1041 | |||
1042 | /* | ||
1043 | * R1033 (0x409) - DAC AEC Control 1 | ||
1044 | */ | ||
1045 | #define WM2200_AEC_LOOPBACK_ENA 0x0004 /* AEC_LOOPBACK_ENA */ | ||
1046 | #define WM2200_AEC_LOOPBACK_ENA_MASK 0x0004 /* AEC_LOOPBACK_ENA */ | ||
1047 | #define WM2200_AEC_LOOPBACK_ENA_SHIFT 2 /* AEC_LOOPBACK_ENA */ | ||
1048 | #define WM2200_AEC_LOOPBACK_ENA_WIDTH 1 /* AEC_LOOPBACK_ENA */ | ||
1049 | #define WM2200_AEC_LOOPBACK_SRC_MASK 0x0003 /* AEC_LOOPBACK_SRC - [1:0] */ | ||
1050 | #define WM2200_AEC_LOOPBACK_SRC_SHIFT 0 /* AEC_LOOPBACK_SRC - [1:0] */ | ||
1051 | #define WM2200_AEC_LOOPBACK_SRC_WIDTH 2 /* AEC_LOOPBACK_SRC - [1:0] */ | ||
1052 | |||
1053 | /* | ||
1054 | * R1034 (0x40A) - Output Volume Ramp | ||
1055 | */ | ||
1056 | #define WM2200_OUT_VD_RAMP_MASK 0x0070 /* OUT_VD_RAMP - [6:4] */ | ||
1057 | #define WM2200_OUT_VD_RAMP_SHIFT 4 /* OUT_VD_RAMP - [6:4] */ | ||
1058 | #define WM2200_OUT_VD_RAMP_WIDTH 3 /* OUT_VD_RAMP - [6:4] */ | ||
1059 | #define WM2200_OUT_VI_RAMP_MASK 0x0007 /* OUT_VI_RAMP - [2:0] */ | ||
1060 | #define WM2200_OUT_VI_RAMP_SHIFT 0 /* OUT_VI_RAMP - [2:0] */ | ||
1061 | #define WM2200_OUT_VI_RAMP_WIDTH 3 /* OUT_VI_RAMP - [2:0] */ | ||
1062 | |||
1063 | /* | ||
1064 | * R1035 (0x40B) - DAC Digital Volume 1L | ||
1065 | */ | ||
1066 | #define WM2200_OUT_VU 0x0200 /* OUT_VU */ | ||
1067 | #define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
1068 | #define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
1069 | #define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
1070 | #define WM2200_OUT1L_MUTE 0x0100 /* OUT1L_MUTE */ | ||
1071 | #define WM2200_OUT1L_MUTE_MASK 0x0100 /* OUT1L_MUTE */ | ||
1072 | #define WM2200_OUT1L_MUTE_SHIFT 8 /* OUT1L_MUTE */ | ||
1073 | #define WM2200_OUT1L_MUTE_WIDTH 1 /* OUT1L_MUTE */ | ||
1074 | #define WM2200_OUT1L_VOL_MASK 0x00FF /* OUT1L_VOL - [7:0] */ | ||
1075 | #define WM2200_OUT1L_VOL_SHIFT 0 /* OUT1L_VOL - [7:0] */ | ||
1076 | #define WM2200_OUT1L_VOL_WIDTH 8 /* OUT1L_VOL - [7:0] */ | ||
1077 | |||
1078 | /* | ||
1079 | * R1036 (0x40C) - DAC Digital Volume 1R | ||
1080 | */ | ||
1081 | #define WM2200_OUT_VU 0x0200 /* OUT_VU */ | ||
1082 | #define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
1083 | #define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
1084 | #define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
1085 | #define WM2200_OUT1R_MUTE 0x0100 /* OUT1R_MUTE */ | ||
1086 | #define WM2200_OUT1R_MUTE_MASK 0x0100 /* OUT1R_MUTE */ | ||
1087 | #define WM2200_OUT1R_MUTE_SHIFT 8 /* OUT1R_MUTE */ | ||
1088 | #define WM2200_OUT1R_MUTE_WIDTH 1 /* OUT1R_MUTE */ | ||
1089 | #define WM2200_OUT1R_VOL_MASK 0x00FF /* OUT1R_VOL - [7:0] */ | ||
1090 | #define WM2200_OUT1R_VOL_SHIFT 0 /* OUT1R_VOL - [7:0] */ | ||
1091 | #define WM2200_OUT1R_VOL_WIDTH 8 /* OUT1R_VOL - [7:0] */ | ||
1092 | |||
1093 | /* | ||
1094 | * R1037 (0x40D) - DAC Digital Volume 2L | ||
1095 | */ | ||
1096 | #define WM2200_OUT_VU 0x0200 /* OUT_VU */ | ||
1097 | #define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
1098 | #define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
1099 | #define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
1100 | #define WM2200_OUT2L_MUTE 0x0100 /* OUT2L_MUTE */ | ||
1101 | #define WM2200_OUT2L_MUTE_MASK 0x0100 /* OUT2L_MUTE */ | ||
1102 | #define WM2200_OUT2L_MUTE_SHIFT 8 /* OUT2L_MUTE */ | ||
1103 | #define WM2200_OUT2L_MUTE_WIDTH 1 /* OUT2L_MUTE */ | ||
1104 | #define WM2200_OUT2L_VOL_MASK 0x00FF /* OUT2L_VOL - [7:0] */ | ||
1105 | #define WM2200_OUT2L_VOL_SHIFT 0 /* OUT2L_VOL - [7:0] */ | ||
1106 | #define WM2200_OUT2L_VOL_WIDTH 8 /* OUT2L_VOL - [7:0] */ | ||
1107 | |||
1108 | /* | ||
1109 | * R1038 (0x40E) - DAC Digital Volume 2R | ||
1110 | */ | ||
1111 | #define WM2200_OUT_VU 0x0200 /* OUT_VU */ | ||
1112 | #define WM2200_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
1113 | #define WM2200_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
1114 | #define WM2200_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
1115 | #define WM2200_OUT2R_MUTE 0x0100 /* OUT2R_MUTE */ | ||
1116 | #define WM2200_OUT2R_MUTE_MASK 0x0100 /* OUT2R_MUTE */ | ||
1117 | #define WM2200_OUT2R_MUTE_SHIFT 8 /* OUT2R_MUTE */ | ||
1118 | #define WM2200_OUT2R_MUTE_WIDTH 1 /* OUT2R_MUTE */ | ||
1119 | #define WM2200_OUT2R_VOL_MASK 0x00FF /* OUT2R_VOL - [7:0] */ | ||
1120 | #define WM2200_OUT2R_VOL_SHIFT 0 /* OUT2R_VOL - [7:0] */ | ||
1121 | #define WM2200_OUT2R_VOL_WIDTH 8 /* OUT2R_VOL - [7:0] */ | ||
1122 | |||
1123 | /* | ||
1124 | * R1047 (0x417) - PDM 1 | ||
1125 | */ | ||
1126 | #define WM2200_SPK1R_MUTE 0x2000 /* SPK1R_MUTE */ | ||
1127 | #define WM2200_SPK1R_MUTE_MASK 0x2000 /* SPK1R_MUTE */ | ||
1128 | #define WM2200_SPK1R_MUTE_SHIFT 13 /* SPK1R_MUTE */ | ||
1129 | #define WM2200_SPK1R_MUTE_WIDTH 1 /* SPK1R_MUTE */ | ||
1130 | #define WM2200_SPK1L_MUTE 0x1000 /* SPK1L_MUTE */ | ||
1131 | #define WM2200_SPK1L_MUTE_MASK 0x1000 /* SPK1L_MUTE */ | ||
1132 | #define WM2200_SPK1L_MUTE_SHIFT 12 /* SPK1L_MUTE */ | ||
1133 | #define WM2200_SPK1L_MUTE_WIDTH 1 /* SPK1L_MUTE */ | ||
1134 | #define WM2200_SPK1_MUTE_ENDIAN 0x0100 /* SPK1_MUTE_ENDIAN */ | ||
1135 | #define WM2200_SPK1_MUTE_ENDIAN_MASK 0x0100 /* SPK1_MUTE_ENDIAN */ | ||
1136 | #define WM2200_SPK1_MUTE_ENDIAN_SHIFT 8 /* SPK1_MUTE_ENDIAN */ | ||
1137 | #define WM2200_SPK1_MUTE_ENDIAN_WIDTH 1 /* SPK1_MUTE_ENDIAN */ | ||
1138 | #define WM2200_SPK1_MUTE_SEQL_MASK 0x00FF /* SPK1_MUTE_SEQL - [7:0] */ | ||
1139 | #define WM2200_SPK1_MUTE_SEQL_SHIFT 0 /* SPK1_MUTE_SEQL - [7:0] */ | ||
1140 | #define WM2200_SPK1_MUTE_SEQL_WIDTH 8 /* SPK1_MUTE_SEQL - [7:0] */ | ||
1141 | |||
1142 | /* | ||
1143 | * R1048 (0x418) - PDM 2 | ||
1144 | */ | ||
1145 | #define WM2200_SPK1_FMT 0x0001 /* SPK1_FMT */ | ||
1146 | #define WM2200_SPK1_FMT_MASK 0x0001 /* SPK1_FMT */ | ||
1147 | #define WM2200_SPK1_FMT_SHIFT 0 /* SPK1_FMT */ | ||
1148 | #define WM2200_SPK1_FMT_WIDTH 1 /* SPK1_FMT */ | ||
1149 | |||
1150 | /* | ||
1151 | * R1280 (0x500) - Audio IF 1_1 | ||
1152 | */ | ||
1153 | #define WM2200_AIF1_BCLK_INV 0x0040 /* AIF1_BCLK_INV */ | ||
1154 | #define WM2200_AIF1_BCLK_INV_MASK 0x0040 /* AIF1_BCLK_INV */ | ||
1155 | #define WM2200_AIF1_BCLK_INV_SHIFT 6 /* AIF1_BCLK_INV */ | ||
1156 | #define WM2200_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */ | ||
1157 | #define WM2200_AIF1_BCLK_FRC 0x0020 /* AIF1_BCLK_FRC */ | ||
1158 | #define WM2200_AIF1_BCLK_FRC_MASK 0x0020 /* AIF1_BCLK_FRC */ | ||
1159 | #define WM2200_AIF1_BCLK_FRC_SHIFT 5 /* AIF1_BCLK_FRC */ | ||
1160 | #define WM2200_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */ | ||
1161 | #define WM2200_AIF1_BCLK_MSTR 0x0010 /* AIF1_BCLK_MSTR */ | ||
1162 | #define WM2200_AIF1_BCLK_MSTR_MASK 0x0010 /* AIF1_BCLK_MSTR */ | ||
1163 | #define WM2200_AIF1_BCLK_MSTR_SHIFT 4 /* AIF1_BCLK_MSTR */ | ||
1164 | #define WM2200_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */ | ||
1165 | #define WM2200_AIF1_BCLK_DIV_MASK 0x000F /* AIF1_BCLK_DIV - [3:0] */ | ||
1166 | #define WM2200_AIF1_BCLK_DIV_SHIFT 0 /* AIF1_BCLK_DIV - [3:0] */ | ||
1167 | #define WM2200_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [3:0] */ | ||
1168 | |||
1169 | /* | ||
1170 | * R1281 (0x501) - Audio IF 1_2 | ||
1171 | */ | ||
1172 | #define WM2200_AIF1TX_DAT_TRI 0x0020 /* AIF1TX_DAT_TRI */ | ||
1173 | #define WM2200_AIF1TX_DAT_TRI_MASK 0x0020 /* AIF1TX_DAT_TRI */ | ||
1174 | #define WM2200_AIF1TX_DAT_TRI_SHIFT 5 /* AIF1TX_DAT_TRI */ | ||
1175 | #define WM2200_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */ | ||
1176 | #define WM2200_AIF1TX_LRCLK_SRC 0x0008 /* AIF1TX_LRCLK_SRC */ | ||
1177 | #define WM2200_AIF1TX_LRCLK_SRC_MASK 0x0008 /* AIF1TX_LRCLK_SRC */ | ||
1178 | #define WM2200_AIF1TX_LRCLK_SRC_SHIFT 3 /* AIF1TX_LRCLK_SRC */ | ||
1179 | #define WM2200_AIF1TX_LRCLK_SRC_WIDTH 1 /* AIF1TX_LRCLK_SRC */ | ||
1180 | #define WM2200_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */ | ||
1181 | #define WM2200_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */ | ||
1182 | #define WM2200_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */ | ||
1183 | #define WM2200_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */ | ||
1184 | #define WM2200_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */ | ||
1185 | #define WM2200_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */ | ||
1186 | #define WM2200_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */ | ||
1187 | #define WM2200_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */ | ||
1188 | #define WM2200_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */ | ||
1189 | #define WM2200_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */ | ||
1190 | #define WM2200_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */ | ||
1191 | #define WM2200_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */ | ||
1192 | |||
1193 | /* | ||
1194 | * R1282 (0x502) - Audio IF 1_3 | ||
1195 | */ | ||
1196 | #define WM2200_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */ | ||
1197 | #define WM2200_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */ | ||
1198 | #define WM2200_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */ | ||
1199 | #define WM2200_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */ | ||
1200 | #define WM2200_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */ | ||
1201 | #define WM2200_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */ | ||
1202 | #define WM2200_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */ | ||
1203 | #define WM2200_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */ | ||
1204 | #define WM2200_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */ | ||
1205 | #define WM2200_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */ | ||
1206 | #define WM2200_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */ | ||
1207 | #define WM2200_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */ | ||
1208 | |||
1209 | /* | ||
1210 | * R1283 (0x503) - Audio IF 1_4 | ||
1211 | */ | ||
1212 | #define WM2200_AIF1_TRI 0x0040 /* AIF1_TRI */ | ||
1213 | #define WM2200_AIF1_TRI_MASK 0x0040 /* AIF1_TRI */ | ||
1214 | #define WM2200_AIF1_TRI_SHIFT 6 /* AIF1_TRI */ | ||
1215 | #define WM2200_AIF1_TRI_WIDTH 1 /* AIF1_TRI */ | ||
1216 | |||
1217 | /* | ||
1218 | * R1284 (0x504) - Audio IF 1_5 | ||
1219 | */ | ||
1220 | #define WM2200_AIF1_FMT_MASK 0x0007 /* AIF1_FMT - [2:0] */ | ||
1221 | #define WM2200_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [2:0] */ | ||
1222 | #define WM2200_AIF1_FMT_WIDTH 3 /* AIF1_FMT - [2:0] */ | ||
1223 | |||
1224 | /* | ||
1225 | * R1285 (0x505) - Audio IF 1_6 | ||
1226 | */ | ||
1227 | #define WM2200_AIF1TX_BCPF_MASK 0x07FF /* AIF1TX_BCPF - [10:0] */ | ||
1228 | #define WM2200_AIF1TX_BCPF_SHIFT 0 /* AIF1TX_BCPF - [10:0] */ | ||
1229 | #define WM2200_AIF1TX_BCPF_WIDTH 11 /* AIF1TX_BCPF - [10:0] */ | ||
1230 | |||
1231 | /* | ||
1232 | * R1286 (0x506) - Audio IF 1_7 | ||
1233 | */ | ||
1234 | #define WM2200_AIF1RX_BCPF_MASK 0x07FF /* AIF1RX_BCPF - [10:0] */ | ||
1235 | #define WM2200_AIF1RX_BCPF_SHIFT 0 /* AIF1RX_BCPF - [10:0] */ | ||
1236 | #define WM2200_AIF1RX_BCPF_WIDTH 11 /* AIF1RX_BCPF - [10:0] */ | ||
1237 | |||
1238 | /* | ||
1239 | * R1287 (0x507) - Audio IF 1_8 | ||
1240 | */ | ||
1241 | #define WM2200_AIF1TX_WL_MASK 0x3F00 /* AIF1TX_WL - [13:8] */ | ||
1242 | #define WM2200_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [13:8] */ | ||
1243 | #define WM2200_AIF1TX_WL_WIDTH 6 /* AIF1TX_WL - [13:8] */ | ||
1244 | #define WM2200_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */ | ||
1245 | #define WM2200_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */ | ||
1246 | #define WM2200_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */ | ||
1247 | |||
1248 | /* | ||
1249 | * R1288 (0x508) - Audio IF 1_9 | ||
1250 | */ | ||
1251 | #define WM2200_AIF1RX_WL_MASK 0x3F00 /* AIF1RX_WL - [13:8] */ | ||
1252 | #define WM2200_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [13:8] */ | ||
1253 | #define WM2200_AIF1RX_WL_WIDTH 6 /* AIF1RX_WL - [13:8] */ | ||
1254 | #define WM2200_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */ | ||
1255 | #define WM2200_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */ | ||
1256 | #define WM2200_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */ | ||
1257 | |||
1258 | /* | ||
1259 | * R1289 (0x509) - Audio IF 1_10 | ||
1260 | */ | ||
1261 | #define WM2200_AIF1TX1_SLOT_MASK 0x003F /* AIF1TX1_SLOT - [5:0] */ | ||
1262 | #define WM2200_AIF1TX1_SLOT_SHIFT 0 /* AIF1TX1_SLOT - [5:0] */ | ||
1263 | #define WM2200_AIF1TX1_SLOT_WIDTH 6 /* AIF1TX1_SLOT - [5:0] */ | ||
1264 | |||
1265 | /* | ||
1266 | * R1290 (0x50A) - Audio IF 1_11 | ||
1267 | */ | ||
1268 | #define WM2200_AIF1TX2_SLOT_MASK 0x003F /* AIF1TX2_SLOT - [5:0] */ | ||
1269 | #define WM2200_AIF1TX2_SLOT_SHIFT 0 /* AIF1TX2_SLOT - [5:0] */ | ||
1270 | #define WM2200_AIF1TX2_SLOT_WIDTH 6 /* AIF1TX2_SLOT - [5:0] */ | ||
1271 | |||
1272 | /* | ||
1273 | * R1291 (0x50B) - Audio IF 1_12 | ||
1274 | */ | ||
1275 | #define WM2200_AIF1TX3_SLOT_MASK 0x003F /* AIF1TX3_SLOT - [5:0] */ | ||
1276 | #define WM2200_AIF1TX3_SLOT_SHIFT 0 /* AIF1TX3_SLOT - [5:0] */ | ||
1277 | #define WM2200_AIF1TX3_SLOT_WIDTH 6 /* AIF1TX3_SLOT - [5:0] */ | ||
1278 | |||
1279 | /* | ||
1280 | * R1292 (0x50C) - Audio IF 1_13 | ||
1281 | */ | ||
1282 | #define WM2200_AIF1TX4_SLOT_MASK 0x003F /* AIF1TX4_SLOT - [5:0] */ | ||
1283 | #define WM2200_AIF1TX4_SLOT_SHIFT 0 /* AIF1TX4_SLOT - [5:0] */ | ||
1284 | #define WM2200_AIF1TX4_SLOT_WIDTH 6 /* AIF1TX4_SLOT - [5:0] */ | ||
1285 | |||
1286 | /* | ||
1287 | * R1293 (0x50D) - Audio IF 1_14 | ||
1288 | */ | ||
1289 | #define WM2200_AIF1TX5_SLOT_MASK 0x003F /* AIF1TX5_SLOT - [5:0] */ | ||
1290 | #define WM2200_AIF1TX5_SLOT_SHIFT 0 /* AIF1TX5_SLOT - [5:0] */ | ||
1291 | #define WM2200_AIF1TX5_SLOT_WIDTH 6 /* AIF1TX5_SLOT - [5:0] */ | ||
1292 | |||
1293 | /* | ||
1294 | * R1294 (0x50E) - Audio IF 1_15 | ||
1295 | */ | ||
1296 | #define WM2200_AIF1TX6_SLOT_MASK 0x003F /* AIF1TX6_SLOT - [5:0] */ | ||
1297 | #define WM2200_AIF1TX6_SLOT_SHIFT 0 /* AIF1TX6_SLOT - [5:0] */ | ||
1298 | #define WM2200_AIF1TX6_SLOT_WIDTH 6 /* AIF1TX6_SLOT - [5:0] */ | ||
1299 | |||
1300 | /* | ||
1301 | * R1295 (0x50F) - Audio IF 1_16 | ||
1302 | */ | ||
1303 | #define WM2200_AIF1RX1_SLOT_MASK 0x003F /* AIF1RX1_SLOT - [5:0] */ | ||
1304 | #define WM2200_AIF1RX1_SLOT_SHIFT 0 /* AIF1RX1_SLOT - [5:0] */ | ||
1305 | #define WM2200_AIF1RX1_SLOT_WIDTH 6 /* AIF1RX1_SLOT - [5:0] */ | ||
1306 | |||
1307 | /* | ||
1308 | * R1296 (0x510) - Audio IF 1_17 | ||
1309 | */ | ||
1310 | #define WM2200_AIF1RX2_SLOT_MASK 0x003F /* AIF1RX2_SLOT - [5:0] */ | ||
1311 | #define WM2200_AIF1RX2_SLOT_SHIFT 0 /* AIF1RX2_SLOT - [5:0] */ | ||
1312 | #define WM2200_AIF1RX2_SLOT_WIDTH 6 /* AIF1RX2_SLOT - [5:0] */ | ||
1313 | |||
1314 | /* | ||
1315 | * R1297 (0x511) - Audio IF 1_18 | ||
1316 | */ | ||
1317 | #define WM2200_AIF1RX3_SLOT_MASK 0x003F /* AIF1RX3_SLOT - [5:0] */ | ||
1318 | #define WM2200_AIF1RX3_SLOT_SHIFT 0 /* AIF1RX3_SLOT - [5:0] */ | ||
1319 | #define WM2200_AIF1RX3_SLOT_WIDTH 6 /* AIF1RX3_SLOT - [5:0] */ | ||
1320 | |||
1321 | /* | ||
1322 | * R1298 (0x512) - Audio IF 1_19 | ||
1323 | */ | ||
1324 | #define WM2200_AIF1RX4_SLOT_MASK 0x003F /* AIF1RX4_SLOT - [5:0] */ | ||
1325 | #define WM2200_AIF1RX4_SLOT_SHIFT 0 /* AIF1RX4_SLOT - [5:0] */ | ||
1326 | #define WM2200_AIF1RX4_SLOT_WIDTH 6 /* AIF1RX4_SLOT - [5:0] */ | ||
1327 | |||
1328 | /* | ||
1329 | * R1299 (0x513) - Audio IF 1_20 | ||
1330 | */ | ||
1331 | #define WM2200_AIF1RX5_SLOT_MASK 0x003F /* AIF1RX5_SLOT - [5:0] */ | ||
1332 | #define WM2200_AIF1RX5_SLOT_SHIFT 0 /* AIF1RX5_SLOT - [5:0] */ | ||
1333 | #define WM2200_AIF1RX5_SLOT_WIDTH 6 /* AIF1RX5_SLOT - [5:0] */ | ||
1334 | |||
1335 | /* | ||
1336 | * R1300 (0x514) - Audio IF 1_21 | ||
1337 | */ | ||
1338 | #define WM2200_AIF1RX6_SLOT_MASK 0x003F /* AIF1RX6_SLOT - [5:0] */ | ||
1339 | #define WM2200_AIF1RX6_SLOT_SHIFT 0 /* AIF1RX6_SLOT - [5:0] */ | ||
1340 | #define WM2200_AIF1RX6_SLOT_WIDTH 6 /* AIF1RX6_SLOT - [5:0] */ | ||
1341 | |||
1342 | /* | ||
1343 | * R1301 (0x515) - Audio IF 1_22 | ||
1344 | */ | ||
1345 | #define WM2200_AIF1RX6_ENA 0x0800 /* AIF1RX6_ENA */ | ||
1346 | #define WM2200_AIF1RX6_ENA_MASK 0x0800 /* AIF1RX6_ENA */ | ||
1347 | #define WM2200_AIF1RX6_ENA_SHIFT 11 /* AIF1RX6_ENA */ | ||
1348 | #define WM2200_AIF1RX6_ENA_WIDTH 1 /* AIF1RX6_ENA */ | ||
1349 | #define WM2200_AIF1RX5_ENA 0x0400 /* AIF1RX5_ENA */ | ||
1350 | #define WM2200_AIF1RX5_ENA_MASK 0x0400 /* AIF1RX5_ENA */ | ||
1351 | #define WM2200_AIF1RX5_ENA_SHIFT 10 /* AIF1RX5_ENA */ | ||
1352 | #define WM2200_AIF1RX5_ENA_WIDTH 1 /* AIF1RX5_ENA */ | ||
1353 | #define WM2200_AIF1RX4_ENA 0x0200 /* AIF1RX4_ENA */ | ||
1354 | #define WM2200_AIF1RX4_ENA_MASK 0x0200 /* AIF1RX4_ENA */ | ||
1355 | #define WM2200_AIF1RX4_ENA_SHIFT 9 /* AIF1RX4_ENA */ | ||
1356 | #define WM2200_AIF1RX4_ENA_WIDTH 1 /* AIF1RX4_ENA */ | ||
1357 | #define WM2200_AIF1RX3_ENA 0x0100 /* AIF1RX3_ENA */ | ||
1358 | #define WM2200_AIF1RX3_ENA_MASK 0x0100 /* AIF1RX3_ENA */ | ||
1359 | #define WM2200_AIF1RX3_ENA_SHIFT 8 /* AIF1RX3_ENA */ | ||
1360 | #define WM2200_AIF1RX3_ENA_WIDTH 1 /* AIF1RX3_ENA */ | ||
1361 | #define WM2200_AIF1RX2_ENA 0x0080 /* AIF1RX2_ENA */ | ||
1362 | #define WM2200_AIF1RX2_ENA_MASK 0x0080 /* AIF1RX2_ENA */ | ||
1363 | #define WM2200_AIF1RX2_ENA_SHIFT 7 /* AIF1RX2_ENA */ | ||
1364 | #define WM2200_AIF1RX2_ENA_WIDTH 1 /* AIF1RX2_ENA */ | ||
1365 | #define WM2200_AIF1RX1_ENA 0x0040 /* AIF1RX1_ENA */ | ||
1366 | #define WM2200_AIF1RX1_ENA_MASK 0x0040 /* AIF1RX1_ENA */ | ||
1367 | #define WM2200_AIF1RX1_ENA_SHIFT 6 /* AIF1RX1_ENA */ | ||
1368 | #define WM2200_AIF1RX1_ENA_WIDTH 1 /* AIF1RX1_ENA */ | ||
1369 | #define WM2200_AIF1TX6_ENA 0x0020 /* AIF1TX6_ENA */ | ||
1370 | #define WM2200_AIF1TX6_ENA_MASK 0x0020 /* AIF1TX6_ENA */ | ||
1371 | #define WM2200_AIF1TX6_ENA_SHIFT 5 /* AIF1TX6_ENA */ | ||
1372 | #define WM2200_AIF1TX6_ENA_WIDTH 1 /* AIF1TX6_ENA */ | ||
1373 | #define WM2200_AIF1TX5_ENA 0x0010 /* AIF1TX5_ENA */ | ||
1374 | #define WM2200_AIF1TX5_ENA_MASK 0x0010 /* AIF1TX5_ENA */ | ||
1375 | #define WM2200_AIF1TX5_ENA_SHIFT 4 /* AIF1TX5_ENA */ | ||
1376 | #define WM2200_AIF1TX5_ENA_WIDTH 1 /* AIF1TX5_ENA */ | ||
1377 | #define WM2200_AIF1TX4_ENA 0x0008 /* AIF1TX4_ENA */ | ||
1378 | #define WM2200_AIF1TX4_ENA_MASK 0x0008 /* AIF1TX4_ENA */ | ||
1379 | #define WM2200_AIF1TX4_ENA_SHIFT 3 /* AIF1TX4_ENA */ | ||
1380 | #define WM2200_AIF1TX4_ENA_WIDTH 1 /* AIF1TX4_ENA */ | ||
1381 | #define WM2200_AIF1TX3_ENA 0x0004 /* AIF1TX3_ENA */ | ||
1382 | #define WM2200_AIF1TX3_ENA_MASK 0x0004 /* AIF1TX3_ENA */ | ||
1383 | #define WM2200_AIF1TX3_ENA_SHIFT 2 /* AIF1TX3_ENA */ | ||
1384 | #define WM2200_AIF1TX3_ENA_WIDTH 1 /* AIF1TX3_ENA */ | ||
1385 | #define WM2200_AIF1TX2_ENA 0x0002 /* AIF1TX2_ENA */ | ||
1386 | #define WM2200_AIF1TX2_ENA_MASK 0x0002 /* AIF1TX2_ENA */ | ||
1387 | #define WM2200_AIF1TX2_ENA_SHIFT 1 /* AIF1TX2_ENA */ | ||
1388 | #define WM2200_AIF1TX2_ENA_WIDTH 1 /* AIF1TX2_ENA */ | ||
1389 | #define WM2200_AIF1TX1_ENA 0x0001 /* AIF1TX1_ENA */ | ||
1390 | #define WM2200_AIF1TX1_ENA_MASK 0x0001 /* AIF1TX1_ENA */ | ||
1391 | #define WM2200_AIF1TX1_ENA_SHIFT 0 /* AIF1TX1_ENA */ | ||
1392 | #define WM2200_AIF1TX1_ENA_WIDTH 1 /* AIF1TX1_ENA */ | ||
1393 | |||
1394 | /* | ||
1395 | * R1536 (0x600) - OUT1LMIX Input 1 Source | ||
1396 | */ | ||
1397 | #define WM2200_OUT1LMIX_SRC1_MASK 0x007F /* OUT1LMIX_SRC1 - [6:0] */ | ||
1398 | #define WM2200_OUT1LMIX_SRC1_SHIFT 0 /* OUT1LMIX_SRC1 - [6:0] */ | ||
1399 | #define WM2200_OUT1LMIX_SRC1_WIDTH 7 /* OUT1LMIX_SRC1 - [6:0] */ | ||
1400 | |||
1401 | /* | ||
1402 | * R1537 (0x601) - OUT1LMIX Input 1 Volume | ||
1403 | */ | ||
1404 | #define WM2200_OUT1LMIX_VOL1_MASK 0x00FE /* OUT1LMIX_VOL1 - [7:1] */ | ||
1405 | #define WM2200_OUT1LMIX_VOL1_SHIFT 1 /* OUT1LMIX_VOL1 - [7:1] */ | ||
1406 | #define WM2200_OUT1LMIX_VOL1_WIDTH 7 /* OUT1LMIX_VOL1 - [7:1] */ | ||
1407 | |||
1408 | /* | ||
1409 | * R1538 (0x602) - OUT1LMIX Input 2 Source | ||
1410 | */ | ||
1411 | #define WM2200_OUT1LMIX_SRC2_MASK 0x007F /* OUT1LMIX_SRC2 - [6:0] */ | ||
1412 | #define WM2200_OUT1LMIX_SRC2_SHIFT 0 /* OUT1LMIX_SRC2 - [6:0] */ | ||
1413 | #define WM2200_OUT1LMIX_SRC2_WIDTH 7 /* OUT1LMIX_SRC2 - [6:0] */ | ||
1414 | |||
1415 | /* | ||
1416 | * R1539 (0x603) - OUT1LMIX Input 2 Volume | ||
1417 | */ | ||
1418 | #define WM2200_OUT1LMIX_VOL2_MASK 0x00FE /* OUT1LMIX_VOL2 - [7:1] */ | ||
1419 | #define WM2200_OUT1LMIX_VOL2_SHIFT 1 /* OUT1LMIX_VOL2 - [7:1] */ | ||
1420 | #define WM2200_OUT1LMIX_VOL2_WIDTH 7 /* OUT1LMIX_VOL2 - [7:1] */ | ||
1421 | |||
1422 | /* | ||
1423 | * R1540 (0x604) - OUT1LMIX Input 3 Source | ||
1424 | */ | ||
1425 | #define WM2200_OUT1LMIX_SRC3_MASK 0x007F /* OUT1LMIX_SRC3 - [6:0] */ | ||
1426 | #define WM2200_OUT1LMIX_SRC3_SHIFT 0 /* OUT1LMIX_SRC3 - [6:0] */ | ||
1427 | #define WM2200_OUT1LMIX_SRC3_WIDTH 7 /* OUT1LMIX_SRC3 - [6:0] */ | ||
1428 | |||
1429 | /* | ||
1430 | * R1541 (0x605) - OUT1LMIX Input 3 Volume | ||
1431 | */ | ||
1432 | #define WM2200_OUT1LMIX_VOL3_MASK 0x00FE /* OUT1LMIX_VOL3 - [7:1] */ | ||
1433 | #define WM2200_OUT1LMIX_VOL3_SHIFT 1 /* OUT1LMIX_VOL3 - [7:1] */ | ||
1434 | #define WM2200_OUT1LMIX_VOL3_WIDTH 7 /* OUT1LMIX_VOL3 - [7:1] */ | ||
1435 | |||
1436 | /* | ||
1437 | * R1542 (0x606) - OUT1LMIX Input 4 Source | ||
1438 | */ | ||
1439 | #define WM2200_OUT1LMIX_SRC4_MASK 0x007F /* OUT1LMIX_SRC4 - [6:0] */ | ||
1440 | #define WM2200_OUT1LMIX_SRC4_SHIFT 0 /* OUT1LMIX_SRC4 - [6:0] */ | ||
1441 | #define WM2200_OUT1LMIX_SRC4_WIDTH 7 /* OUT1LMIX_SRC4 - [6:0] */ | ||
1442 | |||
1443 | /* | ||
1444 | * R1543 (0x607) - OUT1LMIX Input 4 Volume | ||
1445 | */ | ||
1446 | #define WM2200_OUT1LMIX_VOL4_MASK 0x00FE /* OUT1LMIX_VOL4 - [7:1] */ | ||
1447 | #define WM2200_OUT1LMIX_VOL4_SHIFT 1 /* OUT1LMIX_VOL4 - [7:1] */ | ||
1448 | #define WM2200_OUT1LMIX_VOL4_WIDTH 7 /* OUT1LMIX_VOL4 - [7:1] */ | ||
1449 | |||
1450 | /* | ||
1451 | * R1544 (0x608) - OUT1RMIX Input 1 Source | ||
1452 | */ | ||
1453 | #define WM2200_OUT1RMIX_SRC1_MASK 0x007F /* OUT1RMIX_SRC1 - [6:0] */ | ||
1454 | #define WM2200_OUT1RMIX_SRC1_SHIFT 0 /* OUT1RMIX_SRC1 - [6:0] */ | ||
1455 | #define WM2200_OUT1RMIX_SRC1_WIDTH 7 /* OUT1RMIX_SRC1 - [6:0] */ | ||
1456 | |||
1457 | /* | ||
1458 | * R1545 (0x609) - OUT1RMIX Input 1 Volume | ||
1459 | */ | ||
1460 | #define WM2200_OUT1RMIX_VOL1_MASK 0x00FE /* OUT1RMIX_VOL1 - [7:1] */ | ||
1461 | #define WM2200_OUT1RMIX_VOL1_SHIFT 1 /* OUT1RMIX_VOL1 - [7:1] */ | ||
1462 | #define WM2200_OUT1RMIX_VOL1_WIDTH 7 /* OUT1RMIX_VOL1 - [7:1] */ | ||
1463 | |||
1464 | /* | ||
1465 | * R1546 (0x60A) - OUT1RMIX Input 2 Source | ||
1466 | */ | ||
1467 | #define WM2200_OUT1RMIX_SRC2_MASK 0x007F /* OUT1RMIX_SRC2 - [6:0] */ | ||
1468 | #define WM2200_OUT1RMIX_SRC2_SHIFT 0 /* OUT1RMIX_SRC2 - [6:0] */ | ||
1469 | #define WM2200_OUT1RMIX_SRC2_WIDTH 7 /* OUT1RMIX_SRC2 - [6:0] */ | ||
1470 | |||
1471 | /* | ||
1472 | * R1547 (0x60B) - OUT1RMIX Input 2 Volume | ||
1473 | */ | ||
1474 | #define WM2200_OUT1RMIX_VOL2_MASK 0x00FE /* OUT1RMIX_VOL2 - [7:1] */ | ||
1475 | #define WM2200_OUT1RMIX_VOL2_SHIFT 1 /* OUT1RMIX_VOL2 - [7:1] */ | ||
1476 | #define WM2200_OUT1RMIX_VOL2_WIDTH 7 /* OUT1RMIX_VOL2 - [7:1] */ | ||
1477 | |||
1478 | /* | ||
1479 | * R1548 (0x60C) - OUT1RMIX Input 3 Source | ||
1480 | */ | ||
1481 | #define WM2200_OUT1RMIX_SRC3_MASK 0x007F /* OUT1RMIX_SRC3 - [6:0] */ | ||
1482 | #define WM2200_OUT1RMIX_SRC3_SHIFT 0 /* OUT1RMIX_SRC3 - [6:0] */ | ||
1483 | #define WM2200_OUT1RMIX_SRC3_WIDTH 7 /* OUT1RMIX_SRC3 - [6:0] */ | ||
1484 | |||
1485 | /* | ||
1486 | * R1549 (0x60D) - OUT1RMIX Input 3 Volume | ||
1487 | */ | ||
1488 | #define WM2200_OUT1RMIX_VOL3_MASK 0x00FE /* OUT1RMIX_VOL3 - [7:1] */ | ||
1489 | #define WM2200_OUT1RMIX_VOL3_SHIFT 1 /* OUT1RMIX_VOL3 - [7:1] */ | ||
1490 | #define WM2200_OUT1RMIX_VOL3_WIDTH 7 /* OUT1RMIX_VOL3 - [7:1] */ | ||
1491 | |||
1492 | /* | ||
1493 | * R1550 (0x60E) - OUT1RMIX Input 4 Source | ||
1494 | */ | ||
1495 | #define WM2200_OUT1RMIX_SRC4_MASK 0x007F /* OUT1RMIX_SRC4 - [6:0] */ | ||
1496 | #define WM2200_OUT1RMIX_SRC4_SHIFT 0 /* OUT1RMIX_SRC4 - [6:0] */ | ||
1497 | #define WM2200_OUT1RMIX_SRC4_WIDTH 7 /* OUT1RMIX_SRC4 - [6:0] */ | ||
1498 | |||
1499 | /* | ||
1500 | * R1551 (0x60F) - OUT1RMIX Input 4 Volume | ||
1501 | */ | ||
1502 | #define WM2200_OUT1RMIX_VOL4_MASK 0x00FE /* OUT1RMIX_VOL4 - [7:1] */ | ||
1503 | #define WM2200_OUT1RMIX_VOL4_SHIFT 1 /* OUT1RMIX_VOL4 - [7:1] */ | ||
1504 | #define WM2200_OUT1RMIX_VOL4_WIDTH 7 /* OUT1RMIX_VOL4 - [7:1] */ | ||
1505 | |||
1506 | /* | ||
1507 | * R1552 (0x610) - OUT2LMIX Input 1 Source | ||
1508 | */ | ||
1509 | #define WM2200_OUT2LMIX_SRC1_MASK 0x007F /* OUT2LMIX_SRC1 - [6:0] */ | ||
1510 | #define WM2200_OUT2LMIX_SRC1_SHIFT 0 /* OUT2LMIX_SRC1 - [6:0] */ | ||
1511 | #define WM2200_OUT2LMIX_SRC1_WIDTH 7 /* OUT2LMIX_SRC1 - [6:0] */ | ||
1512 | |||
1513 | /* | ||
1514 | * R1553 (0x611) - OUT2LMIX Input 1 Volume | ||
1515 | */ | ||
1516 | #define WM2200_OUT2LMIX_VOL1_MASK 0x00FE /* OUT2LMIX_VOL1 - [7:1] */ | ||
1517 | #define WM2200_OUT2LMIX_VOL1_SHIFT 1 /* OUT2LMIX_VOL1 - [7:1] */ | ||
1518 | #define WM2200_OUT2LMIX_VOL1_WIDTH 7 /* OUT2LMIX_VOL1 - [7:1] */ | ||
1519 | |||
1520 | /* | ||
1521 | * R1554 (0x612) - OUT2LMIX Input 2 Source | ||
1522 | */ | ||
1523 | #define WM2200_OUT2LMIX_SRC2_MASK 0x007F /* OUT2LMIX_SRC2 - [6:0] */ | ||
1524 | #define WM2200_OUT2LMIX_SRC2_SHIFT 0 /* OUT2LMIX_SRC2 - [6:0] */ | ||
1525 | #define WM2200_OUT2LMIX_SRC2_WIDTH 7 /* OUT2LMIX_SRC2 - [6:0] */ | ||
1526 | |||
1527 | /* | ||
1528 | * R1555 (0x613) - OUT2LMIX Input 2 Volume | ||
1529 | */ | ||
1530 | #define WM2200_OUT2LMIX_VOL2_MASK 0x00FE /* OUT2LMIX_VOL2 - [7:1] */ | ||
1531 | #define WM2200_OUT2LMIX_VOL2_SHIFT 1 /* OUT2LMIX_VOL2 - [7:1] */ | ||
1532 | #define WM2200_OUT2LMIX_VOL2_WIDTH 7 /* OUT2LMIX_VOL2 - [7:1] */ | ||
1533 | |||
1534 | /* | ||
1535 | * R1556 (0x614) - OUT2LMIX Input 3 Source | ||
1536 | */ | ||
1537 | #define WM2200_OUT2LMIX_SRC3_MASK 0x007F /* OUT2LMIX_SRC3 - [6:0] */ | ||
1538 | #define WM2200_OUT2LMIX_SRC3_SHIFT 0 /* OUT2LMIX_SRC3 - [6:0] */ | ||
1539 | #define WM2200_OUT2LMIX_SRC3_WIDTH 7 /* OUT2LMIX_SRC3 - [6:0] */ | ||
1540 | |||
1541 | /* | ||
1542 | * R1557 (0x615) - OUT2LMIX Input 3 Volume | ||
1543 | */ | ||
1544 | #define WM2200_OUT2LMIX_VOL3_MASK 0x00FE /* OUT2LMIX_VOL3 - [7:1] */ | ||
1545 | #define WM2200_OUT2LMIX_VOL3_SHIFT 1 /* OUT2LMIX_VOL3 - [7:1] */ | ||
1546 | #define WM2200_OUT2LMIX_VOL3_WIDTH 7 /* OUT2LMIX_VOL3 - [7:1] */ | ||
1547 | |||
1548 | /* | ||
1549 | * R1558 (0x616) - OUT2LMIX Input 4 Source | ||
1550 | */ | ||
1551 | #define WM2200_OUT2LMIX_SRC4_MASK 0x007F /* OUT2LMIX_SRC4 - [6:0] */ | ||
1552 | #define WM2200_OUT2LMIX_SRC4_SHIFT 0 /* OUT2LMIX_SRC4 - [6:0] */ | ||
1553 | #define WM2200_OUT2LMIX_SRC4_WIDTH 7 /* OUT2LMIX_SRC4 - [6:0] */ | ||
1554 | |||
1555 | /* | ||
1556 | * R1559 (0x617) - OUT2LMIX Input 4 Volume | ||
1557 | */ | ||
1558 | #define WM2200_OUT2LMIX_VOL4_MASK 0x00FE /* OUT2LMIX_VOL4 - [7:1] */ | ||
1559 | #define WM2200_OUT2LMIX_VOL4_SHIFT 1 /* OUT2LMIX_VOL4 - [7:1] */ | ||
1560 | #define WM2200_OUT2LMIX_VOL4_WIDTH 7 /* OUT2LMIX_VOL4 - [7:1] */ | ||
1561 | |||
1562 | /* | ||
1563 | * R1560 (0x618) - OUT2RMIX Input 1 Source | ||
1564 | */ | ||
1565 | #define WM2200_OUT2RMIX_SRC1_MASK 0x007F /* OUT2RMIX_SRC1 - [6:0] */ | ||
1566 | #define WM2200_OUT2RMIX_SRC1_SHIFT 0 /* OUT2RMIX_SRC1 - [6:0] */ | ||
1567 | #define WM2200_OUT2RMIX_SRC1_WIDTH 7 /* OUT2RMIX_SRC1 - [6:0] */ | ||
1568 | |||
1569 | /* | ||
1570 | * R1561 (0x619) - OUT2RMIX Input 1 Volume | ||
1571 | */ | ||
1572 | #define WM2200_OUT2RMIX_VOL1_MASK 0x00FE /* OUT2RMIX_VOL1 - [7:1] */ | ||
1573 | #define WM2200_OUT2RMIX_VOL1_SHIFT 1 /* OUT2RMIX_VOL1 - [7:1] */ | ||
1574 | #define WM2200_OUT2RMIX_VOL1_WIDTH 7 /* OUT2RMIX_VOL1 - [7:1] */ | ||
1575 | |||
1576 | /* | ||
1577 | * R1562 (0x61A) - OUT2RMIX Input 2 Source | ||
1578 | */ | ||
1579 | #define WM2200_OUT2RMIX_SRC2_MASK 0x007F /* OUT2RMIX_SRC2 - [6:0] */ | ||
1580 | #define WM2200_OUT2RMIX_SRC2_SHIFT 0 /* OUT2RMIX_SRC2 - [6:0] */ | ||
1581 | #define WM2200_OUT2RMIX_SRC2_WIDTH 7 /* OUT2RMIX_SRC2 - [6:0] */ | ||
1582 | |||
1583 | /* | ||
1584 | * R1563 (0x61B) - OUT2RMIX Input 2 Volume | ||
1585 | */ | ||
1586 | #define WM2200_OUT2RMIX_VOL2_MASK 0x00FE /* OUT2RMIX_VOL2 - [7:1] */ | ||
1587 | #define WM2200_OUT2RMIX_VOL2_SHIFT 1 /* OUT2RMIX_VOL2 - [7:1] */ | ||
1588 | #define WM2200_OUT2RMIX_VOL2_WIDTH 7 /* OUT2RMIX_VOL2 - [7:1] */ | ||
1589 | |||
1590 | /* | ||
1591 | * R1564 (0x61C) - OUT2RMIX Input 3 Source | ||
1592 | */ | ||
1593 | #define WM2200_OUT2RMIX_SRC3_MASK 0x007F /* OUT2RMIX_SRC3 - [6:0] */ | ||
1594 | #define WM2200_OUT2RMIX_SRC3_SHIFT 0 /* OUT2RMIX_SRC3 - [6:0] */ | ||
1595 | #define WM2200_OUT2RMIX_SRC3_WIDTH 7 /* OUT2RMIX_SRC3 - [6:0] */ | ||
1596 | |||
1597 | /* | ||
1598 | * R1565 (0x61D) - OUT2RMIX Input 3 Volume | ||
1599 | */ | ||
1600 | #define WM2200_OUT2RMIX_VOL3_MASK 0x00FE /* OUT2RMIX_VOL3 - [7:1] */ | ||
1601 | #define WM2200_OUT2RMIX_VOL3_SHIFT 1 /* OUT2RMIX_VOL3 - [7:1] */ | ||
1602 | #define WM2200_OUT2RMIX_VOL3_WIDTH 7 /* OUT2RMIX_VOL3 - [7:1] */ | ||
1603 | |||
1604 | /* | ||
1605 | * R1566 (0x61E) - OUT2RMIX Input 4 Source | ||
1606 | */ | ||
1607 | #define WM2200_OUT2RMIX_SRC4_MASK 0x007F /* OUT2RMIX_SRC4 - [6:0] */ | ||
1608 | #define WM2200_OUT2RMIX_SRC4_SHIFT 0 /* OUT2RMIX_SRC4 - [6:0] */ | ||
1609 | #define WM2200_OUT2RMIX_SRC4_WIDTH 7 /* OUT2RMIX_SRC4 - [6:0] */ | ||
1610 | |||
1611 | /* | ||
1612 | * R1567 (0x61F) - OUT2RMIX Input 4 Volume | ||
1613 | */ | ||
1614 | #define WM2200_OUT2RMIX_VOL4_MASK 0x00FE /* OUT2RMIX_VOL4 - [7:1] */ | ||
1615 | #define WM2200_OUT2RMIX_VOL4_SHIFT 1 /* OUT2RMIX_VOL4 - [7:1] */ | ||
1616 | #define WM2200_OUT2RMIX_VOL4_WIDTH 7 /* OUT2RMIX_VOL4 - [7:1] */ | ||
1617 | |||
1618 | /* | ||
1619 | * R1568 (0x620) - AIF1TX1MIX Input 1 Source | ||
1620 | */ | ||
1621 | #define WM2200_AIF1TX1MIX_SRC1_MASK 0x007F /* AIF1TX1MIX_SRC1 - [6:0] */ | ||
1622 | #define WM2200_AIF1TX1MIX_SRC1_SHIFT 0 /* AIF1TX1MIX_SRC1 - [6:0] */ | ||
1623 | #define WM2200_AIF1TX1MIX_SRC1_WIDTH 7 /* AIF1TX1MIX_SRC1 - [6:0] */ | ||
1624 | |||
1625 | /* | ||
1626 | * R1569 (0x621) - AIF1TX1MIX Input 1 Volume | ||
1627 | */ | ||
1628 | #define WM2200_AIF1TX1MIX_VOL1_MASK 0x00FE /* AIF1TX1MIX_VOL1 - [7:1] */ | ||
1629 | #define WM2200_AIF1TX1MIX_VOL1_SHIFT 1 /* AIF1TX1MIX_VOL1 - [7:1] */ | ||
1630 | #define WM2200_AIF1TX1MIX_VOL1_WIDTH 7 /* AIF1TX1MIX_VOL1 - [7:1] */ | ||
1631 | |||
1632 | /* | ||
1633 | * R1570 (0x622) - AIF1TX1MIX Input 2 Source | ||
1634 | */ | ||
1635 | #define WM2200_AIF1TX1MIX_SRC2_MASK 0x007F /* AIF1TX1MIX_SRC2 - [6:0] */ | ||
1636 | #define WM2200_AIF1TX1MIX_SRC2_SHIFT 0 /* AIF1TX1MIX_SRC2 - [6:0] */ | ||
1637 | #define WM2200_AIF1TX1MIX_SRC2_WIDTH 7 /* AIF1TX1MIX_SRC2 - [6:0] */ | ||
1638 | |||
1639 | /* | ||
1640 | * R1571 (0x623) - AIF1TX1MIX Input 2 Volume | ||
1641 | */ | ||
1642 | #define WM2200_AIF1TX1MIX_VOL2_MASK 0x00FE /* AIF1TX1MIX_VOL2 - [7:1] */ | ||
1643 | #define WM2200_AIF1TX1MIX_VOL2_SHIFT 1 /* AIF1TX1MIX_VOL2 - [7:1] */ | ||
1644 | #define WM2200_AIF1TX1MIX_VOL2_WIDTH 7 /* AIF1TX1MIX_VOL2 - [7:1] */ | ||
1645 | |||
1646 | /* | ||
1647 | * R1572 (0x624) - AIF1TX1MIX Input 3 Source | ||
1648 | */ | ||
1649 | #define WM2200_AIF1TX1MIX_SRC3_MASK 0x007F /* AIF1TX1MIX_SRC3 - [6:0] */ | ||
1650 | #define WM2200_AIF1TX1MIX_SRC3_SHIFT 0 /* AIF1TX1MIX_SRC3 - [6:0] */ | ||
1651 | #define WM2200_AIF1TX1MIX_SRC3_WIDTH 7 /* AIF1TX1MIX_SRC3 - [6:0] */ | ||
1652 | |||
1653 | /* | ||
1654 | * R1573 (0x625) - AIF1TX1MIX Input 3 Volume | ||
1655 | */ | ||
1656 | #define WM2200_AIF1TX1MIX_VOL3_MASK 0x00FE /* AIF1TX1MIX_VOL3 - [7:1] */ | ||
1657 | #define WM2200_AIF1TX1MIX_VOL3_SHIFT 1 /* AIF1TX1MIX_VOL3 - [7:1] */ | ||
1658 | #define WM2200_AIF1TX1MIX_VOL3_WIDTH 7 /* AIF1TX1MIX_VOL3 - [7:1] */ | ||
1659 | |||
1660 | /* | ||
1661 | * R1574 (0x626) - AIF1TX1MIX Input 4 Source | ||
1662 | */ | ||
1663 | #define WM2200_AIF1TX1MIX_SRC4_MASK 0x007F /* AIF1TX1MIX_SRC4 - [6:0] */ | ||
1664 | #define WM2200_AIF1TX1MIX_SRC4_SHIFT 0 /* AIF1TX1MIX_SRC4 - [6:0] */ | ||
1665 | #define WM2200_AIF1TX1MIX_SRC4_WIDTH 7 /* AIF1TX1MIX_SRC4 - [6:0] */ | ||
1666 | |||
1667 | /* | ||
1668 | * R1575 (0x627) - AIF1TX1MIX Input 4 Volume | ||
1669 | */ | ||
1670 | #define WM2200_AIF1TX1MIX_VOL4_MASK 0x00FE /* AIF1TX1MIX_VOL4 - [7:1] */ | ||
1671 | #define WM2200_AIF1TX1MIX_VOL4_SHIFT 1 /* AIF1TX1MIX_VOL4 - [7:1] */ | ||
1672 | #define WM2200_AIF1TX1MIX_VOL4_WIDTH 7 /* AIF1TX1MIX_VOL4 - [7:1] */ | ||
1673 | |||
1674 | /* | ||
1675 | * R1576 (0x628) - AIF1TX2MIX Input 1 Source | ||
1676 | */ | ||
1677 | #define WM2200_AIF1TX2MIX_SRC1_MASK 0x007F /* AIF1TX2MIX_SRC1 - [6:0] */ | ||
1678 | #define WM2200_AIF1TX2MIX_SRC1_SHIFT 0 /* AIF1TX2MIX_SRC1 - [6:0] */ | ||
1679 | #define WM2200_AIF1TX2MIX_SRC1_WIDTH 7 /* AIF1TX2MIX_SRC1 - [6:0] */ | ||
1680 | |||
1681 | /* | ||
1682 | * R1577 (0x629) - AIF1TX2MIX Input 1 Volume | ||
1683 | */ | ||
1684 | #define WM2200_AIF1TX2MIX_VOL1_MASK 0x00FE /* AIF1TX2MIX_VOL1 - [7:1] */ | ||
1685 | #define WM2200_AIF1TX2MIX_VOL1_SHIFT 1 /* AIF1TX2MIX_VOL1 - [7:1] */ | ||
1686 | #define WM2200_AIF1TX2MIX_VOL1_WIDTH 7 /* AIF1TX2MIX_VOL1 - [7:1] */ | ||
1687 | |||
1688 | /* | ||
1689 | * R1578 (0x62A) - AIF1TX2MIX Input 2 Source | ||
1690 | */ | ||
1691 | #define WM2200_AIF1TX2MIX_SRC2_MASK 0x007F /* AIF1TX2MIX_SRC2 - [6:0] */ | ||
1692 | #define WM2200_AIF1TX2MIX_SRC2_SHIFT 0 /* AIF1TX2MIX_SRC2 - [6:0] */ | ||
1693 | #define WM2200_AIF1TX2MIX_SRC2_WIDTH 7 /* AIF1TX2MIX_SRC2 - [6:0] */ | ||
1694 | |||
1695 | /* | ||
1696 | * R1579 (0x62B) - AIF1TX2MIX Input 2 Volume | ||
1697 | */ | ||
1698 | #define WM2200_AIF1TX2MIX_VOL2_MASK 0x00FE /* AIF1TX2MIX_VOL2 - [7:1] */ | ||
1699 | #define WM2200_AIF1TX2MIX_VOL2_SHIFT 1 /* AIF1TX2MIX_VOL2 - [7:1] */ | ||
1700 | #define WM2200_AIF1TX2MIX_VOL2_WIDTH 7 /* AIF1TX2MIX_VOL2 - [7:1] */ | ||
1701 | |||
1702 | /* | ||
1703 | * R1580 (0x62C) - AIF1TX2MIX Input 3 Source | ||
1704 | */ | ||
1705 | #define WM2200_AIF1TX2MIX_SRC3_MASK 0x007F /* AIF1TX2MIX_SRC3 - [6:0] */ | ||
1706 | #define WM2200_AIF1TX2MIX_SRC3_SHIFT 0 /* AIF1TX2MIX_SRC3 - [6:0] */ | ||
1707 | #define WM2200_AIF1TX2MIX_SRC3_WIDTH 7 /* AIF1TX2MIX_SRC3 - [6:0] */ | ||
1708 | |||
1709 | /* | ||
1710 | * R1581 (0x62D) - AIF1TX2MIX Input 3 Volume | ||
1711 | */ | ||
1712 | #define WM2200_AIF1TX2MIX_VOL3_MASK 0x00FE /* AIF1TX2MIX_VOL3 - [7:1] */ | ||
1713 | #define WM2200_AIF1TX2MIX_VOL3_SHIFT 1 /* AIF1TX2MIX_VOL3 - [7:1] */ | ||
1714 | #define WM2200_AIF1TX2MIX_VOL3_WIDTH 7 /* AIF1TX2MIX_VOL3 - [7:1] */ | ||
1715 | |||
1716 | /* | ||
1717 | * R1582 (0x62E) - AIF1TX2MIX Input 4 Source | ||
1718 | */ | ||
1719 | #define WM2200_AIF1TX2MIX_SRC4_MASK 0x007F /* AIF1TX2MIX_SRC4 - [6:0] */ | ||
1720 | #define WM2200_AIF1TX2MIX_SRC4_SHIFT 0 /* AIF1TX2MIX_SRC4 - [6:0] */ | ||
1721 | #define WM2200_AIF1TX2MIX_SRC4_WIDTH 7 /* AIF1TX2MIX_SRC4 - [6:0] */ | ||
1722 | |||
1723 | /* | ||
1724 | * R1583 (0x62F) - AIF1TX2MIX Input 4 Volume | ||
1725 | */ | ||
1726 | #define WM2200_AIF1TX2MIX_VOL4_MASK 0x00FE /* AIF1TX2MIX_VOL4 - [7:1] */ | ||
1727 | #define WM2200_AIF1TX2MIX_VOL4_SHIFT 1 /* AIF1TX2MIX_VOL4 - [7:1] */ | ||
1728 | #define WM2200_AIF1TX2MIX_VOL4_WIDTH 7 /* AIF1TX2MIX_VOL4 - [7:1] */ | ||
1729 | |||
1730 | /* | ||
1731 | * R1584 (0x630) - AIF1TX3MIX Input 1 Source | ||
1732 | */ | ||
1733 | #define WM2200_AIF1TX3MIX_SRC1_MASK 0x007F /* AIF1TX3MIX_SRC1 - [6:0] */ | ||
1734 | #define WM2200_AIF1TX3MIX_SRC1_SHIFT 0 /* AIF1TX3MIX_SRC1 - [6:0] */ | ||
1735 | #define WM2200_AIF1TX3MIX_SRC1_WIDTH 7 /* AIF1TX3MIX_SRC1 - [6:0] */ | ||
1736 | |||
1737 | /* | ||
1738 | * R1585 (0x631) - AIF1TX3MIX Input 1 Volume | ||
1739 | */ | ||
1740 | #define WM2200_AIF1TX3MIX_VOL1_MASK 0x00FE /* AIF1TX3MIX_VOL1 - [7:1] */ | ||
1741 | #define WM2200_AIF1TX3MIX_VOL1_SHIFT 1 /* AIF1TX3MIX_VOL1 - [7:1] */ | ||
1742 | #define WM2200_AIF1TX3MIX_VOL1_WIDTH 7 /* AIF1TX3MIX_VOL1 - [7:1] */ | ||
1743 | |||
1744 | /* | ||
1745 | * R1586 (0x632) - AIF1TX3MIX Input 2 Source | ||
1746 | */ | ||
1747 | #define WM2200_AIF1TX3MIX_SRC2_MASK 0x007F /* AIF1TX3MIX_SRC2 - [6:0] */ | ||
1748 | #define WM2200_AIF1TX3MIX_SRC2_SHIFT 0 /* AIF1TX3MIX_SRC2 - [6:0] */ | ||
1749 | #define WM2200_AIF1TX3MIX_SRC2_WIDTH 7 /* AIF1TX3MIX_SRC2 - [6:0] */ | ||
1750 | |||
1751 | /* | ||
1752 | * R1587 (0x633) - AIF1TX3MIX Input 2 Volume | ||
1753 | */ | ||
1754 | #define WM2200_AIF1TX3MIX_VOL2_MASK 0x00FE /* AIF1TX3MIX_VOL2 - [7:1] */ | ||
1755 | #define WM2200_AIF1TX3MIX_VOL2_SHIFT 1 /* AIF1TX3MIX_VOL2 - [7:1] */ | ||
1756 | #define WM2200_AIF1TX3MIX_VOL2_WIDTH 7 /* AIF1TX3MIX_VOL2 - [7:1] */ | ||
1757 | |||
1758 | /* | ||
1759 | * R1588 (0x634) - AIF1TX3MIX Input 3 Source | ||
1760 | */ | ||
1761 | #define WM2200_AIF1TX3MIX_SRC3_MASK 0x007F /* AIF1TX3MIX_SRC3 - [6:0] */ | ||
1762 | #define WM2200_AIF1TX3MIX_SRC3_SHIFT 0 /* AIF1TX3MIX_SRC3 - [6:0] */ | ||
1763 | #define WM2200_AIF1TX3MIX_SRC3_WIDTH 7 /* AIF1TX3MIX_SRC3 - [6:0] */ | ||
1764 | |||
1765 | /* | ||
1766 | * R1589 (0x635) - AIF1TX3MIX Input 3 Volume | ||
1767 | */ | ||
1768 | #define WM2200_AIF1TX3MIX_VOL3_MASK 0x00FE /* AIF1TX3MIX_VOL3 - [7:1] */ | ||
1769 | #define WM2200_AIF1TX3MIX_VOL3_SHIFT 1 /* AIF1TX3MIX_VOL3 - [7:1] */ | ||
1770 | #define WM2200_AIF1TX3MIX_VOL3_WIDTH 7 /* AIF1TX3MIX_VOL3 - [7:1] */ | ||
1771 | |||
1772 | /* | ||
1773 | * R1590 (0x636) - AIF1TX3MIX Input 4 Source | ||
1774 | */ | ||
1775 | #define WM2200_AIF1TX3MIX_SRC4_MASK 0x007F /* AIF1TX3MIX_SRC4 - [6:0] */ | ||
1776 | #define WM2200_AIF1TX3MIX_SRC4_SHIFT 0 /* AIF1TX3MIX_SRC4 - [6:0] */ | ||
1777 | #define WM2200_AIF1TX3MIX_SRC4_WIDTH 7 /* AIF1TX3MIX_SRC4 - [6:0] */ | ||
1778 | |||
1779 | /* | ||
1780 | * R1591 (0x637) - AIF1TX3MIX Input 4 Volume | ||
1781 | */ | ||
1782 | #define WM2200_AIF1TX3MIX_VOL4_MASK 0x00FE /* AIF1TX3MIX_VOL4 - [7:1] */ | ||
1783 | #define WM2200_AIF1TX3MIX_VOL4_SHIFT 1 /* AIF1TX3MIX_VOL4 - [7:1] */ | ||
1784 | #define WM2200_AIF1TX3MIX_VOL4_WIDTH 7 /* AIF1TX3MIX_VOL4 - [7:1] */ | ||
1785 | |||
1786 | /* | ||
1787 | * R1592 (0x638) - AIF1TX4MIX Input 1 Source | ||
1788 | */ | ||
1789 | #define WM2200_AIF1TX4MIX_SRC1_MASK 0x007F /* AIF1TX4MIX_SRC1 - [6:0] */ | ||
1790 | #define WM2200_AIF1TX4MIX_SRC1_SHIFT 0 /* AIF1TX4MIX_SRC1 - [6:0] */ | ||
1791 | #define WM2200_AIF1TX4MIX_SRC1_WIDTH 7 /* AIF1TX4MIX_SRC1 - [6:0] */ | ||
1792 | |||
1793 | /* | ||
1794 | * R1593 (0x639) - AIF1TX4MIX Input 1 Volume | ||
1795 | */ | ||
1796 | #define WM2200_AIF1TX4MIX_VOL1_MASK 0x00FE /* AIF1TX4MIX_VOL1 - [7:1] */ | ||
1797 | #define WM2200_AIF1TX4MIX_VOL1_SHIFT 1 /* AIF1TX4MIX_VOL1 - [7:1] */ | ||
1798 | #define WM2200_AIF1TX4MIX_VOL1_WIDTH 7 /* AIF1TX4MIX_VOL1 - [7:1] */ | ||
1799 | |||
1800 | /* | ||
1801 | * R1594 (0x63A) - AIF1TX4MIX Input 2 Source | ||
1802 | */ | ||
1803 | #define WM2200_AIF1TX4MIX_SRC2_MASK 0x007F /* AIF1TX4MIX_SRC2 - [6:0] */ | ||
1804 | #define WM2200_AIF1TX4MIX_SRC2_SHIFT 0 /* AIF1TX4MIX_SRC2 - [6:0] */ | ||
1805 | #define WM2200_AIF1TX4MIX_SRC2_WIDTH 7 /* AIF1TX4MIX_SRC2 - [6:0] */ | ||
1806 | |||
1807 | /* | ||
1808 | * R1595 (0x63B) - AIF1TX4MIX Input 2 Volume | ||
1809 | */ | ||
1810 | #define WM2200_AIF1TX4MIX_VOL2_MASK 0x00FE /* AIF1TX4MIX_VOL2 - [7:1] */ | ||
1811 | #define WM2200_AIF1TX4MIX_VOL2_SHIFT 1 /* AIF1TX4MIX_VOL2 - [7:1] */ | ||
1812 | #define WM2200_AIF1TX4MIX_VOL2_WIDTH 7 /* AIF1TX4MIX_VOL2 - [7:1] */ | ||
1813 | |||
1814 | /* | ||
1815 | * R1596 (0x63C) - AIF1TX4MIX Input 3 Source | ||
1816 | */ | ||
1817 | #define WM2200_AIF1TX4MIX_SRC3_MASK 0x007F /* AIF1TX4MIX_SRC3 - [6:0] */ | ||
1818 | #define WM2200_AIF1TX4MIX_SRC3_SHIFT 0 /* AIF1TX4MIX_SRC3 - [6:0] */ | ||
1819 | #define WM2200_AIF1TX4MIX_SRC3_WIDTH 7 /* AIF1TX4MIX_SRC3 - [6:0] */ | ||
1820 | |||
1821 | /* | ||
1822 | * R1597 (0x63D) - AIF1TX4MIX Input 3 Volume | ||
1823 | */ | ||
1824 | #define WM2200_AIF1TX4MIX_VOL3_MASK 0x00FE /* AIF1TX4MIX_VOL3 - [7:1] */ | ||
1825 | #define WM2200_AIF1TX4MIX_VOL3_SHIFT 1 /* AIF1TX4MIX_VOL3 - [7:1] */ | ||
1826 | #define WM2200_AIF1TX4MIX_VOL3_WIDTH 7 /* AIF1TX4MIX_VOL3 - [7:1] */ | ||
1827 | |||
1828 | /* | ||
1829 | * R1598 (0x63E) - AIF1TX4MIX Input 4 Source | ||
1830 | */ | ||
1831 | #define WM2200_AIF1TX4MIX_SRC4_MASK 0x007F /* AIF1TX4MIX_SRC4 - [6:0] */ | ||
1832 | #define WM2200_AIF1TX4MIX_SRC4_SHIFT 0 /* AIF1TX4MIX_SRC4 - [6:0] */ | ||
1833 | #define WM2200_AIF1TX4MIX_SRC4_WIDTH 7 /* AIF1TX4MIX_SRC4 - [6:0] */ | ||
1834 | |||
1835 | /* | ||
1836 | * R1599 (0x63F) - AIF1TX4MIX Input 4 Volume | ||
1837 | */ | ||
1838 | #define WM2200_AIF1TX4MIX_VOL4_MASK 0x00FE /* AIF1TX4MIX_VOL4 - [7:1] */ | ||
1839 | #define WM2200_AIF1TX4MIX_VOL4_SHIFT 1 /* AIF1TX4MIX_VOL4 - [7:1] */ | ||
1840 | #define WM2200_AIF1TX4MIX_VOL4_WIDTH 7 /* AIF1TX4MIX_VOL4 - [7:1] */ | ||
1841 | |||
1842 | /* | ||
1843 | * R1600 (0x640) - AIF1TX5MIX Input 1 Source | ||
1844 | */ | ||
1845 | #define WM2200_AIF1TX5MIX_SRC1_MASK 0x007F /* AIF1TX5MIX_SRC1 - [6:0] */ | ||
1846 | #define WM2200_AIF1TX5MIX_SRC1_SHIFT 0 /* AIF1TX5MIX_SRC1 - [6:0] */ | ||
1847 | #define WM2200_AIF1TX5MIX_SRC1_WIDTH 7 /* AIF1TX5MIX_SRC1 - [6:0] */ | ||
1848 | |||
1849 | /* | ||
1850 | * R1601 (0x641) - AIF1TX5MIX Input 1 Volume | ||
1851 | */ | ||
1852 | #define WM2200_AIF1TX5MIX_VOL1_MASK 0x00FE /* AIF1TX5MIX_VOL1 - [7:1] */ | ||
1853 | #define WM2200_AIF1TX5MIX_VOL1_SHIFT 1 /* AIF1TX5MIX_VOL1 - [7:1] */ | ||
1854 | #define WM2200_AIF1TX5MIX_VOL1_WIDTH 7 /* AIF1TX5MIX_VOL1 - [7:1] */ | ||
1855 | |||
1856 | /* | ||
1857 | * R1602 (0x642) - AIF1TX5MIX Input 2 Source | ||
1858 | */ | ||
1859 | #define WM2200_AIF1TX5MIX_SRC2_MASK 0x007F /* AIF1TX5MIX_SRC2 - [6:0] */ | ||
1860 | #define WM2200_AIF1TX5MIX_SRC2_SHIFT 0 /* AIF1TX5MIX_SRC2 - [6:0] */ | ||
1861 | #define WM2200_AIF1TX5MIX_SRC2_WIDTH 7 /* AIF1TX5MIX_SRC2 - [6:0] */ | ||
1862 | |||
1863 | /* | ||
1864 | * R1603 (0x643) - AIF1TX5MIX Input 2 Volume | ||
1865 | */ | ||
1866 | #define WM2200_AIF1TX5MIX_VOL2_MASK 0x00FE /* AIF1TX5MIX_VOL2 - [7:1] */ | ||
1867 | #define WM2200_AIF1TX5MIX_VOL2_SHIFT 1 /* AIF1TX5MIX_VOL2 - [7:1] */ | ||
1868 | #define WM2200_AIF1TX5MIX_VOL2_WIDTH 7 /* AIF1TX5MIX_VOL2 - [7:1] */ | ||
1869 | |||
1870 | /* | ||
1871 | * R1604 (0x644) - AIF1TX5MIX Input 3 Source | ||
1872 | */ | ||
1873 | #define WM2200_AIF1TX5MIX_SRC3_MASK 0x007F /* AIF1TX5MIX_SRC3 - [6:0] */ | ||
1874 | #define WM2200_AIF1TX5MIX_SRC3_SHIFT 0 /* AIF1TX5MIX_SRC3 - [6:0] */ | ||
1875 | #define WM2200_AIF1TX5MIX_SRC3_WIDTH 7 /* AIF1TX5MIX_SRC3 - [6:0] */ | ||
1876 | |||
1877 | /* | ||
1878 | * R1605 (0x645) - AIF1TX5MIX Input 3 Volume | ||
1879 | */ | ||
1880 | #define WM2200_AIF1TX5MIX_VOL3_MASK 0x00FE /* AIF1TX5MIX_VOL3 - [7:1] */ | ||
1881 | #define WM2200_AIF1TX5MIX_VOL3_SHIFT 1 /* AIF1TX5MIX_VOL3 - [7:1] */ | ||
1882 | #define WM2200_AIF1TX5MIX_VOL3_WIDTH 7 /* AIF1TX5MIX_VOL3 - [7:1] */ | ||
1883 | |||
1884 | /* | ||
1885 | * R1606 (0x646) - AIF1TX5MIX Input 4 Source | ||
1886 | */ | ||
1887 | #define WM2200_AIF1TX5MIX_SRC4_MASK 0x007F /* AIF1TX5MIX_SRC4 - [6:0] */ | ||
1888 | #define WM2200_AIF1TX5MIX_SRC4_SHIFT 0 /* AIF1TX5MIX_SRC4 - [6:0] */ | ||
1889 | #define WM2200_AIF1TX5MIX_SRC4_WIDTH 7 /* AIF1TX5MIX_SRC4 - [6:0] */ | ||
1890 | |||
1891 | /* | ||
1892 | * R1607 (0x647) - AIF1TX5MIX Input 4 Volume | ||
1893 | */ | ||
1894 | #define WM2200_AIF1TX5MIX_VOL4_MASK 0x00FE /* AIF1TX5MIX_VOL4 - [7:1] */ | ||
1895 | #define WM2200_AIF1TX5MIX_VOL4_SHIFT 1 /* AIF1TX5MIX_VOL4 - [7:1] */ | ||
1896 | #define WM2200_AIF1TX5MIX_VOL4_WIDTH 7 /* AIF1TX5MIX_VOL4 - [7:1] */ | ||
1897 | |||
1898 | /* | ||
1899 | * R1608 (0x648) - AIF1TX6MIX Input 1 Source | ||
1900 | */ | ||
1901 | #define WM2200_AIF1TX6MIX_SRC1_MASK 0x007F /* AIF1TX6MIX_SRC1 - [6:0] */ | ||
1902 | #define WM2200_AIF1TX6MIX_SRC1_SHIFT 0 /* AIF1TX6MIX_SRC1 - [6:0] */ | ||
1903 | #define WM2200_AIF1TX6MIX_SRC1_WIDTH 7 /* AIF1TX6MIX_SRC1 - [6:0] */ | ||
1904 | |||
1905 | /* | ||
1906 | * R1609 (0x649) - AIF1TX6MIX Input 1 Volume | ||
1907 | */ | ||
1908 | #define WM2200_AIF1TX6MIX_VOL1_MASK 0x00FE /* AIF1TX6MIX_VOL1 - [7:1] */ | ||
1909 | #define WM2200_AIF1TX6MIX_VOL1_SHIFT 1 /* AIF1TX6MIX_VOL1 - [7:1] */ | ||
1910 | #define WM2200_AIF1TX6MIX_VOL1_WIDTH 7 /* AIF1TX6MIX_VOL1 - [7:1] */ | ||
1911 | |||
1912 | /* | ||
1913 | * R1610 (0x64A) - AIF1TX6MIX Input 2 Source | ||
1914 | */ | ||
1915 | #define WM2200_AIF1TX6MIX_SRC2_MASK 0x007F /* AIF1TX6MIX_SRC2 - [6:0] */ | ||
1916 | #define WM2200_AIF1TX6MIX_SRC2_SHIFT 0 /* AIF1TX6MIX_SRC2 - [6:0] */ | ||
1917 | #define WM2200_AIF1TX6MIX_SRC2_WIDTH 7 /* AIF1TX6MIX_SRC2 - [6:0] */ | ||
1918 | |||
1919 | /* | ||
1920 | * R1611 (0x64B) - AIF1TX6MIX Input 2 Volume | ||
1921 | */ | ||
1922 | #define WM2200_AIF1TX6MIX_VOL2_MASK 0x00FE /* AIF1TX6MIX_VOL2 - [7:1] */ | ||
1923 | #define WM2200_AIF1TX6MIX_VOL2_SHIFT 1 /* AIF1TX6MIX_VOL2 - [7:1] */ | ||
1924 | #define WM2200_AIF1TX6MIX_VOL2_WIDTH 7 /* AIF1TX6MIX_VOL2 - [7:1] */ | ||
1925 | |||
1926 | /* | ||
1927 | * R1612 (0x64C) - AIF1TX6MIX Input 3 Source | ||
1928 | */ | ||
1929 | #define WM2200_AIF1TX6MIX_SRC3_MASK 0x007F /* AIF1TX6MIX_SRC3 - [6:0] */ | ||
1930 | #define WM2200_AIF1TX6MIX_SRC3_SHIFT 0 /* AIF1TX6MIX_SRC3 - [6:0] */ | ||
1931 | #define WM2200_AIF1TX6MIX_SRC3_WIDTH 7 /* AIF1TX6MIX_SRC3 - [6:0] */ | ||
1932 | |||
1933 | /* | ||
1934 | * R1613 (0x64D) - AIF1TX6MIX Input 3 Volume | ||
1935 | */ | ||
1936 | #define WM2200_AIF1TX6MIX_VOL3_MASK 0x00FE /* AIF1TX6MIX_VOL3 - [7:1] */ | ||
1937 | #define WM2200_AIF1TX6MIX_VOL3_SHIFT 1 /* AIF1TX6MIX_VOL3 - [7:1] */ | ||
1938 | #define WM2200_AIF1TX6MIX_VOL3_WIDTH 7 /* AIF1TX6MIX_VOL3 - [7:1] */ | ||
1939 | |||
1940 | /* | ||
1941 | * R1614 (0x64E) - AIF1TX6MIX Input 4 Source | ||
1942 | */ | ||
1943 | #define WM2200_AIF1TX6MIX_SRC4_MASK 0x007F /* AIF1TX6MIX_SRC4 - [6:0] */ | ||
1944 | #define WM2200_AIF1TX6MIX_SRC4_SHIFT 0 /* AIF1TX6MIX_SRC4 - [6:0] */ | ||
1945 | #define WM2200_AIF1TX6MIX_SRC4_WIDTH 7 /* AIF1TX6MIX_SRC4 - [6:0] */ | ||
1946 | |||
1947 | /* | ||
1948 | * R1615 (0x64F) - AIF1TX6MIX Input 4 Volume | ||
1949 | */ | ||
1950 | #define WM2200_AIF1TX6MIX_VOL4_MASK 0x00FE /* AIF1TX6MIX_VOL4 - [7:1] */ | ||
1951 | #define WM2200_AIF1TX6MIX_VOL4_SHIFT 1 /* AIF1TX6MIX_VOL4 - [7:1] */ | ||
1952 | #define WM2200_AIF1TX6MIX_VOL4_WIDTH 7 /* AIF1TX6MIX_VOL4 - [7:1] */ | ||
1953 | |||
1954 | /* | ||
1955 | * R1616 (0x650) - EQLMIX Input 1 Source | ||
1956 | */ | ||
1957 | #define WM2200_EQLMIX_SRC1_MASK 0x007F /* EQLMIX_SRC1 - [6:0] */ | ||
1958 | #define WM2200_EQLMIX_SRC1_SHIFT 0 /* EQLMIX_SRC1 - [6:0] */ | ||
1959 | #define WM2200_EQLMIX_SRC1_WIDTH 7 /* EQLMIX_SRC1 - [6:0] */ | ||
1960 | |||
1961 | /* | ||
1962 | * R1617 (0x651) - EQLMIX Input 1 Volume | ||
1963 | */ | ||
1964 | #define WM2200_EQLMIX_VOL1_MASK 0x00FE /* EQLMIX_VOL1 - [7:1] */ | ||
1965 | #define WM2200_EQLMIX_VOL1_SHIFT 1 /* EQLMIX_VOL1 - [7:1] */ | ||
1966 | #define WM2200_EQLMIX_VOL1_WIDTH 7 /* EQLMIX_VOL1 - [7:1] */ | ||
1967 | |||
1968 | /* | ||
1969 | * R1618 (0x652) - EQLMIX Input 2 Source | ||
1970 | */ | ||
1971 | #define WM2200_EQLMIX_SRC2_MASK 0x007F /* EQLMIX_SRC2 - [6:0] */ | ||
1972 | #define WM2200_EQLMIX_SRC2_SHIFT 0 /* EQLMIX_SRC2 - [6:0] */ | ||
1973 | #define WM2200_EQLMIX_SRC2_WIDTH 7 /* EQLMIX_SRC2 - [6:0] */ | ||
1974 | |||
1975 | /* | ||
1976 | * R1619 (0x653) - EQLMIX Input 2 Volume | ||
1977 | */ | ||
1978 | #define WM2200_EQLMIX_VOL2_MASK 0x00FE /* EQLMIX_VOL2 - [7:1] */ | ||
1979 | #define WM2200_EQLMIX_VOL2_SHIFT 1 /* EQLMIX_VOL2 - [7:1] */ | ||
1980 | #define WM2200_EQLMIX_VOL2_WIDTH 7 /* EQLMIX_VOL2 - [7:1] */ | ||
1981 | |||
1982 | /* | ||
1983 | * R1620 (0x654) - EQLMIX Input 3 Source | ||
1984 | */ | ||
1985 | #define WM2200_EQLMIX_SRC3_MASK 0x007F /* EQLMIX_SRC3 - [6:0] */ | ||
1986 | #define WM2200_EQLMIX_SRC3_SHIFT 0 /* EQLMIX_SRC3 - [6:0] */ | ||
1987 | #define WM2200_EQLMIX_SRC3_WIDTH 7 /* EQLMIX_SRC3 - [6:0] */ | ||
1988 | |||
1989 | /* | ||
1990 | * R1621 (0x655) - EQLMIX Input 3 Volume | ||
1991 | */ | ||
1992 | #define WM2200_EQLMIX_VOL3_MASK 0x00FE /* EQLMIX_VOL3 - [7:1] */ | ||
1993 | #define WM2200_EQLMIX_VOL3_SHIFT 1 /* EQLMIX_VOL3 - [7:1] */ | ||
1994 | #define WM2200_EQLMIX_VOL3_WIDTH 7 /* EQLMIX_VOL3 - [7:1] */ | ||
1995 | |||
1996 | /* | ||
1997 | * R1622 (0x656) - EQLMIX Input 4 Source | ||
1998 | */ | ||
1999 | #define WM2200_EQLMIX_SRC4_MASK 0x007F /* EQLMIX_SRC4 - [6:0] */ | ||
2000 | #define WM2200_EQLMIX_SRC4_SHIFT 0 /* EQLMIX_SRC4 - [6:0] */ | ||
2001 | #define WM2200_EQLMIX_SRC4_WIDTH 7 /* EQLMIX_SRC4 - [6:0] */ | ||
2002 | |||
2003 | /* | ||
2004 | * R1623 (0x657) - EQLMIX Input 4 Volume | ||
2005 | */ | ||
2006 | #define WM2200_EQLMIX_VOL4_MASK 0x00FE /* EQLMIX_VOL4 - [7:1] */ | ||
2007 | #define WM2200_EQLMIX_VOL4_SHIFT 1 /* EQLMIX_VOL4 - [7:1] */ | ||
2008 | #define WM2200_EQLMIX_VOL4_WIDTH 7 /* EQLMIX_VOL4 - [7:1] */ | ||
2009 | |||
2010 | /* | ||
2011 | * R1624 (0x658) - EQRMIX Input 1 Source | ||
2012 | */ | ||
2013 | #define WM2200_EQRMIX_SRC1_MASK 0x007F /* EQRMIX_SRC1 - [6:0] */ | ||
2014 | #define WM2200_EQRMIX_SRC1_SHIFT 0 /* EQRMIX_SRC1 - [6:0] */ | ||
2015 | #define WM2200_EQRMIX_SRC1_WIDTH 7 /* EQRMIX_SRC1 - [6:0] */ | ||
2016 | |||
2017 | /* | ||
2018 | * R1625 (0x659) - EQRMIX Input 1 Volume | ||
2019 | */ | ||
2020 | #define WM2200_EQRMIX_VOL1_MASK 0x00FE /* EQRMIX_VOL1 - [7:1] */ | ||
2021 | #define WM2200_EQRMIX_VOL1_SHIFT 1 /* EQRMIX_VOL1 - [7:1] */ | ||
2022 | #define WM2200_EQRMIX_VOL1_WIDTH 7 /* EQRMIX_VOL1 - [7:1] */ | ||
2023 | |||
2024 | /* | ||
2025 | * R1626 (0x65A) - EQRMIX Input 2 Source | ||
2026 | */ | ||
2027 | #define WM2200_EQRMIX_SRC2_MASK 0x007F /* EQRMIX_SRC2 - [6:0] */ | ||
2028 | #define WM2200_EQRMIX_SRC2_SHIFT 0 /* EQRMIX_SRC2 - [6:0] */ | ||
2029 | #define WM2200_EQRMIX_SRC2_WIDTH 7 /* EQRMIX_SRC2 - [6:0] */ | ||
2030 | |||
2031 | /* | ||
2032 | * R1627 (0x65B) - EQRMIX Input 2 Volume | ||
2033 | */ | ||
2034 | #define WM2200_EQRMIX_VOL2_MASK 0x00FE /* EQRMIX_VOL2 - [7:1] */ | ||
2035 | #define WM2200_EQRMIX_VOL2_SHIFT 1 /* EQRMIX_VOL2 - [7:1] */ | ||
2036 | #define WM2200_EQRMIX_VOL2_WIDTH 7 /* EQRMIX_VOL2 - [7:1] */ | ||
2037 | |||
2038 | /* | ||
2039 | * R1628 (0x65C) - EQRMIX Input 3 Source | ||
2040 | */ | ||
2041 | #define WM2200_EQRMIX_SRC3_MASK 0x007F /* EQRMIX_SRC3 - [6:0] */ | ||
2042 | #define WM2200_EQRMIX_SRC3_SHIFT 0 /* EQRMIX_SRC3 - [6:0] */ | ||
2043 | #define WM2200_EQRMIX_SRC3_WIDTH 7 /* EQRMIX_SRC3 - [6:0] */ | ||
2044 | |||
2045 | /* | ||
2046 | * R1629 (0x65D) - EQRMIX Input 3 Volume | ||
2047 | */ | ||
2048 | #define WM2200_EQRMIX_VOL3_MASK 0x00FE /* EQRMIX_VOL3 - [7:1] */ | ||
2049 | #define WM2200_EQRMIX_VOL3_SHIFT 1 /* EQRMIX_VOL3 - [7:1] */ | ||
2050 | #define WM2200_EQRMIX_VOL3_WIDTH 7 /* EQRMIX_VOL3 - [7:1] */ | ||
2051 | |||
2052 | /* | ||
2053 | * R1630 (0x65E) - EQRMIX Input 4 Source | ||
2054 | */ | ||
2055 | #define WM2200_EQRMIX_SRC4_MASK 0x007F /* EQRMIX_SRC4 - [6:0] */ | ||
2056 | #define WM2200_EQRMIX_SRC4_SHIFT 0 /* EQRMIX_SRC4 - [6:0] */ | ||
2057 | #define WM2200_EQRMIX_SRC4_WIDTH 7 /* EQRMIX_SRC4 - [6:0] */ | ||
2058 | |||
2059 | /* | ||
2060 | * R1631 (0x65F) - EQRMIX Input 4 Volume | ||
2061 | */ | ||
2062 | #define WM2200_EQRMIX_VOL4_MASK 0x00FE /* EQRMIX_VOL4 - [7:1] */ | ||
2063 | #define WM2200_EQRMIX_VOL4_SHIFT 1 /* EQRMIX_VOL4 - [7:1] */ | ||
2064 | #define WM2200_EQRMIX_VOL4_WIDTH 7 /* EQRMIX_VOL4 - [7:1] */ | ||
2065 | |||
2066 | /* | ||
2067 | * R1632 (0x660) - LHPF1MIX Input 1 Source | ||
2068 | */ | ||
2069 | #define WM2200_LHPF1MIX_SRC1_MASK 0x007F /* LHPF1MIX_SRC1 - [6:0] */ | ||
2070 | #define WM2200_LHPF1MIX_SRC1_SHIFT 0 /* LHPF1MIX_SRC1 - [6:0] */ | ||
2071 | #define WM2200_LHPF1MIX_SRC1_WIDTH 7 /* LHPF1MIX_SRC1 - [6:0] */ | ||
2072 | |||
2073 | /* | ||
2074 | * R1633 (0x661) - LHPF1MIX Input 1 Volume | ||
2075 | */ | ||
2076 | #define WM2200_LHPF1MIX_VOL1_MASK 0x00FE /* LHPF1MIX_VOL1 - [7:1] */ | ||
2077 | #define WM2200_LHPF1MIX_VOL1_SHIFT 1 /* LHPF1MIX_VOL1 - [7:1] */ | ||
2078 | #define WM2200_LHPF1MIX_VOL1_WIDTH 7 /* LHPF1MIX_VOL1 - [7:1] */ | ||
2079 | |||
2080 | /* | ||
2081 | * R1634 (0x662) - LHPF1MIX Input 2 Source | ||
2082 | */ | ||
2083 | #define WM2200_LHPF1MIX_SRC2_MASK 0x007F /* LHPF1MIX_SRC2 - [6:0] */ | ||
2084 | #define WM2200_LHPF1MIX_SRC2_SHIFT 0 /* LHPF1MIX_SRC2 - [6:0] */ | ||
2085 | #define WM2200_LHPF1MIX_SRC2_WIDTH 7 /* LHPF1MIX_SRC2 - [6:0] */ | ||
2086 | |||
2087 | /* | ||
2088 | * R1635 (0x663) - LHPF1MIX Input 2 Volume | ||
2089 | */ | ||
2090 | #define WM2200_LHPF1MIX_VOL2_MASK 0x00FE /* LHPF1MIX_VOL2 - [7:1] */ | ||
2091 | #define WM2200_LHPF1MIX_VOL2_SHIFT 1 /* LHPF1MIX_VOL2 - [7:1] */ | ||
2092 | #define WM2200_LHPF1MIX_VOL2_WIDTH 7 /* LHPF1MIX_VOL2 - [7:1] */ | ||
2093 | |||
2094 | /* | ||
2095 | * R1636 (0x664) - LHPF1MIX Input 3 Source | ||
2096 | */ | ||
2097 | #define WM2200_LHPF1MIX_SRC3_MASK 0x007F /* LHPF1MIX_SRC3 - [6:0] */ | ||
2098 | #define WM2200_LHPF1MIX_SRC3_SHIFT 0 /* LHPF1MIX_SRC3 - [6:0] */ | ||
2099 | #define WM2200_LHPF1MIX_SRC3_WIDTH 7 /* LHPF1MIX_SRC3 - [6:0] */ | ||
2100 | |||
2101 | /* | ||
2102 | * R1637 (0x665) - LHPF1MIX Input 3 Volume | ||
2103 | */ | ||
2104 | #define WM2200_LHPF1MIX_VOL3_MASK 0x00FE /* LHPF1MIX_VOL3 - [7:1] */ | ||
2105 | #define WM2200_LHPF1MIX_VOL3_SHIFT 1 /* LHPF1MIX_VOL3 - [7:1] */ | ||
2106 | #define WM2200_LHPF1MIX_VOL3_WIDTH 7 /* LHPF1MIX_VOL3 - [7:1] */ | ||
2107 | |||
2108 | /* | ||
2109 | * R1638 (0x666) - LHPF1MIX Input 4 Source | ||
2110 | */ | ||
2111 | #define WM2200_LHPF1MIX_SRC4_MASK 0x007F /* LHPF1MIX_SRC4 - [6:0] */ | ||
2112 | #define WM2200_LHPF1MIX_SRC4_SHIFT 0 /* LHPF1MIX_SRC4 - [6:0] */ | ||
2113 | #define WM2200_LHPF1MIX_SRC4_WIDTH 7 /* LHPF1MIX_SRC4 - [6:0] */ | ||
2114 | |||
2115 | /* | ||
2116 | * R1639 (0x667) - LHPF1MIX Input 4 Volume | ||
2117 | */ | ||
2118 | #define WM2200_LHPF1MIX_VOL4_MASK 0x00FE /* LHPF1MIX_VOL4 - [7:1] */ | ||
2119 | #define WM2200_LHPF1MIX_VOL4_SHIFT 1 /* LHPF1MIX_VOL4 - [7:1] */ | ||
2120 | #define WM2200_LHPF1MIX_VOL4_WIDTH 7 /* LHPF1MIX_VOL4 - [7:1] */ | ||
2121 | |||
2122 | /* | ||
2123 | * R1640 (0x668) - LHPF2MIX Input 1 Source | ||
2124 | */ | ||
2125 | #define WM2200_LHPF2MIX_SRC1_MASK 0x007F /* LHPF2MIX_SRC1 - [6:0] */ | ||
2126 | #define WM2200_LHPF2MIX_SRC1_SHIFT 0 /* LHPF2MIX_SRC1 - [6:0] */ | ||
2127 | #define WM2200_LHPF2MIX_SRC1_WIDTH 7 /* LHPF2MIX_SRC1 - [6:0] */ | ||
2128 | |||
2129 | /* | ||
2130 | * R1641 (0x669) - LHPF2MIX Input 1 Volume | ||
2131 | */ | ||
2132 | #define WM2200_LHPF2MIX_VOL1_MASK 0x00FE /* LHPF2MIX_VOL1 - [7:1] */ | ||
2133 | #define WM2200_LHPF2MIX_VOL1_SHIFT 1 /* LHPF2MIX_VOL1 - [7:1] */ | ||
2134 | #define WM2200_LHPF2MIX_VOL1_WIDTH 7 /* LHPF2MIX_VOL1 - [7:1] */ | ||
2135 | |||
2136 | /* | ||
2137 | * R1642 (0x66A) - LHPF2MIX Input 2 Source | ||
2138 | */ | ||
2139 | #define WM2200_LHPF2MIX_SRC2_MASK 0x007F /* LHPF2MIX_SRC2 - [6:0] */ | ||
2140 | #define WM2200_LHPF2MIX_SRC2_SHIFT 0 /* LHPF2MIX_SRC2 - [6:0] */ | ||
2141 | #define WM2200_LHPF2MIX_SRC2_WIDTH 7 /* LHPF2MIX_SRC2 - [6:0] */ | ||
2142 | |||
2143 | /* | ||
2144 | * R1643 (0x66B) - LHPF2MIX Input 2 Volume | ||
2145 | */ | ||
2146 | #define WM2200_LHPF2MIX_VOL2_MASK 0x00FE /* LHPF2MIX_VOL2 - [7:1] */ | ||
2147 | #define WM2200_LHPF2MIX_VOL2_SHIFT 1 /* LHPF2MIX_VOL2 - [7:1] */ | ||
2148 | #define WM2200_LHPF2MIX_VOL2_WIDTH 7 /* LHPF2MIX_VOL2 - [7:1] */ | ||
2149 | |||
2150 | /* | ||
2151 | * R1644 (0x66C) - LHPF2MIX Input 3 Source | ||
2152 | */ | ||
2153 | #define WM2200_LHPF2MIX_SRC3_MASK 0x007F /* LHPF2MIX_SRC3 - [6:0] */ | ||
2154 | #define WM2200_LHPF2MIX_SRC3_SHIFT 0 /* LHPF2MIX_SRC3 - [6:0] */ | ||
2155 | #define WM2200_LHPF2MIX_SRC3_WIDTH 7 /* LHPF2MIX_SRC3 - [6:0] */ | ||
2156 | |||
2157 | /* | ||
2158 | * R1645 (0x66D) - LHPF2MIX Input 3 Volume | ||
2159 | */ | ||
2160 | #define WM2200_LHPF2MIX_VOL3_MASK 0x00FE /* LHPF2MIX_VOL3 - [7:1] */ | ||
2161 | #define WM2200_LHPF2MIX_VOL3_SHIFT 1 /* LHPF2MIX_VOL3 - [7:1] */ | ||
2162 | #define WM2200_LHPF2MIX_VOL3_WIDTH 7 /* LHPF2MIX_VOL3 - [7:1] */ | ||
2163 | |||
2164 | /* | ||
2165 | * R1646 (0x66E) - LHPF2MIX Input 4 Source | ||
2166 | */ | ||
2167 | #define WM2200_LHPF2MIX_SRC4_MASK 0x007F /* LHPF2MIX_SRC4 - [6:0] */ | ||
2168 | #define WM2200_LHPF2MIX_SRC4_SHIFT 0 /* LHPF2MIX_SRC4 - [6:0] */ | ||
2169 | #define WM2200_LHPF2MIX_SRC4_WIDTH 7 /* LHPF2MIX_SRC4 - [6:0] */ | ||
2170 | |||
2171 | /* | ||
2172 | * R1647 (0x66F) - LHPF2MIX Input 4 Volume | ||
2173 | */ | ||
2174 | #define WM2200_LHPF2MIX_VOL4_MASK 0x00FE /* LHPF2MIX_VOL4 - [7:1] */ | ||
2175 | #define WM2200_LHPF2MIX_VOL4_SHIFT 1 /* LHPF2MIX_VOL4 - [7:1] */ | ||
2176 | #define WM2200_LHPF2MIX_VOL4_WIDTH 7 /* LHPF2MIX_VOL4 - [7:1] */ | ||
2177 | |||
2178 | /* | ||
2179 | * R1648 (0x670) - DSP1LMIX Input 1 Source | ||
2180 | */ | ||
2181 | #define WM2200_DSP1LMIX_SRC1_MASK 0x007F /* DSP1LMIX_SRC1 - [6:0] */ | ||
2182 | #define WM2200_DSP1LMIX_SRC1_SHIFT 0 /* DSP1LMIX_SRC1 - [6:0] */ | ||
2183 | #define WM2200_DSP1LMIX_SRC1_WIDTH 7 /* DSP1LMIX_SRC1 - [6:0] */ | ||
2184 | |||
2185 | /* | ||
2186 | * R1649 (0x671) - DSP1LMIX Input 1 Volume | ||
2187 | */ | ||
2188 | #define WM2200_DSP1LMIX_VOL1_MASK 0x00FE /* DSP1LMIX_VOL1 - [7:1] */ | ||
2189 | #define WM2200_DSP1LMIX_VOL1_SHIFT 1 /* DSP1LMIX_VOL1 - [7:1] */ | ||
2190 | #define WM2200_DSP1LMIX_VOL1_WIDTH 7 /* DSP1LMIX_VOL1 - [7:1] */ | ||
2191 | |||
2192 | /* | ||
2193 | * R1650 (0x672) - DSP1LMIX Input 2 Source | ||
2194 | */ | ||
2195 | #define WM2200_DSP1LMIX_SRC2_MASK 0x007F /* DSP1LMIX_SRC2 - [6:0] */ | ||
2196 | #define WM2200_DSP1LMIX_SRC2_SHIFT 0 /* DSP1LMIX_SRC2 - [6:0] */ | ||
2197 | #define WM2200_DSP1LMIX_SRC2_WIDTH 7 /* DSP1LMIX_SRC2 - [6:0] */ | ||
2198 | |||
2199 | /* | ||
2200 | * R1651 (0x673) - DSP1LMIX Input 2 Volume | ||
2201 | */ | ||
2202 | #define WM2200_DSP1LMIX_VOL2_MASK 0x00FE /* DSP1LMIX_VOL2 - [7:1] */ | ||
2203 | #define WM2200_DSP1LMIX_VOL2_SHIFT 1 /* DSP1LMIX_VOL2 - [7:1] */ | ||
2204 | #define WM2200_DSP1LMIX_VOL2_WIDTH 7 /* DSP1LMIX_VOL2 - [7:1] */ | ||
2205 | |||
2206 | /* | ||
2207 | * R1652 (0x674) - DSP1LMIX Input 3 Source | ||
2208 | */ | ||
2209 | #define WM2200_DSP1LMIX_SRC3_MASK 0x007F /* DSP1LMIX_SRC3 - [6:0] */ | ||
2210 | #define WM2200_DSP1LMIX_SRC3_SHIFT 0 /* DSP1LMIX_SRC3 - [6:0] */ | ||
2211 | #define WM2200_DSP1LMIX_SRC3_WIDTH 7 /* DSP1LMIX_SRC3 - [6:0] */ | ||
2212 | |||
2213 | /* | ||
2214 | * R1653 (0x675) - DSP1LMIX Input 3 Volume | ||
2215 | */ | ||
2216 | #define WM2200_DSP1LMIX_VOL3_MASK 0x00FE /* DSP1LMIX_VOL3 - [7:1] */ | ||
2217 | #define WM2200_DSP1LMIX_VOL3_SHIFT 1 /* DSP1LMIX_VOL3 - [7:1] */ | ||
2218 | #define WM2200_DSP1LMIX_VOL3_WIDTH 7 /* DSP1LMIX_VOL3 - [7:1] */ | ||
2219 | |||
2220 | /* | ||
2221 | * R1654 (0x676) - DSP1LMIX Input 4 Source | ||
2222 | */ | ||
2223 | #define WM2200_DSP1LMIX_SRC4_MASK 0x007F /* DSP1LMIX_SRC4 - [6:0] */ | ||
2224 | #define WM2200_DSP1LMIX_SRC4_SHIFT 0 /* DSP1LMIX_SRC4 - [6:0] */ | ||
2225 | #define WM2200_DSP1LMIX_SRC4_WIDTH 7 /* DSP1LMIX_SRC4 - [6:0] */ | ||
2226 | |||
2227 | /* | ||
2228 | * R1655 (0x677) - DSP1LMIX Input 4 Volume | ||
2229 | */ | ||
2230 | #define WM2200_DSP1LMIX_VOL4_MASK 0x00FE /* DSP1LMIX_VOL4 - [7:1] */ | ||
2231 | #define WM2200_DSP1LMIX_VOL4_SHIFT 1 /* DSP1LMIX_VOL4 - [7:1] */ | ||
2232 | #define WM2200_DSP1LMIX_VOL4_WIDTH 7 /* DSP1LMIX_VOL4 - [7:1] */ | ||
2233 | |||
2234 | /* | ||
2235 | * R1656 (0x678) - DSP1RMIX Input 1 Source | ||
2236 | */ | ||
2237 | #define WM2200_DSP1RMIX_SRC1_MASK 0x007F /* DSP1RMIX_SRC1 - [6:0] */ | ||
2238 | #define WM2200_DSP1RMIX_SRC1_SHIFT 0 /* DSP1RMIX_SRC1 - [6:0] */ | ||
2239 | #define WM2200_DSP1RMIX_SRC1_WIDTH 7 /* DSP1RMIX_SRC1 - [6:0] */ | ||
2240 | |||
2241 | /* | ||
2242 | * R1657 (0x679) - DSP1RMIX Input 1 Volume | ||
2243 | */ | ||
2244 | #define WM2200_DSP1RMIX_VOL1_MASK 0x00FE /* DSP1RMIX_VOL1 - [7:1] */ | ||
2245 | #define WM2200_DSP1RMIX_VOL1_SHIFT 1 /* DSP1RMIX_VOL1 - [7:1] */ | ||
2246 | #define WM2200_DSP1RMIX_VOL1_WIDTH 7 /* DSP1RMIX_VOL1 - [7:1] */ | ||
2247 | |||
2248 | /* | ||
2249 | * R1658 (0x67A) - DSP1RMIX Input 2 Source | ||
2250 | */ | ||
2251 | #define WM2200_DSP1RMIX_SRC2_MASK 0x007F /* DSP1RMIX_SRC2 - [6:0] */ | ||
2252 | #define WM2200_DSP1RMIX_SRC2_SHIFT 0 /* DSP1RMIX_SRC2 - [6:0] */ | ||
2253 | #define WM2200_DSP1RMIX_SRC2_WIDTH 7 /* DSP1RMIX_SRC2 - [6:0] */ | ||
2254 | |||
2255 | /* | ||
2256 | * R1659 (0x67B) - DSP1RMIX Input 2 Volume | ||
2257 | */ | ||
2258 | #define WM2200_DSP1RMIX_VOL2_MASK 0x00FE /* DSP1RMIX_VOL2 - [7:1] */ | ||
2259 | #define WM2200_DSP1RMIX_VOL2_SHIFT 1 /* DSP1RMIX_VOL2 - [7:1] */ | ||
2260 | #define WM2200_DSP1RMIX_VOL2_WIDTH 7 /* DSP1RMIX_VOL2 - [7:1] */ | ||
2261 | |||
2262 | /* | ||
2263 | * R1660 (0x67C) - DSP1RMIX Input 3 Source | ||
2264 | */ | ||
2265 | #define WM2200_DSP1RMIX_SRC3_MASK 0x007F /* DSP1RMIX_SRC3 - [6:0] */ | ||
2266 | #define WM2200_DSP1RMIX_SRC3_SHIFT 0 /* DSP1RMIX_SRC3 - [6:0] */ | ||
2267 | #define WM2200_DSP1RMIX_SRC3_WIDTH 7 /* DSP1RMIX_SRC3 - [6:0] */ | ||
2268 | |||
2269 | /* | ||
2270 | * R1661 (0x67D) - DSP1RMIX Input 3 Volume | ||
2271 | */ | ||
2272 | #define WM2200_DSP1RMIX_VOL3_MASK 0x00FE /* DSP1RMIX_VOL3 - [7:1] */ | ||
2273 | #define WM2200_DSP1RMIX_VOL3_SHIFT 1 /* DSP1RMIX_VOL3 - [7:1] */ | ||
2274 | #define WM2200_DSP1RMIX_VOL3_WIDTH 7 /* DSP1RMIX_VOL3 - [7:1] */ | ||
2275 | |||
2276 | /* | ||
2277 | * R1662 (0x67E) - DSP1RMIX Input 4 Source | ||
2278 | */ | ||
2279 | #define WM2200_DSP1RMIX_SRC4_MASK 0x007F /* DSP1RMIX_SRC4 - [6:0] */ | ||
2280 | #define WM2200_DSP1RMIX_SRC4_SHIFT 0 /* DSP1RMIX_SRC4 - [6:0] */ | ||
2281 | #define WM2200_DSP1RMIX_SRC4_WIDTH 7 /* DSP1RMIX_SRC4 - [6:0] */ | ||
2282 | |||
2283 | /* | ||
2284 | * R1663 (0x67F) - DSP1RMIX Input 4 Volume | ||
2285 | */ | ||
2286 | #define WM2200_DSP1RMIX_VOL4_MASK 0x00FE /* DSP1RMIX_VOL4 - [7:1] */ | ||
2287 | #define WM2200_DSP1RMIX_VOL4_SHIFT 1 /* DSP1RMIX_VOL4 - [7:1] */ | ||
2288 | #define WM2200_DSP1RMIX_VOL4_WIDTH 7 /* DSP1RMIX_VOL4 - [7:1] */ | ||
2289 | |||
2290 | /* | ||
2291 | * R1664 (0x680) - DSP1AUX1MIX Input 1 Source | ||
2292 | */ | ||
2293 | #define WM2200_DSP1AUX1MIX_SRC1_MASK 0x007F /* DSP1AUX1MIX_SRC1 - [6:0] */ | ||
2294 | #define WM2200_DSP1AUX1MIX_SRC1_SHIFT 0 /* DSP1AUX1MIX_SRC1 - [6:0] */ | ||
2295 | #define WM2200_DSP1AUX1MIX_SRC1_WIDTH 7 /* DSP1AUX1MIX_SRC1 - [6:0] */ | ||
2296 | |||
2297 | /* | ||
2298 | * R1665 (0x681) - DSP1AUX2MIX Input 1 Source | ||
2299 | */ | ||
2300 | #define WM2200_DSP1AUX2MIX_SRC1_MASK 0x007F /* DSP1AUX2MIX_SRC1 - [6:0] */ | ||
2301 | #define WM2200_DSP1AUX2MIX_SRC1_SHIFT 0 /* DSP1AUX2MIX_SRC1 - [6:0] */ | ||
2302 | #define WM2200_DSP1AUX2MIX_SRC1_WIDTH 7 /* DSP1AUX2MIX_SRC1 - [6:0] */ | ||
2303 | |||
2304 | /* | ||
2305 | * R1666 (0x682) - DSP1AUX3MIX Input 1 Source | ||
2306 | */ | ||
2307 | #define WM2200_DSP1AUX3MIX_SRC1_MASK 0x007F /* DSP1AUX3MIX_SRC1 - [6:0] */ | ||
2308 | #define WM2200_DSP1AUX3MIX_SRC1_SHIFT 0 /* DSP1AUX3MIX_SRC1 - [6:0] */ | ||
2309 | #define WM2200_DSP1AUX3MIX_SRC1_WIDTH 7 /* DSP1AUX3MIX_SRC1 - [6:0] */ | ||
2310 | |||
2311 | /* | ||
2312 | * R1667 (0x683) - DSP1AUX4MIX Input 1 Source | ||
2313 | */ | ||
2314 | #define WM2200_DSP1AUX4MIX_SRC1_MASK 0x007F /* DSP1AUX4MIX_SRC1 - [6:0] */ | ||
2315 | #define WM2200_DSP1AUX4MIX_SRC1_SHIFT 0 /* DSP1AUX4MIX_SRC1 - [6:0] */ | ||
2316 | #define WM2200_DSP1AUX4MIX_SRC1_WIDTH 7 /* DSP1AUX4MIX_SRC1 - [6:0] */ | ||
2317 | |||
2318 | /* | ||
2319 | * R1668 (0x684) - DSP1AUX5MIX Input 1 Source | ||
2320 | */ | ||
2321 | #define WM2200_DSP1AUX5MIX_SRC1_MASK 0x007F /* DSP1AUX5MIX_SRC1 - [6:0] */ | ||
2322 | #define WM2200_DSP1AUX5MIX_SRC1_SHIFT 0 /* DSP1AUX5MIX_SRC1 - [6:0] */ | ||
2323 | #define WM2200_DSP1AUX5MIX_SRC1_WIDTH 7 /* DSP1AUX5MIX_SRC1 - [6:0] */ | ||
2324 | |||
2325 | /* | ||
2326 | * R1669 (0x685) - DSP1AUX6MIX Input 1 Source | ||
2327 | */ | ||
2328 | #define WM2200_DSP1AUX6MIX_SRC1_MASK 0x007F /* DSP1AUX6MIX_SRC1 - [6:0] */ | ||
2329 | #define WM2200_DSP1AUX6MIX_SRC1_SHIFT 0 /* DSP1AUX6MIX_SRC1 - [6:0] */ | ||
2330 | #define WM2200_DSP1AUX6MIX_SRC1_WIDTH 7 /* DSP1AUX6MIX_SRC1 - [6:0] */ | ||
2331 | |||
2332 | /* | ||
2333 | * R1670 (0x686) - DSP2LMIX Input 1 Source | ||
2334 | */ | ||
2335 | #define WM2200_DSP2LMIX_SRC1_MASK 0x007F /* DSP2LMIX_SRC1 - [6:0] */ | ||
2336 | #define WM2200_DSP2LMIX_SRC1_SHIFT 0 /* DSP2LMIX_SRC1 - [6:0] */ | ||
2337 | #define WM2200_DSP2LMIX_SRC1_WIDTH 7 /* DSP2LMIX_SRC1 - [6:0] */ | ||
2338 | |||
2339 | /* | ||
2340 | * R1671 (0x687) - DSP2LMIX Input 1 Volume | ||
2341 | */ | ||
2342 | #define WM2200_DSP2LMIX_VOL1_MASK 0x00FE /* DSP2LMIX_VOL1 - [7:1] */ | ||
2343 | #define WM2200_DSP2LMIX_VOL1_SHIFT 1 /* DSP2LMIX_VOL1 - [7:1] */ | ||
2344 | #define WM2200_DSP2LMIX_VOL1_WIDTH 7 /* DSP2LMIX_VOL1 - [7:1] */ | ||
2345 | |||
2346 | /* | ||
2347 | * R1672 (0x688) - DSP2LMIX Input 2 Source | ||
2348 | */ | ||
2349 | #define WM2200_DSP2LMIX_SRC2_MASK 0x007F /* DSP2LMIX_SRC2 - [6:0] */ | ||
2350 | #define WM2200_DSP2LMIX_SRC2_SHIFT 0 /* DSP2LMIX_SRC2 - [6:0] */ | ||
2351 | #define WM2200_DSP2LMIX_SRC2_WIDTH 7 /* DSP2LMIX_SRC2 - [6:0] */ | ||
2352 | |||
2353 | /* | ||
2354 | * R1673 (0x689) - DSP2LMIX Input 2 Volume | ||
2355 | */ | ||
2356 | #define WM2200_DSP2LMIX_VOL2_MASK 0x00FE /* DSP2LMIX_VOL2 - [7:1] */ | ||
2357 | #define WM2200_DSP2LMIX_VOL2_SHIFT 1 /* DSP2LMIX_VOL2 - [7:1] */ | ||
2358 | #define WM2200_DSP2LMIX_VOL2_WIDTH 7 /* DSP2LMIX_VOL2 - [7:1] */ | ||
2359 | |||
2360 | /* | ||
2361 | * R1674 (0x68A) - DSP2LMIX Input 3 Source | ||
2362 | */ | ||
2363 | #define WM2200_DSP2LMIX_SRC3_MASK 0x007F /* DSP2LMIX_SRC3 - [6:0] */ | ||
2364 | #define WM2200_DSP2LMIX_SRC3_SHIFT 0 /* DSP2LMIX_SRC3 - [6:0] */ | ||
2365 | #define WM2200_DSP2LMIX_SRC3_WIDTH 7 /* DSP2LMIX_SRC3 - [6:0] */ | ||
2366 | |||
2367 | /* | ||
2368 | * R1675 (0x68B) - DSP2LMIX Input 3 Volume | ||
2369 | */ | ||
2370 | #define WM2200_DSP2LMIX_VOL3_MASK 0x00FE /* DSP2LMIX_VOL3 - [7:1] */ | ||
2371 | #define WM2200_DSP2LMIX_VOL3_SHIFT 1 /* DSP2LMIX_VOL3 - [7:1] */ | ||
2372 | #define WM2200_DSP2LMIX_VOL3_WIDTH 7 /* DSP2LMIX_VOL3 - [7:1] */ | ||
2373 | |||
2374 | /* | ||
2375 | * R1676 (0x68C) - DSP2LMIX Input 4 Source | ||
2376 | */ | ||
2377 | #define WM2200_DSP2LMIX_SRC4_MASK 0x007F /* DSP2LMIX_SRC4 - [6:0] */ | ||
2378 | #define WM2200_DSP2LMIX_SRC4_SHIFT 0 /* DSP2LMIX_SRC4 - [6:0] */ | ||
2379 | #define WM2200_DSP2LMIX_SRC4_WIDTH 7 /* DSP2LMIX_SRC4 - [6:0] */ | ||
2380 | |||
2381 | /* | ||
2382 | * R1677 (0x68D) - DSP2LMIX Input 4 Volume | ||
2383 | */ | ||
2384 | #define WM2200_DSP2LMIX_VOL4_MASK 0x00FE /* DSP2LMIX_VOL4 - [7:1] */ | ||
2385 | #define WM2200_DSP2LMIX_VOL4_SHIFT 1 /* DSP2LMIX_VOL4 - [7:1] */ | ||
2386 | #define WM2200_DSP2LMIX_VOL4_WIDTH 7 /* DSP2LMIX_VOL4 - [7:1] */ | ||
2387 | |||
2388 | /* | ||
2389 | * R1678 (0x68E) - DSP2RMIX Input 1 Source | ||
2390 | */ | ||
2391 | #define WM2200_DSP2RMIX_SRC1_MASK 0x007F /* DSP2RMIX_SRC1 - [6:0] */ | ||
2392 | #define WM2200_DSP2RMIX_SRC1_SHIFT 0 /* DSP2RMIX_SRC1 - [6:0] */ | ||
2393 | #define WM2200_DSP2RMIX_SRC1_WIDTH 7 /* DSP2RMIX_SRC1 - [6:0] */ | ||
2394 | |||
2395 | /* | ||
2396 | * R1679 (0x68F) - DSP2RMIX Input 1 Volume | ||
2397 | */ | ||
2398 | #define WM2200_DSP2RMIX_VOL1_MASK 0x00FE /* DSP2RMIX_VOL1 - [7:1] */ | ||
2399 | #define WM2200_DSP2RMIX_VOL1_SHIFT 1 /* DSP2RMIX_VOL1 - [7:1] */ | ||
2400 | #define WM2200_DSP2RMIX_VOL1_WIDTH 7 /* DSP2RMIX_VOL1 - [7:1] */ | ||
2401 | |||
2402 | /* | ||
2403 | * R1680 (0x690) - DSP2RMIX Input 2 Source | ||
2404 | */ | ||
2405 | #define WM2200_DSP2RMIX_SRC2_MASK 0x007F /* DSP2RMIX_SRC2 - [6:0] */ | ||
2406 | #define WM2200_DSP2RMIX_SRC2_SHIFT 0 /* DSP2RMIX_SRC2 - [6:0] */ | ||
2407 | #define WM2200_DSP2RMIX_SRC2_WIDTH 7 /* DSP2RMIX_SRC2 - [6:0] */ | ||
2408 | |||
2409 | /* | ||
2410 | * R1681 (0x691) - DSP2RMIX Input 2 Volume | ||
2411 | */ | ||
2412 | #define WM2200_DSP2RMIX_VOL2_MASK 0x00FE /* DSP2RMIX_VOL2 - [7:1] */ | ||
2413 | #define WM2200_DSP2RMIX_VOL2_SHIFT 1 /* DSP2RMIX_VOL2 - [7:1] */ | ||
2414 | #define WM2200_DSP2RMIX_VOL2_WIDTH 7 /* DSP2RMIX_VOL2 - [7:1] */ | ||
2415 | |||
2416 | /* | ||
2417 | * R1682 (0x692) - DSP2RMIX Input 3 Source | ||
2418 | */ | ||
2419 | #define WM2200_DSP2RMIX_SRC3_MASK 0x007F /* DSP2RMIX_SRC3 - [6:0] */ | ||
2420 | #define WM2200_DSP2RMIX_SRC3_SHIFT 0 /* DSP2RMIX_SRC3 - [6:0] */ | ||
2421 | #define WM2200_DSP2RMIX_SRC3_WIDTH 7 /* DSP2RMIX_SRC3 - [6:0] */ | ||
2422 | |||
2423 | /* | ||
2424 | * R1683 (0x693) - DSP2RMIX Input 3 Volume | ||
2425 | */ | ||
2426 | #define WM2200_DSP2RMIX_VOL3_MASK 0x00FE /* DSP2RMIX_VOL3 - [7:1] */ | ||
2427 | #define WM2200_DSP2RMIX_VOL3_SHIFT 1 /* DSP2RMIX_VOL3 - [7:1] */ | ||
2428 | #define WM2200_DSP2RMIX_VOL3_WIDTH 7 /* DSP2RMIX_VOL3 - [7:1] */ | ||
2429 | |||
2430 | /* | ||
2431 | * R1684 (0x694) - DSP2RMIX Input 4 Source | ||
2432 | */ | ||
2433 | #define WM2200_DSP2RMIX_SRC4_MASK 0x007F /* DSP2RMIX_SRC4 - [6:0] */ | ||
2434 | #define WM2200_DSP2RMIX_SRC4_SHIFT 0 /* DSP2RMIX_SRC4 - [6:0] */ | ||
2435 | #define WM2200_DSP2RMIX_SRC4_WIDTH 7 /* DSP2RMIX_SRC4 - [6:0] */ | ||
2436 | |||
2437 | /* | ||
2438 | * R1685 (0x695) - DSP2RMIX Input 4 Volume | ||
2439 | */ | ||
2440 | #define WM2200_DSP2RMIX_VOL4_MASK 0x00FE /* DSP2RMIX_VOL4 - [7:1] */ | ||
2441 | #define WM2200_DSP2RMIX_VOL4_SHIFT 1 /* DSP2RMIX_VOL4 - [7:1] */ | ||
2442 | #define WM2200_DSP2RMIX_VOL4_WIDTH 7 /* DSP2RMIX_VOL4 - [7:1] */ | ||
2443 | |||
2444 | /* | ||
2445 | * R1686 (0x696) - DSP2AUX1MIX Input 1 Source | ||
2446 | */ | ||
2447 | #define WM2200_DSP2AUX1MIX_SRC1_MASK 0x007F /* DSP2AUX1MIX_SRC1 - [6:0] */ | ||
2448 | #define WM2200_DSP2AUX1MIX_SRC1_SHIFT 0 /* DSP2AUX1MIX_SRC1 - [6:0] */ | ||
2449 | #define WM2200_DSP2AUX1MIX_SRC1_WIDTH 7 /* DSP2AUX1MIX_SRC1 - [6:0] */ | ||
2450 | |||
2451 | /* | ||
2452 | * R1687 (0x697) - DSP2AUX2MIX Input 1 Source | ||
2453 | */ | ||
2454 | #define WM2200_DSP2AUX2MIX_SRC1_MASK 0x007F /* DSP2AUX2MIX_SRC1 - [6:0] */ | ||
2455 | #define WM2200_DSP2AUX2MIX_SRC1_SHIFT 0 /* DSP2AUX2MIX_SRC1 - [6:0] */ | ||
2456 | #define WM2200_DSP2AUX2MIX_SRC1_WIDTH 7 /* DSP2AUX2MIX_SRC1 - [6:0] */ | ||
2457 | |||
2458 | /* | ||
2459 | * R1688 (0x698) - DSP2AUX3MIX Input 1 Source | ||
2460 | */ | ||
2461 | #define WM2200_DSP2AUX3MIX_SRC1_MASK 0x007F /* DSP2AUX3MIX_SRC1 - [6:0] */ | ||
2462 | #define WM2200_DSP2AUX3MIX_SRC1_SHIFT 0 /* DSP2AUX3MIX_SRC1 - [6:0] */ | ||
2463 | #define WM2200_DSP2AUX3MIX_SRC1_WIDTH 7 /* DSP2AUX3MIX_SRC1 - [6:0] */ | ||
2464 | |||
2465 | /* | ||
2466 | * R1689 (0x699) - DSP2AUX4MIX Input 1 Source | ||
2467 | */ | ||
2468 | #define WM2200_DSP2AUX4MIX_SRC1_MASK 0x007F /* DSP2AUX4MIX_SRC1 - [6:0] */ | ||
2469 | #define WM2200_DSP2AUX4MIX_SRC1_SHIFT 0 /* DSP2AUX4MIX_SRC1 - [6:0] */ | ||
2470 | #define WM2200_DSP2AUX4MIX_SRC1_WIDTH 7 /* DSP2AUX4MIX_SRC1 - [6:0] */ | ||
2471 | |||
2472 | /* | ||
2473 | * R1690 (0x69A) - DSP2AUX5MIX Input 1 Source | ||
2474 | */ | ||
2475 | #define WM2200_DSP2AUX5MIX_SRC1_MASK 0x007F /* DSP2AUX5MIX_SRC1 - [6:0] */ | ||
2476 | #define WM2200_DSP2AUX5MIX_SRC1_SHIFT 0 /* DSP2AUX5MIX_SRC1 - [6:0] */ | ||
2477 | #define WM2200_DSP2AUX5MIX_SRC1_WIDTH 7 /* DSP2AUX5MIX_SRC1 - [6:0] */ | ||
2478 | |||
2479 | /* | ||
2480 | * R1691 (0x69B) - DSP2AUX6MIX Input 1 Source | ||
2481 | */ | ||
2482 | #define WM2200_DSP2AUX6MIX_SRC1_MASK 0x007F /* DSP2AUX6MIX_SRC1 - [6:0] */ | ||
2483 | #define WM2200_DSP2AUX6MIX_SRC1_SHIFT 0 /* DSP2AUX6MIX_SRC1 - [6:0] */ | ||
2484 | #define WM2200_DSP2AUX6MIX_SRC1_WIDTH 7 /* DSP2AUX6MIX_SRC1 - [6:0] */ | ||
2485 | |||
2486 | /* | ||
2487 | * R1792 (0x700) - GPIO CTRL 1 | ||
2488 | */ | ||
2489 | #define WM2200_GP1_DIR 0x8000 /* GP1_DIR */ | ||
2490 | #define WM2200_GP1_DIR_MASK 0x8000 /* GP1_DIR */ | ||
2491 | #define WM2200_GP1_DIR_SHIFT 15 /* GP1_DIR */ | ||
2492 | #define WM2200_GP1_DIR_WIDTH 1 /* GP1_DIR */ | ||
2493 | #define WM2200_GP1_PU 0x4000 /* GP1_PU */ | ||
2494 | #define WM2200_GP1_PU_MASK 0x4000 /* GP1_PU */ | ||
2495 | #define WM2200_GP1_PU_SHIFT 14 /* GP1_PU */ | ||
2496 | #define WM2200_GP1_PU_WIDTH 1 /* GP1_PU */ | ||
2497 | #define WM2200_GP1_PD 0x2000 /* GP1_PD */ | ||
2498 | #define WM2200_GP1_PD_MASK 0x2000 /* GP1_PD */ | ||
2499 | #define WM2200_GP1_PD_SHIFT 13 /* GP1_PD */ | ||
2500 | #define WM2200_GP1_PD_WIDTH 1 /* GP1_PD */ | ||
2501 | #define WM2200_GP1_POL 0x0400 /* GP1_POL */ | ||
2502 | #define WM2200_GP1_POL_MASK 0x0400 /* GP1_POL */ | ||
2503 | #define WM2200_GP1_POL_SHIFT 10 /* GP1_POL */ | ||
2504 | #define WM2200_GP1_POL_WIDTH 1 /* GP1_POL */ | ||
2505 | #define WM2200_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */ | ||
2506 | #define WM2200_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */ | ||
2507 | #define WM2200_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */ | ||
2508 | #define WM2200_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */ | ||
2509 | #define WM2200_GP1_DB 0x0100 /* GP1_DB */ | ||
2510 | #define WM2200_GP1_DB_MASK 0x0100 /* GP1_DB */ | ||
2511 | #define WM2200_GP1_DB_SHIFT 8 /* GP1_DB */ | ||
2512 | #define WM2200_GP1_DB_WIDTH 1 /* GP1_DB */ | ||
2513 | #define WM2200_GP1_LVL 0x0040 /* GP1_LVL */ | ||
2514 | #define WM2200_GP1_LVL_MASK 0x0040 /* GP1_LVL */ | ||
2515 | #define WM2200_GP1_LVL_SHIFT 6 /* GP1_LVL */ | ||
2516 | #define WM2200_GP1_LVL_WIDTH 1 /* GP1_LVL */ | ||
2517 | #define WM2200_GP1_FN_MASK 0x003F /* GP1_FN - [5:0] */ | ||
2518 | #define WM2200_GP1_FN_SHIFT 0 /* GP1_FN - [5:0] */ | ||
2519 | #define WM2200_GP1_FN_WIDTH 6 /* GP1_FN - [5:0] */ | ||
2520 | |||
2521 | /* | ||
2522 | * R1793 (0x701) - GPIO CTRL 2 | ||
2523 | */ | ||
2524 | #define WM2200_GP2_DIR 0x8000 /* GP2_DIR */ | ||
2525 | #define WM2200_GP2_DIR_MASK 0x8000 /* GP2_DIR */ | ||
2526 | #define WM2200_GP2_DIR_SHIFT 15 /* GP2_DIR */ | ||
2527 | #define WM2200_GP2_DIR_WIDTH 1 /* GP2_DIR */ | ||
2528 | #define WM2200_GP2_PU 0x4000 /* GP2_PU */ | ||
2529 | #define WM2200_GP2_PU_MASK 0x4000 /* GP2_PU */ | ||
2530 | #define WM2200_GP2_PU_SHIFT 14 /* GP2_PU */ | ||
2531 | #define WM2200_GP2_PU_WIDTH 1 /* GP2_PU */ | ||
2532 | #define WM2200_GP2_PD 0x2000 /* GP2_PD */ | ||
2533 | #define WM2200_GP2_PD_MASK 0x2000 /* GP2_PD */ | ||
2534 | #define WM2200_GP2_PD_SHIFT 13 /* GP2_PD */ | ||
2535 | #define WM2200_GP2_PD_WIDTH 1 /* GP2_PD */ | ||
2536 | #define WM2200_GP2_POL 0x0400 /* GP2_POL */ | ||
2537 | #define WM2200_GP2_POL_MASK 0x0400 /* GP2_POL */ | ||
2538 | #define WM2200_GP2_POL_SHIFT 10 /* GP2_POL */ | ||
2539 | #define WM2200_GP2_POL_WIDTH 1 /* GP2_POL */ | ||
2540 | #define WM2200_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */ | ||
2541 | #define WM2200_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */ | ||
2542 | #define WM2200_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */ | ||
2543 | #define WM2200_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */ | ||
2544 | #define WM2200_GP2_DB 0x0100 /* GP2_DB */ | ||
2545 | #define WM2200_GP2_DB_MASK 0x0100 /* GP2_DB */ | ||
2546 | #define WM2200_GP2_DB_SHIFT 8 /* GP2_DB */ | ||
2547 | #define WM2200_GP2_DB_WIDTH 1 /* GP2_DB */ | ||
2548 | #define WM2200_GP2_LVL 0x0040 /* GP2_LVL */ | ||
2549 | #define WM2200_GP2_LVL_MASK 0x0040 /* GP2_LVL */ | ||
2550 | #define WM2200_GP2_LVL_SHIFT 6 /* GP2_LVL */ | ||
2551 | #define WM2200_GP2_LVL_WIDTH 1 /* GP2_LVL */ | ||
2552 | #define WM2200_GP2_FN_MASK 0x003F /* GP2_FN - [5:0] */ | ||
2553 | #define WM2200_GP2_FN_SHIFT 0 /* GP2_FN - [5:0] */ | ||
2554 | #define WM2200_GP2_FN_WIDTH 6 /* GP2_FN - [5:0] */ | ||
2555 | |||
2556 | /* | ||
2557 | * R1794 (0x702) - GPIO CTRL 3 | ||
2558 | */ | ||
2559 | #define WM2200_GP3_DIR 0x8000 /* GP3_DIR */ | ||
2560 | #define WM2200_GP3_DIR_MASK 0x8000 /* GP3_DIR */ | ||
2561 | #define WM2200_GP3_DIR_SHIFT 15 /* GP3_DIR */ | ||
2562 | #define WM2200_GP3_DIR_WIDTH 1 /* GP3_DIR */ | ||
2563 | #define WM2200_GP3_PU 0x4000 /* GP3_PU */ | ||
2564 | #define WM2200_GP3_PU_MASK 0x4000 /* GP3_PU */ | ||
2565 | #define WM2200_GP3_PU_SHIFT 14 /* GP3_PU */ | ||
2566 | #define WM2200_GP3_PU_WIDTH 1 /* GP3_PU */ | ||
2567 | #define WM2200_GP3_PD 0x2000 /* GP3_PD */ | ||
2568 | #define WM2200_GP3_PD_MASK 0x2000 /* GP3_PD */ | ||
2569 | #define WM2200_GP3_PD_SHIFT 13 /* GP3_PD */ | ||
2570 | #define WM2200_GP3_PD_WIDTH 1 /* GP3_PD */ | ||
2571 | #define WM2200_GP3_POL 0x0400 /* GP3_POL */ | ||
2572 | #define WM2200_GP3_POL_MASK 0x0400 /* GP3_POL */ | ||
2573 | #define WM2200_GP3_POL_SHIFT 10 /* GP3_POL */ | ||
2574 | #define WM2200_GP3_POL_WIDTH 1 /* GP3_POL */ | ||
2575 | #define WM2200_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */ | ||
2576 | #define WM2200_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */ | ||
2577 | #define WM2200_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */ | ||
2578 | #define WM2200_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */ | ||
2579 | #define WM2200_GP3_DB 0x0100 /* GP3_DB */ | ||
2580 | #define WM2200_GP3_DB_MASK 0x0100 /* GP3_DB */ | ||
2581 | #define WM2200_GP3_DB_SHIFT 8 /* GP3_DB */ | ||
2582 | #define WM2200_GP3_DB_WIDTH 1 /* GP3_DB */ | ||
2583 | #define WM2200_GP3_LVL 0x0040 /* GP3_LVL */ | ||
2584 | #define WM2200_GP3_LVL_MASK 0x0040 /* GP3_LVL */ | ||
2585 | #define WM2200_GP3_LVL_SHIFT 6 /* GP3_LVL */ | ||
2586 | #define WM2200_GP3_LVL_WIDTH 1 /* GP3_LVL */ | ||
2587 | #define WM2200_GP3_FN_MASK 0x003F /* GP3_FN - [5:0] */ | ||
2588 | #define WM2200_GP3_FN_SHIFT 0 /* GP3_FN - [5:0] */ | ||
2589 | #define WM2200_GP3_FN_WIDTH 6 /* GP3_FN - [5:0] */ | ||
2590 | |||
2591 | /* | ||
2592 | * R1795 (0x703) - GPIO CTRL 4 | ||
2593 | */ | ||
2594 | #define WM2200_GP4_DIR 0x8000 /* GP4_DIR */ | ||
2595 | #define WM2200_GP4_DIR_MASK 0x8000 /* GP4_DIR */ | ||
2596 | #define WM2200_GP4_DIR_SHIFT 15 /* GP4_DIR */ | ||
2597 | #define WM2200_GP4_DIR_WIDTH 1 /* GP4_DIR */ | ||
2598 | #define WM2200_GP4_PU 0x4000 /* GP4_PU */ | ||
2599 | #define WM2200_GP4_PU_MASK 0x4000 /* GP4_PU */ | ||
2600 | #define WM2200_GP4_PU_SHIFT 14 /* GP4_PU */ | ||
2601 | #define WM2200_GP4_PU_WIDTH 1 /* GP4_PU */ | ||
2602 | #define WM2200_GP4_PD 0x2000 /* GP4_PD */ | ||
2603 | #define WM2200_GP4_PD_MASK 0x2000 /* GP4_PD */ | ||
2604 | #define WM2200_GP4_PD_SHIFT 13 /* GP4_PD */ | ||
2605 | #define WM2200_GP4_PD_WIDTH 1 /* GP4_PD */ | ||
2606 | #define WM2200_GP4_POL 0x0400 /* GP4_POL */ | ||
2607 | #define WM2200_GP4_POL_MASK 0x0400 /* GP4_POL */ | ||
2608 | #define WM2200_GP4_POL_SHIFT 10 /* GP4_POL */ | ||
2609 | #define WM2200_GP4_POL_WIDTH 1 /* GP4_POL */ | ||
2610 | #define WM2200_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */ | ||
2611 | #define WM2200_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */ | ||
2612 | #define WM2200_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */ | ||
2613 | #define WM2200_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */ | ||
2614 | #define WM2200_GP4_DB 0x0100 /* GP4_DB */ | ||
2615 | #define WM2200_GP4_DB_MASK 0x0100 /* GP4_DB */ | ||
2616 | #define WM2200_GP4_DB_SHIFT 8 /* GP4_DB */ | ||
2617 | #define WM2200_GP4_DB_WIDTH 1 /* GP4_DB */ | ||
2618 | #define WM2200_GP4_LVL 0x0040 /* GP4_LVL */ | ||
2619 | #define WM2200_GP4_LVL_MASK 0x0040 /* GP4_LVL */ | ||
2620 | #define WM2200_GP4_LVL_SHIFT 6 /* GP4_LVL */ | ||
2621 | #define WM2200_GP4_LVL_WIDTH 1 /* GP4_LVL */ | ||
2622 | #define WM2200_GP4_FN_MASK 0x003F /* GP4_FN - [5:0] */ | ||
2623 | #define WM2200_GP4_FN_SHIFT 0 /* GP4_FN - [5:0] */ | ||
2624 | #define WM2200_GP4_FN_WIDTH 6 /* GP4_FN - [5:0] */ | ||
2625 | |||
2626 | /* | ||
2627 | * R1799 (0x707) - ADPS1 IRQ0 | ||
2628 | */ | ||
2629 | #define WM2200_DSP_IRQ1 0x0002 /* DSP_IRQ1 */ | ||
2630 | #define WM2200_DSP_IRQ1_MASK 0x0002 /* DSP_IRQ1 */ | ||
2631 | #define WM2200_DSP_IRQ1_SHIFT 1 /* DSP_IRQ1 */ | ||
2632 | #define WM2200_DSP_IRQ1_WIDTH 1 /* DSP_IRQ1 */ | ||
2633 | #define WM2200_DSP_IRQ0 0x0001 /* DSP_IRQ0 */ | ||
2634 | #define WM2200_DSP_IRQ0_MASK 0x0001 /* DSP_IRQ0 */ | ||
2635 | #define WM2200_DSP_IRQ0_SHIFT 0 /* DSP_IRQ0 */ | ||
2636 | #define WM2200_DSP_IRQ0_WIDTH 1 /* DSP_IRQ0 */ | ||
2637 | |||
2638 | /* | ||
2639 | * R1800 (0x708) - ADPS1 IRQ1 | ||
2640 | */ | ||
2641 | #define WM2200_DSP_IRQ3 0x0002 /* DSP_IRQ3 */ | ||
2642 | #define WM2200_DSP_IRQ3_MASK 0x0002 /* DSP_IRQ3 */ | ||
2643 | #define WM2200_DSP_IRQ3_SHIFT 1 /* DSP_IRQ3 */ | ||
2644 | #define WM2200_DSP_IRQ3_WIDTH 1 /* DSP_IRQ3 */ | ||
2645 | #define WM2200_DSP_IRQ2 0x0001 /* DSP_IRQ2 */ | ||
2646 | #define WM2200_DSP_IRQ2_MASK 0x0001 /* DSP_IRQ2 */ | ||
2647 | #define WM2200_DSP_IRQ2_SHIFT 0 /* DSP_IRQ2 */ | ||
2648 | #define WM2200_DSP_IRQ2_WIDTH 1 /* DSP_IRQ2 */ | ||
2649 | |||
2650 | /* | ||
2651 | * R1801 (0x709) - Misc Pad Ctrl 1 | ||
2652 | */ | ||
2653 | #define WM2200_LDO1ENA_PD 0x8000 /* LDO1ENA_PD */ | ||
2654 | #define WM2200_LDO1ENA_PD_MASK 0x8000 /* LDO1ENA_PD */ | ||
2655 | #define WM2200_LDO1ENA_PD_SHIFT 15 /* LDO1ENA_PD */ | ||
2656 | #define WM2200_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */ | ||
2657 | #define WM2200_MCLK2_PD 0x2000 /* MCLK2_PD */ | ||
2658 | #define WM2200_MCLK2_PD_MASK 0x2000 /* MCLK2_PD */ | ||
2659 | #define WM2200_MCLK2_PD_SHIFT 13 /* MCLK2_PD */ | ||
2660 | #define WM2200_MCLK2_PD_WIDTH 1 /* MCLK2_PD */ | ||
2661 | #define WM2200_MCLK1_PD 0x1000 /* MCLK1_PD */ | ||
2662 | #define WM2200_MCLK1_PD_MASK 0x1000 /* MCLK1_PD */ | ||
2663 | #define WM2200_MCLK1_PD_SHIFT 12 /* MCLK1_PD */ | ||
2664 | #define WM2200_MCLK1_PD_WIDTH 1 /* MCLK1_PD */ | ||
2665 | #define WM2200_DACLRCLK1_PU 0x0400 /* DACLRCLK1_PU */ | ||
2666 | #define WM2200_DACLRCLK1_PU_MASK 0x0400 /* DACLRCLK1_PU */ | ||
2667 | #define WM2200_DACLRCLK1_PU_SHIFT 10 /* DACLRCLK1_PU */ | ||
2668 | #define WM2200_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */ | ||
2669 | #define WM2200_DACLRCLK1_PD 0x0200 /* DACLRCLK1_PD */ | ||
2670 | #define WM2200_DACLRCLK1_PD_MASK 0x0200 /* DACLRCLK1_PD */ | ||
2671 | #define WM2200_DACLRCLK1_PD_SHIFT 9 /* DACLRCLK1_PD */ | ||
2672 | #define WM2200_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */ | ||
2673 | #define WM2200_BCLK1_PU 0x0100 /* BCLK1_PU */ | ||
2674 | #define WM2200_BCLK1_PU_MASK 0x0100 /* BCLK1_PU */ | ||
2675 | #define WM2200_BCLK1_PU_SHIFT 8 /* BCLK1_PU */ | ||
2676 | #define WM2200_BCLK1_PU_WIDTH 1 /* BCLK1_PU */ | ||
2677 | #define WM2200_BCLK1_PD 0x0080 /* BCLK1_PD */ | ||
2678 | #define WM2200_BCLK1_PD_MASK 0x0080 /* BCLK1_PD */ | ||
2679 | #define WM2200_BCLK1_PD_SHIFT 7 /* BCLK1_PD */ | ||
2680 | #define WM2200_BCLK1_PD_WIDTH 1 /* BCLK1_PD */ | ||
2681 | #define WM2200_DACDAT1_PU 0x0040 /* DACDAT1_PU */ | ||
2682 | #define WM2200_DACDAT1_PU_MASK 0x0040 /* DACDAT1_PU */ | ||
2683 | #define WM2200_DACDAT1_PU_SHIFT 6 /* DACDAT1_PU */ | ||
2684 | #define WM2200_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */ | ||
2685 | #define WM2200_DACDAT1_PD 0x0020 /* DACDAT1_PD */ | ||
2686 | #define WM2200_DACDAT1_PD_MASK 0x0020 /* DACDAT1_PD */ | ||
2687 | #define WM2200_DACDAT1_PD_SHIFT 5 /* DACDAT1_PD */ | ||
2688 | #define WM2200_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */ | ||
2689 | #define WM2200_DMICDAT3_PD 0x0010 /* DMICDAT3_PD */ | ||
2690 | #define WM2200_DMICDAT3_PD_MASK 0x0010 /* DMICDAT3_PD */ | ||
2691 | #define WM2200_DMICDAT3_PD_SHIFT 4 /* DMICDAT3_PD */ | ||
2692 | #define WM2200_DMICDAT3_PD_WIDTH 1 /* DMICDAT3_PD */ | ||
2693 | #define WM2200_DMICDAT2_PD 0x0008 /* DMICDAT2_PD */ | ||
2694 | #define WM2200_DMICDAT2_PD_MASK 0x0008 /* DMICDAT2_PD */ | ||
2695 | #define WM2200_DMICDAT2_PD_SHIFT 3 /* DMICDAT2_PD */ | ||
2696 | #define WM2200_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */ | ||
2697 | #define WM2200_DMICDAT1_PD 0x0004 /* DMICDAT1_PD */ | ||
2698 | #define WM2200_DMICDAT1_PD_MASK 0x0004 /* DMICDAT1_PD */ | ||
2699 | #define WM2200_DMICDAT1_PD_SHIFT 2 /* DMICDAT1_PD */ | ||
2700 | #define WM2200_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */ | ||
2701 | #define WM2200_RSTB_PU 0x0002 /* RSTB_PU */ | ||
2702 | #define WM2200_RSTB_PU_MASK 0x0002 /* RSTB_PU */ | ||
2703 | #define WM2200_RSTB_PU_SHIFT 1 /* RSTB_PU */ | ||
2704 | #define WM2200_RSTB_PU_WIDTH 1 /* RSTB_PU */ | ||
2705 | #define WM2200_ADDR_PD 0x0001 /* ADDR_PD */ | ||
2706 | #define WM2200_ADDR_PD_MASK 0x0001 /* ADDR_PD */ | ||
2707 | #define WM2200_ADDR_PD_SHIFT 0 /* ADDR_PD */ | ||
2708 | #define WM2200_ADDR_PD_WIDTH 1 /* ADDR_PD */ | ||
2709 | |||
2710 | /* | ||
2711 | * R2048 (0x800) - Interrupt Status 1 | ||
2712 | */ | ||
2713 | #define WM2200_DSP_IRQ0_EINT 0x0080 /* DSP_IRQ0_EINT */ | ||
2714 | #define WM2200_DSP_IRQ0_EINT_MASK 0x0080 /* DSP_IRQ0_EINT */ | ||
2715 | #define WM2200_DSP_IRQ0_EINT_SHIFT 7 /* DSP_IRQ0_EINT */ | ||
2716 | #define WM2200_DSP_IRQ0_EINT_WIDTH 1 /* DSP_IRQ0_EINT */ | ||
2717 | #define WM2200_DSP_IRQ1_EINT 0x0040 /* DSP_IRQ1_EINT */ | ||
2718 | #define WM2200_DSP_IRQ1_EINT_MASK 0x0040 /* DSP_IRQ1_EINT */ | ||
2719 | #define WM2200_DSP_IRQ1_EINT_SHIFT 6 /* DSP_IRQ1_EINT */ | ||
2720 | #define WM2200_DSP_IRQ1_EINT_WIDTH 1 /* DSP_IRQ1_EINT */ | ||
2721 | #define WM2200_DSP_IRQ2_EINT 0x0020 /* DSP_IRQ2_EINT */ | ||
2722 | #define WM2200_DSP_IRQ2_EINT_MASK 0x0020 /* DSP_IRQ2_EINT */ | ||
2723 | #define WM2200_DSP_IRQ2_EINT_SHIFT 5 /* DSP_IRQ2_EINT */ | ||
2724 | #define WM2200_DSP_IRQ2_EINT_WIDTH 1 /* DSP_IRQ2_EINT */ | ||
2725 | #define WM2200_DSP_IRQ3_EINT 0x0010 /* DSP_IRQ3_EINT */ | ||
2726 | #define WM2200_DSP_IRQ3_EINT_MASK 0x0010 /* DSP_IRQ3_EINT */ | ||
2727 | #define WM2200_DSP_IRQ3_EINT_SHIFT 4 /* DSP_IRQ3_EINT */ | ||
2728 | #define WM2200_DSP_IRQ3_EINT_WIDTH 1 /* DSP_IRQ3_EINT */ | ||
2729 | #define WM2200_GP4_EINT 0x0008 /* GP4_EINT */ | ||
2730 | #define WM2200_GP4_EINT_MASK 0x0008 /* GP4_EINT */ | ||
2731 | #define WM2200_GP4_EINT_SHIFT 3 /* GP4_EINT */ | ||
2732 | #define WM2200_GP4_EINT_WIDTH 1 /* GP4_EINT */ | ||
2733 | #define WM2200_GP3_EINT 0x0004 /* GP3_EINT */ | ||
2734 | #define WM2200_GP3_EINT_MASK 0x0004 /* GP3_EINT */ | ||
2735 | #define WM2200_GP3_EINT_SHIFT 2 /* GP3_EINT */ | ||
2736 | #define WM2200_GP3_EINT_WIDTH 1 /* GP3_EINT */ | ||
2737 | #define WM2200_GP2_EINT 0x0002 /* GP2_EINT */ | ||
2738 | #define WM2200_GP2_EINT_MASK 0x0002 /* GP2_EINT */ | ||
2739 | #define WM2200_GP2_EINT_SHIFT 1 /* GP2_EINT */ | ||
2740 | #define WM2200_GP2_EINT_WIDTH 1 /* GP2_EINT */ | ||
2741 | #define WM2200_GP1_EINT 0x0001 /* GP1_EINT */ | ||
2742 | #define WM2200_GP1_EINT_MASK 0x0001 /* GP1_EINT */ | ||
2743 | #define WM2200_GP1_EINT_SHIFT 0 /* GP1_EINT */ | ||
2744 | #define WM2200_GP1_EINT_WIDTH 1 /* GP1_EINT */ | ||
2745 | |||
2746 | /* | ||
2747 | * R2049 (0x801) - Interrupt Status 1 Mask | ||
2748 | */ | ||
2749 | #define WM2200_IM_DSP_IRQ0_EINT 0x0080 /* IM_DSP_IRQ0_EINT */ | ||
2750 | #define WM2200_IM_DSP_IRQ0_EINT_MASK 0x0080 /* IM_DSP_IRQ0_EINT */ | ||
2751 | #define WM2200_IM_DSP_IRQ0_EINT_SHIFT 7 /* IM_DSP_IRQ0_EINT */ | ||
2752 | #define WM2200_IM_DSP_IRQ0_EINT_WIDTH 1 /* IM_DSP_IRQ0_EINT */ | ||
2753 | #define WM2200_IM_DSP_IRQ1_EINT 0x0040 /* IM_DSP_IRQ1_EINT */ | ||
2754 | #define WM2200_IM_DSP_IRQ1_EINT_MASK 0x0040 /* IM_DSP_IRQ1_EINT */ | ||
2755 | #define WM2200_IM_DSP_IRQ1_EINT_SHIFT 6 /* IM_DSP_IRQ1_EINT */ | ||
2756 | #define WM2200_IM_DSP_IRQ1_EINT_WIDTH 1 /* IM_DSP_IRQ1_EINT */ | ||
2757 | #define WM2200_IM_DSP_IRQ2_EINT 0x0020 /* IM_DSP_IRQ2_EINT */ | ||
2758 | #define WM2200_IM_DSP_IRQ2_EINT_MASK 0x0020 /* IM_DSP_IRQ2_EINT */ | ||
2759 | #define WM2200_IM_DSP_IRQ2_EINT_SHIFT 5 /* IM_DSP_IRQ2_EINT */ | ||
2760 | #define WM2200_IM_DSP_IRQ2_EINT_WIDTH 1 /* IM_DSP_IRQ2_EINT */ | ||
2761 | #define WM2200_IM_DSP_IRQ3_EINT 0x0010 /* IM_DSP_IRQ3_EINT */ | ||
2762 | #define WM2200_IM_DSP_IRQ3_EINT_MASK 0x0010 /* IM_DSP_IRQ3_EINT */ | ||
2763 | #define WM2200_IM_DSP_IRQ3_EINT_SHIFT 4 /* IM_DSP_IRQ3_EINT */ | ||
2764 | #define WM2200_IM_DSP_IRQ3_EINT_WIDTH 1 /* IM_DSP_IRQ3_EINT */ | ||
2765 | #define WM2200_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */ | ||
2766 | #define WM2200_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */ | ||
2767 | #define WM2200_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */ | ||
2768 | #define WM2200_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */ | ||
2769 | #define WM2200_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */ | ||
2770 | #define WM2200_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */ | ||
2771 | #define WM2200_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */ | ||
2772 | #define WM2200_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */ | ||
2773 | #define WM2200_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */ | ||
2774 | #define WM2200_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */ | ||
2775 | #define WM2200_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */ | ||
2776 | #define WM2200_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */ | ||
2777 | #define WM2200_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */ | ||
2778 | #define WM2200_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */ | ||
2779 | #define WM2200_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */ | ||
2780 | #define WM2200_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */ | ||
2781 | |||
2782 | /* | ||
2783 | * R2050 (0x802) - Interrupt Status 2 | ||
2784 | */ | ||
2785 | #define WM2200_WSEQ_BUSY_EINT 0x0100 /* WSEQ_BUSY_EINT */ | ||
2786 | #define WM2200_WSEQ_BUSY_EINT_MASK 0x0100 /* WSEQ_BUSY_EINT */ | ||
2787 | #define WM2200_WSEQ_BUSY_EINT_SHIFT 8 /* WSEQ_BUSY_EINT */ | ||
2788 | #define WM2200_WSEQ_BUSY_EINT_WIDTH 1 /* WSEQ_BUSY_EINT */ | ||
2789 | #define WM2200_FLL_LOCK_EINT 0x0002 /* FLL_LOCK_EINT */ | ||
2790 | #define WM2200_FLL_LOCK_EINT_MASK 0x0002 /* FLL_LOCK_EINT */ | ||
2791 | #define WM2200_FLL_LOCK_EINT_SHIFT 1 /* FLL_LOCK_EINT */ | ||
2792 | #define WM2200_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */ | ||
2793 | #define WM2200_CLKGEN_EINT 0x0001 /* CLKGEN_EINT */ | ||
2794 | #define WM2200_CLKGEN_EINT_MASK 0x0001 /* CLKGEN_EINT */ | ||
2795 | #define WM2200_CLKGEN_EINT_SHIFT 0 /* CLKGEN_EINT */ | ||
2796 | #define WM2200_CLKGEN_EINT_WIDTH 1 /* CLKGEN_EINT */ | ||
2797 | |||
2798 | /* | ||
2799 | * R2051 (0x803) - Interrupt Raw Status 2 | ||
2800 | */ | ||
2801 | #define WM2200_WSEQ_BUSY_STS 0x0100 /* WSEQ_BUSY_STS */ | ||
2802 | #define WM2200_WSEQ_BUSY_STS_MASK 0x0100 /* WSEQ_BUSY_STS */ | ||
2803 | #define WM2200_WSEQ_BUSY_STS_SHIFT 8 /* WSEQ_BUSY_STS */ | ||
2804 | #define WM2200_WSEQ_BUSY_STS_WIDTH 1 /* WSEQ_BUSY_STS */ | ||
2805 | #define WM2200_FLL_LOCK_STS 0x0002 /* FLL_LOCK_STS */ | ||
2806 | #define WM2200_FLL_LOCK_STS_MASK 0x0002 /* FLL_LOCK_STS */ | ||
2807 | #define WM2200_FLL_LOCK_STS_SHIFT 1 /* FLL_LOCK_STS */ | ||
2808 | #define WM2200_FLL_LOCK_STS_WIDTH 1 /* FLL_LOCK_STS */ | ||
2809 | #define WM2200_CLKGEN_STS 0x0001 /* CLKGEN_STS */ | ||
2810 | #define WM2200_CLKGEN_STS_MASK 0x0001 /* CLKGEN_STS */ | ||
2811 | #define WM2200_CLKGEN_STS_SHIFT 0 /* CLKGEN_STS */ | ||
2812 | #define WM2200_CLKGEN_STS_WIDTH 1 /* CLKGEN_STS */ | ||
2813 | |||
2814 | /* | ||
2815 | * R2052 (0x804) - Interrupt Status 2 Mask | ||
2816 | */ | ||
2817 | #define WM2200_IM_WSEQ_BUSY_EINT 0x0100 /* IM_WSEQ_BUSY_EINT */ | ||
2818 | #define WM2200_IM_WSEQ_BUSY_EINT_MASK 0x0100 /* IM_WSEQ_BUSY_EINT */ | ||
2819 | #define WM2200_IM_WSEQ_BUSY_EINT_SHIFT 8 /* IM_WSEQ_BUSY_EINT */ | ||
2820 | #define WM2200_IM_WSEQ_BUSY_EINT_WIDTH 1 /* IM_WSEQ_BUSY_EINT */ | ||
2821 | #define WM2200_IM_FLL_LOCK_EINT 0x0002 /* IM_FLL_LOCK_EINT */ | ||
2822 | #define WM2200_IM_FLL_LOCK_EINT_MASK 0x0002 /* IM_FLL_LOCK_EINT */ | ||
2823 | #define WM2200_IM_FLL_LOCK_EINT_SHIFT 1 /* IM_FLL_LOCK_EINT */ | ||
2824 | #define WM2200_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */ | ||
2825 | #define WM2200_IM_CLKGEN_EINT 0x0001 /* IM_CLKGEN_EINT */ | ||
2826 | #define WM2200_IM_CLKGEN_EINT_MASK 0x0001 /* IM_CLKGEN_EINT */ | ||
2827 | #define WM2200_IM_CLKGEN_EINT_SHIFT 0 /* IM_CLKGEN_EINT */ | ||
2828 | #define WM2200_IM_CLKGEN_EINT_WIDTH 1 /* IM_CLKGEN_EINT */ | ||
2829 | |||
2830 | /* | ||
2831 | * R2056 (0x808) - Interrupt Control | ||
2832 | */ | ||
2833 | #define WM2200_IM_IRQ 0x0001 /* IM_IRQ */ | ||
2834 | #define WM2200_IM_IRQ_MASK 0x0001 /* IM_IRQ */ | ||
2835 | #define WM2200_IM_IRQ_SHIFT 0 /* IM_IRQ */ | ||
2836 | #define WM2200_IM_IRQ_WIDTH 1 /* IM_IRQ */ | ||
2837 | |||
2838 | /* | ||
2839 | * R2304 (0x900) - EQL_1 | ||
2840 | */ | ||
2841 | #define WM2200_EQL_B1_GAIN_MASK 0xF800 /* EQL_B1_GAIN - [15:11] */ | ||
2842 | #define WM2200_EQL_B1_GAIN_SHIFT 11 /* EQL_B1_GAIN - [15:11] */ | ||
2843 | #define WM2200_EQL_B1_GAIN_WIDTH 5 /* EQL_B1_GAIN - [15:11] */ | ||
2844 | #define WM2200_EQL_B2_GAIN_MASK 0x07C0 /* EQL_B2_GAIN - [10:6] */ | ||
2845 | #define WM2200_EQL_B2_GAIN_SHIFT 6 /* EQL_B2_GAIN - [10:6] */ | ||
2846 | #define WM2200_EQL_B2_GAIN_WIDTH 5 /* EQL_B2_GAIN - [10:6] */ | ||
2847 | #define WM2200_EQL_B3_GAIN_MASK 0x003E /* EQL_B3_GAIN - [5:1] */ | ||
2848 | #define WM2200_EQL_B3_GAIN_SHIFT 1 /* EQL_B3_GAIN - [5:1] */ | ||
2849 | #define WM2200_EQL_B3_GAIN_WIDTH 5 /* EQL_B3_GAIN - [5:1] */ | ||
2850 | #define WM2200_EQL_ENA 0x0001 /* EQL_ENA */ | ||
2851 | #define WM2200_EQL_ENA_MASK 0x0001 /* EQL_ENA */ | ||
2852 | #define WM2200_EQL_ENA_SHIFT 0 /* EQL_ENA */ | ||
2853 | #define WM2200_EQL_ENA_WIDTH 1 /* EQL_ENA */ | ||
2854 | |||
2855 | /* | ||
2856 | * R2305 (0x901) - EQL_2 | ||
2857 | */ | ||
2858 | #define WM2200_EQL_B4_GAIN_MASK 0xF800 /* EQL_B4_GAIN - [15:11] */ | ||
2859 | #define WM2200_EQL_B4_GAIN_SHIFT 11 /* EQL_B4_GAIN - [15:11] */ | ||
2860 | #define WM2200_EQL_B4_GAIN_WIDTH 5 /* EQL_B4_GAIN - [15:11] */ | ||
2861 | #define WM2200_EQL_B5_GAIN_MASK 0x07C0 /* EQL_B5_GAIN - [10:6] */ | ||
2862 | #define WM2200_EQL_B5_GAIN_SHIFT 6 /* EQL_B5_GAIN - [10:6] */ | ||
2863 | #define WM2200_EQL_B5_GAIN_WIDTH 5 /* EQL_B5_GAIN - [10:6] */ | ||
2864 | |||
2865 | /* | ||
2866 | * R2306 (0x902) - EQL_3 | ||
2867 | */ | ||
2868 | #define WM2200_EQL_B1_A_MASK 0xFFFF /* EQL_B1_A - [15:0] */ | ||
2869 | #define WM2200_EQL_B1_A_SHIFT 0 /* EQL_B1_A - [15:0] */ | ||
2870 | #define WM2200_EQL_B1_A_WIDTH 16 /* EQL_B1_A - [15:0] */ | ||
2871 | |||
2872 | /* | ||
2873 | * R2307 (0x903) - EQL_4 | ||
2874 | */ | ||
2875 | #define WM2200_EQL_B1_B_MASK 0xFFFF /* EQL_B1_B - [15:0] */ | ||
2876 | #define WM2200_EQL_B1_B_SHIFT 0 /* EQL_B1_B - [15:0] */ | ||
2877 | #define WM2200_EQL_B1_B_WIDTH 16 /* EQL_B1_B - [15:0] */ | ||
2878 | |||
2879 | /* | ||
2880 | * R2308 (0x904) - EQL_5 | ||
2881 | */ | ||
2882 | #define WM2200_EQL_B1_PG_MASK 0xFFFF /* EQL_B1_PG - [15:0] */ | ||
2883 | #define WM2200_EQL_B1_PG_SHIFT 0 /* EQL_B1_PG - [15:0] */ | ||
2884 | #define WM2200_EQL_B1_PG_WIDTH 16 /* EQL_B1_PG - [15:0] */ | ||
2885 | |||
2886 | /* | ||
2887 | * R2309 (0x905) - EQL_6 | ||
2888 | */ | ||
2889 | #define WM2200_EQL_B2_A_MASK 0xFFFF /* EQL_B2_A - [15:0] */ | ||
2890 | #define WM2200_EQL_B2_A_SHIFT 0 /* EQL_B2_A - [15:0] */ | ||
2891 | #define WM2200_EQL_B2_A_WIDTH 16 /* EQL_B2_A - [15:0] */ | ||
2892 | |||
2893 | /* | ||
2894 | * R2310 (0x906) - EQL_7 | ||
2895 | */ | ||
2896 | #define WM2200_EQL_B2_B_MASK 0xFFFF /* EQL_B2_B - [15:0] */ | ||
2897 | #define WM2200_EQL_B2_B_SHIFT 0 /* EQL_B2_B - [15:0] */ | ||
2898 | #define WM2200_EQL_B2_B_WIDTH 16 /* EQL_B2_B - [15:0] */ | ||
2899 | |||
2900 | /* | ||
2901 | * R2311 (0x907) - EQL_8 | ||
2902 | */ | ||
2903 | #define WM2200_EQL_B2_C_MASK 0xFFFF /* EQL_B2_C - [15:0] */ | ||
2904 | #define WM2200_EQL_B2_C_SHIFT 0 /* EQL_B2_C - [15:0] */ | ||
2905 | #define WM2200_EQL_B2_C_WIDTH 16 /* EQL_B2_C - [15:0] */ | ||
2906 | |||
2907 | /* | ||
2908 | * R2312 (0x908) - EQL_9 | ||
2909 | */ | ||
2910 | #define WM2200_EQL_B2_PG_MASK 0xFFFF /* EQL_B2_PG - [15:0] */ | ||
2911 | #define WM2200_EQL_B2_PG_SHIFT 0 /* EQL_B2_PG - [15:0] */ | ||
2912 | #define WM2200_EQL_B2_PG_WIDTH 16 /* EQL_B2_PG - [15:0] */ | ||
2913 | |||
2914 | /* | ||
2915 | * R2313 (0x909) - EQL_10 | ||
2916 | */ | ||
2917 | #define WM2200_EQL_B3_A_MASK 0xFFFF /* EQL_B3_A - [15:0] */ | ||
2918 | #define WM2200_EQL_B3_A_SHIFT 0 /* EQL_B3_A - [15:0] */ | ||
2919 | #define WM2200_EQL_B3_A_WIDTH 16 /* EQL_B3_A - [15:0] */ | ||
2920 | |||
2921 | /* | ||
2922 | * R2314 (0x90A) - EQL_11 | ||
2923 | */ | ||
2924 | #define WM2200_EQL_B3_B_MASK 0xFFFF /* EQL_B3_B - [15:0] */ | ||
2925 | #define WM2200_EQL_B3_B_SHIFT 0 /* EQL_B3_B - [15:0] */ | ||
2926 | #define WM2200_EQL_B3_B_WIDTH 16 /* EQL_B3_B - [15:0] */ | ||
2927 | |||
2928 | /* | ||
2929 | * R2315 (0x90B) - EQL_12 | ||
2930 | */ | ||
2931 | #define WM2200_EQL_B3_C_MASK 0xFFFF /* EQL_B3_C - [15:0] */ | ||
2932 | #define WM2200_EQL_B3_C_SHIFT 0 /* EQL_B3_C - [15:0] */ | ||
2933 | #define WM2200_EQL_B3_C_WIDTH 16 /* EQL_B3_C - [15:0] */ | ||
2934 | |||
2935 | /* | ||
2936 | * R2316 (0x90C) - EQL_13 | ||
2937 | */ | ||
2938 | #define WM2200_EQL_B3_PG_MASK 0xFFFF /* EQL_B3_PG - [15:0] */ | ||
2939 | #define WM2200_EQL_B3_PG_SHIFT 0 /* EQL_B3_PG - [15:0] */ | ||
2940 | #define WM2200_EQL_B3_PG_WIDTH 16 /* EQL_B3_PG - [15:0] */ | ||
2941 | |||
2942 | /* | ||
2943 | * R2317 (0x90D) - EQL_14 | ||
2944 | */ | ||
2945 | #define WM2200_EQL_B4_A_MASK 0xFFFF /* EQL_B4_A - [15:0] */ | ||
2946 | #define WM2200_EQL_B4_A_SHIFT 0 /* EQL_B4_A - [15:0] */ | ||
2947 | #define WM2200_EQL_B4_A_WIDTH 16 /* EQL_B4_A - [15:0] */ | ||
2948 | |||
2949 | /* | ||
2950 | * R2318 (0x90E) - EQL_15 | ||
2951 | */ | ||
2952 | #define WM2200_EQL_B4_B_MASK 0xFFFF /* EQL_B4_B - [15:0] */ | ||
2953 | #define WM2200_EQL_B4_B_SHIFT 0 /* EQL_B4_B - [15:0] */ | ||
2954 | #define WM2200_EQL_B4_B_WIDTH 16 /* EQL_B4_B - [15:0] */ | ||
2955 | |||
2956 | /* | ||
2957 | * R2319 (0x90F) - EQL_16 | ||
2958 | */ | ||
2959 | #define WM2200_EQL_B4_C_MASK 0xFFFF /* EQL_B4_C - [15:0] */ | ||
2960 | #define WM2200_EQL_B4_C_SHIFT 0 /* EQL_B4_C - [15:0] */ | ||
2961 | #define WM2200_EQL_B4_C_WIDTH 16 /* EQL_B4_C - [15:0] */ | ||
2962 | |||
2963 | /* | ||
2964 | * R2320 (0x910) - EQL_17 | ||
2965 | */ | ||
2966 | #define WM2200_EQL_B4_PG_MASK 0xFFFF /* EQL_B4_PG - [15:0] */ | ||
2967 | #define WM2200_EQL_B4_PG_SHIFT 0 /* EQL_B4_PG - [15:0] */ | ||
2968 | #define WM2200_EQL_B4_PG_WIDTH 16 /* EQL_B4_PG - [15:0] */ | ||
2969 | |||
2970 | /* | ||
2971 | * R2321 (0x911) - EQL_18 | ||
2972 | */ | ||
2973 | #define WM2200_EQL_B5_A_MASK 0xFFFF /* EQL_B5_A - [15:0] */ | ||
2974 | #define WM2200_EQL_B5_A_SHIFT 0 /* EQL_B5_A - [15:0] */ | ||
2975 | #define WM2200_EQL_B5_A_WIDTH 16 /* EQL_B5_A - [15:0] */ | ||
2976 | |||
2977 | /* | ||
2978 | * R2322 (0x912) - EQL_19 | ||
2979 | */ | ||
2980 | #define WM2200_EQL_B5_B_MASK 0xFFFF /* EQL_B5_B - [15:0] */ | ||
2981 | #define WM2200_EQL_B5_B_SHIFT 0 /* EQL_B5_B - [15:0] */ | ||
2982 | #define WM2200_EQL_B5_B_WIDTH 16 /* EQL_B5_B - [15:0] */ | ||
2983 | |||
2984 | /* | ||
2985 | * R2323 (0x913) - EQL_20 | ||
2986 | */ | ||
2987 | #define WM2200_EQL_B5_PG_MASK 0xFFFF /* EQL_B5_PG - [15:0] */ | ||
2988 | #define WM2200_EQL_B5_PG_SHIFT 0 /* EQL_B5_PG - [15:0] */ | ||
2989 | #define WM2200_EQL_B5_PG_WIDTH 16 /* EQL_B5_PG - [15:0] */ | ||
2990 | |||
2991 | /* | ||
2992 | * R2326 (0x916) - EQR_1 | ||
2993 | */ | ||
2994 | #define WM2200_EQR_B1_GAIN_MASK 0xF800 /* EQR_B1_GAIN - [15:11] */ | ||
2995 | #define WM2200_EQR_B1_GAIN_SHIFT 11 /* EQR_B1_GAIN - [15:11] */ | ||
2996 | #define WM2200_EQR_B1_GAIN_WIDTH 5 /* EQR_B1_GAIN - [15:11] */ | ||
2997 | #define WM2200_EQR_B2_GAIN_MASK 0x07C0 /* EQR_B2_GAIN - [10:6] */ | ||
2998 | #define WM2200_EQR_B2_GAIN_SHIFT 6 /* EQR_B2_GAIN - [10:6] */ | ||
2999 | #define WM2200_EQR_B2_GAIN_WIDTH 5 /* EQR_B2_GAIN - [10:6] */ | ||
3000 | #define WM2200_EQR_B3_GAIN_MASK 0x003E /* EQR_B3_GAIN - [5:1] */ | ||
3001 | #define WM2200_EQR_B3_GAIN_SHIFT 1 /* EQR_B3_GAIN - [5:1] */ | ||
3002 | #define WM2200_EQR_B3_GAIN_WIDTH 5 /* EQR_B3_GAIN - [5:1] */ | ||
3003 | #define WM2200_EQR_ENA 0x0001 /* EQR_ENA */ | ||
3004 | #define WM2200_EQR_ENA_MASK 0x0001 /* EQR_ENA */ | ||
3005 | #define WM2200_EQR_ENA_SHIFT 0 /* EQR_ENA */ | ||
3006 | #define WM2200_EQR_ENA_WIDTH 1 /* EQR_ENA */ | ||
3007 | |||
3008 | /* | ||
3009 | * R2327 (0x917) - EQR_2 | ||
3010 | */ | ||
3011 | #define WM2200_EQR_B4_GAIN_MASK 0xF800 /* EQR_B4_GAIN - [15:11] */ | ||
3012 | #define WM2200_EQR_B4_GAIN_SHIFT 11 /* EQR_B4_GAIN - [15:11] */ | ||
3013 | #define WM2200_EQR_B4_GAIN_WIDTH 5 /* EQR_B4_GAIN - [15:11] */ | ||
3014 | #define WM2200_EQR_B5_GAIN_MASK 0x07C0 /* EQR_B5_GAIN - [10:6] */ | ||
3015 | #define WM2200_EQR_B5_GAIN_SHIFT 6 /* EQR_B5_GAIN - [10:6] */ | ||
3016 | #define WM2200_EQR_B5_GAIN_WIDTH 5 /* EQR_B5_GAIN - [10:6] */ | ||
3017 | |||
3018 | /* | ||
3019 | * R2328 (0x918) - EQR_3 | ||
3020 | */ | ||
3021 | #define WM2200_EQR_B1_A_MASK 0xFFFF /* EQR_B1_A - [15:0] */ | ||
3022 | #define WM2200_EQR_B1_A_SHIFT 0 /* EQR_B1_A - [15:0] */ | ||
3023 | #define WM2200_EQR_B1_A_WIDTH 16 /* EQR_B1_A - [15:0] */ | ||
3024 | |||
3025 | /* | ||
3026 | * R2329 (0x919) - EQR_4 | ||
3027 | */ | ||
3028 | #define WM2200_EQR_B1_B_MASK 0xFFFF /* EQR_B1_B - [15:0] */ | ||
3029 | #define WM2200_EQR_B1_B_SHIFT 0 /* EQR_B1_B - [15:0] */ | ||
3030 | #define WM2200_EQR_B1_B_WIDTH 16 /* EQR_B1_B - [15:0] */ | ||
3031 | |||
3032 | /* | ||
3033 | * R2330 (0x91A) - EQR_5 | ||
3034 | */ | ||
3035 | #define WM2200_EQR_B1_PG_MASK 0xFFFF /* EQR_B1_PG - [15:0] */ | ||
3036 | #define WM2200_EQR_B1_PG_SHIFT 0 /* EQR_B1_PG - [15:0] */ | ||
3037 | #define WM2200_EQR_B1_PG_WIDTH 16 /* EQR_B1_PG - [15:0] */ | ||
3038 | |||
3039 | /* | ||
3040 | * R2331 (0x91B) - EQR_6 | ||
3041 | */ | ||
3042 | #define WM2200_EQR_B2_A_MASK 0xFFFF /* EQR_B2_A - [15:0] */ | ||
3043 | #define WM2200_EQR_B2_A_SHIFT 0 /* EQR_B2_A - [15:0] */ | ||
3044 | #define WM2200_EQR_B2_A_WIDTH 16 /* EQR_B2_A - [15:0] */ | ||
3045 | |||
3046 | /* | ||
3047 | * R2332 (0x91C) - EQR_7 | ||
3048 | */ | ||
3049 | #define WM2200_EQR_B2_B_MASK 0xFFFF /* EQR_B2_B - [15:0] */ | ||
3050 | #define WM2200_EQR_B2_B_SHIFT 0 /* EQR_B2_B - [15:0] */ | ||
3051 | #define WM2200_EQR_B2_B_WIDTH 16 /* EQR_B2_B - [15:0] */ | ||
3052 | |||
3053 | /* | ||
3054 | * R2333 (0x91D) - EQR_8 | ||
3055 | */ | ||
3056 | #define WM2200_EQR_B2_C_MASK 0xFFFF /* EQR_B2_C - [15:0] */ | ||
3057 | #define WM2200_EQR_B2_C_SHIFT 0 /* EQR_B2_C - [15:0] */ | ||
3058 | #define WM2200_EQR_B2_C_WIDTH 16 /* EQR_B2_C - [15:0] */ | ||
3059 | |||
3060 | /* | ||
3061 | * R2334 (0x91E) - EQR_9 | ||
3062 | */ | ||
3063 | #define WM2200_EQR_B2_PG_MASK 0xFFFF /* EQR_B2_PG - [15:0] */ | ||
3064 | #define WM2200_EQR_B2_PG_SHIFT 0 /* EQR_B2_PG - [15:0] */ | ||
3065 | #define WM2200_EQR_B2_PG_WIDTH 16 /* EQR_B2_PG - [15:0] */ | ||
3066 | |||
3067 | /* | ||
3068 | * R2335 (0x91F) - EQR_10 | ||
3069 | */ | ||
3070 | #define WM2200_EQR_B3_A_MASK 0xFFFF /* EQR_B3_A - [15:0] */ | ||
3071 | #define WM2200_EQR_B3_A_SHIFT 0 /* EQR_B3_A - [15:0] */ | ||
3072 | #define WM2200_EQR_B3_A_WIDTH 16 /* EQR_B3_A - [15:0] */ | ||
3073 | |||
3074 | /* | ||
3075 | * R2336 (0x920) - EQR_11 | ||
3076 | */ | ||
3077 | #define WM2200_EQR_B3_B_MASK 0xFFFF /* EQR_B3_B - [15:0] */ | ||
3078 | #define WM2200_EQR_B3_B_SHIFT 0 /* EQR_B3_B - [15:0] */ | ||
3079 | #define WM2200_EQR_B3_B_WIDTH 16 /* EQR_B3_B - [15:0] */ | ||
3080 | |||
3081 | /* | ||
3082 | * R2337 (0x921) - EQR_12 | ||
3083 | */ | ||
3084 | #define WM2200_EQR_B3_C_MASK 0xFFFF /* EQR_B3_C - [15:0] */ | ||
3085 | #define WM2200_EQR_B3_C_SHIFT 0 /* EQR_B3_C - [15:0] */ | ||
3086 | #define WM2200_EQR_B3_C_WIDTH 16 /* EQR_B3_C - [15:0] */ | ||
3087 | |||
3088 | /* | ||
3089 | * R2338 (0x922) - EQR_13 | ||
3090 | */ | ||
3091 | #define WM2200_EQR_B3_PG_MASK 0xFFFF /* EQR_B3_PG - [15:0] */ | ||
3092 | #define WM2200_EQR_B3_PG_SHIFT 0 /* EQR_B3_PG - [15:0] */ | ||
3093 | #define WM2200_EQR_B3_PG_WIDTH 16 /* EQR_B3_PG - [15:0] */ | ||
3094 | |||
3095 | /* | ||
3096 | * R2339 (0x923) - EQR_14 | ||
3097 | */ | ||
3098 | #define WM2200_EQR_B4_A_MASK 0xFFFF /* EQR_B4_A - [15:0] */ | ||
3099 | #define WM2200_EQR_B4_A_SHIFT 0 /* EQR_B4_A - [15:0] */ | ||
3100 | #define WM2200_EQR_B4_A_WIDTH 16 /* EQR_B4_A - [15:0] */ | ||
3101 | |||
3102 | /* | ||
3103 | * R2340 (0x924) - EQR_15 | ||
3104 | */ | ||
3105 | #define WM2200_EQR_B4_B_MASK 0xFFFF /* EQR_B4_B - [15:0] */ | ||
3106 | #define WM2200_EQR_B4_B_SHIFT 0 /* EQR_B4_B - [15:0] */ | ||
3107 | #define WM2200_EQR_B4_B_WIDTH 16 /* EQR_B4_B - [15:0] */ | ||
3108 | |||
3109 | /* | ||
3110 | * R2341 (0x925) - EQR_16 | ||
3111 | */ | ||
3112 | #define WM2200_EQR_B4_C_MASK 0xFFFF /* EQR_B4_C - [15:0] */ | ||
3113 | #define WM2200_EQR_B4_C_SHIFT 0 /* EQR_B4_C - [15:0] */ | ||
3114 | #define WM2200_EQR_B4_C_WIDTH 16 /* EQR_B4_C - [15:0] */ | ||
3115 | |||
3116 | /* | ||
3117 | * R2342 (0x926) - EQR_17 | ||
3118 | */ | ||
3119 | #define WM2200_EQR_B4_PG_MASK 0xFFFF /* EQR_B4_PG - [15:0] */ | ||
3120 | #define WM2200_EQR_B4_PG_SHIFT 0 /* EQR_B4_PG - [15:0] */ | ||
3121 | #define WM2200_EQR_B4_PG_WIDTH 16 /* EQR_B4_PG - [15:0] */ | ||
3122 | |||
3123 | /* | ||
3124 | * R2343 (0x927) - EQR_18 | ||
3125 | */ | ||
3126 | #define WM2200_EQR_B5_A_MASK 0xFFFF /* EQR_B5_A - [15:0] */ | ||
3127 | #define WM2200_EQR_B5_A_SHIFT 0 /* EQR_B5_A - [15:0] */ | ||
3128 | #define WM2200_EQR_B5_A_WIDTH 16 /* EQR_B5_A - [15:0] */ | ||
3129 | |||
3130 | /* | ||
3131 | * R2344 (0x928) - EQR_19 | ||
3132 | */ | ||
3133 | #define WM2200_EQR_B5_B_MASK 0xFFFF /* EQR_B5_B - [15:0] */ | ||
3134 | #define WM2200_EQR_B5_B_SHIFT 0 /* EQR_B5_B - [15:0] */ | ||
3135 | #define WM2200_EQR_B5_B_WIDTH 16 /* EQR_B5_B - [15:0] */ | ||
3136 | |||
3137 | /* | ||
3138 | * R2345 (0x929) - EQR_20 | ||
3139 | */ | ||
3140 | #define WM2200_EQR_B5_PG_MASK 0xFFFF /* EQR_B5_PG - [15:0] */ | ||
3141 | #define WM2200_EQR_B5_PG_SHIFT 0 /* EQR_B5_PG - [15:0] */ | ||
3142 | #define WM2200_EQR_B5_PG_WIDTH 16 /* EQR_B5_PG - [15:0] */ | ||
3143 | |||
3144 | /* | ||
3145 | * R2366 (0x93E) - HPLPF1_1 | ||
3146 | */ | ||
3147 | #define WM2200_LHPF1_MODE 0x0002 /* LHPF1_MODE */ | ||
3148 | #define WM2200_LHPF1_MODE_MASK 0x0002 /* LHPF1_MODE */ | ||
3149 | #define WM2200_LHPF1_MODE_SHIFT 1 /* LHPF1_MODE */ | ||
3150 | #define WM2200_LHPF1_MODE_WIDTH 1 /* LHPF1_MODE */ | ||
3151 | #define WM2200_LHPF1_ENA 0x0001 /* LHPF1_ENA */ | ||
3152 | #define WM2200_LHPF1_ENA_MASK 0x0001 /* LHPF1_ENA */ | ||
3153 | #define WM2200_LHPF1_ENA_SHIFT 0 /* LHPF1_ENA */ | ||
3154 | #define WM2200_LHPF1_ENA_WIDTH 1 /* LHPF1_ENA */ | ||
3155 | |||
3156 | /* | ||
3157 | * R2367 (0x93F) - HPLPF1_2 | ||
3158 | */ | ||
3159 | #define WM2200_LHPF1_COEFF_MASK 0xFFFF /* LHPF1_COEFF - [15:0] */ | ||
3160 | #define WM2200_LHPF1_COEFF_SHIFT 0 /* LHPF1_COEFF - [15:0] */ | ||
3161 | #define WM2200_LHPF1_COEFF_WIDTH 16 /* LHPF1_COEFF - [15:0] */ | ||
3162 | |||
3163 | /* | ||
3164 | * R2370 (0x942) - HPLPF2_1 | ||
3165 | */ | ||
3166 | #define WM2200_LHPF2_MODE 0x0002 /* LHPF2_MODE */ | ||
3167 | #define WM2200_LHPF2_MODE_MASK 0x0002 /* LHPF2_MODE */ | ||
3168 | #define WM2200_LHPF2_MODE_SHIFT 1 /* LHPF2_MODE */ | ||
3169 | #define WM2200_LHPF2_MODE_WIDTH 1 /* LHPF2_MODE */ | ||
3170 | #define WM2200_LHPF2_ENA 0x0001 /* LHPF2_ENA */ | ||
3171 | #define WM2200_LHPF2_ENA_MASK 0x0001 /* LHPF2_ENA */ | ||
3172 | #define WM2200_LHPF2_ENA_SHIFT 0 /* LHPF2_ENA */ | ||
3173 | #define WM2200_LHPF2_ENA_WIDTH 1 /* LHPF2_ENA */ | ||
3174 | |||
3175 | /* | ||
3176 | * R2371 (0x943) - HPLPF2_2 | ||
3177 | */ | ||
3178 | #define WM2200_LHPF2_COEFF_MASK 0xFFFF /* LHPF2_COEFF - [15:0] */ | ||
3179 | #define WM2200_LHPF2_COEFF_SHIFT 0 /* LHPF2_COEFF - [15:0] */ | ||
3180 | #define WM2200_LHPF2_COEFF_WIDTH 16 /* LHPF2_COEFF - [15:0] */ | ||
3181 | |||
3182 | /* | ||
3183 | * R2560 (0xA00) - DSP1 Control 1 | ||
3184 | */ | ||
3185 | #define WM2200_DSP1_RW_SEQUENCE_ENA 0x0001 /* DSP1_RW_SEQUENCE_ENA */ | ||
3186 | #define WM2200_DSP1_RW_SEQUENCE_ENA_MASK 0x0001 /* DSP1_RW_SEQUENCE_ENA */ | ||
3187 | #define WM2200_DSP1_RW_SEQUENCE_ENA_SHIFT 0 /* DSP1_RW_SEQUENCE_ENA */ | ||
3188 | #define WM2200_DSP1_RW_SEQUENCE_ENA_WIDTH 1 /* DSP1_RW_SEQUENCE_ENA */ | ||
3189 | |||
3190 | /* | ||
3191 | * R2562 (0xA02) - DSP1 Control 2 | ||
3192 | */ | ||
3193 | #define WM2200_DSP1_PAGE_BASE_PM_0_MASK 0xFF00 /* DSP1_PAGE_BASE_PM - [15:8] */ | ||
3194 | #define WM2200_DSP1_PAGE_BASE_PM_0_SHIFT 8 /* DSP1_PAGE_BASE_PM - [15:8] */ | ||
3195 | #define WM2200_DSP1_PAGE_BASE_PM_0_WIDTH 8 /* DSP1_PAGE_BASE_PM - [15:8] */ | ||
3196 | |||
3197 | /* | ||
3198 | * R2563 (0xA03) - DSP1 Control 3 | ||
3199 | */ | ||
3200 | #define WM2200_DSP1_PAGE_BASE_DM_0_MASK 0xFF00 /* DSP1_PAGE_BASE_DM - [15:8] */ | ||
3201 | #define WM2200_DSP1_PAGE_BASE_DM_0_SHIFT 8 /* DSP1_PAGE_BASE_DM - [15:8] */ | ||
3202 | #define WM2200_DSP1_PAGE_BASE_DM_0_WIDTH 8 /* DSP1_PAGE_BASE_DM - [15:8] */ | ||
3203 | |||
3204 | /* | ||
3205 | * R2564 (0xA04) - DSP1 Control 4 | ||
3206 | */ | ||
3207 | #define WM2200_DSP1_PAGE_BASE_ZM_0_MASK 0xFF00 /* DSP1_PAGE_BASE_ZM - [15:8] */ | ||
3208 | #define WM2200_DSP1_PAGE_BASE_ZM_0_SHIFT 8 /* DSP1_PAGE_BASE_ZM - [15:8] */ | ||
3209 | #define WM2200_DSP1_PAGE_BASE_ZM_0_WIDTH 8 /* DSP1_PAGE_BASE_ZM - [15:8] */ | ||
3210 | |||
3211 | /* | ||
3212 | * R2566 (0xA06) - DSP1 Control 5 | ||
3213 | */ | ||
3214 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */ | ||
3215 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */ | ||
3216 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_0_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */ | ||
3217 | |||
3218 | /* | ||
3219 | * R2567 (0xA07) - DSP1 Control 6 | ||
3220 | */ | ||
3221 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */ | ||
3222 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */ | ||
3223 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_1_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */ | ||
3224 | |||
3225 | /* | ||
3226 | * R2568 (0xA08) - DSP1 Control 7 | ||
3227 | */ | ||
3228 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */ | ||
3229 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */ | ||
3230 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_2_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */ | ||
3231 | |||
3232 | /* | ||
3233 | * R2569 (0xA09) - DSP1 Control 8 | ||
3234 | */ | ||
3235 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */ | ||
3236 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */ | ||
3237 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_3_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */ | ||
3238 | |||
3239 | /* | ||
3240 | * R2570 (0xA0A) - DSP1 Control 9 | ||
3241 | */ | ||
3242 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */ | ||
3243 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */ | ||
3244 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_4_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */ | ||
3245 | |||
3246 | /* | ||
3247 | * R2571 (0xA0B) - DSP1 Control 10 | ||
3248 | */ | ||
3249 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */ | ||
3250 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */ | ||
3251 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_5_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */ | ||
3252 | |||
3253 | /* | ||
3254 | * R2572 (0xA0C) - DSP1 Control 11 | ||
3255 | */ | ||
3256 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */ | ||
3257 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */ | ||
3258 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_6_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */ | ||
3259 | |||
3260 | /* | ||
3261 | * R2573 (0xA0D) - DSP1 Control 12 | ||
3262 | */ | ||
3263 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_MASK 0x3FFF /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */ | ||
3264 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_SHIFT 0 /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */ | ||
3265 | #define WM2200_DSP1_START_ADDRESS_WDMA_BUFFER_7_WIDTH 14 /* DSP1_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */ | ||
3266 | |||
3267 | /* | ||
3268 | * R2575 (0xA0F) - DSP1 Control 13 | ||
3269 | */ | ||
3270 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */ | ||
3271 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */ | ||
3272 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_0_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */ | ||
3273 | |||
3274 | /* | ||
3275 | * R2576 (0xA10) - DSP1 Control 14 | ||
3276 | */ | ||
3277 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */ | ||
3278 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */ | ||
3279 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_1_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */ | ||
3280 | |||
3281 | /* | ||
3282 | * R2577 (0xA11) - DSP1 Control 15 | ||
3283 | */ | ||
3284 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */ | ||
3285 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */ | ||
3286 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_2_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */ | ||
3287 | |||
3288 | /* | ||
3289 | * R2578 (0xA12) - DSP1 Control 16 | ||
3290 | */ | ||
3291 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */ | ||
3292 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */ | ||
3293 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_3_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */ | ||
3294 | |||
3295 | /* | ||
3296 | * R2579 (0xA13) - DSP1 Control 17 | ||
3297 | */ | ||
3298 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */ | ||
3299 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */ | ||
3300 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_4_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */ | ||
3301 | |||
3302 | /* | ||
3303 | * R2580 (0xA14) - DSP1 Control 18 | ||
3304 | */ | ||
3305 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_MASK 0x3FFF /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */ | ||
3306 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_SHIFT 0 /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */ | ||
3307 | #define WM2200_DSP1_START_ADDRESS_RDMA_BUFFER_5_WIDTH 14 /* DSP1_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */ | ||
3308 | |||
3309 | /* | ||
3310 | * R2582 (0xA16) - DSP1 Control 19 | ||
3311 | */ | ||
3312 | #define WM2200_DSP1_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ | ||
3313 | #define WM2200_DSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ | ||
3314 | #define WM2200_DSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ | ||
3315 | |||
3316 | /* | ||
3317 | * R2583 (0xA17) - DSP1 Control 20 | ||
3318 | */ | ||
3319 | #define WM2200_DSP1_WDMA_CHANNEL_ENABLE_MASK 0x00FF /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */ | ||
3320 | #define WM2200_DSP1_WDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */ | ||
3321 | #define WM2200_DSP1_WDMA_CHANNEL_ENABLE_WIDTH 8 /* DSP1_WDMA_CHANNEL_ENABLE - [7:0] */ | ||
3322 | |||
3323 | /* | ||
3324 | * R2584 (0xA18) - DSP1 Control 21 | ||
3325 | */ | ||
3326 | #define WM2200_DSP1_RDMA_CHANNEL_ENABLE_MASK 0x003F /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */ | ||
3327 | #define WM2200_DSP1_RDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */ | ||
3328 | #define WM2200_DSP1_RDMA_CHANNEL_ENABLE_WIDTH 6 /* DSP1_RDMA_CHANNEL_ENABLE - [5:0] */ | ||
3329 | |||
3330 | /* | ||
3331 | * R2586 (0xA1A) - DSP1 Control 22 | ||
3332 | */ | ||
3333 | #define WM2200_DSP1_DM_SIZE_MASK 0xFFFF /* DSP1_DM_SIZE - [15:0] */ | ||
3334 | #define WM2200_DSP1_DM_SIZE_SHIFT 0 /* DSP1_DM_SIZE - [15:0] */ | ||
3335 | #define WM2200_DSP1_DM_SIZE_WIDTH 16 /* DSP1_DM_SIZE - [15:0] */ | ||
3336 | |||
3337 | /* | ||
3338 | * R2587 (0xA1B) - DSP1 Control 23 | ||
3339 | */ | ||
3340 | #define WM2200_DSP1_PM_SIZE_MASK 0xFFFF /* DSP1_PM_SIZE - [15:0] */ | ||
3341 | #define WM2200_DSP1_PM_SIZE_SHIFT 0 /* DSP1_PM_SIZE - [15:0] */ | ||
3342 | #define WM2200_DSP1_PM_SIZE_WIDTH 16 /* DSP1_PM_SIZE - [15:0] */ | ||
3343 | |||
3344 | /* | ||
3345 | * R2588 (0xA1C) - DSP1 Control 24 | ||
3346 | */ | ||
3347 | #define WM2200_DSP1_ZM_SIZE_MASK 0xFFFF /* DSP1_ZM_SIZE - [15:0] */ | ||
3348 | #define WM2200_DSP1_ZM_SIZE_SHIFT 0 /* DSP1_ZM_SIZE - [15:0] */ | ||
3349 | #define WM2200_DSP1_ZM_SIZE_WIDTH 16 /* DSP1_ZM_SIZE - [15:0] */ | ||
3350 | |||
3351 | /* | ||
3352 | * R2590 (0xA1E) - DSP1 Control 25 | ||
3353 | */ | ||
3354 | #define WM2200_DSP1_PING_FULL 0x8000 /* DSP1_PING_FULL */ | ||
3355 | #define WM2200_DSP1_PING_FULL_MASK 0x8000 /* DSP1_PING_FULL */ | ||
3356 | #define WM2200_DSP1_PING_FULL_SHIFT 15 /* DSP1_PING_FULL */ | ||
3357 | #define WM2200_DSP1_PING_FULL_WIDTH 1 /* DSP1_PING_FULL */ | ||
3358 | #define WM2200_DSP1_PONG_FULL 0x4000 /* DSP1_PONG_FULL */ | ||
3359 | #define WM2200_DSP1_PONG_FULL_MASK 0x4000 /* DSP1_PONG_FULL */ | ||
3360 | #define WM2200_DSP1_PONG_FULL_SHIFT 14 /* DSP1_PONG_FULL */ | ||
3361 | #define WM2200_DSP1_PONG_FULL_WIDTH 1 /* DSP1_PONG_FULL */ | ||
3362 | #define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_MASK 0x00FF /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */ | ||
3363 | #define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_SHIFT 0 /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */ | ||
3364 | #define WM2200_DSP1_WDMA_ACTIVE_CHANNELS_WIDTH 8 /* DSP1_WDMA_ACTIVE_CHANNELS - [7:0] */ | ||
3365 | |||
3366 | /* | ||
3367 | * R2592 (0xA20) - DSP1 Control 26 | ||
3368 | */ | ||
3369 | #define WM2200_DSP1_SCRATCH_0_MASK 0xFFFF /* DSP1_SCRATCH_0 - [15:0] */ | ||
3370 | #define WM2200_DSP1_SCRATCH_0_SHIFT 0 /* DSP1_SCRATCH_0 - [15:0] */ | ||
3371 | #define WM2200_DSP1_SCRATCH_0_WIDTH 16 /* DSP1_SCRATCH_0 - [15:0] */ | ||
3372 | |||
3373 | /* | ||
3374 | * R2593 (0xA21) - DSP1 Control 27 | ||
3375 | */ | ||
3376 | #define WM2200_DSP1_SCRATCH_1_MASK 0xFFFF /* DSP1_SCRATCH_1 - [15:0] */ | ||
3377 | #define WM2200_DSP1_SCRATCH_1_SHIFT 0 /* DSP1_SCRATCH_1 - [15:0] */ | ||
3378 | #define WM2200_DSP1_SCRATCH_1_WIDTH 16 /* DSP1_SCRATCH_1 - [15:0] */ | ||
3379 | |||
3380 | /* | ||
3381 | * R2594 (0xA22) - DSP1 Control 28 | ||
3382 | */ | ||
3383 | #define WM2200_DSP1_SCRATCH_2_MASK 0xFFFF /* DSP1_SCRATCH_2 - [15:0] */ | ||
3384 | #define WM2200_DSP1_SCRATCH_2_SHIFT 0 /* DSP1_SCRATCH_2 - [15:0] */ | ||
3385 | #define WM2200_DSP1_SCRATCH_2_WIDTH 16 /* DSP1_SCRATCH_2 - [15:0] */ | ||
3386 | |||
3387 | /* | ||
3388 | * R2595 (0xA23) - DSP1 Control 29 | ||
3389 | */ | ||
3390 | #define WM2200_DSP1_SCRATCH_3_MASK 0xFFFF /* DSP1_SCRATCH_3 - [15:0] */ | ||
3391 | #define WM2200_DSP1_SCRATCH_3_SHIFT 0 /* DSP1_SCRATCH_3 - [15:0] */ | ||
3392 | #define WM2200_DSP1_SCRATCH_3_WIDTH 16 /* DSP1_SCRATCH_3 - [15:0] */ | ||
3393 | |||
3394 | /* | ||
3395 | * R2596 (0xA24) - DSP1 Control 30 | ||
3396 | */ | ||
3397 | #define WM2200_DSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */ | ||
3398 | #define WM2200_DSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */ | ||
3399 | #define WM2200_DSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */ | ||
3400 | #define WM2200_DSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */ | ||
3401 | #define WM2200_DSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ | ||
3402 | #define WM2200_DSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ | ||
3403 | #define WM2200_DSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ | ||
3404 | #define WM2200_DSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ | ||
3405 | #define WM2200_DSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ | ||
3406 | #define WM2200_DSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ | ||
3407 | #define WM2200_DSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ | ||
3408 | #define WM2200_DSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ | ||
3409 | #define WM2200_DSP1_START 0x0001 /* DSP1_START */ | ||
3410 | #define WM2200_DSP1_START_MASK 0x0001 /* DSP1_START */ | ||
3411 | #define WM2200_DSP1_START_SHIFT 0 /* DSP1_START */ | ||
3412 | #define WM2200_DSP1_START_WIDTH 1 /* DSP1_START */ | ||
3413 | |||
3414 | /* | ||
3415 | * R2598 (0xA26) - DSP1 Control 31 | ||
3416 | */ | ||
3417 | #define WM2200_DSP1_CLK_RATE_MASK 0x0018 /* DSP1_CLK_RATE - [4:3] */ | ||
3418 | #define WM2200_DSP1_CLK_RATE_SHIFT 3 /* DSP1_CLK_RATE - [4:3] */ | ||
3419 | #define WM2200_DSP1_CLK_RATE_WIDTH 2 /* DSP1_CLK_RATE - [4:3] */ | ||
3420 | #define WM2200_DSP1_CLK_AVAIL 0x0004 /* DSP1_CLK_AVAIL */ | ||
3421 | #define WM2200_DSP1_CLK_AVAIL_MASK 0x0004 /* DSP1_CLK_AVAIL */ | ||
3422 | #define WM2200_DSP1_CLK_AVAIL_SHIFT 2 /* DSP1_CLK_AVAIL */ | ||
3423 | #define WM2200_DSP1_CLK_AVAIL_WIDTH 1 /* DSP1_CLK_AVAIL */ | ||
3424 | #define WM2200_DSP1_CLK_REQ_MASK 0x0003 /* DSP1_CLK_REQ - [1:0] */ | ||
3425 | #define WM2200_DSP1_CLK_REQ_SHIFT 0 /* DSP1_CLK_REQ - [1:0] */ | ||
3426 | #define WM2200_DSP1_CLK_REQ_WIDTH 2 /* DSP1_CLK_REQ - [1:0] */ | ||
3427 | |||
3428 | /* | ||
3429 | * R2816 (0xB00) - DSP2 Control 1 | ||
3430 | */ | ||
3431 | #define WM2200_DSP2_RW_SEQUENCE_ENA 0x0001 /* DSP2_RW_SEQUENCE_ENA */ | ||
3432 | #define WM2200_DSP2_RW_SEQUENCE_ENA_MASK 0x0001 /* DSP2_RW_SEQUENCE_ENA */ | ||
3433 | #define WM2200_DSP2_RW_SEQUENCE_ENA_SHIFT 0 /* DSP2_RW_SEQUENCE_ENA */ | ||
3434 | #define WM2200_DSP2_RW_SEQUENCE_ENA_WIDTH 1 /* DSP2_RW_SEQUENCE_ENA */ | ||
3435 | |||
3436 | /* | ||
3437 | * R2818 (0xB02) - DSP2 Control 2 | ||
3438 | */ | ||
3439 | #define WM2200_DSP2_PAGE_BASE_PM_0_MASK 0xFF00 /* DSP2_PAGE_BASE_PM - [15:8] */ | ||
3440 | #define WM2200_DSP2_PAGE_BASE_PM_0_SHIFT 8 /* DSP2_PAGE_BASE_PM - [15:8] */ | ||
3441 | #define WM2200_DSP2_PAGE_BASE_PM_0_WIDTH 8 /* DSP2_PAGE_BASE_PM - [15:8] */ | ||
3442 | |||
3443 | /* | ||
3444 | * R2819 (0xB03) - DSP2 Control 3 | ||
3445 | */ | ||
3446 | #define WM2200_DSP2_PAGE_BASE_DM_0_MASK 0xFF00 /* DSP2_PAGE_BASE_DM - [15:8] */ | ||
3447 | #define WM2200_DSP2_PAGE_BASE_DM_0_SHIFT 8 /* DSP2_PAGE_BASE_DM - [15:8] */ | ||
3448 | #define WM2200_DSP2_PAGE_BASE_DM_0_WIDTH 8 /* DSP2_PAGE_BASE_DM - [15:8] */ | ||
3449 | |||
3450 | /* | ||
3451 | * R2820 (0xB04) - DSP2 Control 4 | ||
3452 | */ | ||
3453 | #define WM2200_DSP2_PAGE_BASE_ZM_0_MASK 0xFF00 /* DSP2_PAGE_BASE_ZM - [15:8] */ | ||
3454 | #define WM2200_DSP2_PAGE_BASE_ZM_0_SHIFT 8 /* DSP2_PAGE_BASE_ZM - [15:8] */ | ||
3455 | #define WM2200_DSP2_PAGE_BASE_ZM_0_WIDTH 8 /* DSP2_PAGE_BASE_ZM - [15:8] */ | ||
3456 | |||
3457 | /* | ||
3458 | * R2822 (0xB06) - DSP2 Control 5 | ||
3459 | */ | ||
3460 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */ | ||
3461 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */ | ||
3462 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_0_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_0 - [13:0] */ | ||
3463 | |||
3464 | /* | ||
3465 | * R2823 (0xB07) - DSP2 Control 6 | ||
3466 | */ | ||
3467 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */ | ||
3468 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */ | ||
3469 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_1_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_1 - [13:0] */ | ||
3470 | |||
3471 | /* | ||
3472 | * R2824 (0xB08) - DSP2 Control 7 | ||
3473 | */ | ||
3474 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */ | ||
3475 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */ | ||
3476 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_2_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_2 - [13:0] */ | ||
3477 | |||
3478 | /* | ||
3479 | * R2825 (0xB09) - DSP2 Control 8 | ||
3480 | */ | ||
3481 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */ | ||
3482 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */ | ||
3483 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_3_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_3 - [13:0] */ | ||
3484 | |||
3485 | /* | ||
3486 | * R2826 (0xB0A) - DSP2 Control 9 | ||
3487 | */ | ||
3488 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */ | ||
3489 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */ | ||
3490 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_4_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_4 - [13:0] */ | ||
3491 | |||
3492 | /* | ||
3493 | * R2827 (0xB0B) - DSP2 Control 10 | ||
3494 | */ | ||
3495 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */ | ||
3496 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */ | ||
3497 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_5_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_5 - [13:0] */ | ||
3498 | |||
3499 | /* | ||
3500 | * R2828 (0xB0C) - DSP2 Control 11 | ||
3501 | */ | ||
3502 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */ | ||
3503 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */ | ||
3504 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_6_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_6 - [13:0] */ | ||
3505 | |||
3506 | /* | ||
3507 | * R2829 (0xB0D) - DSP2 Control 12 | ||
3508 | */ | ||
3509 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_MASK 0x3FFF /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */ | ||
3510 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_SHIFT 0 /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */ | ||
3511 | #define WM2200_DSP2_START_ADDRESS_WDMA_BUFFER_7_WIDTH 14 /* DSP2_START_ADDRESS_WDMA_BUFFER_7 - [13:0] */ | ||
3512 | |||
3513 | /* | ||
3514 | * R2831 (0xB0F) - DSP2 Control 13 | ||
3515 | */ | ||
3516 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */ | ||
3517 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */ | ||
3518 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_0_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_0 - [13:0] */ | ||
3519 | |||
3520 | /* | ||
3521 | * R2832 (0xB10) - DSP2 Control 14 | ||
3522 | */ | ||
3523 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */ | ||
3524 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */ | ||
3525 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_1_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_1 - [13:0] */ | ||
3526 | |||
3527 | /* | ||
3528 | * R2833 (0xB11) - DSP2 Control 15 | ||
3529 | */ | ||
3530 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */ | ||
3531 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */ | ||
3532 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_2_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_2 - [13:0] */ | ||
3533 | |||
3534 | /* | ||
3535 | * R2834 (0xB12) - DSP2 Control 16 | ||
3536 | */ | ||
3537 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */ | ||
3538 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */ | ||
3539 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_3_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_3 - [13:0] */ | ||
3540 | |||
3541 | /* | ||
3542 | * R2835 (0xB13) - DSP2 Control 17 | ||
3543 | */ | ||
3544 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */ | ||
3545 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */ | ||
3546 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_4_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_4 - [13:0] */ | ||
3547 | |||
3548 | /* | ||
3549 | * R2836 (0xB14) - DSP2 Control 18 | ||
3550 | */ | ||
3551 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_MASK 0x3FFF /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */ | ||
3552 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_SHIFT 0 /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */ | ||
3553 | #define WM2200_DSP2_START_ADDRESS_RDMA_BUFFER_5_WIDTH 14 /* DSP2_START_ADDRESS_RDMA_BUFFER_5 - [13:0] */ | ||
3554 | |||
3555 | /* | ||
3556 | * R2838 (0xB16) - DSP2 Control 19 | ||
3557 | */ | ||
3558 | #define WM2200_DSP2_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */ | ||
3559 | #define WM2200_DSP2_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */ | ||
3560 | #define WM2200_DSP2_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP2_WDMA_BUFFER_LENGTH - [7:0] */ | ||
3561 | |||
3562 | /* | ||
3563 | * R2839 (0xB17) - DSP2 Control 20 | ||
3564 | */ | ||
3565 | #define WM2200_DSP2_WDMA_CHANNEL_ENABLE_MASK 0x00FF /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */ | ||
3566 | #define WM2200_DSP2_WDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */ | ||
3567 | #define WM2200_DSP2_WDMA_CHANNEL_ENABLE_WIDTH 8 /* DSP2_WDMA_CHANNEL_ENABLE - [7:0] */ | ||
3568 | |||
3569 | /* | ||
3570 | * R2840 (0xB18) - DSP2 Control 21 | ||
3571 | */ | ||
3572 | #define WM2200_DSP2_RDMA_CHANNEL_ENABLE_MASK 0x003F /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */ | ||
3573 | #define WM2200_DSP2_RDMA_CHANNEL_ENABLE_SHIFT 0 /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */ | ||
3574 | #define WM2200_DSP2_RDMA_CHANNEL_ENABLE_WIDTH 6 /* DSP2_RDMA_CHANNEL_ENABLE - [5:0] */ | ||
3575 | |||
3576 | /* | ||
3577 | * R2842 (0xB1A) - DSP2 Control 22 | ||
3578 | */ | ||
3579 | #define WM2200_DSP2_DM_SIZE_MASK 0xFFFF /* DSP2_DM_SIZE - [15:0] */ | ||
3580 | #define WM2200_DSP2_DM_SIZE_SHIFT 0 /* DSP2_DM_SIZE - [15:0] */ | ||
3581 | #define WM2200_DSP2_DM_SIZE_WIDTH 16 /* DSP2_DM_SIZE - [15:0] */ | ||
3582 | |||
3583 | /* | ||
3584 | * R2843 (0xB1B) - DSP2 Control 23 | ||
3585 | */ | ||
3586 | #define WM2200_DSP2_PM_SIZE_MASK 0xFFFF /* DSP2_PM_SIZE - [15:0] */ | ||
3587 | #define WM2200_DSP2_PM_SIZE_SHIFT 0 /* DSP2_PM_SIZE - [15:0] */ | ||
3588 | #define WM2200_DSP2_PM_SIZE_WIDTH 16 /* DSP2_PM_SIZE - [15:0] */ | ||
3589 | |||
3590 | /* | ||
3591 | * R2844 (0xB1C) - DSP2 Control 24 | ||
3592 | */ | ||
3593 | #define WM2200_DSP2_ZM_SIZE_MASK 0xFFFF /* DSP2_ZM_SIZE - [15:0] */ | ||
3594 | #define WM2200_DSP2_ZM_SIZE_SHIFT 0 /* DSP2_ZM_SIZE - [15:0] */ | ||
3595 | #define WM2200_DSP2_ZM_SIZE_WIDTH 16 /* DSP2_ZM_SIZE - [15:0] */ | ||
3596 | |||
3597 | /* | ||
3598 | * R2846 (0xB1E) - DSP2 Control 25 | ||
3599 | */ | ||
3600 | #define WM2200_DSP2_PING_FULL 0x8000 /* DSP2_PING_FULL */ | ||
3601 | #define WM2200_DSP2_PING_FULL_MASK 0x8000 /* DSP2_PING_FULL */ | ||
3602 | #define WM2200_DSP2_PING_FULL_SHIFT 15 /* DSP2_PING_FULL */ | ||
3603 | #define WM2200_DSP2_PING_FULL_WIDTH 1 /* DSP2_PING_FULL */ | ||
3604 | #define WM2200_DSP2_PONG_FULL 0x4000 /* DSP2_PONG_FULL */ | ||
3605 | #define WM2200_DSP2_PONG_FULL_MASK 0x4000 /* DSP2_PONG_FULL */ | ||
3606 | #define WM2200_DSP2_PONG_FULL_SHIFT 14 /* DSP2_PONG_FULL */ | ||
3607 | #define WM2200_DSP2_PONG_FULL_WIDTH 1 /* DSP2_PONG_FULL */ | ||
3608 | #define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_MASK 0x00FF /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */ | ||
3609 | #define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_SHIFT 0 /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */ | ||
3610 | #define WM2200_DSP2_WDMA_ACTIVE_CHANNELS_WIDTH 8 /* DSP2_WDMA_ACTIVE_CHANNELS - [7:0] */ | ||
3611 | |||
3612 | /* | ||
3613 | * R2848 (0xB20) - DSP2 Control 26 | ||
3614 | */ | ||
3615 | #define WM2200_DSP2_SCRATCH_0_MASK 0xFFFF /* DSP2_SCRATCH_0 - [15:0] */ | ||
3616 | #define WM2200_DSP2_SCRATCH_0_SHIFT 0 /* DSP2_SCRATCH_0 - [15:0] */ | ||
3617 | #define WM2200_DSP2_SCRATCH_0_WIDTH 16 /* DSP2_SCRATCH_0 - [15:0] */ | ||
3618 | |||
3619 | /* | ||
3620 | * R2849 (0xB21) - DSP2 Control 27 | ||
3621 | */ | ||
3622 | #define WM2200_DSP2_SCRATCH_1_MASK 0xFFFF /* DSP2_SCRATCH_1 - [15:0] */ | ||
3623 | #define WM2200_DSP2_SCRATCH_1_SHIFT 0 /* DSP2_SCRATCH_1 - [15:0] */ | ||
3624 | #define WM2200_DSP2_SCRATCH_1_WIDTH 16 /* DSP2_SCRATCH_1 - [15:0] */ | ||
3625 | |||
3626 | /* | ||
3627 | * R2850 (0xB22) - DSP2 Control 28 | ||
3628 | */ | ||
3629 | #define WM2200_DSP2_SCRATCH_2_MASK 0xFFFF /* DSP2_SCRATCH_2 - [15:0] */ | ||
3630 | #define WM2200_DSP2_SCRATCH_2_SHIFT 0 /* DSP2_SCRATCH_2 - [15:0] */ | ||
3631 | #define WM2200_DSP2_SCRATCH_2_WIDTH 16 /* DSP2_SCRATCH_2 - [15:0] */ | ||
3632 | |||
3633 | /* | ||
3634 | * R2851 (0xB23) - DSP2 Control 29 | ||
3635 | */ | ||
3636 | #define WM2200_DSP2_SCRATCH_3_MASK 0xFFFF /* DSP2_SCRATCH_3 - [15:0] */ | ||
3637 | #define WM2200_DSP2_SCRATCH_3_SHIFT 0 /* DSP2_SCRATCH_3 - [15:0] */ | ||
3638 | #define WM2200_DSP2_SCRATCH_3_WIDTH 16 /* DSP2_SCRATCH_3 - [15:0] */ | ||
3639 | |||
3640 | /* | ||
3641 | * R2852 (0xB24) - DSP2 Control 30 | ||
3642 | */ | ||
3643 | #define WM2200_DSP2_DBG_CLK_ENA 0x0008 /* DSP2_DBG_CLK_ENA */ | ||
3644 | #define WM2200_DSP2_DBG_CLK_ENA_MASK 0x0008 /* DSP2_DBG_CLK_ENA */ | ||
3645 | #define WM2200_DSP2_DBG_CLK_ENA_SHIFT 3 /* DSP2_DBG_CLK_ENA */ | ||
3646 | #define WM2200_DSP2_DBG_CLK_ENA_WIDTH 1 /* DSP2_DBG_CLK_ENA */ | ||
3647 | #define WM2200_DSP2_SYS_ENA 0x0004 /* DSP2_SYS_ENA */ | ||
3648 | #define WM2200_DSP2_SYS_ENA_MASK 0x0004 /* DSP2_SYS_ENA */ | ||
3649 | #define WM2200_DSP2_SYS_ENA_SHIFT 2 /* DSP2_SYS_ENA */ | ||
3650 | #define WM2200_DSP2_SYS_ENA_WIDTH 1 /* DSP2_SYS_ENA */ | ||
3651 | #define WM2200_DSP2_CORE_ENA 0x0002 /* DSP2_CORE_ENA */ | ||
3652 | #define WM2200_DSP2_CORE_ENA_MASK 0x0002 /* DSP2_CORE_ENA */ | ||
3653 | #define WM2200_DSP2_CORE_ENA_SHIFT 1 /* DSP2_CORE_ENA */ | ||
3654 | #define WM2200_DSP2_CORE_ENA_WIDTH 1 /* DSP2_CORE_ENA */ | ||
3655 | #define WM2200_DSP2_START 0x0001 /* DSP2_START */ | ||
3656 | #define WM2200_DSP2_START_MASK 0x0001 /* DSP2_START */ | ||
3657 | #define WM2200_DSP2_START_SHIFT 0 /* DSP2_START */ | ||
3658 | #define WM2200_DSP2_START_WIDTH 1 /* DSP2_START */ | ||
3659 | |||
3660 | /* | ||
3661 | * R2854 (0xB26) - DSP2 Control 31 | ||
3662 | */ | ||
3663 | #define WM2200_DSP2_CLK_RATE_MASK 0x0018 /* DSP2_CLK_RATE - [4:3] */ | ||
3664 | #define WM2200_DSP2_CLK_RATE_SHIFT 3 /* DSP2_CLK_RATE - [4:3] */ | ||
3665 | #define WM2200_DSP2_CLK_RATE_WIDTH 2 /* DSP2_CLK_RATE - [4:3] */ | ||
3666 | #define WM2200_DSP2_CLK_AVAIL 0x0004 /* DSP2_CLK_AVAIL */ | ||
3667 | #define WM2200_DSP2_CLK_AVAIL_MASK 0x0004 /* DSP2_CLK_AVAIL */ | ||
3668 | #define WM2200_DSP2_CLK_AVAIL_SHIFT 2 /* DSP2_CLK_AVAIL */ | ||
3669 | #define WM2200_DSP2_CLK_AVAIL_WIDTH 1 /* DSP2_CLK_AVAIL */ | ||
3670 | #define WM2200_DSP2_CLK_REQ_MASK 0x0003 /* DSP2_CLK_REQ - [1:0] */ | ||
3671 | #define WM2200_DSP2_CLK_REQ_SHIFT 0 /* DSP2_CLK_REQ - [1:0] */ | ||
3672 | #define WM2200_DSP2_CLK_REQ_WIDTH 2 /* DSP2_CLK_REQ - [1:0] */ | ||
3673 | |||
3674 | #endif | ||
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index 8b24323d6b2c..b9c185ce64e4 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/gcd.h> | 18 | #include <linux/gcd.h> |
19 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/pm_runtime.h> | ||
21 | #include <linux/regulator/consumer.h> | 22 | #include <linux/regulator/consumer.h> |
22 | #include <linux/regulator/fixed.h> | 23 | #include <linux/regulator/fixed.h> |
23 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
@@ -50,13 +51,11 @@ struct wm5100_fll { | |||
50 | 51 | ||
51 | /* codec private data */ | 52 | /* codec private data */ |
52 | struct wm5100_priv { | 53 | struct wm5100_priv { |
54 | struct device *dev; | ||
53 | struct regmap *regmap; | 55 | struct regmap *regmap; |
54 | struct snd_soc_codec *codec; | 56 | struct snd_soc_codec *codec; |
55 | 57 | ||
56 | struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES]; | 58 | struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES]; |
57 | struct regulator *cpvdd; | ||
58 | struct regulator *dbvdd2; | ||
59 | struct regulator *dbvdd3; | ||
60 | 59 | ||
61 | int rev; | 60 | int rev; |
62 | 61 | ||
@@ -73,6 +72,7 @@ struct wm5100_priv { | |||
73 | bool jack_detecting; | 72 | bool jack_detecting; |
74 | bool jack_mic; | 73 | bool jack_mic; |
75 | int jack_mode; | 74 | int jack_mode; |
75 | int jack_flips; | ||
76 | 76 | ||
77 | struct wm5100_fll fll[2]; | 77 | struct wm5100_fll fll[2]; |
78 | 78 | ||
@@ -709,6 +709,8 @@ WM5100_MIXER_CONTROLS("EQ4", WM5100_EQ4MIX_INPUT_1_SOURCE), | |||
709 | 709 | ||
710 | WM5100_MIXER_CONTROLS("DRC1L", WM5100_DRC1LMIX_INPUT_1_SOURCE), | 710 | WM5100_MIXER_CONTROLS("DRC1L", WM5100_DRC1LMIX_INPUT_1_SOURCE), |
711 | WM5100_MIXER_CONTROLS("DRC1R", WM5100_DRC1RMIX_INPUT_1_SOURCE), | 711 | WM5100_MIXER_CONTROLS("DRC1R", WM5100_DRC1RMIX_INPUT_1_SOURCE), |
712 | SND_SOC_BYTES_MASK("DRC", WM5100_DRC1_CTRL1, 5, | ||
713 | WM5100_DRCL_ENA | WM5100_DRCR_ENA), | ||
712 | 714 | ||
713 | WM5100_MIXER_CONTROLS("LHPF1", WM5100_HPLP1MIX_INPUT_1_SOURCE), | 715 | WM5100_MIXER_CONTROLS("LHPF1", WM5100_HPLP1MIX_INPUT_1_SOURCE), |
714 | WM5100_MIXER_CONTROLS("LHPF2", WM5100_HPLP2MIX_INPUT_1_SOURCE), | 716 | WM5100_MIXER_CONTROLS("LHPF2", WM5100_HPLP2MIX_INPUT_1_SOURCE), |
@@ -776,127 +778,48 @@ static int wm5100_out_ev(struct snd_soc_dapm_widget *w, | |||
776 | return 0; | 778 | return 0; |
777 | } | 779 | } |
778 | 780 | ||
779 | static int wm5100_cp_ev(struct snd_soc_dapm_widget *w, | 781 | static void wm5100_log_status3(struct wm5100_priv *wm5100, int val) |
780 | struct snd_kcontrol *kcontrol, | ||
781 | int event) | ||
782 | { | ||
783 | struct snd_soc_codec *codec = w->codec; | ||
784 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
785 | int ret; | ||
786 | |||
787 | switch (event) { | ||
788 | case SND_SOC_DAPM_PRE_PMU: | ||
789 | ret = regulator_enable(wm5100->cpvdd); | ||
790 | if (ret != 0) { | ||
791 | dev_err(codec->dev, "Failed to enable CPVDD: %d\n", | ||
792 | ret); | ||
793 | return ret; | ||
794 | } | ||
795 | return ret; | ||
796 | |||
797 | case SND_SOC_DAPM_POST_PMD: | ||
798 | ret = regulator_disable_deferred(wm5100->cpvdd, 20); | ||
799 | if (ret != 0) { | ||
800 | dev_err(codec->dev, "Failed to disable CPVDD: %d\n", | ||
801 | ret); | ||
802 | return ret; | ||
803 | } | ||
804 | return ret; | ||
805 | |||
806 | default: | ||
807 | BUG(); | ||
808 | return 0; | ||
809 | } | ||
810 | } | ||
811 | |||
812 | static int wm5100_dbvdd_ev(struct snd_soc_dapm_widget *w, | ||
813 | struct snd_kcontrol *kcontrol, | ||
814 | int event) | ||
815 | { | ||
816 | struct snd_soc_codec *codec = w->codec; | ||
817 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
818 | struct regulator *regulator; | ||
819 | int ret; | ||
820 | |||
821 | switch (w->shift) { | ||
822 | case 2: | ||
823 | regulator = wm5100->dbvdd2; | ||
824 | break; | ||
825 | case 3: | ||
826 | regulator = wm5100->dbvdd3; | ||
827 | break; | ||
828 | default: | ||
829 | BUG(); | ||
830 | return 0; | ||
831 | } | ||
832 | |||
833 | switch (event) { | ||
834 | case SND_SOC_DAPM_PRE_PMU: | ||
835 | ret = regulator_enable(regulator); | ||
836 | if (ret != 0) { | ||
837 | dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n", | ||
838 | w->shift, ret); | ||
839 | return ret; | ||
840 | } | ||
841 | return ret; | ||
842 | |||
843 | case SND_SOC_DAPM_POST_PMD: | ||
844 | ret = regulator_disable(regulator); | ||
845 | if (ret != 0) { | ||
846 | dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n", | ||
847 | w->shift, ret); | ||
848 | return ret; | ||
849 | } | ||
850 | return ret; | ||
851 | |||
852 | default: | ||
853 | BUG(); | ||
854 | return 0; | ||
855 | } | ||
856 | } | ||
857 | |||
858 | static void wm5100_log_status3(struct snd_soc_codec *codec, int val) | ||
859 | { | 782 | { |
860 | if (val & WM5100_SPK_SHUTDOWN_WARN_EINT) | 783 | if (val & WM5100_SPK_SHUTDOWN_WARN_EINT) |
861 | dev_crit(codec->dev, "Speaker shutdown warning\n"); | 784 | dev_crit(wm5100->dev, "Speaker shutdown warning\n"); |
862 | if (val & WM5100_SPK_SHUTDOWN_EINT) | 785 | if (val & WM5100_SPK_SHUTDOWN_EINT) |
863 | dev_crit(codec->dev, "Speaker shutdown\n"); | 786 | dev_crit(wm5100->dev, "Speaker shutdown\n"); |
864 | if (val & WM5100_CLKGEN_ERR_EINT) | 787 | if (val & WM5100_CLKGEN_ERR_EINT) |
865 | dev_crit(codec->dev, "SYSCLK underclocked\n"); | 788 | dev_crit(wm5100->dev, "SYSCLK underclocked\n"); |
866 | if (val & WM5100_CLKGEN_ERR_ASYNC_EINT) | 789 | if (val & WM5100_CLKGEN_ERR_ASYNC_EINT) |
867 | dev_crit(codec->dev, "ASYNCCLK underclocked\n"); | 790 | dev_crit(wm5100->dev, "ASYNCCLK underclocked\n"); |
868 | } | 791 | } |
869 | 792 | ||
870 | static void wm5100_log_status4(struct snd_soc_codec *codec, int val) | 793 | static void wm5100_log_status4(struct wm5100_priv *wm5100, int val) |
871 | { | 794 | { |
872 | if (val & WM5100_AIF3_ERR_EINT) | 795 | if (val & WM5100_AIF3_ERR_EINT) |
873 | dev_err(codec->dev, "AIF3 configuration error\n"); | 796 | dev_err(wm5100->dev, "AIF3 configuration error\n"); |
874 | if (val & WM5100_AIF2_ERR_EINT) | 797 | if (val & WM5100_AIF2_ERR_EINT) |
875 | dev_err(codec->dev, "AIF2 configuration error\n"); | 798 | dev_err(wm5100->dev, "AIF2 configuration error\n"); |
876 | if (val & WM5100_AIF1_ERR_EINT) | 799 | if (val & WM5100_AIF1_ERR_EINT) |
877 | dev_err(codec->dev, "AIF1 configuration error\n"); | 800 | dev_err(wm5100->dev, "AIF1 configuration error\n"); |
878 | if (val & WM5100_CTRLIF_ERR_EINT) | 801 | if (val & WM5100_CTRLIF_ERR_EINT) |
879 | dev_err(codec->dev, "Control interface error\n"); | 802 | dev_err(wm5100->dev, "Control interface error\n"); |
880 | if (val & WM5100_ISRC2_UNDERCLOCKED_EINT) | 803 | if (val & WM5100_ISRC2_UNDERCLOCKED_EINT) |
881 | dev_err(codec->dev, "ISRC2 underclocked\n"); | 804 | dev_err(wm5100->dev, "ISRC2 underclocked\n"); |
882 | if (val & WM5100_ISRC1_UNDERCLOCKED_EINT) | 805 | if (val & WM5100_ISRC1_UNDERCLOCKED_EINT) |
883 | dev_err(codec->dev, "ISRC1 underclocked\n"); | 806 | dev_err(wm5100->dev, "ISRC1 underclocked\n"); |
884 | if (val & WM5100_FX_UNDERCLOCKED_EINT) | 807 | if (val & WM5100_FX_UNDERCLOCKED_EINT) |
885 | dev_err(codec->dev, "FX underclocked\n"); | 808 | dev_err(wm5100->dev, "FX underclocked\n"); |
886 | if (val & WM5100_AIF3_UNDERCLOCKED_EINT) | 809 | if (val & WM5100_AIF3_UNDERCLOCKED_EINT) |
887 | dev_err(codec->dev, "AIF3 underclocked\n"); | 810 | dev_err(wm5100->dev, "AIF3 underclocked\n"); |
888 | if (val & WM5100_AIF2_UNDERCLOCKED_EINT) | 811 | if (val & WM5100_AIF2_UNDERCLOCKED_EINT) |
889 | dev_err(codec->dev, "AIF2 underclocked\n"); | 812 | dev_err(wm5100->dev, "AIF2 underclocked\n"); |
890 | if (val & WM5100_AIF1_UNDERCLOCKED_EINT) | 813 | if (val & WM5100_AIF1_UNDERCLOCKED_EINT) |
891 | dev_err(codec->dev, "AIF1 underclocked\n"); | 814 | dev_err(wm5100->dev, "AIF1 underclocked\n"); |
892 | if (val & WM5100_ASRC_UNDERCLOCKED_EINT) | 815 | if (val & WM5100_ASRC_UNDERCLOCKED_EINT) |
893 | dev_err(codec->dev, "ASRC underclocked\n"); | 816 | dev_err(wm5100->dev, "ASRC underclocked\n"); |
894 | if (val & WM5100_DAC_UNDERCLOCKED_EINT) | 817 | if (val & WM5100_DAC_UNDERCLOCKED_EINT) |
895 | dev_err(codec->dev, "DAC underclocked\n"); | 818 | dev_err(wm5100->dev, "DAC underclocked\n"); |
896 | if (val & WM5100_ADC_UNDERCLOCKED_EINT) | 819 | if (val & WM5100_ADC_UNDERCLOCKED_EINT) |
897 | dev_err(codec->dev, "ADC underclocked\n"); | 820 | dev_err(wm5100->dev, "ADC underclocked\n"); |
898 | if (val & WM5100_MIXER_UNDERCLOCKED_EINT) | 821 | if (val & WM5100_MIXER_UNDERCLOCKED_EINT) |
899 | dev_err(codec->dev, "Mixer underclocked\n"); | 822 | dev_err(wm5100->dev, "Mixer underclocked\n"); |
900 | } | 823 | } |
901 | 824 | ||
902 | static int wm5100_post_ev(struct snd_soc_dapm_widget *w, | 825 | static int wm5100_post_ev(struct snd_soc_dapm_widget *w, |
@@ -904,16 +827,17 @@ static int wm5100_post_ev(struct snd_soc_dapm_widget *w, | |||
904 | int event) | 827 | int event) |
905 | { | 828 | { |
906 | struct snd_soc_codec *codec = w->codec; | 829 | struct snd_soc_codec *codec = w->codec; |
830 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
907 | int ret; | 831 | int ret; |
908 | 832 | ||
909 | ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_3); | 833 | ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_3); |
910 | ret &= WM5100_SPK_SHUTDOWN_WARN_STS | | 834 | ret &= WM5100_SPK_SHUTDOWN_WARN_STS | |
911 | WM5100_SPK_SHUTDOWN_STS | WM5100_CLKGEN_ERR_STS | | 835 | WM5100_SPK_SHUTDOWN_STS | WM5100_CLKGEN_ERR_STS | |
912 | WM5100_CLKGEN_ERR_ASYNC_STS; | 836 | WM5100_CLKGEN_ERR_ASYNC_STS; |
913 | wm5100_log_status3(codec, ret); | 837 | wm5100_log_status3(wm5100, ret); |
914 | 838 | ||
915 | ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_4); | 839 | ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_4); |
916 | wm5100_log_status4(codec, ret); | 840 | wm5100_log_status4(wm5100, ret); |
917 | 841 | ||
918 | return 0; | 842 | return 0; |
919 | } | 843 | } |
@@ -924,18 +848,16 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", WM5100_CLOCKING_3, WM5100_SYSCLK_ENA_SHIFT, 0, | |||
924 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT, | 848 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT, |
925 | 0, NULL, 0), | 849 | 0, NULL, 0), |
926 | 850 | ||
851 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20), | ||
852 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0), | ||
853 | SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0), | ||
854 | |||
927 | SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0, | 855 | SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0, |
928 | wm5100_cp_ev, | 856 | NULL, 0), |
929 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
930 | SND_SOC_DAPM_SUPPLY("CP2", WM5100_MIC_CHARGE_PUMP_1, WM5100_CP2_ENA_SHIFT, 0, | 857 | SND_SOC_DAPM_SUPPLY("CP2", WM5100_MIC_CHARGE_PUMP_1, WM5100_CP2_ENA_SHIFT, 0, |
931 | NULL, 0), | 858 | NULL, 0), |
932 | SND_SOC_DAPM_SUPPLY("CP2 Active", WM5100_MIC_CHARGE_PUMP_1, | 859 | SND_SOC_DAPM_SUPPLY("CP2 Active", WM5100_MIC_CHARGE_PUMP_1, |
933 | WM5100_CP2_BYPASS_SHIFT, 1, wm5100_cp_ev, | 860 | WM5100_CP2_BYPASS_SHIFT, 1, NULL, 0), |
934 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
935 | SND_SOC_DAPM_SUPPLY("DBVDD2", SND_SOC_NOPM, 2, 0, wm5100_dbvdd_ev, | ||
936 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
937 | SND_SOC_DAPM_SUPPLY("DBVDD3", SND_SOC_NOPM, 3, 0, wm5100_dbvdd_ev, | ||
938 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
939 | 861 | ||
940 | SND_SOC_DAPM_SUPPLY("MICBIAS1", WM5100_MIC_BIAS_CTRL_1, WM5100_MICB1_ENA_SHIFT, | 862 | SND_SOC_DAPM_SUPPLY("MICBIAS1", WM5100_MIC_BIAS_CTRL_1, WM5100_MICB1_ENA_SHIFT, |
941 | 0, NULL, 0), | 863 | 0, NULL, 0), |
@@ -1146,6 +1068,9 @@ SND_SOC_DAPM_POST("Post", wm5100_post_ev), | |||
1146 | }; | 1068 | }; |
1147 | 1069 | ||
1148 | static const struct snd_soc_dapm_route wm5100_dapm_routes[] = { | 1070 | static const struct snd_soc_dapm_route wm5100_dapm_routes[] = { |
1071 | { "CP1", NULL, "CPVDD" }, | ||
1072 | { "CP2 Active", NULL, "CPVDD" }, | ||
1073 | |||
1149 | { "IN1L", NULL, "SYSCLK" }, | 1074 | { "IN1L", NULL, "SYSCLK" }, |
1150 | { "IN1R", NULL, "SYSCLK" }, | 1075 | { "IN1R", NULL, "SYSCLK" }, |
1151 | { "IN2L", NULL, "SYSCLK" }, | 1076 | { "IN2L", NULL, "SYSCLK" }, |
@@ -1308,10 +1233,7 @@ static const struct snd_soc_dapm_route wm5100_dapm_routes[] = { | |||
1308 | { "PWM2", NULL, "PWM2 Driver" }, | 1233 | { "PWM2", NULL, "PWM2 Driver" }, |
1309 | }; | 1234 | }; |
1310 | 1235 | ||
1311 | static struct { | 1236 | static const __devinitdata struct reg_default wm5100_reva_patches[] = { |
1312 | int reg; | ||
1313 | int val; | ||
1314 | } wm5100_reva_patches[] = { | ||
1315 | { WM5100_AUDIO_IF_1_10, 0 }, | 1237 | { WM5100_AUDIO_IF_1_10, 0 }, |
1316 | { WM5100_AUDIO_IF_1_11, 1 }, | 1238 | { WM5100_AUDIO_IF_1_11, 1 }, |
1317 | { WM5100_AUDIO_IF_1_12, 2 }, | 1239 | { WM5100_AUDIO_IF_1_12, 2 }, |
@@ -1343,76 +1265,6 @@ static struct { | |||
1343 | { WM5100_AUDIO_IF_3_19, 1 }, | 1265 | { WM5100_AUDIO_IF_3_19, 1 }, |
1344 | }; | 1266 | }; |
1345 | 1267 | ||
1346 | static int wm5100_set_bias_level(struct snd_soc_codec *codec, | ||
1347 | enum snd_soc_bias_level level) | ||
1348 | { | ||
1349 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
1350 | int ret, i; | ||
1351 | |||
1352 | switch (level) { | ||
1353 | case SND_SOC_BIAS_ON: | ||
1354 | break; | ||
1355 | |||
1356 | case SND_SOC_BIAS_PREPARE: | ||
1357 | break; | ||
1358 | |||
1359 | case SND_SOC_BIAS_STANDBY: | ||
1360 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
1361 | ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies), | ||
1362 | wm5100->core_supplies); | ||
1363 | if (ret != 0) { | ||
1364 | dev_err(codec->dev, | ||
1365 | "Failed to enable supplies: %d\n", | ||
1366 | ret); | ||
1367 | return ret; | ||
1368 | } | ||
1369 | |||
1370 | if (wm5100->pdata.ldo_ena) { | ||
1371 | gpio_set_value_cansleep(wm5100->pdata.ldo_ena, | ||
1372 | 1); | ||
1373 | msleep(2); | ||
1374 | } | ||
1375 | |||
1376 | regcache_cache_only(wm5100->regmap, false); | ||
1377 | |||
1378 | switch (wm5100->rev) { | ||
1379 | case 0: | ||
1380 | snd_soc_write(codec, 0x11, 0x3); | ||
1381 | snd_soc_write(codec, 0x203, 0xc); | ||
1382 | snd_soc_write(codec, 0x206, 0); | ||
1383 | snd_soc_write(codec, 0x207, 0xf0); | ||
1384 | snd_soc_write(codec, 0x208, 0x3c); | ||
1385 | snd_soc_write(codec, 0x209, 0); | ||
1386 | snd_soc_write(codec, 0x211, 0x20d8); | ||
1387 | snd_soc_write(codec, 0x11, 0); | ||
1388 | |||
1389 | for (i = 0; | ||
1390 | i < ARRAY_SIZE(wm5100_reva_patches); | ||
1391 | i++) | ||
1392 | snd_soc_write(codec, | ||
1393 | wm5100_reva_patches[i].reg, | ||
1394 | wm5100_reva_patches[i].val); | ||
1395 | break; | ||
1396 | default: | ||
1397 | break; | ||
1398 | } | ||
1399 | |||
1400 | regcache_sync(wm5100->regmap); | ||
1401 | } | ||
1402 | break; | ||
1403 | |||
1404 | case SND_SOC_BIAS_OFF: | ||
1405 | if (wm5100->pdata.ldo_ena) | ||
1406 | gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); | ||
1407 | regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), | ||
1408 | wm5100->core_supplies); | ||
1409 | break; | ||
1410 | } | ||
1411 | codec->dapm.bias_level = level; | ||
1412 | |||
1413 | return 0; | ||
1414 | } | ||
1415 | |||
1416 | static int wm5100_dai_to_base(struct snd_soc_dai *dai) | 1268 | static int wm5100_dai_to_base(struct snd_soc_dai *dai) |
1417 | { | 1269 | { |
1418 | switch (dai->id) { | 1270 | switch (dai->id) { |
@@ -1940,6 +1792,8 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
1940 | 1792 | ||
1941 | if (!Fout) { | 1793 | if (!Fout) { |
1942 | dev_dbg(codec->dev, "FLL%d disabled", fll_id); | 1794 | dev_dbg(codec->dev, "FLL%d disabled", fll_id); |
1795 | if (fll->fout) | ||
1796 | pm_runtime_put(codec->dev); | ||
1943 | fll->fout = 0; | 1797 | fll->fout = 0; |
1944 | snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0); | 1798 | snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0); |
1945 | return 0; | 1799 | return 0; |
@@ -1984,6 +1838,8 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
1984 | /* Clear any pending completions */ | 1838 | /* Clear any pending completions */ |
1985 | try_wait_for_completion(&fll->lock); | 1839 | try_wait_for_completion(&fll->lock); |
1986 | 1840 | ||
1841 | pm_runtime_get_sync(codec->dev); | ||
1842 | |||
1987 | snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA); | 1843 | snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA); |
1988 | 1844 | ||
1989 | if (i2c->irq) | 1845 | if (i2c->irq) |
@@ -2018,6 +1874,7 @@ static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
2018 | } | 1874 | } |
2019 | if (i == timeout) { | 1875 | if (i == timeout) { |
2020 | dev_err(codec->dev, "FLL%d lock timed out\n", fll_id); | 1876 | dev_err(codec->dev, "FLL%d lock timed out\n", fll_id); |
1877 | pm_runtime_put(codec->dev); | ||
2021 | return -ETIMEDOUT; | 1878 | return -ETIMEDOUT; |
2022 | } | 1879 | } |
2023 | 1880 | ||
@@ -2120,55 +1977,73 @@ static int wm5100_dig_vu[] = { | |||
2120 | WM5100_DAC_DIGITAL_VOLUME_6R, | 1977 | WM5100_DAC_DIGITAL_VOLUME_6R, |
2121 | }; | 1978 | }; |
2122 | 1979 | ||
2123 | static void wm5100_set_detect_mode(struct snd_soc_codec *codec, int the_mode) | 1980 | static void wm5100_set_detect_mode(struct wm5100_priv *wm5100, int the_mode) |
2124 | { | 1981 | { |
2125 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
2126 | struct wm5100_jack_mode *mode = &wm5100->pdata.jack_modes[the_mode]; | 1982 | struct wm5100_jack_mode *mode = &wm5100->pdata.jack_modes[the_mode]; |
2127 | 1983 | ||
2128 | BUG_ON(the_mode >= ARRAY_SIZE(wm5100->pdata.jack_modes)); | 1984 | BUG_ON(the_mode >= ARRAY_SIZE(wm5100->pdata.jack_modes)); |
2129 | 1985 | ||
2130 | gpio_set_value_cansleep(wm5100->pdata.hp_pol, mode->hp_pol); | 1986 | gpio_set_value_cansleep(wm5100->pdata.hp_pol, mode->hp_pol); |
2131 | snd_soc_update_bits(codec, WM5100_ACCESSORY_DETECT_MODE_1, | 1987 | regmap_update_bits(wm5100->regmap, WM5100_ACCESSORY_DETECT_MODE_1, |
2132 | WM5100_ACCDET_BIAS_SRC_MASK | | 1988 | WM5100_ACCDET_BIAS_SRC_MASK | |
2133 | WM5100_ACCDET_SRC, | 1989 | WM5100_ACCDET_SRC, |
2134 | (mode->bias << WM5100_ACCDET_BIAS_SRC_SHIFT) | | 1990 | (mode->bias << WM5100_ACCDET_BIAS_SRC_SHIFT) | |
2135 | mode->micd_src << WM5100_ACCDET_SRC_SHIFT); | 1991 | mode->micd_src << WM5100_ACCDET_SRC_SHIFT); |
2136 | snd_soc_update_bits(codec, WM5100_MISC_CONTROL, | 1992 | regmap_update_bits(wm5100->regmap, WM5100_MISC_CONTROL, |
2137 | WM5100_HPCOM_SRC, | 1993 | WM5100_HPCOM_SRC, |
2138 | mode->micd_src << WM5100_HPCOM_SRC_SHIFT); | 1994 | mode->micd_src << WM5100_HPCOM_SRC_SHIFT); |
2139 | 1995 | ||
2140 | wm5100->jack_mode = the_mode; | 1996 | wm5100->jack_mode = the_mode; |
2141 | 1997 | ||
2142 | dev_dbg(codec->dev, "Set microphone polarity to %d\n", | 1998 | dev_dbg(wm5100->dev, "Set microphone polarity to %d\n", |
2143 | wm5100->jack_mode); | 1999 | wm5100->jack_mode); |
2144 | } | 2000 | } |
2145 | 2001 | ||
2146 | static void wm5100_micd_irq(struct snd_soc_codec *codec) | 2002 | static void wm5100_report_headphone(struct wm5100_priv *wm5100) |
2147 | { | 2003 | { |
2148 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | 2004 | dev_dbg(wm5100->dev, "Headphone detected\n"); |
2149 | int val; | 2005 | wm5100->jack_detecting = false; |
2006 | snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE, | ||
2007 | SND_JACK_HEADPHONE); | ||
2008 | |||
2009 | /* Increase the detection rate a bit for responsiveness. */ | ||
2010 | regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1, | ||
2011 | WM5100_ACCDET_RATE_MASK, | ||
2012 | 7 << WM5100_ACCDET_RATE_SHIFT); | ||
2013 | } | ||
2150 | 2014 | ||
2151 | val = snd_soc_read(codec, WM5100_MIC_DETECT_3); | 2015 | static void wm5100_micd_irq(struct wm5100_priv *wm5100) |
2016 | { | ||
2017 | unsigned int val; | ||
2018 | int ret; | ||
2152 | 2019 | ||
2153 | dev_dbg(codec->dev, "Microphone event: %x\n", val); | 2020 | ret = regmap_read(wm5100->regmap, WM5100_MIC_DETECT_3, &val); |
2021 | if (ret != 0) { | ||
2022 | dev_err(wm5100->dev, "Failed to read micropone status: %d\n", | ||
2023 | ret); | ||
2024 | return; | ||
2025 | } | ||
2026 | |||
2027 | dev_dbg(wm5100->dev, "Microphone event: %x\n", val); | ||
2154 | 2028 | ||
2155 | if (!(val & WM5100_ACCDET_VALID)) { | 2029 | if (!(val & WM5100_ACCDET_VALID)) { |
2156 | dev_warn(codec->dev, "Microphone detection state invalid\n"); | 2030 | dev_warn(wm5100->dev, "Microphone detection state invalid\n"); |
2157 | return; | 2031 | return; |
2158 | } | 2032 | } |
2159 | 2033 | ||
2160 | /* No accessory, reset everything and report removal */ | 2034 | /* No accessory, reset everything and report removal */ |
2161 | if (!(val & WM5100_ACCDET_STS)) { | 2035 | if (!(val & WM5100_ACCDET_STS)) { |
2162 | dev_dbg(codec->dev, "Jack removal detected\n"); | 2036 | dev_dbg(wm5100->dev, "Jack removal detected\n"); |
2163 | wm5100->jack_mic = false; | 2037 | wm5100->jack_mic = false; |
2164 | wm5100->jack_detecting = true; | 2038 | wm5100->jack_detecting = true; |
2039 | wm5100->jack_flips = 0; | ||
2165 | snd_soc_jack_report(wm5100->jack, 0, | 2040 | snd_soc_jack_report(wm5100->jack, 0, |
2166 | SND_JACK_LINEOUT | SND_JACK_HEADSET | | 2041 | SND_JACK_LINEOUT | SND_JACK_HEADSET | |
2167 | SND_JACK_BTN_0); | 2042 | SND_JACK_BTN_0); |
2168 | 2043 | ||
2169 | snd_soc_update_bits(codec, WM5100_MIC_DETECT_1, | 2044 | regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1, |
2170 | WM5100_ACCDET_RATE_MASK, | 2045 | WM5100_ACCDET_RATE_MASK, |
2171 | WM5100_ACCDET_RATE_MASK); | 2046 | WM5100_ACCDET_RATE_MASK); |
2172 | return; | 2047 | return; |
2173 | } | 2048 | } |
2174 | 2049 | ||
@@ -2178,19 +2053,20 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec) | |||
2178 | */ | 2053 | */ |
2179 | if (val & 0x400) { | 2054 | if (val & 0x400) { |
2180 | if (wm5100->jack_detecting) { | 2055 | if (wm5100->jack_detecting) { |
2181 | dev_dbg(codec->dev, "Microphone detected\n"); | 2056 | dev_dbg(wm5100->dev, "Microphone detected\n"); |
2182 | wm5100->jack_mic = true; | 2057 | wm5100->jack_mic = true; |
2058 | wm5100->jack_detecting = false; | ||
2183 | snd_soc_jack_report(wm5100->jack, | 2059 | snd_soc_jack_report(wm5100->jack, |
2184 | SND_JACK_HEADSET, | 2060 | SND_JACK_HEADSET, |
2185 | SND_JACK_HEADSET | SND_JACK_BTN_0); | 2061 | SND_JACK_HEADSET | SND_JACK_BTN_0); |
2186 | 2062 | ||
2187 | /* Increase poll rate to give better responsiveness | 2063 | /* Increase poll rate to give better responsiveness |
2188 | * for buttons */ | 2064 | * for buttons */ |
2189 | snd_soc_update_bits(codec, WM5100_MIC_DETECT_1, | 2065 | regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1, |
2190 | WM5100_ACCDET_RATE_MASK, | 2066 | WM5100_ACCDET_RATE_MASK, |
2191 | 5 << WM5100_ACCDET_RATE_SHIFT); | 2067 | 5 << WM5100_ACCDET_RATE_SHIFT); |
2192 | } else { | 2068 | } else { |
2193 | dev_dbg(codec->dev, "Mic button up\n"); | 2069 | dev_dbg(wm5100->dev, "Mic button up\n"); |
2194 | snd_soc_jack_report(wm5100->jack, 0, SND_JACK_BTN_0); | 2070 | snd_soc_jack_report(wm5100->jack, 0, SND_JACK_BTN_0); |
2195 | } | 2071 | } |
2196 | 2072 | ||
@@ -2200,10 +2076,16 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec) | |||
2200 | /* If we detected a lower impedence during initial startup | 2076 | /* If we detected a lower impedence during initial startup |
2201 | * then we probably have the wrong polarity, flip it. Don't | 2077 | * then we probably have the wrong polarity, flip it. Don't |
2202 | * do this for the lowest impedences to speed up detection of | 2078 | * do this for the lowest impedences to speed up detection of |
2203 | * plain headphones. | 2079 | * plain headphones and give up if neither polarity looks |
2080 | * sensible. | ||
2204 | */ | 2081 | */ |
2205 | if (wm5100->jack_detecting && (val & 0x3f8)) { | 2082 | if (wm5100->jack_detecting && (val & 0x3f8)) { |
2206 | wm5100_set_detect_mode(codec, !wm5100->jack_mode); | 2083 | wm5100->jack_flips++; |
2084 | |||
2085 | if (wm5100->jack_flips > 1) | ||
2086 | wm5100_report_headphone(wm5100); | ||
2087 | else | ||
2088 | wm5100_set_detect_mode(wm5100, !wm5100->jack_mode); | ||
2207 | 2089 | ||
2208 | return; | 2090 | return; |
2209 | } | 2091 | } |
@@ -2213,20 +2095,11 @@ static void wm5100_micd_irq(struct snd_soc_codec *codec) | |||
2213 | */ | 2095 | */ |
2214 | if (val & 0x3fc) { | 2096 | if (val & 0x3fc) { |
2215 | if (wm5100->jack_mic) { | 2097 | if (wm5100->jack_mic) { |
2216 | dev_dbg(codec->dev, "Mic button detected\n"); | 2098 | dev_dbg(wm5100->dev, "Mic button detected\n"); |
2217 | snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0, | 2099 | snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0, |
2218 | SND_JACK_BTN_0); | 2100 | SND_JACK_BTN_0); |
2219 | } else if (wm5100->jack_detecting) { | 2101 | } else if (wm5100->jack_detecting) { |
2220 | dev_dbg(codec->dev, "Headphone detected\n"); | 2102 | wm5100_report_headphone(wm5100); |
2221 | snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE, | ||
2222 | SND_JACK_HEADPHONE); | ||
2223 | |||
2224 | /* Increase the detection rate a bit for | ||
2225 | * responsiveness. | ||
2226 | */ | ||
2227 | snd_soc_update_bits(codec, WM5100_MIC_DETECT_1, | ||
2228 | WM5100_ACCDET_RATE_MASK, | ||
2229 | 7 << WM5100_ACCDET_RATE_SHIFT); | ||
2230 | } | 2103 | } |
2231 | } | 2104 | } |
2232 | } | 2105 | } |
@@ -2238,8 +2111,9 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) | |||
2238 | if (jack) { | 2111 | if (jack) { |
2239 | wm5100->jack = jack; | 2112 | wm5100->jack = jack; |
2240 | wm5100->jack_detecting = true; | 2113 | wm5100->jack_detecting = true; |
2114 | wm5100->jack_flips = 0; | ||
2241 | 2115 | ||
2242 | wm5100_set_detect_mode(codec, 0); | 2116 | wm5100_set_detect_mode(wm5100, 0); |
2243 | 2117 | ||
2244 | /* Slowest detection rate, gives debounce for initial | 2118 | /* Slowest detection rate, gives debounce for initial |
2245 | * detection */ | 2119 | * detection */ |
@@ -2278,52 +2152,70 @@ int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) | |||
2278 | 2152 | ||
2279 | static irqreturn_t wm5100_irq(int irq, void *data) | 2153 | static irqreturn_t wm5100_irq(int irq, void *data) |
2280 | { | 2154 | { |
2281 | struct snd_soc_codec *codec = data; | 2155 | struct wm5100_priv *wm5100 = data; |
2282 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
2283 | irqreturn_t status = IRQ_NONE; | 2156 | irqreturn_t status = IRQ_NONE; |
2284 | int irq_val; | 2157 | unsigned int irq_val, mask_val; |
2158 | int ret; | ||
2285 | 2159 | ||
2286 | irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3); | 2160 | ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_3, &irq_val); |
2287 | if (irq_val < 0) { | 2161 | if (ret < 0) { |
2288 | dev_err(codec->dev, "Failed to read IRQ status 3: %d\n", | 2162 | dev_err(wm5100->dev, "Failed to read IRQ status 3: %d\n", |
2289 | irq_val); | 2163 | ret); |
2290 | irq_val = 0; | 2164 | irq_val = 0; |
2291 | } | 2165 | } |
2292 | irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3_MASK); | ||
2293 | 2166 | ||
2294 | snd_soc_write(codec, WM5100_INTERRUPT_STATUS_3, irq_val); | 2167 | ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_3_MASK, |
2168 | &mask_val); | ||
2169 | if (ret < 0) { | ||
2170 | dev_err(wm5100->dev, "Failed to read IRQ mask 3: %d\n", | ||
2171 | ret); | ||
2172 | mask_val = 0xffff; | ||
2173 | } | ||
2174 | |||
2175 | irq_val &= ~mask_val; | ||
2176 | |||
2177 | regmap_write(wm5100->regmap, WM5100_INTERRUPT_STATUS_3, irq_val); | ||
2295 | 2178 | ||
2296 | if (irq_val) | 2179 | if (irq_val) |
2297 | status = IRQ_HANDLED; | 2180 | status = IRQ_HANDLED; |
2298 | 2181 | ||
2299 | wm5100_log_status3(codec, irq_val); | 2182 | wm5100_log_status3(wm5100, irq_val); |
2300 | 2183 | ||
2301 | if (irq_val & WM5100_FLL1_LOCK_EINT) { | 2184 | if (irq_val & WM5100_FLL1_LOCK_EINT) { |
2302 | dev_dbg(codec->dev, "FLL1 locked\n"); | 2185 | dev_dbg(wm5100->dev, "FLL1 locked\n"); |
2303 | complete(&wm5100->fll[0].lock); | 2186 | complete(&wm5100->fll[0].lock); |
2304 | } | 2187 | } |
2305 | if (irq_val & WM5100_FLL2_LOCK_EINT) { | 2188 | if (irq_val & WM5100_FLL2_LOCK_EINT) { |
2306 | dev_dbg(codec->dev, "FLL2 locked\n"); | 2189 | dev_dbg(wm5100->dev, "FLL2 locked\n"); |
2307 | complete(&wm5100->fll[1].lock); | 2190 | complete(&wm5100->fll[1].lock); |
2308 | } | 2191 | } |
2309 | 2192 | ||
2310 | if (irq_val & WM5100_ACCDET_EINT) | 2193 | if (irq_val & WM5100_ACCDET_EINT) |
2311 | wm5100_micd_irq(codec); | 2194 | wm5100_micd_irq(wm5100); |
2312 | 2195 | ||
2313 | irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4); | 2196 | ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_4, &irq_val); |
2314 | if (irq_val < 0) { | 2197 | if (ret < 0) { |
2315 | dev_err(codec->dev, "Failed to read IRQ status 4: %d\n", | 2198 | dev_err(wm5100->dev, "Failed to read IRQ status 4: %d\n", |
2316 | irq_val); | 2199 | ret); |
2317 | irq_val = 0; | 2200 | irq_val = 0; |
2318 | } | 2201 | } |
2319 | irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4_MASK); | 2202 | |
2203 | ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_4_MASK, | ||
2204 | &mask_val); | ||
2205 | if (ret < 0) { | ||
2206 | dev_err(wm5100->dev, "Failed to read IRQ mask 4: %d\n", | ||
2207 | ret); | ||
2208 | mask_val = 0xffff; | ||
2209 | } | ||
2210 | |||
2211 | irq_val &= ~mask_val; | ||
2320 | 2212 | ||
2321 | if (irq_val) | 2213 | if (irq_val) |
2322 | status = IRQ_HANDLED; | 2214 | status = IRQ_HANDLED; |
2323 | 2215 | ||
2324 | snd_soc_write(codec, WM5100_INTERRUPT_STATUS_4, irq_val); | 2216 | regmap_write(wm5100->regmap, WM5100_INTERRUPT_STATUS_4, irq_val); |
2325 | 2217 | ||
2326 | wm5100_log_status4(codec, irq_val); | 2218 | wm5100_log_status4(wm5100, irq_val); |
2327 | 2219 | ||
2328 | return status; | 2220 | return status; |
2329 | } | 2221 | } |
@@ -2448,7 +2340,7 @@ static int wm5100_probe(struct snd_soc_codec *codec) | |||
2448 | { | 2340 | { |
2449 | struct i2c_client *i2c = to_i2c_client(codec->dev); | 2341 | struct i2c_client *i2c = to_i2c_client(codec->dev); |
2450 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | 2342 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); |
2451 | int ret, i, irq_flags; | 2343 | int ret, i; |
2452 | 2344 | ||
2453 | wm5100->codec = codec; | 2345 | wm5100->codec = codec; |
2454 | codec->control_data = wm5100->regmap; | 2346 | codec->control_data = wm5100->regmap; |
@@ -2459,9 +2351,6 @@ static int wm5100_probe(struct snd_soc_codec *codec) | |||
2459 | return ret; | 2351 | return ret; |
2460 | } | 2352 | } |
2461 | 2353 | ||
2462 | regcache_cache_only(wm5100->regmap, true); | ||
2463 | |||
2464 | |||
2465 | for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++) | 2354 | for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++) |
2466 | snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU, | 2355 | snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU, |
2467 | WM5100_OUT_VU); | 2356 | WM5100_OUT_VU); |
@@ -2472,60 +2361,10 @@ static int wm5100_probe(struct snd_soc_codec *codec) | |||
2472 | 2361 | ||
2473 | /* TODO: check if we're symmetric */ | 2362 | /* TODO: check if we're symmetric */ |
2474 | 2363 | ||
2475 | if (i2c->irq) { | 2364 | if (i2c->irq) |
2476 | if (wm5100->pdata.irq_flags) | ||
2477 | irq_flags = wm5100->pdata.irq_flags; | ||
2478 | else | ||
2479 | irq_flags = IRQF_TRIGGER_LOW; | ||
2480 | |||
2481 | irq_flags |= IRQF_ONESHOT; | ||
2482 | |||
2483 | if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) | ||
2484 | ret = request_threaded_irq(i2c->irq, NULL, | ||
2485 | wm5100_edge_irq, | ||
2486 | irq_flags, "wm5100", codec); | ||
2487 | else | ||
2488 | ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq, | ||
2489 | irq_flags, "wm5100", codec); | ||
2490 | |||
2491 | if (ret != 0) { | ||
2492 | dev_err(codec->dev, "Failed to request IRQ %d: %d\n", | ||
2493 | i2c->irq, ret); | ||
2494 | } else { | ||
2495 | /* Enable default interrupts */ | ||
2496 | snd_soc_update_bits(codec, | ||
2497 | WM5100_INTERRUPT_STATUS_3_MASK, | ||
2498 | WM5100_IM_SPK_SHUTDOWN_WARN_EINT | | ||
2499 | WM5100_IM_SPK_SHUTDOWN_EINT | | ||
2500 | WM5100_IM_ASRC2_LOCK_EINT | | ||
2501 | WM5100_IM_ASRC1_LOCK_EINT | | ||
2502 | WM5100_IM_FLL2_LOCK_EINT | | ||
2503 | WM5100_IM_FLL1_LOCK_EINT | | ||
2504 | WM5100_CLKGEN_ERR_EINT | | ||
2505 | WM5100_CLKGEN_ERR_ASYNC_EINT, 0); | ||
2506 | |||
2507 | snd_soc_update_bits(codec, | ||
2508 | WM5100_INTERRUPT_STATUS_4_MASK, | ||
2509 | WM5100_AIF3_ERR_EINT | | ||
2510 | WM5100_AIF2_ERR_EINT | | ||
2511 | WM5100_AIF1_ERR_EINT | | ||
2512 | WM5100_CTRLIF_ERR_EINT | | ||
2513 | WM5100_ISRC2_UNDERCLOCKED_EINT | | ||
2514 | WM5100_ISRC1_UNDERCLOCKED_EINT | | ||
2515 | WM5100_FX_UNDERCLOCKED_EINT | | ||
2516 | WM5100_AIF3_UNDERCLOCKED_EINT | | ||
2517 | WM5100_AIF2_UNDERCLOCKED_EINT | | ||
2518 | WM5100_AIF1_UNDERCLOCKED_EINT | | ||
2519 | WM5100_ASRC_UNDERCLOCKED_EINT | | ||
2520 | WM5100_DAC_UNDERCLOCKED_EINT | | ||
2521 | WM5100_ADC_UNDERCLOCKED_EINT | | ||
2522 | WM5100_MIXER_UNDERCLOCKED_EINT, 0); | ||
2523 | } | ||
2524 | } else { | ||
2525 | snd_soc_dapm_new_controls(&codec->dapm, | 2365 | snd_soc_dapm_new_controls(&codec->dapm, |
2526 | wm5100_dapm_widgets_noirq, | 2366 | wm5100_dapm_widgets_noirq, |
2527 | ARRAY_SIZE(wm5100_dapm_widgets_noirq)); | 2367 | ARRAY_SIZE(wm5100_dapm_widgets_noirq)); |
2528 | } | ||
2529 | 2368 | ||
2530 | if (wm5100->pdata.hp_pol) { | 2369 | if (wm5100->pdata.hp_pol) { |
2531 | ret = gpio_request_one(wm5100->pdata.hp_pol, | 2370 | ret = gpio_request_one(wm5100->pdata.hp_pol, |
@@ -2537,19 +2376,9 @@ static int wm5100_probe(struct snd_soc_codec *codec) | |||
2537 | } | 2376 | } |
2538 | } | 2377 | } |
2539 | 2378 | ||
2540 | /* We'll get woken up again when the system has something useful | ||
2541 | * for us to do. | ||
2542 | */ | ||
2543 | if (wm5100->pdata.ldo_ena) | ||
2544 | gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); | ||
2545 | regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), | ||
2546 | wm5100->core_supplies); | ||
2547 | |||
2548 | return 0; | 2379 | return 0; |
2549 | 2380 | ||
2550 | err_gpio: | 2381 | err_gpio: |
2551 | if (i2c->irq) | ||
2552 | free_irq(i2c->irq, codec); | ||
2553 | 2382 | ||
2554 | return ret; | 2383 | return ret; |
2555 | } | 2384 | } |
@@ -2557,14 +2386,11 @@ err_gpio: | |||
2557 | static int wm5100_remove(struct snd_soc_codec *codec) | 2386 | static int wm5100_remove(struct snd_soc_codec *codec) |
2558 | { | 2387 | { |
2559 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | 2388 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); |
2560 | struct i2c_client *i2c = to_i2c_client(codec->dev); | ||
2561 | 2389 | ||
2562 | wm5100_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
2563 | if (wm5100->pdata.hp_pol) { | 2390 | if (wm5100->pdata.hp_pol) { |
2564 | gpio_free(wm5100->pdata.hp_pol); | 2391 | gpio_free(wm5100->pdata.hp_pol); |
2565 | } | 2392 | } |
2566 | if (i2c->irq) | 2393 | |
2567 | free_irq(i2c->irq, codec); | ||
2568 | return 0; | 2394 | return 0; |
2569 | } | 2395 | } |
2570 | 2396 | ||
@@ -2581,7 +2407,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5100 = { | |||
2581 | 2407 | ||
2582 | .set_sysclk = wm5100_set_sysclk, | 2408 | .set_sysclk = wm5100_set_sysclk, |
2583 | .set_pll = wm5100_set_fll, | 2409 | .set_pll = wm5100_set_fll, |
2584 | .set_bias_level = wm5100_set_bias_level, | ||
2585 | .idle_bias_off = 1, | 2410 | .idle_bias_off = 1, |
2586 | .reg_cache_size = WM5100_MAX_REGISTER, | 2411 | .reg_cache_size = WM5100_MAX_REGISTER, |
2587 | .volatile_register = wm5100_soc_volatile, | 2412 | .volatile_register = wm5100_soc_volatile, |
@@ -2607,19 +2432,28 @@ static const struct regmap_config wm5100_regmap = { | |||
2607 | .cache_type = REGCACHE_RBTREE, | 2432 | .cache_type = REGCACHE_RBTREE, |
2608 | }; | 2433 | }; |
2609 | 2434 | ||
2435 | static const unsigned int wm5100_mic_ctrl_reg[] = { | ||
2436 | WM5100_IN1L_CONTROL, | ||
2437 | WM5100_IN2L_CONTROL, | ||
2438 | WM5100_IN3L_CONTROL, | ||
2439 | WM5100_IN4L_CONTROL, | ||
2440 | }; | ||
2441 | |||
2610 | static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, | 2442 | static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, |
2611 | const struct i2c_device_id *id) | 2443 | const struct i2c_device_id *id) |
2612 | { | 2444 | { |
2613 | struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev); | 2445 | struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev); |
2614 | struct wm5100_priv *wm5100; | 2446 | struct wm5100_priv *wm5100; |
2615 | unsigned int reg; | 2447 | unsigned int reg; |
2616 | int ret, i; | 2448 | int ret, i, irq_flags; |
2617 | 2449 | ||
2618 | wm5100 = devm_kzalloc(&i2c->dev, sizeof(struct wm5100_priv), | 2450 | wm5100 = devm_kzalloc(&i2c->dev, sizeof(struct wm5100_priv), |
2619 | GFP_KERNEL); | 2451 | GFP_KERNEL); |
2620 | if (wm5100 == NULL) | 2452 | if (wm5100 == NULL) |
2621 | return -ENOMEM; | 2453 | return -ENOMEM; |
2622 | 2454 | ||
2455 | wm5100->dev = &i2c->dev; | ||
2456 | |||
2623 | wm5100->regmap = regmap_init_i2c(i2c, &wm5100_regmap); | 2457 | wm5100->regmap = regmap_init_i2c(i2c, &wm5100_regmap); |
2624 | if (IS_ERR(wm5100->regmap)) { | 2458 | if (IS_ERR(wm5100->regmap)) { |
2625 | ret = PTR_ERR(wm5100->regmap); | 2459 | ret = PTR_ERR(wm5100->regmap); |
@@ -2639,41 +2473,21 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, | |||
2639 | for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++) | 2473 | for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++) |
2640 | wm5100->core_supplies[i].supply = wm5100_core_supply_names[i]; | 2474 | wm5100->core_supplies[i].supply = wm5100_core_supply_names[i]; |
2641 | 2475 | ||
2642 | ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies), | 2476 | ret = devm_regulator_bulk_get(&i2c->dev, |
2643 | wm5100->core_supplies); | 2477 | ARRAY_SIZE(wm5100->core_supplies), |
2478 | wm5100->core_supplies); | ||
2644 | if (ret != 0) { | 2479 | if (ret != 0) { |
2645 | dev_err(&i2c->dev, "Failed to request core supplies: %d\n", | 2480 | dev_err(&i2c->dev, "Failed to request core supplies: %d\n", |
2646 | ret); | 2481 | ret); |
2647 | goto err_regmap; | 2482 | goto err_regmap; |
2648 | } | 2483 | } |
2649 | 2484 | ||
2650 | wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD"); | ||
2651 | if (IS_ERR(wm5100->cpvdd)) { | ||
2652 | ret = PTR_ERR(wm5100->cpvdd); | ||
2653 | dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret); | ||
2654 | goto err_core; | ||
2655 | } | ||
2656 | |||
2657 | wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2"); | ||
2658 | if (IS_ERR(wm5100->dbvdd2)) { | ||
2659 | ret = PTR_ERR(wm5100->dbvdd2); | ||
2660 | dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret); | ||
2661 | goto err_cpvdd; | ||
2662 | } | ||
2663 | |||
2664 | wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3"); | ||
2665 | if (IS_ERR(wm5100->dbvdd3)) { | ||
2666 | ret = PTR_ERR(wm5100->dbvdd3); | ||
2667 | dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret); | ||
2668 | goto err_dbvdd2; | ||
2669 | } | ||
2670 | |||
2671 | ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies), | 2485 | ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies), |
2672 | wm5100->core_supplies); | 2486 | wm5100->core_supplies); |
2673 | if (ret != 0) { | 2487 | if (ret != 0) { |
2674 | dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", | 2488 | dev_err(&i2c->dev, "Failed to enable core supplies: %d\n", |
2675 | ret); | 2489 | ret); |
2676 | goto err_dbvdd3; | 2490 | goto err_regmap; |
2677 | } | 2491 | } |
2678 | 2492 | ||
2679 | if (wm5100->pdata.ldo_ena) { | 2493 | if (wm5100->pdata.ldo_ena) { |
@@ -2699,7 +2513,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, | |||
2699 | 2513 | ||
2700 | ret = regmap_read(wm5100->regmap, WM5100_SOFTWARE_RESET, ®); | 2514 | ret = regmap_read(wm5100->regmap, WM5100_SOFTWARE_RESET, ®); |
2701 | if (ret < 0) { | 2515 | if (ret < 0) { |
2702 | dev_err(&i2c->dev, "Failed to read ID register\n"); | 2516 | dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret); |
2703 | goto err_reset; | 2517 | goto err_reset; |
2704 | } | 2518 | } |
2705 | switch (reg) { | 2519 | switch (reg) { |
@@ -2728,6 +2542,22 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, | |||
2728 | goto err_reset; | 2542 | goto err_reset; |
2729 | } | 2543 | } |
2730 | 2544 | ||
2545 | switch (wm5100->rev) { | ||
2546 | case 0: | ||
2547 | ret = regmap_register_patch(wm5100->regmap, | ||
2548 | wm5100_reva_patches, | ||
2549 | ARRAY_SIZE(wm5100_reva_patches)); | ||
2550 | if (ret != 0) { | ||
2551 | dev_err(&i2c->dev, "Failed to register patches: %d\n", | ||
2552 | ret); | ||
2553 | goto err_reset; | ||
2554 | } | ||
2555 | break; | ||
2556 | default: | ||
2557 | break; | ||
2558 | } | ||
2559 | |||
2560 | |||
2731 | wm5100_init_gpio(i2c); | 2561 | wm5100_init_gpio(i2c); |
2732 | 2562 | ||
2733 | for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) { | 2563 | for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) { |
@@ -2739,7 +2569,7 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, | |||
2739 | } | 2569 | } |
2740 | 2570 | ||
2741 | for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) { | 2571 | for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) { |
2742 | regmap_update_bits(wm5100->regmap, WM5100_IN1L_CONTROL, | 2572 | regmap_update_bits(wm5100->regmap, wm5100_mic_ctrl_reg[i], |
2743 | WM5100_IN1_MODE_MASK | | 2573 | WM5100_IN1_MODE_MASK | |
2744 | WM5100_IN1_DMIC_SUP_MASK, | 2574 | WM5100_IN1_DMIC_SUP_MASK, |
2745 | (wm5100->pdata.in_mode[i] << | 2575 | (wm5100->pdata.in_mode[i] << |
@@ -2748,6 +2578,62 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, | |||
2748 | WM5100_IN1_DMIC_SUP_SHIFT)); | 2578 | WM5100_IN1_DMIC_SUP_SHIFT)); |
2749 | } | 2579 | } |
2750 | 2580 | ||
2581 | if (i2c->irq) { | ||
2582 | if (wm5100->pdata.irq_flags) | ||
2583 | irq_flags = wm5100->pdata.irq_flags; | ||
2584 | else | ||
2585 | irq_flags = IRQF_TRIGGER_LOW; | ||
2586 | |||
2587 | irq_flags |= IRQF_ONESHOT; | ||
2588 | |||
2589 | if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) | ||
2590 | ret = request_threaded_irq(i2c->irq, NULL, | ||
2591 | wm5100_edge_irq, irq_flags, | ||
2592 | "wm5100", wm5100); | ||
2593 | else | ||
2594 | ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq, | ||
2595 | irq_flags, "wm5100", | ||
2596 | wm5100); | ||
2597 | |||
2598 | if (ret != 0) { | ||
2599 | dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n", | ||
2600 | i2c->irq, ret); | ||
2601 | } else { | ||
2602 | /* Enable default interrupts */ | ||
2603 | regmap_update_bits(wm5100->regmap, | ||
2604 | WM5100_INTERRUPT_STATUS_3_MASK, | ||
2605 | WM5100_IM_SPK_SHUTDOWN_WARN_EINT | | ||
2606 | WM5100_IM_SPK_SHUTDOWN_EINT | | ||
2607 | WM5100_IM_ASRC2_LOCK_EINT | | ||
2608 | WM5100_IM_ASRC1_LOCK_EINT | | ||
2609 | WM5100_IM_FLL2_LOCK_EINT | | ||
2610 | WM5100_IM_FLL1_LOCK_EINT | | ||
2611 | WM5100_CLKGEN_ERR_EINT | | ||
2612 | WM5100_CLKGEN_ERR_ASYNC_EINT, 0); | ||
2613 | |||
2614 | regmap_update_bits(wm5100->regmap, | ||
2615 | WM5100_INTERRUPT_STATUS_4_MASK, | ||
2616 | WM5100_AIF3_ERR_EINT | | ||
2617 | WM5100_AIF2_ERR_EINT | | ||
2618 | WM5100_AIF1_ERR_EINT | | ||
2619 | WM5100_CTRLIF_ERR_EINT | | ||
2620 | WM5100_ISRC2_UNDERCLOCKED_EINT | | ||
2621 | WM5100_ISRC1_UNDERCLOCKED_EINT | | ||
2622 | WM5100_FX_UNDERCLOCKED_EINT | | ||
2623 | WM5100_AIF3_UNDERCLOCKED_EINT | | ||
2624 | WM5100_AIF2_UNDERCLOCKED_EINT | | ||
2625 | WM5100_AIF1_UNDERCLOCKED_EINT | | ||
2626 | WM5100_ASRC_UNDERCLOCKED_EINT | | ||
2627 | WM5100_DAC_UNDERCLOCKED_EINT | | ||
2628 | WM5100_ADC_UNDERCLOCKED_EINT | | ||
2629 | WM5100_MIXER_UNDERCLOCKED_EINT, 0); | ||
2630 | } | ||
2631 | } | ||
2632 | |||
2633 | pm_runtime_set_active(&i2c->dev); | ||
2634 | pm_runtime_enable(&i2c->dev); | ||
2635 | pm_request_idle(&i2c->dev); | ||
2636 | |||
2751 | ret = snd_soc_register_codec(&i2c->dev, | 2637 | ret = snd_soc_register_codec(&i2c->dev, |
2752 | &soc_codec_dev_wm5100, wm5100_dai, | 2638 | &soc_codec_dev_wm5100, wm5100_dai, |
2753 | ARRAY_SIZE(wm5100_dai)); | 2639 | ARRAY_SIZE(wm5100_dai)); |
@@ -2759,9 +2645,11 @@ static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, | |||
2759 | return ret; | 2645 | return ret; |
2760 | 2646 | ||
2761 | err_reset: | 2647 | err_reset: |
2648 | if (i2c->irq) | ||
2649 | free_irq(i2c->irq, wm5100); | ||
2762 | wm5100_free_gpio(i2c); | 2650 | wm5100_free_gpio(i2c); |
2763 | if (wm5100->pdata.reset) { | 2651 | if (wm5100->pdata.reset) { |
2764 | gpio_set_value_cansleep(wm5100->pdata.reset, 1); | 2652 | gpio_set_value_cansleep(wm5100->pdata.reset, 0); |
2765 | gpio_free(wm5100->pdata.reset); | 2653 | gpio_free(wm5100->pdata.reset); |
2766 | } | 2654 | } |
2767 | err_ldo: | 2655 | err_ldo: |
@@ -2772,45 +2660,78 @@ err_ldo: | |||
2772 | err_enable: | 2660 | err_enable: |
2773 | regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), | 2661 | regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), |
2774 | wm5100->core_supplies); | 2662 | wm5100->core_supplies); |
2775 | err_dbvdd3: | ||
2776 | regulator_put(wm5100->dbvdd3); | ||
2777 | err_dbvdd2: | ||
2778 | regulator_put(wm5100->dbvdd2); | ||
2779 | err_cpvdd: | ||
2780 | regulator_put(wm5100->cpvdd); | ||
2781 | err_core: | ||
2782 | regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies), | ||
2783 | wm5100->core_supplies); | ||
2784 | err_regmap: | 2663 | err_regmap: |
2785 | regmap_exit(wm5100->regmap); | 2664 | regmap_exit(wm5100->regmap); |
2786 | err: | 2665 | err: |
2787 | return ret; | 2666 | return ret; |
2788 | } | 2667 | } |
2789 | 2668 | ||
2790 | static __devexit int wm5100_i2c_remove(struct i2c_client *client) | 2669 | static __devexit int wm5100_i2c_remove(struct i2c_client *i2c) |
2791 | { | 2670 | { |
2792 | struct wm5100_priv *wm5100 = i2c_get_clientdata(client); | 2671 | struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c); |
2793 | 2672 | ||
2794 | snd_soc_unregister_codec(&client->dev); | 2673 | snd_soc_unregister_codec(&i2c->dev); |
2795 | wm5100_free_gpio(client); | 2674 | if (i2c->irq) |
2675 | free_irq(i2c->irq, wm5100); | ||
2676 | wm5100_free_gpio(i2c); | ||
2796 | if (wm5100->pdata.reset) { | 2677 | if (wm5100->pdata.reset) { |
2797 | gpio_set_value_cansleep(wm5100->pdata.reset, 1); | 2678 | gpio_set_value_cansleep(wm5100->pdata.reset, 0); |
2798 | gpio_free(wm5100->pdata.reset); | 2679 | gpio_free(wm5100->pdata.reset); |
2799 | } | 2680 | } |
2800 | if (wm5100->pdata.ldo_ena) { | 2681 | if (wm5100->pdata.ldo_ena) { |
2801 | gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); | 2682 | gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); |
2802 | gpio_free(wm5100->pdata.ldo_ena); | 2683 | gpio_free(wm5100->pdata.ldo_ena); |
2803 | } | 2684 | } |
2804 | regulator_put(wm5100->dbvdd3); | ||
2805 | regulator_put(wm5100->dbvdd2); | ||
2806 | regulator_put(wm5100->cpvdd); | ||
2807 | regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies), | ||
2808 | wm5100->core_supplies); | ||
2809 | regmap_exit(wm5100->regmap); | 2685 | regmap_exit(wm5100->regmap); |
2810 | 2686 | ||
2811 | return 0; | 2687 | return 0; |
2812 | } | 2688 | } |
2813 | 2689 | ||
2690 | #ifdef CONFIG_PM_RUNTIME | ||
2691 | static int wm5100_runtime_suspend(struct device *dev) | ||
2692 | { | ||
2693 | struct wm5100_priv *wm5100 = dev_get_drvdata(dev); | ||
2694 | |||
2695 | regcache_cache_only(wm5100->regmap, true); | ||
2696 | regcache_mark_dirty(wm5100->regmap); | ||
2697 | if (wm5100->pdata.ldo_ena) | ||
2698 | gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); | ||
2699 | regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), | ||
2700 | wm5100->core_supplies); | ||
2701 | |||
2702 | return 0; | ||
2703 | } | ||
2704 | |||
2705 | static int wm5100_runtime_resume(struct device *dev) | ||
2706 | { | ||
2707 | struct wm5100_priv *wm5100 = dev_get_drvdata(dev); | ||
2708 | int ret; | ||
2709 | |||
2710 | ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies), | ||
2711 | wm5100->core_supplies); | ||
2712 | if (ret != 0) { | ||
2713 | dev_err(dev, "Failed to enable supplies: %d\n", | ||
2714 | ret); | ||
2715 | return ret; | ||
2716 | } | ||
2717 | |||
2718 | if (wm5100->pdata.ldo_ena) { | ||
2719 | gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 1); | ||
2720 | msleep(2); | ||
2721 | } | ||
2722 | |||
2723 | regcache_cache_only(wm5100->regmap, false); | ||
2724 | regcache_sync(wm5100->regmap); | ||
2725 | |||
2726 | return 0; | ||
2727 | } | ||
2728 | #endif | ||
2729 | |||
2730 | static struct dev_pm_ops wm5100_pm = { | ||
2731 | SET_RUNTIME_PM_OPS(wm5100_runtime_suspend, wm5100_runtime_resume, | ||
2732 | NULL) | ||
2733 | }; | ||
2734 | |||
2814 | static const struct i2c_device_id wm5100_i2c_id[] = { | 2735 | static const struct i2c_device_id wm5100_i2c_id[] = { |
2815 | { "wm5100", 0 }, | 2736 | { "wm5100", 0 }, |
2816 | { } | 2737 | { } |
@@ -2821,6 +2742,7 @@ static struct i2c_driver wm5100_i2c_driver = { | |||
2821 | .driver = { | 2742 | .driver = { |
2822 | .name = "wm5100", | 2743 | .name = "wm5100", |
2823 | .owner = THIS_MODULE, | 2744 | .owner = THIS_MODULE, |
2745 | .pm = &wm5100_pm, | ||
2824 | }, | 2746 | }, |
2825 | .probe = wm5100_i2c_probe, | 2747 | .probe = wm5100_i2c_probe, |
2826 | .remove = __devexit_p(wm5100_i2c_remove), | 2748 | .remove = __devexit_p(wm5100_i2c_remove), |
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 8821af70e660..a32caa72bd7d 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/pm.h> | 19 | #include <linux/pm.h> |
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/regmap.h> | ||
22 | #include <linux/regulator/consumer.h> | 23 | #include <linux/regulator/consumer.h> |
23 | #include <linux/spi/spi.h> | 24 | #include <linux/spi/spi.h> |
24 | #include <linux/of_device.h> | 25 | #include <linux/of_device.h> |
@@ -41,7 +42,7 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { | |||
41 | 42 | ||
42 | /* codec private data */ | 43 | /* codec private data */ |
43 | struct wm8731_priv { | 44 | struct wm8731_priv { |
44 | enum snd_soc_control_type control_type; | 45 | struct regmap *regmap; |
45 | struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; | 46 | struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; |
46 | unsigned int sysclk; | 47 | unsigned int sysclk; |
47 | int sysclk_type; | 48 | int sysclk_type; |
@@ -52,16 +53,30 @@ struct wm8731_priv { | |||
52 | 53 | ||
53 | /* | 54 | /* |
54 | * wm8731 register cache | 55 | * wm8731 register cache |
55 | * We can't read the WM8731 register space when we are | ||
56 | * using 2 wire for device control, so we cache them instead. | ||
57 | * There is no point in caching the reset register | ||
58 | */ | 56 | */ |
59 | static const u16 wm8731_reg[WM8731_CACHEREGNUM] = { | 57 | static const struct reg_default wm8731_reg_defaults[] = { |
60 | 0x0097, 0x0097, 0x0079, 0x0079, | 58 | { 0, 0x0097 }, |
61 | 0x000a, 0x0008, 0x009f, 0x000a, | 59 | { 1, 0x0097 }, |
62 | 0x0000, 0x0000 | 60 | { 2, 0x0079 }, |
61 | { 3, 0x0079 }, | ||
62 | { 4, 0x000a }, | ||
63 | { 5, 0x0008 }, | ||
64 | { 6, 0x009f }, | ||
65 | { 7, 0x000a }, | ||
66 | { 8, 0x0000 }, | ||
67 | { 9, 0x0000 }, | ||
63 | }; | 68 | }; |
64 | 69 | ||
70 | static bool wm8731_volatile(struct device *dev, unsigned int reg) | ||
71 | { | ||
72 | return reg == WM8731_RESET; | ||
73 | } | ||
74 | |||
75 | static bool wm8731_writeable(struct device *dev, unsigned int reg) | ||
76 | { | ||
77 | return reg <= WM8731_RESET; | ||
78 | } | ||
79 | |||
65 | #define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0) | 80 | #define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0) |
66 | 81 | ||
67 | static const char *wm8731_input_select[] = {"Line In", "Mic"}; | 82 | static const char *wm8731_input_select[] = {"Line In", "Mic"}; |
@@ -441,7 +456,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, | |||
441 | if (ret != 0) | 456 | if (ret != 0) |
442 | return ret; | 457 | return ret; |
443 | 458 | ||
444 | snd_soc_cache_sync(codec); | 459 | regcache_sync(wm8731->regmap); |
445 | } | 460 | } |
446 | 461 | ||
447 | /* Clear PWROFF, gate CLKOUT, everything else as-is */ | 462 | /* Clear PWROFF, gate CLKOUT, everything else as-is */ |
@@ -452,7 +467,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, | |||
452 | snd_soc_write(codec, WM8731_PWR, 0xffff); | 467 | snd_soc_write(codec, WM8731_PWR, 0xffff); |
453 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), | 468 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), |
454 | wm8731->supplies); | 469 | wm8731->supplies); |
455 | codec->cache_sync = 1; | 470 | regcache_mark_dirty(wm8731->regmap); |
456 | break; | 471 | break; |
457 | } | 472 | } |
458 | codec->dapm.bias_level = level; | 473 | codec->dapm.bias_level = level; |
@@ -513,7 +528,8 @@ static int wm8731_probe(struct snd_soc_codec *codec) | |||
513 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | 528 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
514 | int ret = 0, i; | 529 | int ret = 0, i; |
515 | 530 | ||
516 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8731->control_type); | 531 | codec->control_data = wm8731->regmap; |
532 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
517 | if (ret < 0) { | 533 | if (ret < 0) { |
518 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 534 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
519 | return ret; | 535 | return ret; |
@@ -585,9 +601,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = { | |||
585 | .suspend = wm8731_suspend, | 601 | .suspend = wm8731_suspend, |
586 | .resume = wm8731_resume, | 602 | .resume = wm8731_resume, |
587 | .set_bias_level = wm8731_set_bias_level, | 603 | .set_bias_level = wm8731_set_bias_level, |
588 | .reg_cache_size = ARRAY_SIZE(wm8731_reg), | ||
589 | .reg_word_size = sizeof(u16), | ||
590 | .reg_cache_default = wm8731_reg, | ||
591 | .dapm_widgets = wm8731_dapm_widgets, | 604 | .dapm_widgets = wm8731_dapm_widgets, |
592 | .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), | 605 | .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), |
593 | .dapm_routes = wm8731_intercon, | 606 | .dapm_routes = wm8731_intercon, |
@@ -603,6 +616,19 @@ static const struct of_device_id wm8731_of_match[] = { | |||
603 | 616 | ||
604 | MODULE_DEVICE_TABLE(of, wm8731_of_match); | 617 | MODULE_DEVICE_TABLE(of, wm8731_of_match); |
605 | 618 | ||
619 | static const struct regmap_config wm8731_regmap = { | ||
620 | .reg_bits = 7, | ||
621 | .val_bits = 9, | ||
622 | |||
623 | .max_register = WM8731_RESET, | ||
624 | .volatile_reg = wm8731_volatile, | ||
625 | .writeable_reg = wm8731_writeable, | ||
626 | |||
627 | .cache_type = REGCACHE_RBTREE, | ||
628 | .reg_defaults = wm8731_reg_defaults, | ||
629 | .num_reg_defaults = ARRAY_SIZE(wm8731_reg_defaults), | ||
630 | }; | ||
631 | |||
606 | #if defined(CONFIG_SPI_MASTER) | 632 | #if defined(CONFIG_SPI_MASTER) |
607 | static int __devinit wm8731_spi_probe(struct spi_device *spi) | 633 | static int __devinit wm8731_spi_probe(struct spi_device *spi) |
608 | { | 634 | { |
@@ -613,20 +639,39 @@ static int __devinit wm8731_spi_probe(struct spi_device *spi) | |||
613 | if (wm8731 == NULL) | 639 | if (wm8731 == NULL) |
614 | return -ENOMEM; | 640 | return -ENOMEM; |
615 | 641 | ||
616 | wm8731->control_type = SND_SOC_SPI; | 642 | wm8731->regmap = regmap_init_spi(spi, &wm8731_regmap); |
643 | if (IS_ERR(wm8731->regmap)) { | ||
644 | ret = PTR_ERR(wm8731->regmap); | ||
645 | dev_err(&spi->dev, "Failed to allocate register map: %d\n", | ||
646 | ret); | ||
647 | goto err; | ||
648 | } | ||
649 | |||
617 | spi_set_drvdata(spi, wm8731); | 650 | spi_set_drvdata(spi, wm8731); |
618 | 651 | ||
619 | ret = snd_soc_register_codec(&spi->dev, | 652 | ret = snd_soc_register_codec(&spi->dev, |
620 | &soc_codec_dev_wm8731, &wm8731_dai, 1); | 653 | &soc_codec_dev_wm8731, &wm8731_dai, 1); |
621 | if (ret < 0) | 654 | if (ret != 0) { |
622 | kfree(wm8731); | 655 | dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); |
656 | goto err_regmap; | ||
657 | } | ||
658 | |||
659 | return 0; | ||
660 | |||
661 | err_regmap: | ||
662 | regmap_exit(wm8731->regmap); | ||
663 | err: | ||
664 | kfree(wm8731); | ||
623 | return ret; | 665 | return ret; |
624 | } | 666 | } |
625 | 667 | ||
626 | static int __devexit wm8731_spi_remove(struct spi_device *spi) | 668 | static int __devexit wm8731_spi_remove(struct spi_device *spi) |
627 | { | 669 | { |
670 | struct wm8731_priv *wm8731 = spi_get_drvdata(spi); | ||
671 | |||
628 | snd_soc_unregister_codec(&spi->dev); | 672 | snd_soc_unregister_codec(&spi->dev); |
629 | kfree(spi_get_drvdata(spi)); | 673 | regmap_exit(wm8731->regmap); |
674 | kfree(wm8731); | ||
630 | return 0; | 675 | return 0; |
631 | } | 676 | } |
632 | 677 | ||
@@ -652,20 +697,38 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c, | |||
652 | if (wm8731 == NULL) | 697 | if (wm8731 == NULL) |
653 | return -ENOMEM; | 698 | return -ENOMEM; |
654 | 699 | ||
700 | wm8731->regmap = regmap_init_i2c(i2c, &wm8731_regmap); | ||
701 | if (IS_ERR(wm8731->regmap)) { | ||
702 | ret = PTR_ERR(wm8731->regmap); | ||
703 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
704 | ret); | ||
705 | goto err; | ||
706 | } | ||
707 | |||
655 | i2c_set_clientdata(i2c, wm8731); | 708 | i2c_set_clientdata(i2c, wm8731); |
656 | wm8731->control_type = SND_SOC_I2C; | ||
657 | 709 | ||
658 | ret = snd_soc_register_codec(&i2c->dev, | 710 | ret = snd_soc_register_codec(&i2c->dev, |
659 | &soc_codec_dev_wm8731, &wm8731_dai, 1); | 711 | &soc_codec_dev_wm8731, &wm8731_dai, 1); |
660 | if (ret < 0) | 712 | if (ret != 0) { |
661 | kfree(wm8731); | 713 | dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); |
714 | goto err_regmap; | ||
715 | } | ||
716 | |||
717 | return 0; | ||
718 | |||
719 | err_regmap: | ||
720 | regmap_exit(wm8731->regmap); | ||
721 | err: | ||
722 | kfree(wm8731); | ||
662 | return ret; | 723 | return ret; |
663 | } | 724 | } |
664 | 725 | ||
665 | static __devexit int wm8731_i2c_remove(struct i2c_client *client) | 726 | static __devexit int wm8731_i2c_remove(struct i2c_client *client) |
666 | { | 727 | { |
728 | struct wm8731_priv *wm8731 = i2c_get_clientdata(client); | ||
667 | snd_soc_unregister_codec(&client->dev); | 729 | snd_soc_unregister_codec(&client->dev); |
668 | kfree(i2c_get_clientdata(client)); | 730 | regmap_exit(wm8731->regmap); |
731 | kfree(wm8731); | ||
669 | return 0; | 732 | return 0; |
670 | } | 733 | } |
671 | 734 | ||
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index ff95e62c56b9..4fe9d191e277 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c | |||
@@ -599,7 +599,7 @@ static int wm8737_probe(struct snd_soc_codec *codec) | |||
599 | /* Bias level configuration will have done an extra enable */ | 599 | /* Bias level configuration will have done an extra enable */ |
600 | regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); | 600 | regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); |
601 | 601 | ||
602 | snd_soc_add_controls(codec, wm8737_snd_controls, | 602 | snd_soc_add_codec_controls(codec, wm8737_snd_controls, |
603 | ARRAY_SIZE(wm8737_snd_controls)); | 603 | ARRAY_SIZE(wm8737_snd_controls)); |
604 | wm8737_add_widgets(codec); | 604 | wm8737_add_widgets(codec); |
605 | 605 | ||
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index b114c19f530a..e27e7b62b365 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/pm.h> | 39 | #include <linux/pm.h> |
40 | #include <linux/i2c.h> | 40 | #include <linux/i2c.h> |
41 | #include <linux/of_device.h> | 41 | #include <linux/of_device.h> |
42 | #include <linux/regmap.h> | ||
42 | #include <linux/spi/spi.h> | 43 | #include <linux/spi/spi.h> |
43 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
44 | #include <sound/core.h> | 45 | #include <sound/core.h> |
@@ -65,28 +66,86 @@ static int wm8753_voice_write_dai_fmt(struct snd_soc_codec *codec, | |||
65 | * We can't read the WM8753 register space when we | 66 | * We can't read the WM8753 register space when we |
66 | * are using 2 wire for device control, so we cache them instead. | 67 | * are using 2 wire for device control, so we cache them instead. |
67 | */ | 68 | */ |
68 | static const u16 wm8753_reg[] = { | 69 | static const struct reg_default wm8753_reg_defaults[] = { |
69 | 0x0000, 0x0008, 0x0000, 0x000a, | 70 | { 0x00, 0x0000 }, |
70 | 0x000a, 0x0033, 0x0000, 0x0007, | 71 | { 0x01, 0x0008 }, |
71 | 0x00ff, 0x00ff, 0x000f, 0x000f, | 72 | { 0x02, 0x0000 }, |
72 | 0x007b, 0x0000, 0x0032, 0x0000, | 73 | { 0x03, 0x000a }, |
73 | 0x00c3, 0x00c3, 0x00c0, 0x0000, | 74 | { 0x04, 0x000a }, |
74 | 0x0000, 0x0000, 0x0000, 0x0000, | 75 | { 0x05, 0x0033 }, |
75 | 0x0000, 0x0000, 0x0000, 0x0000, | 76 | { 0x06, 0x0000 }, |
76 | 0x0000, 0x0000, 0x0000, 0x0000, | 77 | { 0x07, 0x0007 }, |
77 | 0x0055, 0x0005, 0x0050, 0x0055, | 78 | { 0x08, 0x00ff }, |
78 | 0x0050, 0x0055, 0x0050, 0x0055, | 79 | { 0x09, 0x00ff }, |
79 | 0x0079, 0x0079, 0x0079, 0x0079, | 80 | { 0x0a, 0x000f }, |
80 | 0x0079, 0x0000, 0x0000, 0x0000, | 81 | { 0x0b, 0x000f }, |
81 | 0x0000, 0x0097, 0x0097, 0x0000, | 82 | { 0x0c, 0x007b }, |
82 | 0x0004, 0x0000, 0x0083, 0x0024, | 83 | { 0x0d, 0x0000 }, |
83 | 0x01ba, 0x0000, 0x0083, 0x0024, | 84 | { 0x0e, 0x0032 }, |
84 | 0x01ba, 0x0000, 0x0000, 0x0000 | 85 | { 0x0f, 0x0000 }, |
86 | { 0x10, 0x00c3 }, | ||
87 | { 0x11, 0x00c3 }, | ||
88 | { 0x12, 0x00c0 }, | ||
89 | { 0x13, 0x0000 }, | ||
90 | { 0x14, 0x0000 }, | ||
91 | { 0x15, 0x0000 }, | ||
92 | { 0x16, 0x0000 }, | ||
93 | { 0x17, 0x0000 }, | ||
94 | { 0x18, 0x0000 }, | ||
95 | { 0x19, 0x0000 }, | ||
96 | { 0x1a, 0x0000 }, | ||
97 | { 0x1b, 0x0000 }, | ||
98 | { 0x1c, 0x0000 }, | ||
99 | { 0x1d, 0x0000 }, | ||
100 | { 0x1e, 0x0000 }, | ||
101 | { 0x1f, 0x0000 }, | ||
102 | { 0x20, 0x0055 }, | ||
103 | { 0x21, 0x0005 }, | ||
104 | { 0x22, 0x0050 }, | ||
105 | { 0x23, 0x0055 }, | ||
106 | { 0x24, 0x0050 }, | ||
107 | { 0x25, 0x0055 }, | ||
108 | { 0x26, 0x0050 }, | ||
109 | { 0x27, 0x0055 }, | ||
110 | { 0x28, 0x0079 }, | ||
111 | { 0x29, 0x0079 }, | ||
112 | { 0x2a, 0x0079 }, | ||
113 | { 0x2b, 0x0079 }, | ||
114 | { 0x2c, 0x0079 }, | ||
115 | { 0x2d, 0x0000 }, | ||
116 | { 0x2e, 0x0000 }, | ||
117 | { 0x2f, 0x0000 }, | ||
118 | { 0x30, 0x0000 }, | ||
119 | { 0x31, 0x0097 }, | ||
120 | { 0x32, 0x0097 }, | ||
121 | { 0x33, 0x0000 }, | ||
122 | { 0x34, 0x0004 }, | ||
123 | { 0x35, 0x0000 }, | ||
124 | { 0x36, 0x0083 }, | ||
125 | { 0x37, 0x0024 }, | ||
126 | { 0x38, 0x01ba }, | ||
127 | { 0x39, 0x0000 }, | ||
128 | { 0x3a, 0x0083 }, | ||
129 | { 0x3b, 0x0024 }, | ||
130 | { 0x3c, 0x01ba }, | ||
131 | { 0x3d, 0x0000 }, | ||
132 | { 0x3e, 0x0000 }, | ||
133 | { 0x3f, 0x0000 }, | ||
85 | }; | 134 | }; |
86 | 135 | ||
136 | static bool wm8753_volatile(struct device *dev, unsigned int reg) | ||
137 | { | ||
138 | return reg == WM8753_RESET; | ||
139 | } | ||
140 | |||
141 | static bool wm8753_writeable(struct device *dev, unsigned int reg) | ||
142 | { | ||
143 | return reg <= WM8753_ADCTL2; | ||
144 | } | ||
145 | |||
87 | /* codec private data */ | 146 | /* codec private data */ |
88 | struct wm8753_priv { | 147 | struct wm8753_priv { |
89 | enum snd_soc_control_type control_type; | 148 | struct regmap *regmap; |
90 | unsigned int sysclk; | 149 | unsigned int sysclk; |
91 | unsigned int pcmclk; | 150 | unsigned int pcmclk; |
92 | 151 | ||
@@ -1383,25 +1442,15 @@ static void wm8753_work(struct work_struct *work) | |||
1383 | static int wm8753_suspend(struct snd_soc_codec *codec) | 1442 | static int wm8753_suspend(struct snd_soc_codec *codec) |
1384 | { | 1443 | { |
1385 | wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1444 | wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1445 | codec->cache_sync = 1; | ||
1386 | return 0; | 1446 | return 0; |
1387 | } | 1447 | } |
1388 | 1448 | ||
1389 | static int wm8753_resume(struct snd_soc_codec *codec) | 1449 | static int wm8753_resume(struct snd_soc_codec *codec) |
1390 | { | 1450 | { |
1391 | u16 *reg_cache = codec->reg_cache; | 1451 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); |
1392 | int i; | ||
1393 | |||
1394 | /* Sync reg_cache with the hardware */ | ||
1395 | for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) { | ||
1396 | if (i == WM8753_RESET) | ||
1397 | continue; | ||
1398 | |||
1399 | /* No point in writing hardware default values back */ | ||
1400 | if (reg_cache[i] == wm8753_reg[i]) | ||
1401 | continue; | ||
1402 | 1452 | ||
1403 | snd_soc_write(codec, i, reg_cache[i]); | 1453 | regcache_sync(wm8753->regmap); |
1404 | } | ||
1405 | 1454 | ||
1406 | wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1455 | wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1407 | 1456 | ||
@@ -1423,7 +1472,8 @@ static int wm8753_probe(struct snd_soc_codec *codec) | |||
1423 | 1472 | ||
1424 | INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work); | 1473 | INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work); |
1425 | 1474 | ||
1426 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type); | 1475 | codec->control_data = wm8753->regmap; |
1476 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
1427 | if (ret < 0) { | 1477 | if (ret < 0) { |
1428 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 1478 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
1429 | return ret; | 1479 | return ret; |
@@ -1473,9 +1523,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8753 = { | |||
1473 | .suspend = wm8753_suspend, | 1523 | .suspend = wm8753_suspend, |
1474 | .resume = wm8753_resume, | 1524 | .resume = wm8753_resume, |
1475 | .set_bias_level = wm8753_set_bias_level, | 1525 | .set_bias_level = wm8753_set_bias_level, |
1476 | .reg_cache_size = ARRAY_SIZE(wm8753_reg), | ||
1477 | .reg_word_size = sizeof(u16), | ||
1478 | .reg_cache_default = wm8753_reg, | ||
1479 | 1526 | ||
1480 | .controls = wm8753_snd_controls, | 1527 | .controls = wm8753_snd_controls, |
1481 | .num_controls = ARRAY_SIZE(wm8753_snd_controls), | 1528 | .num_controls = ARRAY_SIZE(wm8753_snd_controls), |
@@ -1491,30 +1538,62 @@ static const struct of_device_id wm8753_of_match[] = { | |||
1491 | }; | 1538 | }; |
1492 | MODULE_DEVICE_TABLE(of, wm8753_of_match); | 1539 | MODULE_DEVICE_TABLE(of, wm8753_of_match); |
1493 | 1540 | ||
1541 | static const struct regmap_config wm8753_regmap = { | ||
1542 | .reg_bits = 7, | ||
1543 | .val_bits = 9, | ||
1544 | |||
1545 | .max_register = WM8753_ADCTL2, | ||
1546 | .writeable_reg = wm8753_writeable, | ||
1547 | .volatile_reg = wm8753_volatile, | ||
1548 | |||
1549 | .cache_type = REGCACHE_RBTREE, | ||
1550 | .reg_defaults = wm8753_reg_defaults, | ||
1551 | .num_reg_defaults = ARRAY_SIZE(wm8753_reg_defaults), | ||
1552 | }; | ||
1553 | |||
1494 | #if defined(CONFIG_SPI_MASTER) | 1554 | #if defined(CONFIG_SPI_MASTER) |
1495 | static int __devinit wm8753_spi_probe(struct spi_device *spi) | 1555 | static int __devinit wm8753_spi_probe(struct spi_device *spi) |
1496 | { | 1556 | { |
1497 | struct wm8753_priv *wm8753; | 1557 | struct wm8753_priv *wm8753; |
1498 | int ret; | 1558 | int ret; |
1499 | 1559 | ||
1500 | wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); | 1560 | wm8753 = devm_kzalloc(&spi->dev, sizeof(struct wm8753_priv), |
1561 | GFP_KERNEL); | ||
1501 | if (wm8753 == NULL) | 1562 | if (wm8753 == NULL) |
1502 | return -ENOMEM; | 1563 | return -ENOMEM; |
1503 | 1564 | ||
1504 | wm8753->control_type = SND_SOC_SPI; | ||
1505 | spi_set_drvdata(spi, wm8753); | 1565 | spi_set_drvdata(spi, wm8753); |
1506 | 1566 | ||
1507 | ret = snd_soc_register_codec(&spi->dev, | 1567 | wm8753->regmap = regmap_init_spi(spi, &wm8753_regmap); |
1508 | &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai)); | 1568 | if (IS_ERR(wm8753->regmap)) { |
1509 | if (ret < 0) | 1569 | ret = PTR_ERR(wm8753->regmap); |
1510 | kfree(wm8753); | 1570 | dev_err(&spi->dev, "Failed to allocate register map: %d\n", |
1571 | ret); | ||
1572 | goto err; | ||
1573 | } | ||
1574 | |||
1575 | ret = snd_soc_register_codec(&spi->dev, &soc_codec_dev_wm8753, | ||
1576 | wm8753_dai, ARRAY_SIZE(wm8753_dai)); | ||
1577 | if (ret != 0) { | ||
1578 | dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); | ||
1579 | goto err_regmap; | ||
1580 | } | ||
1581 | |||
1582 | return 0; | ||
1583 | |||
1584 | err_regmap: | ||
1585 | regmap_exit(wm8753->regmap); | ||
1586 | err: | ||
1511 | return ret; | 1587 | return ret; |
1512 | } | 1588 | } |
1513 | 1589 | ||
1514 | static int __devexit wm8753_spi_remove(struct spi_device *spi) | 1590 | static int __devexit wm8753_spi_remove(struct spi_device *spi) |
1515 | { | 1591 | { |
1592 | struct wm8753_priv *wm8753 = spi_get_drvdata(spi); | ||
1593 | |||
1516 | snd_soc_unregister_codec(&spi->dev); | 1594 | snd_soc_unregister_codec(&spi->dev); |
1517 | kfree(spi_get_drvdata(spi)); | 1595 | regmap_exit(wm8753->regmap); |
1596 | kfree(wm8753); | ||
1518 | return 0; | 1597 | return 0; |
1519 | } | 1598 | } |
1520 | 1599 | ||
@@ -1536,24 +1615,42 @@ static __devinit int wm8753_i2c_probe(struct i2c_client *i2c, | |||
1536 | struct wm8753_priv *wm8753; | 1615 | struct wm8753_priv *wm8753; |
1537 | int ret; | 1616 | int ret; |
1538 | 1617 | ||
1539 | wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL); | 1618 | wm8753 = devm_kzalloc(&i2c->dev, sizeof(struct wm8753_priv), |
1619 | GFP_KERNEL); | ||
1540 | if (wm8753 == NULL) | 1620 | if (wm8753 == NULL) |
1541 | return -ENOMEM; | 1621 | return -ENOMEM; |
1542 | 1622 | ||
1543 | i2c_set_clientdata(i2c, wm8753); | 1623 | i2c_set_clientdata(i2c, wm8753); |
1544 | wm8753->control_type = SND_SOC_I2C; | ||
1545 | 1624 | ||
1546 | ret = snd_soc_register_codec(&i2c->dev, | 1625 | wm8753->regmap = regmap_init_i2c(i2c, &wm8753_regmap); |
1547 | &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai)); | 1626 | if (IS_ERR(wm8753->regmap)) { |
1548 | if (ret < 0) | 1627 | ret = PTR_ERR(wm8753->regmap); |
1549 | kfree(wm8753); | 1628 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
1629 | ret); | ||
1630 | goto err; | ||
1631 | } | ||
1632 | |||
1633 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8753, | ||
1634 | wm8753_dai, ARRAY_SIZE(wm8753_dai)); | ||
1635 | if (ret != 0) { | ||
1636 | dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); | ||
1637 | goto err_regmap; | ||
1638 | } | ||
1639 | |||
1640 | return 0; | ||
1641 | |||
1642 | err_regmap: | ||
1643 | regmap_exit(wm8753->regmap); | ||
1644 | err: | ||
1550 | return ret; | 1645 | return ret; |
1551 | } | 1646 | } |
1552 | 1647 | ||
1553 | static __devexit int wm8753_i2c_remove(struct i2c_client *client) | 1648 | static __devexit int wm8753_i2c_remove(struct i2c_client *client) |
1554 | { | 1649 | { |
1650 | struct wm8753_priv *wm8753 = i2c_get_clientdata(client); | ||
1651 | |||
1555 | snd_soc_unregister_codec(&client->dev); | 1652 | snd_soc_unregister_codec(&client->dev); |
1556 | kfree(i2c_get_clientdata(client)); | 1653 | regmap_exit(wm8753->regmap); |
1557 | return 0; | 1654 | return 0; |
1558 | } | 1655 | } |
1559 | 1656 | ||
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index 19374a9e5ba6..a5127b4ff9e1 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c | |||
@@ -580,8 +580,6 @@ static int wm8770_probe(struct snd_soc_codec *codec) | |||
580 | wm8770 = snd_soc_codec_get_drvdata(codec); | 580 | wm8770 = snd_soc_codec_get_drvdata(codec); |
581 | wm8770->codec = codec; | 581 | wm8770->codec = codec; |
582 | 582 | ||
583 | codec->dapm.idle_bias_off = 1; | ||
584 | |||
585 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type); | 583 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type); |
586 | if (ret < 0) { | 584 | if (ret < 0) { |
587 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 585 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
@@ -643,7 +641,7 @@ static int wm8770_probe(struct snd_soc_codec *codec) | |||
643 | /* mute all DACs */ | 641 | /* mute all DACs */ |
644 | snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10); | 642 | snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10); |
645 | 643 | ||
646 | snd_soc_add_controls(codec, wm8770_snd_controls, | 644 | snd_soc_add_codec_controls(codec, wm8770_snd_controls, |
647 | ARRAY_SIZE(wm8770_snd_controls)); | 645 | ARRAY_SIZE(wm8770_snd_controls)); |
648 | snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets, | 646 | snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets, |
649 | ARRAY_SIZE(wm8770_dapm_widgets)); | 647 | ARRAY_SIZE(wm8770_dapm_widgets)); |
@@ -679,6 +677,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8770 = { | |||
679 | .suspend = wm8770_suspend, | 677 | .suspend = wm8770_suspend, |
680 | .resume = wm8770_resume, | 678 | .resume = wm8770_resume, |
681 | .set_bias_level = wm8770_set_bias_level, | 679 | .set_bias_level = wm8770_set_bias_level, |
680 | .idle_bias_off = true, | ||
682 | .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs), | 681 | .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs), |
683 | .reg_word_size = sizeof (u16), | 682 | .reg_word_size = sizeof (u16), |
684 | .reg_cache_default = wm8770_reg_defs | 683 | .reg_cache_default = wm8770_reg_defs |
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 33e97d1d8f46..a19db5a0a17a 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c | |||
@@ -30,6 +30,11 @@ | |||
30 | 30 | ||
31 | #include "wm8776.h" | 31 | #include "wm8776.h" |
32 | 32 | ||
33 | enum wm8776_chip_type { | ||
34 | WM8775 = 1, | ||
35 | WM8776, | ||
36 | }; | ||
37 | |||
33 | /* codec private data */ | 38 | /* codec private data */ |
34 | struct wm8776_priv { | 39 | struct wm8776_priv { |
35 | enum snd_soc_control_type control_type; | 40 | enum snd_soc_control_type control_type; |
@@ -512,7 +517,8 @@ static __devexit int wm8776_i2c_remove(struct i2c_client *client) | |||
512 | } | 517 | } |
513 | 518 | ||
514 | static const struct i2c_device_id wm8776_i2c_id[] = { | 519 | static const struct i2c_device_id wm8776_i2c_id[] = { |
515 | { "wm8776", 0 }, | 520 | { "wm8775", WM8775 }, |
521 | { "wm8776", WM8776 }, | ||
516 | { } | 522 | { } |
517 | }; | 523 | }; |
518 | MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id); | 524 | MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id); |
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index d54a3ca5e19e..6bd1b767b138 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <linux/of_device.h> | 19 | #include <linux/of_device.h> |
20 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
21 | #include <linux/regmap.h> | ||
21 | #include <linux/regulator/consumer.h> | 22 | #include <linux/regulator/consumer.h> |
22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
23 | #include <sound/core.h> | 24 | #include <sound/core.h> |
@@ -35,45 +36,33 @@ static const char *wm8804_supply_names[WM8804_NUM_SUPPLIES] = { | |||
35 | "DVDD" | 36 | "DVDD" |
36 | }; | 37 | }; |
37 | 38 | ||
38 | static const u8 wm8804_reg_defs[] = { | 39 | static const struct reg_default wm8804_reg_defaults[] = { |
39 | 0x05, /* R0 - RST/DEVID1 */ | 40 | { 3, 0x21 }, /* R3 - PLL1 */ |
40 | 0x88, /* R1 - DEVID2 */ | 41 | { 4, 0xFD }, /* R4 - PLL2 */ |
41 | 0x04, /* R2 - DEVREV */ | 42 | { 5, 0x36 }, /* R5 - PLL3 */ |
42 | 0x21, /* R3 - PLL1 */ | 43 | { 6, 0x07 }, /* R6 - PLL4 */ |
43 | 0xFD, /* R4 - PLL2 */ | 44 | { 7, 0x16 }, /* R7 - PLL5 */ |
44 | 0x36, /* R5 - PLL3 */ | 45 | { 8, 0x18 }, /* R8 - PLL6 */ |
45 | 0x07, /* R6 - PLL4 */ | 46 | { 9, 0xFF }, /* R9 - SPDMODE */ |
46 | 0x16, /* R7 - PLL5 */ | 47 | { 10, 0x00 }, /* R10 - INTMASK */ |
47 | 0x18, /* R8 - PLL6 */ | 48 | { 18, 0x00 }, /* R18 - SPDTX1 */ |
48 | 0xFF, /* R9 - SPDMODE */ | 49 | { 19, 0x00 }, /* R19 - SPDTX2 */ |
49 | 0x00, /* R10 - INTMASK */ | 50 | { 20, 0x00 }, /* R20 - SPDTX3 */ |
50 | 0x00, /* R11 - INTSTAT */ | 51 | { 21, 0x71 }, /* R21 - SPDTX4 */ |
51 | 0x00, /* R12 - SPDSTAT */ | 52 | { 22, 0x0B }, /* R22 - SPDTX5 */ |
52 | 0x00, /* R13 - RXCHAN1 */ | 53 | { 23, 0x70 }, /* R23 - GPO0 */ |
53 | 0x00, /* R14 - RXCHAN2 */ | 54 | { 24, 0x57 }, /* R24 - GPO1 */ |
54 | 0x00, /* R15 - RXCHAN3 */ | 55 | { 26, 0x42 }, /* R26 - GPO2 */ |
55 | 0x00, /* R16 - RXCHAN4 */ | 56 | { 27, 0x06 }, /* R27 - AIFTX */ |
56 | 0x00, /* R17 - RXCHAN5 */ | 57 | { 28, 0x06 }, /* R28 - AIFRX */ |
57 | 0x00, /* R18 - SPDTX1 */ | 58 | { 29, 0x80 }, /* R29 - SPDRX1 */ |
58 | 0x00, /* R19 - SPDTX2 */ | 59 | { 30, 0x07 }, /* R30 - PWRDN */ |
59 | 0x00, /* R20 - SPDTX3 */ | ||
60 | 0x71, /* R21 - SPDTX4 */ | ||
61 | 0x0B, /* R22 - SPDTX5 */ | ||
62 | 0x70, /* R23 - GPO0 */ | ||
63 | 0x57, /* R24 - GPO1 */ | ||
64 | 0x00, /* R25 */ | ||
65 | 0x42, /* R26 - GPO2 */ | ||
66 | 0x06, /* R27 - AIFTX */ | ||
67 | 0x06, /* R28 - AIFRX */ | ||
68 | 0x80, /* R29 - SPDRX1 */ | ||
69 | 0x07, /* R30 - PWRDN */ | ||
70 | }; | 60 | }; |
71 | 61 | ||
72 | struct wm8804_priv { | 62 | struct wm8804_priv { |
73 | enum snd_soc_control_type control_type; | 63 | struct regmap *regmap; |
74 | struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES]; | 64 | struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES]; |
75 | struct notifier_block disable_nb[WM8804_NUM_SUPPLIES]; | 65 | struct notifier_block disable_nb[WM8804_NUM_SUPPLIES]; |
76 | struct snd_soc_codec *codec; | ||
77 | }; | 66 | }; |
78 | 67 | ||
79 | static int txsrc_get(struct snd_kcontrol *kcontrol, | 68 | static int txsrc_get(struct snd_kcontrol *kcontrol, |
@@ -94,7 +83,7 @@ static int wm8804_regulator_event_##n(struct notifier_block *nb, \ | |||
94 | struct wm8804_priv *wm8804 = container_of(nb, struct wm8804_priv, \ | 83 | struct wm8804_priv *wm8804 = container_of(nb, struct wm8804_priv, \ |
95 | disable_nb[n]); \ | 84 | disable_nb[n]); \ |
96 | if (event & REGULATOR_EVENT_DISABLE) { \ | 85 | if (event & REGULATOR_EVENT_DISABLE) { \ |
97 | wm8804->codec->cache_sync = 1; \ | 86 | regcache_mark_dirty(wm8804->regmap); \ |
98 | } \ | 87 | } \ |
99 | return 0; \ | 88 | return 0; \ |
100 | } | 89 | } |
@@ -176,7 +165,7 @@ static int txsrc_put(struct snd_kcontrol *kcontrol, | |||
176 | return 0; | 165 | return 0; |
177 | } | 166 | } |
178 | 167 | ||
179 | static int wm8804_volatile(struct snd_soc_codec *codec, unsigned int reg) | 168 | static bool wm8804_volatile(struct device *dev, unsigned int reg) |
180 | { | 169 | { |
181 | switch (reg) { | 170 | switch (reg) { |
182 | case WM8804_RST_DEVID1: | 171 | case WM8804_RST_DEVID1: |
@@ -189,12 +178,10 @@ static int wm8804_volatile(struct snd_soc_codec *codec, unsigned int reg) | |||
189 | case WM8804_RXCHAN3: | 178 | case WM8804_RXCHAN3: |
190 | case WM8804_RXCHAN4: | 179 | case WM8804_RXCHAN4: |
191 | case WM8804_RXCHAN5: | 180 | case WM8804_RXCHAN5: |
192 | return 1; | 181 | return true; |
193 | default: | 182 | default: |
194 | break; | 183 | return false; |
195 | } | 184 | } |
196 | |||
197 | return 0; | ||
198 | } | 185 | } |
199 | 186 | ||
200 | static int wm8804_reset(struct snd_soc_codec *codec) | 187 | static int wm8804_reset(struct snd_soc_codec *codec) |
@@ -482,24 +469,6 @@ static int wm8804_set_clkdiv(struct snd_soc_dai *dai, | |||
482 | return 0; | 469 | return 0; |
483 | } | 470 | } |
484 | 471 | ||
485 | static void wm8804_sync_cache(struct snd_soc_codec *codec) | ||
486 | { | ||
487 | short i; | ||
488 | u8 *cache; | ||
489 | |||
490 | if (!codec->cache_sync) | ||
491 | return; | ||
492 | |||
493 | codec->cache_only = 0; | ||
494 | cache = codec->reg_cache; | ||
495 | for (i = 0; i < codec->driver->reg_cache_size; i++) { | ||
496 | if (i == WM8804_RST_DEVID1 || cache[i] == wm8804_reg_defs[i]) | ||
497 | continue; | ||
498 | snd_soc_write(codec, i, cache[i]); | ||
499 | } | ||
500 | codec->cache_sync = 0; | ||
501 | } | ||
502 | |||
503 | static int wm8804_set_bias_level(struct snd_soc_codec *codec, | 472 | static int wm8804_set_bias_level(struct snd_soc_codec *codec, |
504 | enum snd_soc_bias_level level) | 473 | enum snd_soc_bias_level level) |
505 | { | 474 | { |
@@ -524,7 +493,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec, | |||
524 | ret); | 493 | ret); |
525 | return ret; | 494 | return ret; |
526 | } | 495 | } |
527 | wm8804_sync_cache(codec); | 496 | regcache_sync(wm8804->regmap); |
528 | } | 497 | } |
529 | /* power down the OSC and the PLL */ | 498 | /* power down the OSC and the PLL */ |
530 | snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9); | 499 | snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0x9); |
@@ -579,11 +548,10 @@ static int wm8804_probe(struct snd_soc_codec *codec) | |||
579 | int i, id1, id2, ret; | 548 | int i, id1, id2, ret; |
580 | 549 | ||
581 | wm8804 = snd_soc_codec_get_drvdata(codec); | 550 | wm8804 = snd_soc_codec_get_drvdata(codec); |
582 | wm8804->codec = codec; | ||
583 | 551 | ||
584 | codec->dapm.idle_bias_off = 1; | 552 | codec->control_data = wm8804->regmap; |
585 | 553 | ||
586 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, wm8804->control_type); | 554 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP); |
587 | if (ret < 0) { | 555 | if (ret < 0) { |
588 | dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); | 556 | dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); |
589 | return ret; | 557 | return ret; |
@@ -636,8 +604,7 @@ static int wm8804_probe(struct snd_soc_codec *codec) | |||
636 | 604 | ||
637 | id2 = (id2 << 8) | id1; | 605 | id2 = (id2 << 8) | id1; |
638 | 606 | ||
639 | if (id2 != ((wm8804_reg_defs[WM8804_DEVID2] << 8) | 607 | if (id2 != 0x8805) { |
640 | | wm8804_reg_defs[WM8804_RST_DEVID1])) { | ||
641 | dev_err(codec->dev, "Invalid device ID: %#x\n", id2); | 608 | dev_err(codec->dev, "Invalid device ID: %#x\n", id2); |
642 | ret = -EINVAL; | 609 | ret = -EINVAL; |
643 | goto err_reg_enable; | 610 | goto err_reg_enable; |
@@ -710,10 +677,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8804 = { | |||
710 | .suspend = wm8804_suspend, | 677 | .suspend = wm8804_suspend, |
711 | .resume = wm8804_resume, | 678 | .resume = wm8804_resume, |
712 | .set_bias_level = wm8804_set_bias_level, | 679 | .set_bias_level = wm8804_set_bias_level, |
713 | .reg_cache_size = ARRAY_SIZE(wm8804_reg_defs), | 680 | .idle_bias_off = true, |
714 | .reg_word_size = sizeof(u8), | ||
715 | .reg_cache_default = wm8804_reg_defs, | ||
716 | .volatile_register = wm8804_volatile, | ||
717 | 681 | ||
718 | .controls = wm8804_snd_controls, | 682 | .controls = wm8804_snd_controls, |
719 | .num_controls = ARRAY_SIZE(wm8804_snd_controls), | 683 | .num_controls = ARRAY_SIZE(wm8804_snd_controls), |
@@ -725,30 +689,47 @@ static const struct of_device_id wm8804_of_match[] = { | |||
725 | }; | 689 | }; |
726 | MODULE_DEVICE_TABLE(of, wm8804_of_match); | 690 | MODULE_DEVICE_TABLE(of, wm8804_of_match); |
727 | 691 | ||
692 | static struct regmap_config wm8804_regmap_config = { | ||
693 | .reg_bits = 8, | ||
694 | .val_bits = 8, | ||
695 | |||
696 | .max_register = WM8804_MAX_REGISTER, | ||
697 | .volatile_reg = wm8804_volatile, | ||
698 | |||
699 | .cache_type = REGCACHE_RBTREE, | ||
700 | .reg_defaults = wm8804_reg_defaults, | ||
701 | .num_reg_defaults = ARRAY_SIZE(wm8804_reg_defaults), | ||
702 | }; | ||
703 | |||
728 | #if defined(CONFIG_SPI_MASTER) | 704 | #if defined(CONFIG_SPI_MASTER) |
729 | static int __devinit wm8804_spi_probe(struct spi_device *spi) | 705 | static int __devinit wm8804_spi_probe(struct spi_device *spi) |
730 | { | 706 | { |
731 | struct wm8804_priv *wm8804; | 707 | struct wm8804_priv *wm8804; |
732 | int ret; | 708 | int ret; |
733 | 709 | ||
734 | wm8804 = kzalloc(sizeof *wm8804, GFP_KERNEL); | 710 | wm8804 = devm_kzalloc(&spi->dev, sizeof *wm8804, GFP_KERNEL); |
735 | if (!wm8804) | 711 | if (!wm8804) |
736 | return -ENOMEM; | 712 | return -ENOMEM; |
737 | 713 | ||
738 | wm8804->control_type = SND_SOC_SPI; | 714 | wm8804->regmap = regmap_init_spi(spi, &wm8804_regmap_config); |
715 | if (IS_ERR(wm8804->regmap)) { | ||
716 | ret = PTR_ERR(wm8804->regmap); | ||
717 | return ret; | ||
718 | } | ||
719 | |||
739 | spi_set_drvdata(spi, wm8804); | 720 | spi_set_drvdata(spi, wm8804); |
740 | 721 | ||
741 | ret = snd_soc_register_codec(&spi->dev, | 722 | ret = snd_soc_register_codec(&spi->dev, |
742 | &soc_codec_dev_wm8804, &wm8804_dai, 1); | 723 | &soc_codec_dev_wm8804, &wm8804_dai, 1); |
743 | if (ret < 0) | 724 | |
744 | kfree(wm8804); | ||
745 | return ret; | 725 | return ret; |
746 | } | 726 | } |
747 | 727 | ||
748 | static int __devexit wm8804_spi_remove(struct spi_device *spi) | 728 | static int __devexit wm8804_spi_remove(struct spi_device *spi) |
749 | { | 729 | { |
730 | struct wm8804_priv *wm8804 = spi_get_drvdata(spi); | ||
750 | snd_soc_unregister_codec(&spi->dev); | 731 | snd_soc_unregister_codec(&spi->dev); |
751 | kfree(spi_get_drvdata(spi)); | 732 | regmap_exit(wm8804->regmap); |
752 | return 0; | 733 | return 0; |
753 | } | 734 | } |
754 | 735 | ||
@@ -770,24 +751,37 @@ static __devinit int wm8804_i2c_probe(struct i2c_client *i2c, | |||
770 | struct wm8804_priv *wm8804; | 751 | struct wm8804_priv *wm8804; |
771 | int ret; | 752 | int ret; |
772 | 753 | ||
773 | wm8804 = kzalloc(sizeof *wm8804, GFP_KERNEL); | 754 | wm8804 = devm_kzalloc(&i2c->dev, sizeof *wm8804, GFP_KERNEL); |
774 | if (!wm8804) | 755 | if (!wm8804) |
775 | return -ENOMEM; | 756 | return -ENOMEM; |
776 | 757 | ||
777 | wm8804->control_type = SND_SOC_I2C; | 758 | wm8804->regmap = regmap_init_i2c(i2c, &wm8804_regmap_config); |
759 | if (IS_ERR(wm8804->regmap)) { | ||
760 | ret = PTR_ERR(wm8804->regmap); | ||
761 | return ret; | ||
762 | } | ||
763 | |||
778 | i2c_set_clientdata(i2c, wm8804); | 764 | i2c_set_clientdata(i2c, wm8804); |
779 | 765 | ||
780 | ret = snd_soc_register_codec(&i2c->dev, | 766 | ret = snd_soc_register_codec(&i2c->dev, |
781 | &soc_codec_dev_wm8804, &wm8804_dai, 1); | 767 | &soc_codec_dev_wm8804, &wm8804_dai, 1); |
782 | if (ret < 0) | 768 | if (ret != 0) |
783 | kfree(wm8804); | 769 | goto err; |
770 | |||
771 | return 0; | ||
772 | |||
773 | err: | ||
774 | regmap_exit(wm8804->regmap); | ||
784 | return ret; | 775 | return ret; |
785 | } | 776 | } |
786 | 777 | ||
787 | static __devexit int wm8804_i2c_remove(struct i2c_client *client) | 778 | static __devexit int wm8804_i2c_remove(struct i2c_client *i2c) |
788 | { | 779 | { |
789 | snd_soc_unregister_codec(&client->dev); | 780 | struct wm8804_priv *wm8804 = i2c_get_clientdata(i2c); |
790 | kfree(i2c_get_clientdata(client)); | 781 | |
782 | snd_soc_unregister_codec(&i2c->dev); | ||
783 | regmap_exit(wm8804->regmap); | ||
784 | |||
791 | return 0; | 785 | return 0; |
792 | } | 786 | } |
793 | 787 | ||
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index f31c754c8865..65d525d74c54 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
19 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
20 | #include <linux/regmap.h> | ||
20 | #include <linux/regulator/consumer.h> | 21 | #include <linux/regulator/consumer.h> |
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
22 | #include <sound/core.h> | 23 | #include <sound/core.h> |
@@ -47,6 +48,7 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = { | |||
47 | 48 | ||
48 | /* codec private data */ | 49 | /* codec private data */ |
49 | struct wm8904_priv { | 50 | struct wm8904_priv { |
51 | struct regmap *regmap; | ||
50 | 52 | ||
51 | enum wm8904_type devtype; | 53 | enum wm8904_type devtype; |
52 | 54 | ||
@@ -86,517 +88,230 @@ struct wm8904_priv { | |||
86 | int dcs_state[WM8904_NUM_DCS_CHANNELS]; | 88 | int dcs_state[WM8904_NUM_DCS_CHANNELS]; |
87 | }; | 89 | }; |
88 | 90 | ||
89 | static const u16 wm8904_reg[WM8904_MAX_REGISTER + 1] = { | 91 | static const struct reg_default wm8904_reg_defaults[] = { |
90 | 0x8904, /* R0 - SW Reset and ID */ | 92 | { 4, 0x0018 }, /* R4 - Bias Control 0 */ |
91 | 0x0000, /* R1 - Revision */ | 93 | { 5, 0x0000 }, /* R5 - VMID Control 0 */ |
92 | 0x0000, /* R2 */ | 94 | { 6, 0x0000 }, /* R6 - Mic Bias Control 0 */ |
93 | 0x0000, /* R3 */ | 95 | { 7, 0x0000 }, /* R7 - Mic Bias Control 1 */ |
94 | 0x0018, /* R4 - Bias Control 0 */ | 96 | { 8, 0x0001 }, /* R8 - Analogue DAC 0 */ |
95 | 0x0000, /* R5 - VMID Control 0 */ | 97 | { 9, 0x9696 }, /* R9 - mic Filter Control */ |
96 | 0x0000, /* R6 - Mic Bias Control 0 */ | 98 | { 10, 0x0001 }, /* R10 - Analogue ADC 0 */ |
97 | 0x0000, /* R7 - Mic Bias Control 1 */ | 99 | { 12, 0x0000 }, /* R12 - Power Management 0 */ |
98 | 0x0001, /* R8 - Analogue DAC 0 */ | 100 | { 14, 0x0000 }, /* R14 - Power Management 2 */ |
99 | 0x9696, /* R9 - mic Filter Control */ | 101 | { 15, 0x0000 }, /* R15 - Power Management 3 */ |
100 | 0x0001, /* R10 - Analogue ADC 0 */ | 102 | { 18, 0x0000 }, /* R18 - Power Management 6 */ |
101 | 0x0000, /* R11 */ | 103 | { 19, 0x945E }, /* R20 - Clock Rates 0 */ |
102 | 0x0000, /* R12 - Power Management 0 */ | 104 | { 21, 0x0C05 }, /* R21 - Clock Rates 1 */ |
103 | 0x0000, /* R13 */ | 105 | { 22, 0x0006 }, /* R22 - Clock Rates 2 */ |
104 | 0x0000, /* R14 - Power Management 2 */ | 106 | { 24, 0x0050 }, /* R24 - Audio Interface 0 */ |
105 | 0x0000, /* R15 - Power Management 3 */ | 107 | { 25, 0x000A }, /* R25 - Audio Interface 1 */ |
106 | 0x0000, /* R16 */ | 108 | { 26, 0x00E4 }, /* R26 - Audio Interface 2 */ |
107 | 0x0000, /* R17 */ | 109 | { 27, 0x0040 }, /* R27 - Audio Interface 3 */ |
108 | 0x0000, /* R18 - Power Management 6 */ | 110 | { 30, 0x00C0 }, /* R30 - DAC Digital Volume Left */ |
109 | 0x0000, /* R19 */ | 111 | { 31, 0x00C0 }, /* R31 - DAC Digital Volume Right */ |
110 | 0x945E, /* R20 - Clock Rates 0 */ | 112 | { 32, 0x0000 }, /* R32 - DAC Digital 0 */ |
111 | 0x0C05, /* R21 - Clock Rates 1 */ | 113 | { 33, 0x0008 }, /* R33 - DAC Digital 1 */ |
112 | 0x0006, /* R22 - Clock Rates 2 */ | 114 | { 36, 0x00C0 }, /* R36 - ADC Digital Volume Left */ |
113 | 0x0000, /* R23 */ | 115 | { 37, 0x00C0 }, /* R37 - ADC Digital Volume Right */ |
114 | 0x0050, /* R24 - Audio Interface 0 */ | 116 | { 38, 0x0010 }, /* R38 - ADC Digital 0 */ |
115 | 0x000A, /* R25 - Audio Interface 1 */ | 117 | { 39, 0x0000 }, /* R39 - Digital Microphone 0 */ |
116 | 0x00E4, /* R26 - Audio Interface 2 */ | 118 | { 40, 0x01AF }, /* R40 - DRC 0 */ |
117 | 0x0040, /* R27 - Audio Interface 3 */ | 119 | { 41, 0x3248 }, /* R41 - DRC 1 */ |
118 | 0x0000, /* R28 */ | 120 | { 42, 0x0000 }, /* R42 - DRC 2 */ |
119 | 0x0000, /* R29 */ | 121 | { 43, 0x0000 }, /* R43 - DRC 3 */ |
120 | 0x00C0, /* R30 - DAC Digital Volume Left */ | 122 | { 44, 0x0085 }, /* R44 - Analogue Left Input 0 */ |
121 | 0x00C0, /* R31 - DAC Digital Volume Right */ | 123 | { 45, 0x0085 }, /* R45 - Analogue Right Input 0 */ |
122 | 0x0000, /* R32 - DAC Digital 0 */ | 124 | { 46, 0x0044 }, /* R46 - Analogue Left Input 1 */ |
123 | 0x0008, /* R33 - DAC Digital 1 */ | 125 | { 47, 0x0044 }, /* R47 - Analogue Right Input 1 */ |
124 | 0x0000, /* R34 */ | 126 | { 57, 0x002D }, /* R57 - Analogue OUT1 Left */ |
125 | 0x0000, /* R35 */ | 127 | { 58, 0x002D }, /* R58 - Analogue OUT1 Right */ |
126 | 0x00C0, /* R36 - ADC Digital Volume Left */ | 128 | { 59, 0x0039 }, /* R59 - Analogue OUT2 Left */ |
127 | 0x00C0, /* R37 - ADC Digital Volume Right */ | 129 | { 60, 0x0039 }, /* R60 - Analogue OUT2 Right */ |
128 | 0x0010, /* R38 - ADC Digital 0 */ | 130 | { 61, 0x0000 }, /* R61 - Analogue OUT12 ZC */ |
129 | 0x0000, /* R39 - Digital Microphone 0 */ | 131 | { 67, 0x0000 }, /* R67 - DC Servo 0 */ |
130 | 0x01AF, /* R40 - DRC 0 */ | 132 | { 69, 0xAAAA }, /* R69 - DC Servo 2 */ |
131 | 0x3248, /* R41 - DRC 1 */ | 133 | { 71, 0xAAAA }, /* R71 - DC Servo 4 */ |
132 | 0x0000, /* R42 - DRC 2 */ | 134 | { 72, 0xAAAA }, /* R72 - DC Servo 5 */ |
133 | 0x0000, /* R43 - DRC 3 */ | 135 | { 90, 0x0000 }, /* R90 - Analogue HP 0 */ |
134 | 0x0085, /* R44 - Analogue Left Input 0 */ | 136 | { 94, 0x0000 }, /* R94 - Analogue Lineout 0 */ |
135 | 0x0085, /* R45 - Analogue Right Input 0 */ | 137 | { 98, 0x0000 }, /* R98 - Charge Pump 0 */ |
136 | 0x0044, /* R46 - Analogue Left Input 1 */ | 138 | { 104, 0x0004 }, /* R104 - Class W 0 */ |
137 | 0x0044, /* R47 - Analogue Right Input 1 */ | 139 | { 108, 0x0000 }, /* R108 - Write Sequencer 0 */ |
138 | 0x0000, /* R48 */ | 140 | { 109, 0x0000 }, /* R109 - Write Sequencer 1 */ |
139 | 0x0000, /* R49 */ | 141 | { 110, 0x0000 }, /* R110 - Write Sequencer 2 */ |
140 | 0x0000, /* R50 */ | 142 | { 111, 0x0000 }, /* R111 - Write Sequencer 3 */ |
141 | 0x0000, /* R51 */ | 143 | { 112, 0x0000 }, /* R112 - Write Sequencer 4 */ |
142 | 0x0000, /* R52 */ | 144 | { 116, 0x0000 }, /* R116 - FLL Control 1 */ |
143 | 0x0000, /* R53 */ | 145 | { 117, 0x0007 }, /* R117 - FLL Control 2 */ |
144 | 0x0000, /* R54 */ | 146 | { 118, 0x0000 }, /* R118 - FLL Control 3 */ |
145 | 0x0000, /* R55 */ | 147 | { 119, 0x2EE0 }, /* R119 - FLL Control 4 */ |
146 | 0x0000, /* R56 */ | 148 | { 120, 0x0004 }, /* R120 - FLL Control 5 */ |
147 | 0x002D, /* R57 - Analogue OUT1 Left */ | 149 | { 121, 0x0014 }, /* R121 - GPIO Control 1 */ |
148 | 0x002D, /* R58 - Analogue OUT1 Right */ | 150 | { 122, 0x0010 }, /* R122 - GPIO Control 2 */ |
149 | 0x0039, /* R59 - Analogue OUT2 Left */ | 151 | { 123, 0x0010 }, /* R123 - GPIO Control 3 */ |
150 | 0x0039, /* R60 - Analogue OUT2 Right */ | 152 | { 124, 0x0000 }, /* R124 - GPIO Control 4 */ |
151 | 0x0000, /* R61 - Analogue OUT12 ZC */ | 153 | { 126, 0x0000 }, /* R126 - Digital Pulls */ |
152 | 0x0000, /* R62 */ | 154 | { 128, 0xFFFF }, /* R128 - Interrupt Status Mask */ |
153 | 0x0000, /* R63 */ | 155 | { 129, 0x0000 }, /* R129 - Interrupt Polarity */ |
154 | 0x0000, /* R64 */ | 156 | { 130, 0x0000 }, /* R130 - Interrupt Debounce */ |
155 | 0x0000, /* R65 */ | 157 | { 134, 0x0000 }, /* R134 - EQ1 */ |
156 | 0x0000, /* R66 */ | 158 | { 135, 0x000C }, /* R135 - EQ2 */ |
157 | 0x0000, /* R67 - DC Servo 0 */ | 159 | { 136, 0x000C }, /* R136 - EQ3 */ |
158 | 0x0000, /* R68 - DC Servo 1 */ | 160 | { 137, 0x000C }, /* R137 - EQ4 */ |
159 | 0xAAAA, /* R69 - DC Servo 2 */ | 161 | { 138, 0x000C }, /* R138 - EQ5 */ |
160 | 0x0000, /* R70 */ | 162 | { 139, 0x000C }, /* R139 - EQ6 */ |
161 | 0xAAAA, /* R71 - DC Servo 4 */ | 163 | { 140, 0x0FCA }, /* R140 - EQ7 */ |
162 | 0xAAAA, /* R72 - DC Servo 5 */ | 164 | { 141, 0x0400 }, /* R141 - EQ8 */ |
163 | 0x0000, /* R73 - DC Servo 6 */ | 165 | { 142, 0x00D8 }, /* R142 - EQ9 */ |
164 | 0x0000, /* R74 - DC Servo 7 */ | 166 | { 143, 0x1EB5 }, /* R143 - EQ10 */ |
165 | 0x0000, /* R75 - DC Servo 8 */ | 167 | { 144, 0xF145 }, /* R144 - EQ11 */ |
166 | 0x0000, /* R76 - DC Servo 9 */ | 168 | { 145, 0x0B75 }, /* R145 - EQ12 */ |
167 | 0x0000, /* R77 - DC Servo Readback 0 */ | 169 | { 146, 0x01C5 }, /* R146 - EQ13 */ |
168 | 0x0000, /* R78 */ | 170 | { 147, 0x1C58 }, /* R147 - EQ14 */ |
169 | 0x0000, /* R79 */ | 171 | { 148, 0xF373 }, /* R148 - EQ15 */ |
170 | 0x0000, /* R80 */ | 172 | { 149, 0x0A54 }, /* R149 - EQ16 */ |
171 | 0x0000, /* R81 */ | 173 | { 150, 0x0558 }, /* R150 - EQ17 */ |
172 | 0x0000, /* R82 */ | 174 | { 151, 0x168E }, /* R151 - EQ18 */ |
173 | 0x0000, /* R83 */ | 175 | { 152, 0xF829 }, /* R152 - EQ19 */ |
174 | 0x0000, /* R84 */ | 176 | { 153, 0x07AD }, /* R153 - EQ20 */ |
175 | 0x0000, /* R85 */ | 177 | { 154, 0x1103 }, /* R154 - EQ21 */ |
176 | 0x0000, /* R86 */ | 178 | { 155, 0x0564 }, /* R155 - EQ22 */ |
177 | 0x0000, /* R87 */ | 179 | { 156, 0x0559 }, /* R156 - EQ23 */ |
178 | 0x0000, /* R88 */ | 180 | { 157, 0x4000 }, /* R157 - EQ24 */ |
179 | 0x0000, /* R89 */ | 181 | { 161, 0x0000 }, /* R161 - Control Interface Test 1 */ |
180 | 0x0000, /* R90 - Analogue HP 0 */ | 182 | { 204, 0x0000 }, /* R204 - Analogue Output Bias 0 */ |
181 | 0x0000, /* R91 */ | 183 | { 247, 0x0000 }, /* R247 - FLL NCO Test 0 */ |
182 | 0x0000, /* R92 */ | 184 | { 248, 0x0019 }, /* R248 - FLL NCO Test 1 */ |
183 | 0x0000, /* R93 */ | ||
184 | 0x0000, /* R94 - Analogue Lineout 0 */ | ||
185 | 0x0000, /* R95 */ | ||
186 | 0x0000, /* R96 */ | ||
187 | 0x0000, /* R97 */ | ||
188 | 0x0000, /* R98 - Charge Pump 0 */ | ||
189 | 0x0000, /* R99 */ | ||
190 | 0x0000, /* R100 */ | ||
191 | 0x0000, /* R101 */ | ||
192 | 0x0000, /* R102 */ | ||
193 | 0x0000, /* R103 */ | ||
194 | 0x0004, /* R104 - Class W 0 */ | ||
195 | 0x0000, /* R105 */ | ||
196 | 0x0000, /* R106 */ | ||
197 | 0x0000, /* R107 */ | ||
198 | 0x0000, /* R108 - Write Sequencer 0 */ | ||
199 | 0x0000, /* R109 - Write Sequencer 1 */ | ||
200 | 0x0000, /* R110 - Write Sequencer 2 */ | ||
201 | 0x0000, /* R111 - Write Sequencer 3 */ | ||
202 | 0x0000, /* R112 - Write Sequencer 4 */ | ||
203 | 0x0000, /* R113 */ | ||
204 | 0x0000, /* R114 */ | ||
205 | 0x0000, /* R115 */ | ||
206 | 0x0000, /* R116 - FLL Control 1 */ | ||
207 | 0x0007, /* R117 - FLL Control 2 */ | ||
208 | 0x0000, /* R118 - FLL Control 3 */ | ||
209 | 0x2EE0, /* R119 - FLL Control 4 */ | ||
210 | 0x0004, /* R120 - FLL Control 5 */ | ||
211 | 0x0014, /* R121 - GPIO Control 1 */ | ||
212 | 0x0010, /* R122 - GPIO Control 2 */ | ||
213 | 0x0010, /* R123 - GPIO Control 3 */ | ||
214 | 0x0000, /* R124 - GPIO Control 4 */ | ||
215 | 0x0000, /* R125 */ | ||
216 | 0x0000, /* R126 - Digital Pulls */ | ||
217 | 0x0000, /* R127 - Interrupt Status */ | ||
218 | 0xFFFF, /* R128 - Interrupt Status Mask */ | ||
219 | 0x0000, /* R129 - Interrupt Polarity */ | ||
220 | 0x0000, /* R130 - Interrupt Debounce */ | ||
221 | 0x0000, /* R131 */ | ||
222 | 0x0000, /* R132 */ | ||
223 | 0x0000, /* R133 */ | ||
224 | 0x0000, /* R134 - EQ1 */ | ||
225 | 0x000C, /* R135 - EQ2 */ | ||
226 | 0x000C, /* R136 - EQ3 */ | ||
227 | 0x000C, /* R137 - EQ4 */ | ||
228 | 0x000C, /* R138 - EQ5 */ | ||
229 | 0x000C, /* R139 - EQ6 */ | ||
230 | 0x0FCA, /* R140 - EQ7 */ | ||
231 | 0x0400, /* R141 - EQ8 */ | ||
232 | 0x00D8, /* R142 - EQ9 */ | ||
233 | 0x1EB5, /* R143 - EQ10 */ | ||
234 | 0xF145, /* R144 - EQ11 */ | ||
235 | 0x0B75, /* R145 - EQ12 */ | ||
236 | 0x01C5, /* R146 - EQ13 */ | ||
237 | 0x1C58, /* R147 - EQ14 */ | ||
238 | 0xF373, /* R148 - EQ15 */ | ||
239 | 0x0A54, /* R149 - EQ16 */ | ||
240 | 0x0558, /* R150 - EQ17 */ | ||
241 | 0x168E, /* R151 - EQ18 */ | ||
242 | 0xF829, /* R152 - EQ19 */ | ||
243 | 0x07AD, /* R153 - EQ20 */ | ||
244 | 0x1103, /* R154 - EQ21 */ | ||
245 | 0x0564, /* R155 - EQ22 */ | ||
246 | 0x0559, /* R156 - EQ23 */ | ||
247 | 0x4000, /* R157 - EQ24 */ | ||
248 | 0x0000, /* R158 */ | ||
249 | 0x0000, /* R159 */ | ||
250 | 0x0000, /* R160 */ | ||
251 | 0x0000, /* R161 - Control Interface Test 1 */ | ||
252 | 0x0000, /* R162 */ | ||
253 | 0x0000, /* R163 */ | ||
254 | 0x0000, /* R164 */ | ||
255 | 0x0000, /* R165 */ | ||
256 | 0x0000, /* R166 */ | ||
257 | 0x0000, /* R167 */ | ||
258 | 0x0000, /* R168 */ | ||
259 | 0x0000, /* R169 */ | ||
260 | 0x0000, /* R170 */ | ||
261 | 0x0000, /* R171 */ | ||
262 | 0x0000, /* R172 */ | ||
263 | 0x0000, /* R173 */ | ||
264 | 0x0000, /* R174 */ | ||
265 | 0x0000, /* R175 */ | ||
266 | 0x0000, /* R176 */ | ||
267 | 0x0000, /* R177 */ | ||
268 | 0x0000, /* R178 */ | ||
269 | 0x0000, /* R179 */ | ||
270 | 0x0000, /* R180 */ | ||
271 | 0x0000, /* R181 */ | ||
272 | 0x0000, /* R182 */ | ||
273 | 0x0000, /* R183 */ | ||
274 | 0x0000, /* R184 */ | ||
275 | 0x0000, /* R185 */ | ||
276 | 0x0000, /* R186 */ | ||
277 | 0x0000, /* R187 */ | ||
278 | 0x0000, /* R188 */ | ||
279 | 0x0000, /* R189 */ | ||
280 | 0x0000, /* R190 */ | ||
281 | 0x0000, /* R191 */ | ||
282 | 0x0000, /* R192 */ | ||
283 | 0x0000, /* R193 */ | ||
284 | 0x0000, /* R194 */ | ||
285 | 0x0000, /* R195 */ | ||
286 | 0x0000, /* R196 */ | ||
287 | 0x0000, /* R197 */ | ||
288 | 0x0000, /* R198 */ | ||
289 | 0x0000, /* R199 */ | ||
290 | 0x0000, /* R200 */ | ||
291 | 0x0000, /* R201 */ | ||
292 | 0x0000, /* R202 */ | ||
293 | 0x0000, /* R203 */ | ||
294 | 0x0000, /* R204 - Analogue Output Bias 0 */ | ||
295 | 0x0000, /* R205 */ | ||
296 | 0x0000, /* R206 */ | ||
297 | 0x0000, /* R207 */ | ||
298 | 0x0000, /* R208 */ | ||
299 | 0x0000, /* R209 */ | ||
300 | 0x0000, /* R210 */ | ||
301 | 0x0000, /* R211 */ | ||
302 | 0x0000, /* R212 */ | ||
303 | 0x0000, /* R213 */ | ||
304 | 0x0000, /* R214 */ | ||
305 | 0x0000, /* R215 */ | ||
306 | 0x0000, /* R216 */ | ||
307 | 0x0000, /* R217 */ | ||
308 | 0x0000, /* R218 */ | ||
309 | 0x0000, /* R219 */ | ||
310 | 0x0000, /* R220 */ | ||
311 | 0x0000, /* R221 */ | ||
312 | 0x0000, /* R222 */ | ||
313 | 0x0000, /* R223 */ | ||
314 | 0x0000, /* R224 */ | ||
315 | 0x0000, /* R225 */ | ||
316 | 0x0000, /* R226 */ | ||
317 | 0x0000, /* R227 */ | ||
318 | 0x0000, /* R228 */ | ||
319 | 0x0000, /* R229 */ | ||
320 | 0x0000, /* R230 */ | ||
321 | 0x0000, /* R231 */ | ||
322 | 0x0000, /* R232 */ | ||
323 | 0x0000, /* R233 */ | ||
324 | 0x0000, /* R234 */ | ||
325 | 0x0000, /* R235 */ | ||
326 | 0x0000, /* R236 */ | ||
327 | 0x0000, /* R237 */ | ||
328 | 0x0000, /* R238 */ | ||
329 | 0x0000, /* R239 */ | ||
330 | 0x0000, /* R240 */ | ||
331 | 0x0000, /* R241 */ | ||
332 | 0x0000, /* R242 */ | ||
333 | 0x0000, /* R243 */ | ||
334 | 0x0000, /* R244 */ | ||
335 | 0x0000, /* R245 */ | ||
336 | 0x0000, /* R246 */ | ||
337 | 0x0000, /* R247 - FLL NCO Test 0 */ | ||
338 | 0x0019, /* R248 - FLL NCO Test 1 */ | ||
339 | }; | 185 | }; |
340 | 186 | ||
341 | static struct { | 187 | static bool wm8904_volatile_register(struct device *dev, unsigned int reg) |
342 | int readable; | 188 | { |
343 | int writable; | 189 | switch (reg) { |
344 | int vol; | 190 | case WM8904_SW_RESET_AND_ID: |
345 | } wm8904_access[] = { | 191 | case WM8904_REVISION: |
346 | { 0xFFFF, 0xFFFF, 1 }, /* R0 - SW Reset and ID */ | 192 | case WM8904_DC_SERVO_1: |
347 | { 0x0000, 0x0000, 0 }, /* R1 - Revision */ | 193 | case WM8904_DC_SERVO_6: |
348 | { 0x0000, 0x0000, 0 }, /* R2 */ | 194 | case WM8904_DC_SERVO_7: |
349 | { 0x0000, 0x0000, 0 }, /* R3 */ | 195 | case WM8904_DC_SERVO_8: |
350 | { 0x001F, 0x001F, 0 }, /* R4 - Bias Control 0 */ | 196 | case WM8904_DC_SERVO_9: |
351 | { 0x0047, 0x0047, 0 }, /* R5 - VMID Control 0 */ | 197 | case WM8904_DC_SERVO_READBACK_0: |
352 | { 0x007F, 0x007F, 0 }, /* R6 - Mic Bias Control 0 */ | 198 | case WM8904_INTERRUPT_STATUS: |
353 | { 0xC007, 0xC007, 0 }, /* R7 - Mic Bias Control 1 */ | 199 | return true; |
354 | { 0x001E, 0x001E, 0 }, /* R8 - Analogue DAC 0 */ | 200 | default: |
355 | { 0xFFFF, 0xFFFF, 0 }, /* R9 - mic Filter Control */ | 201 | return false; |
356 | { 0x0001, 0x0001, 0 }, /* R10 - Analogue ADC 0 */ | 202 | } |
357 | { 0x0000, 0x0000, 0 }, /* R11 */ | 203 | } |
358 | { 0x0003, 0x0003, 0 }, /* R12 - Power Management 0 */ | ||
359 | { 0x0000, 0x0000, 0 }, /* R13 */ | ||
360 | { 0x0003, 0x0003, 0 }, /* R14 - Power Management 2 */ | ||
361 | { 0x0003, 0x0003, 0 }, /* R15 - Power Management 3 */ | ||
362 | { 0x0000, 0x0000, 0 }, /* R16 */ | ||
363 | { 0x0000, 0x0000, 0 }, /* R17 */ | ||
364 | { 0x000F, 0x000F, 0 }, /* R18 - Power Management 6 */ | ||
365 | { 0x0000, 0x0000, 0 }, /* R19 */ | ||
366 | { 0x7001, 0x7001, 0 }, /* R20 - Clock Rates 0 */ | ||
367 | { 0x3C07, 0x3C07, 0 }, /* R21 - Clock Rates 1 */ | ||
368 | { 0xD00F, 0xD00F, 0 }, /* R22 - Clock Rates 2 */ | ||
369 | { 0x0000, 0x0000, 0 }, /* R23 */ | ||
370 | { 0x1FFF, 0x1FFF, 0 }, /* R24 - Audio Interface 0 */ | ||
371 | { 0x3DDF, 0x3DDF, 0 }, /* R25 - Audio Interface 1 */ | ||
372 | { 0x0F1F, 0x0F1F, 0 }, /* R26 - Audio Interface 2 */ | ||
373 | { 0x0FFF, 0x0FFF, 0 }, /* R27 - Audio Interface 3 */ | ||
374 | { 0x0000, 0x0000, 0 }, /* R28 */ | ||
375 | { 0x0000, 0x0000, 0 }, /* R29 */ | ||
376 | { 0x00FF, 0x01FF, 0 }, /* R30 - DAC Digital Volume Left */ | ||
377 | { 0x00FF, 0x01FF, 0 }, /* R31 - DAC Digital Volume Right */ | ||
378 | { 0x0FFF, 0x0FFF, 0 }, /* R32 - DAC Digital 0 */ | ||
379 | { 0x1E4E, 0x1E4E, 0 }, /* R33 - DAC Digital 1 */ | ||
380 | { 0x0000, 0x0000, 0 }, /* R34 */ | ||
381 | { 0x0000, 0x0000, 0 }, /* R35 */ | ||
382 | { 0x00FF, 0x01FF, 0 }, /* R36 - ADC Digital Volume Left */ | ||
383 | { 0x00FF, 0x01FF, 0 }, /* R37 - ADC Digital Volume Right */ | ||
384 | { 0x0073, 0x0073, 0 }, /* R38 - ADC Digital 0 */ | ||
385 | { 0x1800, 0x1800, 0 }, /* R39 - Digital Microphone 0 */ | ||
386 | { 0xDFEF, 0xDFEF, 0 }, /* R40 - DRC 0 */ | ||
387 | { 0xFFFF, 0xFFFF, 0 }, /* R41 - DRC 1 */ | ||
388 | { 0x003F, 0x003F, 0 }, /* R42 - DRC 2 */ | ||
389 | { 0x07FF, 0x07FF, 0 }, /* R43 - DRC 3 */ | ||
390 | { 0x009F, 0x009F, 0 }, /* R44 - Analogue Left Input 0 */ | ||
391 | { 0x009F, 0x009F, 0 }, /* R45 - Analogue Right Input 0 */ | ||
392 | { 0x007F, 0x007F, 0 }, /* R46 - Analogue Left Input 1 */ | ||
393 | { 0x007F, 0x007F, 0 }, /* R47 - Analogue Right Input 1 */ | ||
394 | { 0x0000, 0x0000, 0 }, /* R48 */ | ||
395 | { 0x0000, 0x0000, 0 }, /* R49 */ | ||
396 | { 0x0000, 0x0000, 0 }, /* R50 */ | ||
397 | { 0x0000, 0x0000, 0 }, /* R51 */ | ||
398 | { 0x0000, 0x0000, 0 }, /* R52 */ | ||
399 | { 0x0000, 0x0000, 0 }, /* R53 */ | ||
400 | { 0x0000, 0x0000, 0 }, /* R54 */ | ||
401 | { 0x0000, 0x0000, 0 }, /* R55 */ | ||
402 | { 0x0000, 0x0000, 0 }, /* R56 */ | ||
403 | { 0x017F, 0x01FF, 0 }, /* R57 - Analogue OUT1 Left */ | ||
404 | { 0x017F, 0x01FF, 0 }, /* R58 - Analogue OUT1 Right */ | ||
405 | { 0x017F, 0x01FF, 0 }, /* R59 - Analogue OUT2 Left */ | ||
406 | { 0x017F, 0x01FF, 0 }, /* R60 - Analogue OUT2 Right */ | ||
407 | { 0x000F, 0x000F, 0 }, /* R61 - Analogue OUT12 ZC */ | ||
408 | { 0x0000, 0x0000, 0 }, /* R62 */ | ||
409 | { 0x0000, 0x0000, 0 }, /* R63 */ | ||
410 | { 0x0000, 0x0000, 0 }, /* R64 */ | ||
411 | { 0x0000, 0x0000, 0 }, /* R65 */ | ||
412 | { 0x0000, 0x0000, 0 }, /* R66 */ | ||
413 | { 0x000F, 0x000F, 0 }, /* R67 - DC Servo 0 */ | ||
414 | { 0xFFFF, 0xFFFF, 1 }, /* R68 - DC Servo 1 */ | ||
415 | { 0x0F0F, 0x0F0F, 0 }, /* R69 - DC Servo 2 */ | ||
416 | { 0x0000, 0x0000, 0 }, /* R70 */ | ||
417 | { 0x007F, 0x007F, 0 }, /* R71 - DC Servo 4 */ | ||
418 | { 0x007F, 0x007F, 0 }, /* R72 - DC Servo 5 */ | ||
419 | { 0x00FF, 0x00FF, 1 }, /* R73 - DC Servo 6 */ | ||
420 | { 0x00FF, 0x00FF, 1 }, /* R74 - DC Servo 7 */ | ||
421 | { 0x00FF, 0x00FF, 1 }, /* R75 - DC Servo 8 */ | ||
422 | { 0x00FF, 0x00FF, 1 }, /* R76 - DC Servo 9 */ | ||
423 | { 0x0FFF, 0x0000, 1 }, /* R77 - DC Servo Readback 0 */ | ||
424 | { 0x0000, 0x0000, 0 }, /* R78 */ | ||
425 | { 0x0000, 0x0000, 0 }, /* R79 */ | ||
426 | { 0x0000, 0x0000, 0 }, /* R80 */ | ||
427 | { 0x0000, 0x0000, 0 }, /* R81 */ | ||
428 | { 0x0000, 0x0000, 0 }, /* R82 */ | ||
429 | { 0x0000, 0x0000, 0 }, /* R83 */ | ||
430 | { 0x0000, 0x0000, 0 }, /* R84 */ | ||
431 | { 0x0000, 0x0000, 0 }, /* R85 */ | ||
432 | { 0x0000, 0x0000, 0 }, /* R86 */ | ||
433 | { 0x0000, 0x0000, 0 }, /* R87 */ | ||
434 | { 0x0000, 0x0000, 0 }, /* R88 */ | ||
435 | { 0x0000, 0x0000, 0 }, /* R89 */ | ||
436 | { 0x00FF, 0x00FF, 0 }, /* R90 - Analogue HP 0 */ | ||
437 | { 0x0000, 0x0000, 0 }, /* R91 */ | ||
438 | { 0x0000, 0x0000, 0 }, /* R92 */ | ||
439 | { 0x0000, 0x0000, 0 }, /* R93 */ | ||
440 | { 0x00FF, 0x00FF, 0 }, /* R94 - Analogue Lineout 0 */ | ||
441 | { 0x0000, 0x0000, 0 }, /* R95 */ | ||
442 | { 0x0000, 0x0000, 0 }, /* R96 */ | ||
443 | { 0x0000, 0x0000, 0 }, /* R97 */ | ||
444 | { 0x0001, 0x0001, 0 }, /* R98 - Charge Pump 0 */ | ||
445 | { 0x0000, 0x0000, 0 }, /* R99 */ | ||
446 | { 0x0000, 0x0000, 0 }, /* R100 */ | ||
447 | { 0x0000, 0x0000, 0 }, /* R101 */ | ||
448 | { 0x0000, 0x0000, 0 }, /* R102 */ | ||
449 | { 0x0000, 0x0000, 0 }, /* R103 */ | ||
450 | { 0x0001, 0x0001, 0 }, /* R104 - Class W 0 */ | ||
451 | { 0x0000, 0x0000, 0 }, /* R105 */ | ||
452 | { 0x0000, 0x0000, 0 }, /* R106 */ | ||
453 | { 0x0000, 0x0000, 0 }, /* R107 */ | ||
454 | { 0x011F, 0x011F, 0 }, /* R108 - Write Sequencer 0 */ | ||
455 | { 0x7FFF, 0x7FFF, 0 }, /* R109 - Write Sequencer 1 */ | ||
456 | { 0x4FFF, 0x4FFF, 0 }, /* R110 - Write Sequencer 2 */ | ||
457 | { 0x003F, 0x033F, 0 }, /* R111 - Write Sequencer 3 */ | ||
458 | { 0x03F1, 0x0000, 0 }, /* R112 - Write Sequencer 4 */ | ||
459 | { 0x0000, 0x0000, 0 }, /* R113 */ | ||
460 | { 0x0000, 0x0000, 0 }, /* R114 */ | ||
461 | { 0x0000, 0x0000, 0 }, /* R115 */ | ||
462 | { 0x0007, 0x0007, 0 }, /* R116 - FLL Control 1 */ | ||
463 | { 0x3F77, 0x3F77, 0 }, /* R117 - FLL Control 2 */ | ||
464 | { 0xFFFF, 0xFFFF, 0 }, /* R118 - FLL Control 3 */ | ||
465 | { 0x7FEF, 0x7FEF, 0 }, /* R119 - FLL Control 4 */ | ||
466 | { 0x001B, 0x001B, 0 }, /* R120 - FLL Control 5 */ | ||
467 | { 0x003F, 0x003F, 0 }, /* R121 - GPIO Control 1 */ | ||
468 | { 0x003F, 0x003F, 0 }, /* R122 - GPIO Control 2 */ | ||
469 | { 0x003F, 0x003F, 0 }, /* R123 - GPIO Control 3 */ | ||
470 | { 0x038F, 0x038F, 0 }, /* R124 - GPIO Control 4 */ | ||
471 | { 0x0000, 0x0000, 0 }, /* R125 */ | ||
472 | { 0x00FF, 0x00FF, 0 }, /* R126 - Digital Pulls */ | ||
473 | { 0x07FF, 0x03FF, 1 }, /* R127 - Interrupt Status */ | ||
474 | { 0x03FF, 0x03FF, 0 }, /* R128 - Interrupt Status Mask */ | ||
475 | { 0x03FF, 0x03FF, 0 }, /* R129 - Interrupt Polarity */ | ||
476 | { 0x03FF, 0x03FF, 0 }, /* R130 - Interrupt Debounce */ | ||
477 | { 0x0000, 0x0000, 0 }, /* R131 */ | ||
478 | { 0x0000, 0x0000, 0 }, /* R132 */ | ||
479 | { 0x0000, 0x0000, 0 }, /* R133 */ | ||
480 | { 0x0001, 0x0001, 0 }, /* R134 - EQ1 */ | ||
481 | { 0x001F, 0x001F, 0 }, /* R135 - EQ2 */ | ||
482 | { 0x001F, 0x001F, 0 }, /* R136 - EQ3 */ | ||
483 | { 0x001F, 0x001F, 0 }, /* R137 - EQ4 */ | ||
484 | { 0x001F, 0x001F, 0 }, /* R138 - EQ5 */ | ||
485 | { 0x001F, 0x001F, 0 }, /* R139 - EQ6 */ | ||
486 | { 0xFFFF, 0xFFFF, 0 }, /* R140 - EQ7 */ | ||
487 | { 0xFFFF, 0xFFFF, 0 }, /* R141 - EQ8 */ | ||
488 | { 0xFFFF, 0xFFFF, 0 }, /* R142 - EQ9 */ | ||
489 | { 0xFFFF, 0xFFFF, 0 }, /* R143 - EQ10 */ | ||
490 | { 0xFFFF, 0xFFFF, 0 }, /* R144 - EQ11 */ | ||
491 | { 0xFFFF, 0xFFFF, 0 }, /* R145 - EQ12 */ | ||
492 | { 0xFFFF, 0xFFFF, 0 }, /* R146 - EQ13 */ | ||
493 | { 0xFFFF, 0xFFFF, 0 }, /* R147 - EQ14 */ | ||
494 | { 0xFFFF, 0xFFFF, 0 }, /* R148 - EQ15 */ | ||
495 | { 0xFFFF, 0xFFFF, 0 }, /* R149 - EQ16 */ | ||
496 | { 0xFFFF, 0xFFFF, 0 }, /* R150 - EQ17 */ | ||
497 | { 0xFFFF, 0xFFFF, 0 }, /* R151wm8523_dai - EQ18 */ | ||
498 | { 0xFFFF, 0xFFFF, 0 }, /* R152 - EQ19 */ | ||
499 | { 0xFFFF, 0xFFFF, 0 }, /* R153 - EQ20 */ | ||
500 | { 0xFFFF, 0xFFFF, 0 }, /* R154 - EQ21 */ | ||
501 | { 0xFFFF, 0xFFFF, 0 }, /* R155 - EQ22 */ | ||
502 | { 0xFFFF, 0xFFFF, 0 }, /* R156 - EQ23 */ | ||
503 | { 0xFFFF, 0xFFFF, 0 }, /* R157 - EQ24 */ | ||
504 | { 0x0000, 0x0000, 0 }, /* R158 */ | ||
505 | { 0x0000, 0x0000, 0 }, /* R159 */ | ||
506 | { 0x0000, 0x0000, 0 }, /* R160 */ | ||
507 | { 0x0002, 0x0002, 0 }, /* R161 - Control Interface Test 1 */ | ||
508 | { 0x0000, 0x0000, 0 }, /* R162 */ | ||
509 | { 0x0000, 0x0000, 0 }, /* R163 */ | ||
510 | { 0x0000, 0x0000, 0 }, /* R164 */ | ||
511 | { 0x0000, 0x0000, 0 }, /* R165 */ | ||
512 | { 0x0000, 0x0000, 0 }, /* R166 */ | ||
513 | { 0x0000, 0x0000, 0 }, /* R167 */ | ||
514 | { 0x0000, 0x0000, 0 }, /* R168 */ | ||
515 | { 0x0000, 0x0000, 0 }, /* R169 */ | ||
516 | { 0x0000, 0x0000, 0 }, /* R170 */ | ||
517 | { 0x0000, 0x0000, 0 }, /* R171 */ | ||
518 | { 0x0000, 0x0000, 0 }, /* R172 */ | ||
519 | { 0x0000, 0x0000, 0 }, /* R173 */ | ||
520 | { 0x0000, 0x0000, 0 }, /* R174 */ | ||
521 | { 0x0000, 0x0000, 0 }, /* R175 */ | ||
522 | { 0x0000, 0x0000, 0 }, /* R176 */ | ||
523 | { 0x0000, 0x0000, 0 }, /* R177 */ | ||
524 | { 0x0000, 0x0000, 0 }, /* R178 */ | ||
525 | { 0x0000, 0x0000, 0 }, /* R179 */ | ||
526 | { 0x0000, 0x0000, 0 }, /* R180 */ | ||
527 | { 0x0000, 0x0000, 0 }, /* R181 */ | ||
528 | { 0x0000, 0x0000, 0 }, /* R182 */ | ||
529 | { 0x0000, 0x0000, 0 }, /* R183 */ | ||
530 | { 0x0000, 0x0000, 0 }, /* R184 */ | ||
531 | { 0x0000, 0x0000, 0 }, /* R185 */ | ||
532 | { 0x0000, 0x0000, 0 }, /* R186 */ | ||
533 | { 0x0000, 0x0000, 0 }, /* R187 */ | ||
534 | { 0x0000, 0x0000, 0 }, /* R188 */ | ||
535 | { 0x0000, 0x0000, 0 }, /* R189 */ | ||
536 | { 0x0000, 0x0000, 0 }, /* R190 */ | ||
537 | { 0x0000, 0x0000, 0 }, /* R191 */ | ||
538 | { 0x0000, 0x0000, 0 }, /* R192 */ | ||
539 | { 0x0000, 0x0000, 0 }, /* R193 */ | ||
540 | { 0x0000, 0x0000, 0 }, /* R194 */ | ||
541 | { 0x0000, 0x0000, 0 }, /* R195 */ | ||
542 | { 0x0000, 0x0000, 0 }, /* R196 */ | ||
543 | { 0x0000, 0x0000, 0 }, /* R197 */ | ||
544 | { 0x0000, 0x0000, 0 }, /* R198 */ | ||
545 | { 0x0000, 0x0000, 0 }, /* R199 */ | ||
546 | { 0x0000, 0x0000, 0 }, /* R200 */ | ||
547 | { 0x0000, 0x0000, 0 }, /* R201 */ | ||
548 | { 0x0000, 0x0000, 0 }, /* R202 */ | ||
549 | { 0x0000, 0x0000, 0 }, /* R203 */ | ||
550 | { 0x0070, 0x0070, 0 }, /* R204 - Analogue Output Bias 0 */ | ||
551 | { 0x0000, 0x0000, 0 }, /* R205 */ | ||
552 | { 0x0000, 0x0000, 0 }, /* R206 */ | ||
553 | { 0x0000, 0x0000, 0 }, /* R207 */ | ||
554 | { 0x0000, 0x0000, 0 }, /* R208 */ | ||
555 | { 0x0000, 0x0000, 0 }, /* R209 */ | ||
556 | { 0x0000, 0x0000, 0 }, /* R210 */ | ||
557 | { 0x0000, 0x0000, 0 }, /* R211 */ | ||
558 | { 0x0000, 0x0000, 0 }, /* R212 */ | ||
559 | { 0x0000, 0x0000, 0 }, /* R213 */ | ||
560 | { 0x0000, 0x0000, 0 }, /* R214 */ | ||
561 | { 0x0000, 0x0000, 0 }, /* R215 */ | ||
562 | { 0x0000, 0x0000, 0 }, /* R216 */ | ||
563 | { 0x0000, 0x0000, 0 }, /* R217 */ | ||
564 | { 0x0000, 0x0000, 0 }, /* R218 */ | ||
565 | { 0x0000, 0x0000, 0 }, /* R219 */ | ||
566 | { 0x0000, 0x0000, 0 }, /* R220 */ | ||
567 | { 0x0000, 0x0000, 0 }, /* R221 */ | ||
568 | { 0x0000, 0x0000, 0 }, /* R222 */ | ||
569 | { 0x0000, 0x0000, 0 }, /* R223 */ | ||
570 | { 0x0000, 0x0000, 0 }, /* R224 */ | ||
571 | { 0x0000, 0x0000, 0 }, /* R225 */ | ||
572 | { 0x0000, 0x0000, 0 }, /* R226 */ | ||
573 | { 0x0000, 0x0000, 0 }, /* R227 */ | ||
574 | { 0x0000, 0x0000, 0 }, /* R228 */ | ||
575 | { 0x0000, 0x0000, 0 }, /* R229 */ | ||
576 | { 0x0000, 0x0000, 0 }, /* R230 */ | ||
577 | { 0x0000, 0x0000, 0 }, /* R231 */ | ||
578 | { 0x0000, 0x0000, 0 }, /* R232 */ | ||
579 | { 0x0000, 0x0000, 0 }, /* R233 */ | ||
580 | { 0x0000, 0x0000, 0 }, /* R234 */ | ||
581 | { 0x0000, 0x0000, 0 }, /* R235 */ | ||
582 | { 0x0000, 0x0000, 0 }, /* R236 */ | ||
583 | { 0x0000, 0x0000, 0 }, /* R237 */ | ||
584 | { 0x0000, 0x0000, 0 }, /* R238 */ | ||
585 | { 0x0000, 0x0000, 0 }, /* R239 */ | ||
586 | { 0x0000, 0x0000, 0 }, /* R240 */ | ||
587 | { 0x0000, 0x0000, 0 }, /* R241 */ | ||
588 | { 0x0000, 0x0000, 0 }, /* R242 */ | ||
589 | { 0x0000, 0x0000, 0 }, /* R243 */ | ||
590 | { 0x0000, 0x0000, 0 }, /* R244 */ | ||
591 | { 0x0000, 0x0000, 0 }, /* R245 */ | ||
592 | { 0x0000, 0x0000, 0 }, /* R246 */ | ||
593 | { 0x0001, 0x0001, 0 }, /* R247 - FLL NCO Test 0 */ | ||
594 | { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */ | ||
595 | }; | ||
596 | 204 | ||
597 | static int wm8904_volatile_register(struct snd_soc_codec *codec, unsigned int reg) | 205 | static bool wm8904_readable_register(struct device *dev, unsigned int reg) |
598 | { | 206 | { |
599 | return wm8904_access[reg].vol; | 207 | switch (reg) { |
208 | case WM8904_SW_RESET_AND_ID: | ||
209 | case WM8904_REVISION: | ||
210 | case WM8904_BIAS_CONTROL_0: | ||
211 | case WM8904_VMID_CONTROL_0: | ||
212 | case WM8904_MIC_BIAS_CONTROL_0: | ||
213 | case WM8904_MIC_BIAS_CONTROL_1: | ||
214 | case WM8904_ANALOGUE_DAC_0: | ||
215 | case WM8904_MIC_FILTER_CONTROL: | ||
216 | case WM8904_ANALOGUE_ADC_0: | ||
217 | case WM8904_POWER_MANAGEMENT_0: | ||
218 | case WM8904_POWER_MANAGEMENT_2: | ||
219 | case WM8904_POWER_MANAGEMENT_3: | ||
220 | case WM8904_POWER_MANAGEMENT_6: | ||
221 | case WM8904_CLOCK_RATES_0: | ||
222 | case WM8904_CLOCK_RATES_1: | ||
223 | case WM8904_CLOCK_RATES_2: | ||
224 | case WM8904_AUDIO_INTERFACE_0: | ||
225 | case WM8904_AUDIO_INTERFACE_1: | ||
226 | case WM8904_AUDIO_INTERFACE_2: | ||
227 | case WM8904_AUDIO_INTERFACE_3: | ||
228 | case WM8904_DAC_DIGITAL_VOLUME_LEFT: | ||
229 | case WM8904_DAC_DIGITAL_VOLUME_RIGHT: | ||
230 | case WM8904_DAC_DIGITAL_0: | ||
231 | case WM8904_DAC_DIGITAL_1: | ||
232 | case WM8904_ADC_DIGITAL_VOLUME_LEFT: | ||
233 | case WM8904_ADC_DIGITAL_VOLUME_RIGHT: | ||
234 | case WM8904_ADC_DIGITAL_0: | ||
235 | case WM8904_DIGITAL_MICROPHONE_0: | ||
236 | case WM8904_DRC_0: | ||
237 | case WM8904_DRC_1: | ||
238 | case WM8904_DRC_2: | ||
239 | case WM8904_DRC_3: | ||
240 | case WM8904_ANALOGUE_LEFT_INPUT_0: | ||
241 | case WM8904_ANALOGUE_RIGHT_INPUT_0: | ||
242 | case WM8904_ANALOGUE_LEFT_INPUT_1: | ||
243 | case WM8904_ANALOGUE_RIGHT_INPUT_1: | ||
244 | case WM8904_ANALOGUE_OUT1_LEFT: | ||
245 | case WM8904_ANALOGUE_OUT1_RIGHT: | ||
246 | case WM8904_ANALOGUE_OUT2_LEFT: | ||
247 | case WM8904_ANALOGUE_OUT2_RIGHT: | ||
248 | case WM8904_ANALOGUE_OUT12_ZC: | ||
249 | case WM8904_DC_SERVO_0: | ||
250 | case WM8904_DC_SERVO_1: | ||
251 | case WM8904_DC_SERVO_2: | ||
252 | case WM8904_DC_SERVO_4: | ||
253 | case WM8904_DC_SERVO_5: | ||
254 | case WM8904_DC_SERVO_6: | ||
255 | case WM8904_DC_SERVO_7: | ||
256 | case WM8904_DC_SERVO_8: | ||
257 | case WM8904_DC_SERVO_9: | ||
258 | case WM8904_DC_SERVO_READBACK_0: | ||
259 | case WM8904_ANALOGUE_HP_0: | ||
260 | case WM8904_ANALOGUE_LINEOUT_0: | ||
261 | case WM8904_CHARGE_PUMP_0: | ||
262 | case WM8904_CLASS_W_0: | ||
263 | case WM8904_WRITE_SEQUENCER_0: | ||
264 | case WM8904_WRITE_SEQUENCER_1: | ||
265 | case WM8904_WRITE_SEQUENCER_2: | ||
266 | case WM8904_WRITE_SEQUENCER_3: | ||
267 | case WM8904_WRITE_SEQUENCER_4: | ||
268 | case WM8904_FLL_CONTROL_1: | ||
269 | case WM8904_FLL_CONTROL_2: | ||
270 | case WM8904_FLL_CONTROL_3: | ||
271 | case WM8904_FLL_CONTROL_4: | ||
272 | case WM8904_FLL_CONTROL_5: | ||
273 | case WM8904_GPIO_CONTROL_1: | ||
274 | case WM8904_GPIO_CONTROL_2: | ||
275 | case WM8904_GPIO_CONTROL_3: | ||
276 | case WM8904_GPIO_CONTROL_4: | ||
277 | case WM8904_DIGITAL_PULLS: | ||
278 | case WM8904_INTERRUPT_STATUS: | ||
279 | case WM8904_INTERRUPT_STATUS_MASK: | ||
280 | case WM8904_INTERRUPT_POLARITY: | ||
281 | case WM8904_INTERRUPT_DEBOUNCE: | ||
282 | case WM8904_EQ1: | ||
283 | case WM8904_EQ2: | ||
284 | case WM8904_EQ3: | ||
285 | case WM8904_EQ4: | ||
286 | case WM8904_EQ5: | ||
287 | case WM8904_EQ6: | ||
288 | case WM8904_EQ7: | ||
289 | case WM8904_EQ8: | ||
290 | case WM8904_EQ9: | ||
291 | case WM8904_EQ10: | ||
292 | case WM8904_EQ11: | ||
293 | case WM8904_EQ12: | ||
294 | case WM8904_EQ13: | ||
295 | case WM8904_EQ14: | ||
296 | case WM8904_EQ15: | ||
297 | case WM8904_EQ16: | ||
298 | case WM8904_EQ17: | ||
299 | case WM8904_EQ18: | ||
300 | case WM8904_EQ19: | ||
301 | case WM8904_EQ20: | ||
302 | case WM8904_EQ21: | ||
303 | case WM8904_EQ22: | ||
304 | case WM8904_EQ23: | ||
305 | case WM8904_EQ24: | ||
306 | case WM8904_CONTROL_INTERFACE_TEST_1: | ||
307 | case WM8904_ADC_TEST_0: | ||
308 | case WM8904_ANALOGUE_OUTPUT_BIAS_0: | ||
309 | case WM8904_FLL_NCO_TEST_0: | ||
310 | case WM8904_FLL_NCO_TEST_1: | ||
311 | return true; | ||
312 | default: | ||
313 | return true; | ||
314 | } | ||
600 | } | 315 | } |
601 | 316 | ||
602 | static int wm8904_reset(struct snd_soc_codec *codec) | 317 | static int wm8904_reset(struct snd_soc_codec *codec) |
@@ -855,6 +570,29 @@ static const char *hpf_mode_text[] = { | |||
855 | static const struct soc_enum hpf_mode = | 570 | static const struct soc_enum hpf_mode = |
856 | SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text); | 571 | SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text); |
857 | 572 | ||
573 | static int wm8904_adc_osr_put(struct snd_kcontrol *kcontrol, | ||
574 | struct snd_ctl_elem_value *ucontrol) | ||
575 | { | ||
576 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
577 | unsigned int val; | ||
578 | int ret; | ||
579 | |||
580 | ret = snd_soc_put_volsw(kcontrol, ucontrol); | ||
581 | if (ret < 0) | ||
582 | return ret; | ||
583 | |||
584 | if (ucontrol->value.integer.value[0]) | ||
585 | val = 0; | ||
586 | else | ||
587 | val = WM8904_ADC_128_OSR_TST_MODE | WM8904_ADC_BIASX1P5; | ||
588 | |||
589 | snd_soc_update_bits(codec, WM8904_ADC_TEST_0, | ||
590 | WM8904_ADC_128_OSR_TST_MODE | WM8904_ADC_BIASX1P5, | ||
591 | val); | ||
592 | |||
593 | return ret; | ||
594 | } | ||
595 | |||
858 | static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = { | 596 | static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = { |
859 | SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT, | 597 | SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT, |
860 | WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv), | 598 | WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv), |
@@ -871,7 +609,12 @@ SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0, | |||
871 | SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0), | 609 | SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0), |
872 | SOC_ENUM("High Pass Filter Mode", hpf_mode), | 610 | SOC_ENUM("High Pass Filter Mode", hpf_mode), |
873 | 611 | ||
874 | SOC_SINGLE("ADC 128x OSR Switch", WM8904_ANALOGUE_ADC_0, 0, 1, 0), | 612 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
613 | .name = "ADC 128x OSR Switch", | ||
614 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, | ||
615 | .put = wm8904_adc_osr_put, | ||
616 | .private_value = SOC_SINGLE_VALUE(WM8904_ANALOGUE_ADC_0, 0, 1, 0), | ||
617 | }, | ||
875 | }; | 618 | }; |
876 | 619 | ||
877 | static const char *drc_path_text[] = { | 620 | static const char *drc_path_text[] = { |
@@ -1433,11 +1176,11 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec) | |||
1433 | 1176 | ||
1434 | switch (wm8904->devtype) { | 1177 | switch (wm8904->devtype) { |
1435 | case WM8904: | 1178 | case WM8904: |
1436 | snd_soc_add_controls(codec, wm8904_adc_snd_controls, | 1179 | snd_soc_add_codec_controls(codec, wm8904_adc_snd_controls, |
1437 | ARRAY_SIZE(wm8904_adc_snd_controls)); | 1180 | ARRAY_SIZE(wm8904_adc_snd_controls)); |
1438 | snd_soc_add_controls(codec, wm8904_dac_snd_controls, | 1181 | snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls, |
1439 | ARRAY_SIZE(wm8904_dac_snd_controls)); | 1182 | ARRAY_SIZE(wm8904_dac_snd_controls)); |
1440 | snd_soc_add_controls(codec, wm8904_snd_controls, | 1183 | snd_soc_add_codec_controls(codec, wm8904_snd_controls, |
1441 | ARRAY_SIZE(wm8904_snd_controls)); | 1184 | ARRAY_SIZE(wm8904_snd_controls)); |
1442 | 1185 | ||
1443 | snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets, | 1186 | snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets, |
@@ -1458,7 +1201,7 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec) | |||
1458 | break; | 1201 | break; |
1459 | 1202 | ||
1460 | case WM8912: | 1203 | case WM8912: |
1461 | snd_soc_add_controls(codec, wm8904_dac_snd_controls, | 1204 | snd_soc_add_codec_controls(codec, wm8904_dac_snd_controls, |
1462 | ARRAY_SIZE(wm8904_dac_snd_controls)); | 1205 | ARRAY_SIZE(wm8904_dac_snd_controls)); |
1463 | 1206 | ||
1464 | snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets, | 1207 | snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets, |
@@ -2088,32 +1831,6 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute) | |||
2088 | return 0; | 1831 | return 0; |
2089 | } | 1832 | } |
2090 | 1833 | ||
2091 | static void wm8904_sync_cache(struct snd_soc_codec *codec) | ||
2092 | { | ||
2093 | u16 *reg_cache = codec->reg_cache; | ||
2094 | int i; | ||
2095 | |||
2096 | if (!codec->cache_sync) | ||
2097 | return; | ||
2098 | |||
2099 | codec->cache_only = 0; | ||
2100 | |||
2101 | /* Sync back cached values if they're different from the | ||
2102 | * hardware default. | ||
2103 | */ | ||
2104 | for (i = 1; i < codec->driver->reg_cache_size; i++) { | ||
2105 | if (!wm8904_access[i].writable) | ||
2106 | continue; | ||
2107 | |||
2108 | if (reg_cache[i] == wm8904_reg[i]) | ||
2109 | continue; | ||
2110 | |||
2111 | snd_soc_write(codec, i, reg_cache[i]); | ||
2112 | } | ||
2113 | |||
2114 | codec->cache_sync = 0; | ||
2115 | } | ||
2116 | |||
2117 | static int wm8904_set_bias_level(struct snd_soc_codec *codec, | 1834 | static int wm8904_set_bias_level(struct snd_soc_codec *codec, |
2118 | enum snd_soc_bias_level level) | 1835 | enum snd_soc_bias_level level) |
2119 | { | 1836 | { |
@@ -2146,7 +1863,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec, | |||
2146 | return ret; | 1863 | return ret; |
2147 | } | 1864 | } |
2148 | 1865 | ||
2149 | wm8904_sync_cache(codec); | 1866 | regcache_sync(wm8904->regmap); |
2150 | 1867 | ||
2151 | /* Enable bias */ | 1868 | /* Enable bias */ |
2152 | snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, | 1869 | snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, |
@@ -2303,7 +2020,7 @@ static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec) | |||
2303 | wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts; | 2020 | wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts; |
2304 | wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; | 2021 | wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts; |
2305 | 2022 | ||
2306 | ret = snd_soc_add_controls(codec, &control, 1); | 2023 | ret = snd_soc_add_codec_controls(codec, &control, 1); |
2307 | if (ret != 0) | 2024 | if (ret != 0) |
2308 | dev_err(codec->dev, | 2025 | dev_err(codec->dev, |
2309 | "Failed to add ReTune Mobile control: %d\n", ret); | 2026 | "Failed to add ReTune Mobile control: %d\n", ret); |
@@ -2316,7 +2033,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec) | |||
2316 | int ret, i; | 2033 | int ret, i; |
2317 | 2034 | ||
2318 | if (!pdata) { | 2035 | if (!pdata) { |
2319 | snd_soc_add_controls(codec, wm8904_eq_controls, | 2036 | snd_soc_add_codec_controls(codec, wm8904_eq_controls, |
2320 | ARRAY_SIZE(wm8904_eq_controls)); | 2037 | ARRAY_SIZE(wm8904_eq_controls)); |
2321 | return; | 2038 | return; |
2322 | } | 2039 | } |
@@ -2344,7 +2061,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec) | |||
2344 | wm8904->drc_enum.max = pdata->num_drc_cfgs; | 2061 | wm8904->drc_enum.max = pdata->num_drc_cfgs; |
2345 | wm8904->drc_enum.texts = wm8904->drc_texts; | 2062 | wm8904->drc_enum.texts = wm8904->drc_texts; |
2346 | 2063 | ||
2347 | ret = snd_soc_add_controls(codec, &control, 1); | 2064 | ret = snd_soc_add_codec_controls(codec, &control, 1); |
2348 | if (ret != 0) | 2065 | if (ret != 0) |
2349 | dev_err(codec->dev, | 2066 | dev_err(codec->dev, |
2350 | "Failed to add DRC mode control: %d\n", ret); | 2067 | "Failed to add DRC mode control: %d\n", ret); |
@@ -2358,7 +2075,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec) | |||
2358 | if (pdata->num_retune_mobile_cfgs) | 2075 | if (pdata->num_retune_mobile_cfgs) |
2359 | wm8904_handle_retune_mobile_pdata(codec); | 2076 | wm8904_handle_retune_mobile_pdata(codec); |
2360 | else | 2077 | else |
2361 | snd_soc_add_controls(codec, wm8904_eq_controls, | 2078 | snd_soc_add_codec_controls(codec, wm8904_eq_controls, |
2362 | ARRAY_SIZE(wm8904_eq_controls)); | 2079 | ARRAY_SIZE(wm8904_eq_controls)); |
2363 | } | 2080 | } |
2364 | 2081 | ||
@@ -2371,7 +2088,7 @@ static int wm8904_probe(struct snd_soc_codec *codec) | |||
2371 | int ret, i; | 2088 | int ret, i; |
2372 | 2089 | ||
2373 | codec->cache_sync = 1; | 2090 | codec->cache_sync = 1; |
2374 | codec->dapm.idle_bias_off = 1; | 2091 | codec->control_data = wm8904->regmap; |
2375 | 2092 | ||
2376 | switch (wm8904->devtype) { | 2093 | switch (wm8904->devtype) { |
2377 | case WM8904: | 2094 | case WM8904: |
@@ -2385,7 +2102,7 @@ static int wm8904_probe(struct snd_soc_codec *codec) | |||
2385 | return -EINVAL; | 2102 | return -EINVAL; |
2386 | } | 2103 | } |
2387 | 2104 | ||
2388 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); | 2105 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); |
2389 | if (ret != 0) { | 2106 | if (ret != 0) { |
2390 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 2107 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
2391 | return ret; | 2108 | return ret; |
@@ -2413,7 +2130,7 @@ static int wm8904_probe(struct snd_soc_codec *codec) | |||
2413 | dev_err(codec->dev, "Failed to read ID register\n"); | 2130 | dev_err(codec->dev, "Failed to read ID register\n"); |
2414 | goto err_enable; | 2131 | goto err_enable; |
2415 | } | 2132 | } |
2416 | if (ret != wm8904_reg[WM8904_SW_RESET_AND_ID]) { | 2133 | if (ret != 0x8904) { |
2417 | dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret); | 2134 | dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret); |
2418 | ret = -EINVAL; | 2135 | ret = -EINVAL; |
2419 | goto err_enable; | 2136 | goto err_enable; |
@@ -2519,38 +2236,62 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8904 = { | |||
2519 | .suspend = wm8904_suspend, | 2236 | .suspend = wm8904_suspend, |
2520 | .resume = wm8904_resume, | 2237 | .resume = wm8904_resume, |
2521 | .set_bias_level = wm8904_set_bias_level, | 2238 | .set_bias_level = wm8904_set_bias_level, |
2522 | .reg_cache_size = ARRAY_SIZE(wm8904_reg), | 2239 | .idle_bias_off = true, |
2523 | .reg_word_size = sizeof(u16), | 2240 | }; |
2524 | .reg_cache_default = wm8904_reg, | 2241 | |
2525 | .volatile_register = wm8904_volatile_register, | 2242 | static const struct regmap_config wm8904_regmap = { |
2243 | .reg_bits = 8, | ||
2244 | .val_bits = 16, | ||
2245 | |||
2246 | .max_register = WM8904_MAX_REGISTER, | ||
2247 | .volatile_reg = wm8904_volatile_register, | ||
2248 | .readable_reg = wm8904_readable_register, | ||
2249 | |||
2250 | .cache_type = REGCACHE_RBTREE, | ||
2251 | .reg_defaults = wm8904_reg_defaults, | ||
2252 | .num_reg_defaults = ARRAY_SIZE(wm8904_reg_defaults), | ||
2526 | }; | 2253 | }; |
2527 | 2254 | ||
2528 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
2529 | static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, | 2255 | static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, |
2530 | const struct i2c_device_id *id) | 2256 | const struct i2c_device_id *id) |
2531 | { | 2257 | { |
2532 | struct wm8904_priv *wm8904; | 2258 | struct wm8904_priv *wm8904; |
2533 | int ret; | 2259 | int ret; |
2534 | 2260 | ||
2535 | wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL); | 2261 | wm8904 = devm_kzalloc(&i2c->dev, sizeof(struct wm8904_priv), |
2262 | GFP_KERNEL); | ||
2536 | if (wm8904 == NULL) | 2263 | if (wm8904 == NULL) |
2537 | return -ENOMEM; | 2264 | return -ENOMEM; |
2538 | 2265 | ||
2266 | wm8904->regmap = regmap_init_i2c(i2c, &wm8904_regmap); | ||
2267 | if (IS_ERR(wm8904->regmap)) { | ||
2268 | ret = PTR_ERR(wm8904->regmap); | ||
2269 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
2270 | ret); | ||
2271 | return ret; | ||
2272 | } | ||
2273 | |||
2539 | wm8904->devtype = id->driver_data; | 2274 | wm8904->devtype = id->driver_data; |
2540 | i2c_set_clientdata(i2c, wm8904); | 2275 | i2c_set_clientdata(i2c, wm8904); |
2541 | wm8904->pdata = i2c->dev.platform_data; | 2276 | wm8904->pdata = i2c->dev.platform_data; |
2542 | 2277 | ||
2543 | ret = snd_soc_register_codec(&i2c->dev, | 2278 | ret = snd_soc_register_codec(&i2c->dev, |
2544 | &soc_codec_dev_wm8904, &wm8904_dai, 1); | 2279 | &soc_codec_dev_wm8904, &wm8904_dai, 1); |
2545 | if (ret < 0) | 2280 | if (ret != 0) |
2546 | kfree(wm8904); | 2281 | goto err; |
2282 | |||
2283 | return 0; | ||
2284 | |||
2285 | err: | ||
2286 | regmap_exit(wm8904->regmap); | ||
2547 | return ret; | 2287 | return ret; |
2548 | } | 2288 | } |
2549 | 2289 | ||
2550 | static __devexit int wm8904_i2c_remove(struct i2c_client *client) | 2290 | static __devexit int wm8904_i2c_remove(struct i2c_client *client) |
2551 | { | 2291 | { |
2292 | struct wm8904_priv *wm8904 = i2c_get_clientdata(client); | ||
2552 | snd_soc_unregister_codec(&client->dev); | 2293 | snd_soc_unregister_codec(&client->dev); |
2553 | kfree(i2c_get_clientdata(client)); | 2294 | regmap_exit(wm8904->regmap); |
2554 | return 0; | 2295 | return 0; |
2555 | } | 2296 | } |
2556 | 2297 | ||
@@ -2571,27 +2312,22 @@ static struct i2c_driver wm8904_i2c_driver = { | |||
2571 | .remove = __devexit_p(wm8904_i2c_remove), | 2312 | .remove = __devexit_p(wm8904_i2c_remove), |
2572 | .id_table = wm8904_i2c_id, | 2313 | .id_table = wm8904_i2c_id, |
2573 | }; | 2314 | }; |
2574 | #endif | ||
2575 | 2315 | ||
2576 | static int __init wm8904_modinit(void) | 2316 | static int __init wm8904_modinit(void) |
2577 | { | 2317 | { |
2578 | int ret = 0; | 2318 | int ret = 0; |
2579 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
2580 | ret = i2c_add_driver(&wm8904_i2c_driver); | 2319 | ret = i2c_add_driver(&wm8904_i2c_driver); |
2581 | if (ret != 0) { | 2320 | if (ret != 0) { |
2582 | printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n", | 2321 | printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n", |
2583 | ret); | 2322 | ret); |
2584 | } | 2323 | } |
2585 | #endif | ||
2586 | return ret; | 2324 | return ret; |
2587 | } | 2325 | } |
2588 | module_init(wm8904_modinit); | 2326 | module_init(wm8904_modinit); |
2589 | 2327 | ||
2590 | static void __exit wm8904_exit(void) | 2328 | static void __exit wm8904_exit(void) |
2591 | { | 2329 | { |
2592 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
2593 | i2c_del_driver(&wm8904_i2c_driver); | 2330 | i2c_del_driver(&wm8904_i2c_driver); |
2594 | #endif | ||
2595 | } | 2331 | } |
2596 | module_exit(wm8904_exit); | 2332 | module_exit(wm8904_exit); |
2597 | 2333 | ||
diff --git a/sound/soc/codecs/wm8904.h b/sound/soc/codecs/wm8904.h index 9e8c84188ba7..c29a0e8131ca 100644 --- a/sound/soc/codecs/wm8904.h +++ b/sound/soc/codecs/wm8904.h | |||
@@ -123,6 +123,7 @@ | |||
123 | #define WM8904_EQ23 0x9C | 123 | #define WM8904_EQ23 0x9C |
124 | #define WM8904_EQ24 0x9D | 124 | #define WM8904_EQ24 0x9D |
125 | #define WM8904_CONTROL_INTERFACE_TEST_1 0xA1 | 125 | #define WM8904_CONTROL_INTERFACE_TEST_1 0xA1 |
126 | #define WM8904_ADC_TEST_0 0xC6 | ||
126 | #define WM8904_ANALOGUE_OUTPUT_BIAS_0 0xCC | 127 | #define WM8904_ANALOGUE_OUTPUT_BIAS_0 0xCC |
127 | #define WM8904_FLL_NCO_TEST_0 0xF7 | 128 | #define WM8904_FLL_NCO_TEST_0 0xF7 |
128 | #define WM8904_FLL_NCO_TEST_1 0xF8 | 129 | #define WM8904_FLL_NCO_TEST_1 0xF8 |
@@ -1557,6 +1558,16 @@ | |||
1557 | #define WM8904_USER_KEY_WIDTH 1 /* USER_KEY */ | 1558 | #define WM8904_USER_KEY_WIDTH 1 /* USER_KEY */ |
1558 | 1559 | ||
1559 | /* | 1560 | /* |
1561 | * R198 (0xC6) - ADC Test 0 | ||
1562 | */ | ||
1563 | #define WM8904_ADC_128_OSR_TST_MODE 0x0004 /* ADC_128_OSR_TST_MODE */ | ||
1564 | #define WM8904_ADC_128_OSR_TST_MODE_SHIFT 2 /* ADC_128_OSR_TST_MODE */ | ||
1565 | #define WM8904_ADC_128_OSR_TST_MODE_WIDTH 1 /* ADC_128_OSR_TST_MODE */ | ||
1566 | #define WM8904_ADC_BIASX1P5 0x0001 /* ADC_BIASX1P5 */ | ||
1567 | #define WM8904_ADC_BIASX1P5_SHIFT 0 /* ADC_BIASX1P5 */ | ||
1568 | #define WM8904_ADC_BIASX1P5_WIDTH 1 /* ADC_BIASX1P5 */ | ||
1569 | |||
1570 | /* | ||
1560 | * R204 (0xCC) - Analogue Output Bias 0 | 1571 | * R204 (0xCC) - Analogue Output Bias 0 |
1561 | */ | 1572 | */ |
1562 | #define WM8904_PGA_BIAS_MASK 0x0070 /* PGA_BIAS - [6:4] */ | 1573 | #define WM8904_PGA_BIAS_MASK 0x0070 /* PGA_BIAS - [6:4] */ |
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 14039ea2f3e4..d2883affea3b 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c | |||
@@ -717,7 +717,7 @@ static int wm8940_probe(struct snd_soc_codec *codec) | |||
717 | return ret; | 717 | return ret; |
718 | } | 718 | } |
719 | 719 | ||
720 | ret = snd_soc_add_controls(codec, wm8940_snd_controls, | 720 | ret = snd_soc_add_codec_controls(codec, wm8940_snd_controls, |
721 | ARRAY_SIZE(wm8940_snd_controls)); | 721 | ARRAY_SIZE(wm8940_snd_controls)); |
722 | if (ret) | 722 | if (ret) |
723 | return ret; | 723 | return ret; |
@@ -743,14 +743,14 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8940 = { | |||
743 | .volatile_register = wm8940_volatile_register, | 743 | .volatile_register = wm8940_volatile_register, |
744 | }; | 744 | }; |
745 | 745 | ||
746 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
747 | static __devinit int wm8940_i2c_probe(struct i2c_client *i2c, | 746 | static __devinit int wm8940_i2c_probe(struct i2c_client *i2c, |
748 | const struct i2c_device_id *id) | 747 | const struct i2c_device_id *id) |
749 | { | 748 | { |
750 | struct wm8940_priv *wm8940; | 749 | struct wm8940_priv *wm8940; |
751 | int ret; | 750 | int ret; |
752 | 751 | ||
753 | wm8940 = kzalloc(sizeof(struct wm8940_priv), GFP_KERNEL); | 752 | wm8940 = devm_kzalloc(&i2c->dev, sizeof(struct wm8940_priv), |
753 | GFP_KERNEL); | ||
754 | if (wm8940 == NULL) | 754 | if (wm8940 == NULL) |
755 | return -ENOMEM; | 755 | return -ENOMEM; |
756 | 756 | ||
@@ -759,15 +759,14 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c, | |||
759 | 759 | ||
760 | ret = snd_soc_register_codec(&i2c->dev, | 760 | ret = snd_soc_register_codec(&i2c->dev, |
761 | &soc_codec_dev_wm8940, &wm8940_dai, 1); | 761 | &soc_codec_dev_wm8940, &wm8940_dai, 1); |
762 | if (ret < 0) | 762 | |
763 | kfree(wm8940); | ||
764 | return ret; | 763 | return ret; |
765 | } | 764 | } |
766 | 765 | ||
767 | static __devexit int wm8940_i2c_remove(struct i2c_client *client) | 766 | static __devexit int wm8940_i2c_remove(struct i2c_client *client) |
768 | { | 767 | { |
769 | snd_soc_unregister_codec(&client->dev); | 768 | snd_soc_unregister_codec(&client->dev); |
770 | kfree(i2c_get_clientdata(client)); | 769 | |
771 | return 0; | 770 | return 0; |
772 | } | 771 | } |
773 | 772 | ||
@@ -786,27 +785,22 @@ static struct i2c_driver wm8940_i2c_driver = { | |||
786 | .remove = __devexit_p(wm8940_i2c_remove), | 785 | .remove = __devexit_p(wm8940_i2c_remove), |
787 | .id_table = wm8940_i2c_id, | 786 | .id_table = wm8940_i2c_id, |
788 | }; | 787 | }; |
789 | #endif | ||
790 | 788 | ||
791 | static int __init wm8940_modinit(void) | 789 | static int __init wm8940_modinit(void) |
792 | { | 790 | { |
793 | int ret = 0; | 791 | int ret = 0; |
794 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
795 | ret = i2c_add_driver(&wm8940_i2c_driver); | 792 | ret = i2c_add_driver(&wm8940_i2c_driver); |
796 | if (ret != 0) { | 793 | if (ret != 0) { |
797 | printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n", | 794 | printk(KERN_ERR "Failed to register wm8940 I2C driver: %d\n", |
798 | ret); | 795 | ret); |
799 | } | 796 | } |
800 | #endif | ||
801 | return ret; | 797 | return ret; |
802 | } | 798 | } |
803 | module_init(wm8940_modinit); | 799 | module_init(wm8940_modinit); |
804 | 800 | ||
805 | static void __exit wm8940_exit(void) | 801 | static void __exit wm8940_exit(void) |
806 | { | 802 | { |
807 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
808 | i2c_del_driver(&wm8940_i2c_driver); | 803 | i2c_del_driver(&wm8940_i2c_driver); |
809 | #endif | ||
810 | } | 804 | } |
811 | module_exit(wm8940_exit); | 805 | module_exit(wm8940_exit); |
812 | 806 | ||
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index 924548182d58..61fe97433e73 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <linux/regmap.h> | ||
19 | #include <linux/regulator/consumer.h> | 20 | #include <linux/regulator/consumer.h> |
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
21 | #include <sound/core.h> | 22 | #include <sound/core.h> |
@@ -38,7 +39,7 @@ static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = { | |||
38 | 39 | ||
39 | /* codec private data */ | 40 | /* codec private data */ |
40 | struct wm8955_priv { | 41 | struct wm8955_priv { |
41 | enum snd_soc_control_type control_type; | 42 | struct regmap *regmap; |
42 | 43 | ||
43 | unsigned int mclk_rate; | 44 | unsigned int mclk_rate; |
44 | 45 | ||
@@ -48,69 +49,85 @@ struct wm8955_priv { | |||
48 | struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES]; | 49 | struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES]; |
49 | }; | 50 | }; |
50 | 51 | ||
51 | static const u16 wm8955_reg[WM8955_MAX_REGISTER + 1] = { | 52 | static const struct reg_default wm8955_reg_defaults[] = { |
52 | 0x0000, /* R0 */ | 53 | { 2, 0x0079 }, /* R2 - LOUT1 volume */ |
53 | 0x0000, /* R1 */ | 54 | { 3, 0x0079 }, /* R3 - ROUT1 volume */ |
54 | 0x0079, /* R2 - LOUT1 volume */ | 55 | { 5, 0x0008 }, /* R5 - DAC Control */ |
55 | 0x0079, /* R3 - ROUT1 volume */ | 56 | { 7, 0x000A }, /* R7 - Audio Interface */ |
56 | 0x0000, /* R4 */ | 57 | { 8, 0x0000 }, /* R8 - Sample Rate */ |
57 | 0x0008, /* R5 - DAC Control */ | 58 | { 10, 0x00FF }, /* R10 - Left DAC volume */ |
58 | 0x0000, /* R6 */ | 59 | { 11, 0x00FF }, /* R11 - Right DAC volume */ |
59 | 0x000A, /* R7 - Audio Interface */ | 60 | { 12, 0x000F }, /* R12 - Bass control */ |
60 | 0x0000, /* R8 - Sample Rate */ | 61 | { 13, 0x000F }, /* R13 - Treble control */ |
61 | 0x0000, /* R9 */ | 62 | { 23, 0x00C1 }, /* R23 - Additional control (1) */ |
62 | 0x00FF, /* R10 - Left DAC volume */ | 63 | { 24, 0x0000 }, /* R24 - Additional control (2) */ |
63 | 0x00FF, /* R11 - Right DAC volume */ | 64 | { 25, 0x0000 }, /* R25 - Power Management (1) */ |
64 | 0x000F, /* R12 - Bass control */ | 65 | { 26, 0x0000 }, /* R26 - Power Management (2) */ |
65 | 0x000F, /* R13 - Treble control */ | 66 | { 27, 0x0000 }, /* R27 - Additional Control (3) */ |
66 | 0x0000, /* R14 */ | 67 | { 34, 0x0050 }, /* R34 - Left out Mix (1) */ |
67 | 0x0000, /* R15 - Reset */ | 68 | { 35, 0x0050 }, /* R35 - Left out Mix (2) */ |
68 | 0x0000, /* R16 */ | 69 | { 36, 0x0050 }, /* R36 - Right out Mix (1) */ |
69 | 0x0000, /* R17 */ | 70 | { 37, 0x0050 }, /* R37 - Right Out Mix (2) */ |
70 | 0x0000, /* R18 */ | 71 | { 38, 0x0050 }, /* R38 - Mono out Mix (1) */ |
71 | 0x0000, /* R19 */ | 72 | { 39, 0x0050 }, /* R39 - Mono out Mix (2) */ |
72 | 0x0000, /* R20 */ | 73 | { 40, 0x0079 }, /* R40 - LOUT2 volume */ |
73 | 0x0000, /* R21 */ | 74 | { 41, 0x0079 }, /* R41 - ROUT2 volume */ |
74 | 0x0000, /* R22 */ | 75 | { 42, 0x0079 }, /* R42 - MONOOUT volume */ |
75 | 0x00C1, /* R23 - Additional control (1) */ | 76 | { 43, 0x0000 }, /* R43 - Clocking / PLL */ |
76 | 0x0000, /* R24 - Additional control (2) */ | 77 | { 44, 0x0103 }, /* R44 - PLL Control 1 */ |
77 | 0x0000, /* R25 - Power Management (1) */ | 78 | { 45, 0x0024 }, /* R45 - PLL Control 2 */ |
78 | 0x0000, /* R26 - Power Management (2) */ | 79 | { 46, 0x01BA }, /* R46 - PLL Control 3 */ |
79 | 0x0000, /* R27 - Additional Control (3) */ | 80 | { 59, 0x0000 }, /* R59 - PLL Control 4 */ |
80 | 0x0000, /* R28 */ | ||
81 | 0x0000, /* R29 */ | ||
82 | 0x0000, /* R30 */ | ||
83 | 0x0000, /* R31 */ | ||
84 | 0x0000, /* R32 */ | ||
85 | 0x0000, /* R33 */ | ||
86 | 0x0050, /* R34 - Left out Mix (1) */ | ||
87 | 0x0050, /* R35 - Left out Mix (2) */ | ||
88 | 0x0050, /* R36 - Right out Mix (1) */ | ||
89 | 0x0050, /* R37 - Right Out Mix (2) */ | ||
90 | 0x0050, /* R38 - Mono out Mix (1) */ | ||
91 | 0x0050, /* R39 - Mono out Mix (2) */ | ||
92 | 0x0079, /* R40 - LOUT2 volume */ | ||
93 | 0x0079, /* R41 - ROUT2 volume */ | ||
94 | 0x0079, /* R42 - MONOOUT volume */ | ||
95 | 0x0000, /* R43 - Clocking / PLL */ | ||
96 | 0x0103, /* R44 - PLL Control 1 */ | ||
97 | 0x0024, /* R45 - PLL Control 2 */ | ||
98 | 0x01BA, /* R46 - PLL Control 3 */ | ||
99 | 0x0000, /* R47 */ | ||
100 | 0x0000, /* R48 */ | ||
101 | 0x0000, /* R49 */ | ||
102 | 0x0000, /* R50 */ | ||
103 | 0x0000, /* R51 */ | ||
104 | 0x0000, /* R52 */ | ||
105 | 0x0000, /* R53 */ | ||
106 | 0x0000, /* R54 */ | ||
107 | 0x0000, /* R55 */ | ||
108 | 0x0000, /* R56 */ | ||
109 | 0x0000, /* R57 */ | ||
110 | 0x0000, /* R58 */ | ||
111 | 0x0000, /* R59 - PLL Control 4 */ | ||
112 | }; | 81 | }; |
113 | 82 | ||
83 | static bool wm8955_writeable(struct device *dev, unsigned int reg) | ||
84 | { | ||
85 | switch (reg) { | ||
86 | case WM8955_LOUT1_VOLUME: | ||
87 | case WM8955_ROUT1_VOLUME: | ||
88 | case WM8955_DAC_CONTROL: | ||
89 | case WM8955_AUDIO_INTERFACE: | ||
90 | case WM8955_SAMPLE_RATE: | ||
91 | case WM8955_LEFT_DAC_VOLUME: | ||
92 | case WM8955_RIGHT_DAC_VOLUME: | ||
93 | case WM8955_BASS_CONTROL: | ||
94 | case WM8955_TREBLE_CONTROL: | ||
95 | case WM8955_RESET: | ||
96 | case WM8955_ADDITIONAL_CONTROL_1: | ||
97 | case WM8955_ADDITIONAL_CONTROL_2: | ||
98 | case WM8955_POWER_MANAGEMENT_1: | ||
99 | case WM8955_POWER_MANAGEMENT_2: | ||
100 | case WM8955_ADDITIONAL_CONTROL_3: | ||
101 | case WM8955_LEFT_OUT_MIX_1: | ||
102 | case WM8955_LEFT_OUT_MIX_2: | ||
103 | case WM8955_RIGHT_OUT_MIX_1: | ||
104 | case WM8955_RIGHT_OUT_MIX_2: | ||
105 | case WM8955_MONO_OUT_MIX_1: | ||
106 | case WM8955_MONO_OUT_MIX_2: | ||
107 | case WM8955_LOUT2_VOLUME: | ||
108 | case WM8955_ROUT2_VOLUME: | ||
109 | case WM8955_MONOOUT_VOLUME: | ||
110 | case WM8955_CLOCKING_PLL: | ||
111 | case WM8955_PLL_CONTROL_1: | ||
112 | case WM8955_PLL_CONTROL_2: | ||
113 | case WM8955_PLL_CONTROL_3: | ||
114 | case WM8955_PLL_CONTROL_4: | ||
115 | return true; | ||
116 | default: | ||
117 | return false; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | static bool wm8955_volatile(struct device *dev, unsigned int reg) | ||
122 | { | ||
123 | switch (reg) { | ||
124 | case WM8955_RESET: | ||
125 | return true; | ||
126 | default: | ||
127 | return false; | ||
128 | } | ||
129 | } | ||
130 | |||
114 | static int wm8955_reset(struct snd_soc_codec *codec) | 131 | static int wm8955_reset(struct snd_soc_codec *codec) |
115 | { | 132 | { |
116 | return snd_soc_write(codec, WM8955_RESET, 0); | 133 | return snd_soc_write(codec, WM8955_RESET, 0); |
@@ -527,7 +544,7 @@ SND_SOC_DAPM_OUTPUT("MONOOUT"), | |||
527 | SND_SOC_DAPM_OUTPUT("OUT3"), | 544 | SND_SOC_DAPM_OUTPUT("OUT3"), |
528 | }; | 545 | }; |
529 | 546 | ||
530 | static const struct snd_soc_dapm_route wm8955_intercon[] = { | 547 | static const struct snd_soc_dapm_route wm8955_dapm_routes[] = { |
531 | { "DACL", NULL, "SYSCLK" }, | 548 | { "DACL", NULL, "SYSCLK" }, |
532 | { "DACR", NULL, "SYSCLK" }, | 549 | { "DACR", NULL, "SYSCLK" }, |
533 | 550 | ||
@@ -572,21 +589,6 @@ static const struct snd_soc_dapm_route wm8955_intercon[] = { | |||
572 | { "OUT3", NULL, "OUT3 PGA" }, | 589 | { "OUT3", NULL, "OUT3 PGA" }, |
573 | }; | 590 | }; |
574 | 591 | ||
575 | static int wm8955_add_widgets(struct snd_soc_codec *codec) | ||
576 | { | ||
577 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
578 | |||
579 | snd_soc_add_controls(codec, wm8955_snd_controls, | ||
580 | ARRAY_SIZE(wm8955_snd_controls)); | ||
581 | |||
582 | snd_soc_dapm_new_controls(dapm, wm8955_dapm_widgets, | ||
583 | ARRAY_SIZE(wm8955_dapm_widgets)); | ||
584 | snd_soc_dapm_add_routes(dapm, wm8955_intercon, | ||
585 | ARRAY_SIZE(wm8955_intercon)); | ||
586 | |||
587 | return 0; | ||
588 | } | ||
589 | |||
590 | static int wm8955_hw_params(struct snd_pcm_substream *substream, | 592 | static int wm8955_hw_params(struct snd_pcm_substream *substream, |
591 | struct snd_pcm_hw_params *params, | 593 | struct snd_pcm_hw_params *params, |
592 | struct snd_soc_dai *dai) | 594 | struct snd_soc_dai *dai) |
@@ -765,8 +767,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, | |||
765 | enum snd_soc_bias_level level) | 767 | enum snd_soc_bias_level level) |
766 | { | 768 | { |
767 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); | 769 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); |
768 | u16 *reg_cache = codec->reg_cache; | 770 | int ret; |
769 | int ret, i; | ||
770 | 771 | ||
771 | switch (level) { | 772 | switch (level) { |
772 | case SND_SOC_BIAS_ON: | 773 | case SND_SOC_BIAS_ON: |
@@ -795,18 +796,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, | |||
795 | return ret; | 796 | return ret; |
796 | } | 797 | } |
797 | 798 | ||
798 | /* Sync back cached values if they're | 799 | regcache_sync(wm8955->regmap); |
799 | * different from the hardware default. | ||
800 | */ | ||
801 | for (i = 0; i < codec->driver->reg_cache_size; i++) { | ||
802 | if (i == WM8955_RESET) | ||
803 | continue; | ||
804 | |||
805 | if (reg_cache[i] == wm8955_reg[i]) | ||
806 | continue; | ||
807 | |||
808 | snd_soc_write(codec, i, reg_cache[i]); | ||
809 | } | ||
810 | 800 | ||
811 | /* Enable VREF and VMID */ | 801 | /* Enable VREF and VMID */ |
812 | snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1, | 802 | snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1, |
@@ -880,8 +870,12 @@ static struct snd_soc_dai_driver wm8955_dai = { | |||
880 | #ifdef CONFIG_PM | 870 | #ifdef CONFIG_PM |
881 | static int wm8955_suspend(struct snd_soc_codec *codec) | 871 | static int wm8955_suspend(struct snd_soc_codec *codec) |
882 | { | 872 | { |
873 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); | ||
874 | |||
883 | wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF); | 875 | wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF); |
884 | 876 | ||
877 | regcache_mark_dirty(wm8955->regmap); | ||
878 | |||
885 | return 0; | 879 | return 0; |
886 | } | 880 | } |
887 | 881 | ||
@@ -900,10 +894,11 @@ static int wm8955_probe(struct snd_soc_codec *codec) | |||
900 | { | 894 | { |
901 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); | 895 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); |
902 | struct wm8955_pdata *pdata = dev_get_platdata(codec->dev); | 896 | struct wm8955_pdata *pdata = dev_get_platdata(codec->dev); |
903 | u16 *reg_cache = codec->reg_cache; | ||
904 | int ret, i; | 897 | int ret, i; |
905 | 898 | ||
906 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type); | 899 | codec->control_data = wm8955->regmap; |
900 | |||
901 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
907 | if (ret != 0) { | 902 | if (ret != 0) { |
908 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 903 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
909 | return ret; | 904 | return ret; |
@@ -958,12 +953,12 @@ static int wm8955_probe(struct snd_soc_codec *codec) | |||
958 | /* Set platform data values */ | 953 | /* Set platform data values */ |
959 | if (pdata) { | 954 | if (pdata) { |
960 | if (pdata->out2_speaker) | 955 | if (pdata->out2_speaker) |
961 | reg_cache[WM8955_ADDITIONAL_CONTROL_2] | 956 | snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_2, |
962 | |= WM8955_ROUT2INV; | 957 | WM8955_ROUT2INV, WM8955_ROUT2INV); |
963 | 958 | ||
964 | if (pdata->monoin_diff) | 959 | if (pdata->monoin_diff) |
965 | reg_cache[WM8955_MONO_OUT_MIX_1] | 960 | snd_soc_update_bits(codec, WM8955_MONO_OUT_MIX_1, |
966 | |= WM8955_DMEN; | 961 | WM8955_DMEN, WM8955_DMEN); |
967 | } | 962 | } |
968 | 963 | ||
969 | wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 964 | wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
@@ -971,7 +966,6 @@ static int wm8955_probe(struct snd_soc_codec *codec) | |||
971 | /* Bias level configuration will have done an extra enable */ | 966 | /* Bias level configuration will have done an extra enable */ |
972 | regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); | 967 | regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); |
973 | 968 | ||
974 | wm8955_add_widgets(codec); | ||
975 | return 0; | 969 | return 0; |
976 | 970 | ||
977 | err_enable: | 971 | err_enable: |
@@ -996,36 +990,68 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8955 = { | |||
996 | .suspend = wm8955_suspend, | 990 | .suspend = wm8955_suspend, |
997 | .resume = wm8955_resume, | 991 | .resume = wm8955_resume, |
998 | .set_bias_level = wm8955_set_bias_level, | 992 | .set_bias_level = wm8955_set_bias_level, |
999 | .reg_cache_size = ARRAY_SIZE(wm8955_reg), | 993 | |
1000 | .reg_word_size = sizeof(u16), | 994 | .controls = wm8955_snd_controls, |
1001 | .reg_cache_default = wm8955_reg, | 995 | .num_controls = ARRAY_SIZE(wm8955_snd_controls), |
996 | .dapm_widgets = wm8955_dapm_widgets, | ||
997 | .num_dapm_widgets = ARRAY_SIZE(wm8955_dapm_widgets), | ||
998 | .dapm_routes = wm8955_dapm_routes, | ||
999 | .num_dapm_routes = ARRAY_SIZE(wm8955_dapm_routes), | ||
1000 | }; | ||
1001 | |||
1002 | static const struct regmap_config wm8955_regmap = { | ||
1003 | .reg_bits = 7, | ||
1004 | .val_bits = 9, | ||
1005 | |||
1006 | .max_register = WM8955_MAX_REGISTER, | ||
1007 | .volatile_reg = wm8955_volatile, | ||
1008 | .writeable_reg = wm8955_writeable, | ||
1009 | |||
1010 | .cache_type = REGCACHE_RBTREE, | ||
1011 | .reg_defaults = wm8955_reg_defaults, | ||
1012 | .num_reg_defaults = ARRAY_SIZE(wm8955_reg_defaults), | ||
1002 | }; | 1013 | }; |
1003 | 1014 | ||
1004 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1005 | static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, | 1015 | static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, |
1006 | const struct i2c_device_id *id) | 1016 | const struct i2c_device_id *id) |
1007 | { | 1017 | { |
1008 | struct wm8955_priv *wm8955; | 1018 | struct wm8955_priv *wm8955; |
1009 | int ret; | 1019 | int ret; |
1010 | 1020 | ||
1011 | wm8955 = kzalloc(sizeof(struct wm8955_priv), GFP_KERNEL); | 1021 | wm8955 = devm_kzalloc(&i2c->dev, sizeof(struct wm8955_priv), |
1022 | GFP_KERNEL); | ||
1012 | if (wm8955 == NULL) | 1023 | if (wm8955 == NULL) |
1013 | return -ENOMEM; | 1024 | return -ENOMEM; |
1014 | 1025 | ||
1026 | wm8955->regmap = regmap_init_i2c(i2c, &wm8955_regmap); | ||
1027 | if (IS_ERR(wm8955->regmap)) { | ||
1028 | ret = PTR_ERR(wm8955->regmap); | ||
1029 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
1030 | ret); | ||
1031 | return ret; | ||
1032 | } | ||
1033 | |||
1015 | i2c_set_clientdata(i2c, wm8955); | 1034 | i2c_set_clientdata(i2c, wm8955); |
1016 | wm8955->control_type = SND_SOC_I2C; | ||
1017 | 1035 | ||
1018 | ret = snd_soc_register_codec(&i2c->dev, | 1036 | ret = snd_soc_register_codec(&i2c->dev, |
1019 | &soc_codec_dev_wm8955, &wm8955_dai, 1); | 1037 | &soc_codec_dev_wm8955, &wm8955_dai, 1); |
1020 | if (ret < 0) | 1038 | if (ret != 0) |
1021 | kfree(wm8955); | 1039 | goto err; |
1040 | |||
1041 | return ret; | ||
1042 | |||
1043 | err: | ||
1044 | regmap_exit(wm8955->regmap); | ||
1022 | return ret; | 1045 | return ret; |
1023 | } | 1046 | } |
1024 | 1047 | ||
1025 | static __devexit int wm8955_i2c_remove(struct i2c_client *client) | 1048 | static __devexit int wm8955_i2c_remove(struct i2c_client *client) |
1026 | { | 1049 | { |
1050 | struct wm8955_priv *wm8955 = i2c_get_clientdata(client); | ||
1051 | |||
1027 | snd_soc_unregister_codec(&client->dev); | 1052 | snd_soc_unregister_codec(&client->dev); |
1028 | kfree(i2c_get_clientdata(client)); | 1053 | regmap_exit(wm8955->regmap); |
1054 | |||
1029 | return 0; | 1055 | return 0; |
1030 | } | 1056 | } |
1031 | 1057 | ||
@@ -1044,27 +1070,22 @@ static struct i2c_driver wm8955_i2c_driver = { | |||
1044 | .remove = __devexit_p(wm8955_i2c_remove), | 1070 | .remove = __devexit_p(wm8955_i2c_remove), |
1045 | .id_table = wm8955_i2c_id, | 1071 | .id_table = wm8955_i2c_id, |
1046 | }; | 1072 | }; |
1047 | #endif | ||
1048 | 1073 | ||
1049 | static int __init wm8955_modinit(void) | 1074 | static int __init wm8955_modinit(void) |
1050 | { | 1075 | { |
1051 | int ret = 0; | 1076 | int ret = 0; |
1052 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1053 | ret = i2c_add_driver(&wm8955_i2c_driver); | 1077 | ret = i2c_add_driver(&wm8955_i2c_driver); |
1054 | if (ret != 0) { | 1078 | if (ret != 0) { |
1055 | printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n", | 1079 | printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n", |
1056 | ret); | 1080 | ret); |
1057 | } | 1081 | } |
1058 | #endif | ||
1059 | return ret; | 1082 | return ret; |
1060 | } | 1083 | } |
1061 | module_init(wm8955_modinit); | 1084 | module_init(wm8955_modinit); |
1062 | 1085 | ||
1063 | static void __exit wm8955_exit(void) | 1086 | static void __exit wm8955_exit(void) |
1064 | { | 1087 | { |
1065 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1066 | i2c_del_driver(&wm8955_i2c_driver); | 1088 | i2c_del_driver(&wm8955_i2c_driver); |
1067 | #endif | ||
1068 | } | 1089 | } |
1069 | module_exit(wm8955_exit); | 1090 | module_exit(wm8955_exit); |
1070 | 1091 | ||
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 8d4ea43d40a3..1332692ef81b 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c | |||
@@ -55,7 +55,7 @@ static int wm8958_dsp2_fw(struct snd_soc_codec *codec, const char *name, | |||
55 | return 0; | 55 | return 0; |
56 | 56 | ||
57 | if (fw->size < 32) { | 57 | if (fw->size < 32) { |
58 | dev_err(codec->dev, "%s: firmware too short (%d bytes)\n", | 58 | dev_err(codec->dev, "%s: firmware too short (%zd bytes)\n", |
59 | name, fw->size); | 59 | name, fw->size); |
60 | goto err; | 60 | goto err; |
61 | } | 61 | } |
@@ -920,11 +920,11 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
920 | 920 | ||
921 | wm8994->dsp_active = -1; | 921 | wm8994->dsp_active = -1; |
922 | 922 | ||
923 | snd_soc_add_controls(codec, wm8958_mbc_snd_controls, | 923 | snd_soc_add_codec_controls(codec, wm8958_mbc_snd_controls, |
924 | ARRAY_SIZE(wm8958_mbc_snd_controls)); | 924 | ARRAY_SIZE(wm8958_mbc_snd_controls)); |
925 | snd_soc_add_controls(codec, wm8958_vss_snd_controls, | 925 | snd_soc_add_codec_controls(codec, wm8958_vss_snd_controls, |
926 | ARRAY_SIZE(wm8958_vss_snd_controls)); | 926 | ARRAY_SIZE(wm8958_vss_snd_controls)); |
927 | snd_soc_add_controls(codec, wm8958_enh_eq_snd_controls, | 927 | snd_soc_add_codec_controls(codec, wm8958_enh_eq_snd_controls, |
928 | ARRAY_SIZE(wm8958_enh_eq_snd_controls)); | 928 | ARRAY_SIZE(wm8958_enh_eq_snd_controls)); |
929 | 929 | ||
930 | 930 | ||
@@ -958,7 +958,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
958 | wm8994->mbc_enum.max = pdata->num_mbc_cfgs; | 958 | wm8994->mbc_enum.max = pdata->num_mbc_cfgs; |
959 | wm8994->mbc_enum.texts = wm8994->mbc_texts; | 959 | wm8994->mbc_enum.texts = wm8994->mbc_texts; |
960 | 960 | ||
961 | ret = snd_soc_add_controls(wm8994->codec, control, 1); | 961 | ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); |
962 | if (ret != 0) | 962 | if (ret != 0) |
963 | dev_err(wm8994->codec->dev, | 963 | dev_err(wm8994->codec->dev, |
964 | "Failed to add MBC mode controls: %d\n", ret); | 964 | "Failed to add MBC mode controls: %d\n", ret); |
@@ -986,7 +986,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
986 | wm8994->vss_enum.max = pdata->num_vss_cfgs; | 986 | wm8994->vss_enum.max = pdata->num_vss_cfgs; |
987 | wm8994->vss_enum.texts = wm8994->vss_texts; | 987 | wm8994->vss_enum.texts = wm8994->vss_texts; |
988 | 988 | ||
989 | ret = snd_soc_add_controls(wm8994->codec, control, 1); | 989 | ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); |
990 | if (ret != 0) | 990 | if (ret != 0) |
991 | dev_err(wm8994->codec->dev, | 991 | dev_err(wm8994->codec->dev, |
992 | "Failed to add VSS mode controls: %d\n", ret); | 992 | "Failed to add VSS mode controls: %d\n", ret); |
@@ -1015,7 +1015,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
1015 | wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs; | 1015 | wm8994->vss_hpf_enum.max = pdata->num_vss_hpf_cfgs; |
1016 | wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; | 1016 | wm8994->vss_hpf_enum.texts = wm8994->vss_hpf_texts; |
1017 | 1017 | ||
1018 | ret = snd_soc_add_controls(wm8994->codec, control, 1); | 1018 | ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); |
1019 | if (ret != 0) | 1019 | if (ret != 0) |
1020 | dev_err(wm8994->codec->dev, | 1020 | dev_err(wm8994->codec->dev, |
1021 | "Failed to add VSS HPFmode controls: %d\n", | 1021 | "Failed to add VSS HPFmode controls: %d\n", |
@@ -1045,7 +1045,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec) | |||
1045 | wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs; | 1045 | wm8994->enh_eq_enum.max = pdata->num_enh_eq_cfgs; |
1046 | wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; | 1046 | wm8994->enh_eq_enum.texts = wm8994->enh_eq_texts; |
1047 | 1047 | ||
1048 | ret = snd_soc_add_controls(wm8994->codec, control, 1); | 1048 | ret = snd_soc_add_codec_controls(wm8994->codec, control, 1); |
1049 | if (ret != 0) | 1049 | if (ret != 0) |
1050 | dev_err(wm8994->codec->dev, | 1050 | dev_err(wm8994->codec->dev, |
1051 | "Failed to add enhanced EQ controls: %d\n", | 1051 | "Failed to add enhanced EQ controls: %d\n", |
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index e5caae32e541..840d72086d04 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
@@ -940,7 +940,7 @@ static int wm8960_probe(struct snd_soc_codec *codec) | |||
940 | snd_soc_update_bits(codec, WM8960_LOUT2, 0x100, 0x100); | 940 | snd_soc_update_bits(codec, WM8960_LOUT2, 0x100, 0x100); |
941 | snd_soc_update_bits(codec, WM8960_ROUT2, 0x100, 0x100); | 941 | snd_soc_update_bits(codec, WM8960_ROUT2, 0x100, 0x100); |
942 | 942 | ||
943 | snd_soc_add_controls(codec, wm8960_snd_controls, | 943 | snd_soc_add_codec_controls(codec, wm8960_snd_controls, |
944 | ARRAY_SIZE(wm8960_snd_controls)); | 944 | ARRAY_SIZE(wm8960_snd_controls)); |
945 | wm8960_add_widgets(codec); | 945 | wm8960_add_widgets(codec); |
946 | 946 | ||
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index 4f20c72a0f1d..05ea7c274093 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c | |||
@@ -1022,7 +1022,7 @@ static int wm8961_probe(struct snd_soc_codec *codec) | |||
1022 | 1022 | ||
1023 | wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1023 | wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1024 | 1024 | ||
1025 | snd_soc_add_controls(codec, wm8961_snd_controls, | 1025 | snd_soc_add_codec_controls(codec, wm8961_snd_controls, |
1026 | ARRAY_SIZE(wm8961_snd_controls)); | 1026 | ARRAY_SIZE(wm8961_snd_controls)); |
1027 | snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets, | 1027 | snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets, |
1028 | ARRAY_SIZE(wm8961_dapm_widgets)); | 1028 | ARRAY_SIZE(wm8961_dapm_widgets)); |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 296de4e30d26..15d467ff91b4 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
21 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
22 | #include <linux/input.h> | 22 | #include <linux/input.h> |
23 | #include <linux/pm_runtime.h> | ||
23 | #include <linux/regmap.h> | 24 | #include <linux/regmap.h> |
24 | #include <linux/regulator/consumer.h> | 25 | #include <linux/regulator/consumer.h> |
25 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
@@ -96,7 +97,7 @@ static int wm8962_regulator_event_##n(struct notifier_block *nb, \ | |||
96 | struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \ | 97 | struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \ |
97 | disable_nb[n]); \ | 98 | disable_nb[n]); \ |
98 | if (event & REGULATOR_EVENT_DISABLE) { \ | 99 | if (event & REGULATOR_EVENT_DISABLE) { \ |
99 | regcache_cache_only(wm8962->regmap, true); \ | 100 | regcache_mark_dirty(wm8962->regmap); \ |
100 | } \ | 101 | } \ |
101 | return 0; \ | 102 | return 0; \ |
102 | } | 103 | } |
@@ -115,11 +116,11 @@ static struct reg_default wm8962_reg[] = { | |||
115 | { 1, 0x049F }, /* R1 - Right Input volume */ | 116 | { 1, 0x049F }, /* R1 - Right Input volume */ |
116 | { 2, 0x0000 }, /* R2 - HPOUTL volume */ | 117 | { 2, 0x0000 }, /* R2 - HPOUTL volume */ |
117 | { 3, 0x0000 }, /* R3 - HPOUTR volume */ | 118 | { 3, 0x0000 }, /* R3 - HPOUTR volume */ |
118 | { 4, 0x0020 }, /* R4 - Clocking1 */ | 119 | |
119 | { 5, 0x0018 }, /* R5 - ADC & DAC Control 1 */ | 120 | { 5, 0x0018 }, /* R5 - ADC & DAC Control 1 */ |
120 | { 6, 0x2008 }, /* R6 - ADC & DAC Control 2 */ | 121 | { 6, 0x2008 }, /* R6 - ADC & DAC Control 2 */ |
121 | { 7, 0x000A }, /* R7 - Audio Interface 0 */ | 122 | { 7, 0x000A }, /* R7 - Audio Interface 0 */ |
122 | { 8, 0x01E4 }, /* R8 - Clocking2 */ | 123 | |
123 | { 9, 0x0300 }, /* R9 - Audio Interface 1 */ | 124 | { 9, 0x0300 }, /* R9 - Audio Interface 1 */ |
124 | { 10, 0x00C0 }, /* R10 - Left DAC volume */ | 125 | { 10, 0x00C0 }, /* R10 - Left DAC volume */ |
125 | { 11, 0x00C0 }, /* R11 - Right DAC volume */ | 126 | { 11, 0x00C0 }, /* R11 - Right DAC volume */ |
@@ -128,7 +129,7 @@ static struct reg_default wm8962_reg[] = { | |||
128 | { 15, 0x6243 }, /* R15 - Software Reset */ | 129 | { 15, 0x6243 }, /* R15 - Software Reset */ |
129 | 130 | ||
130 | { 17, 0x007B }, /* R17 - ALC1 */ | 131 | { 17, 0x007B }, /* R17 - ALC1 */ |
131 | { 18, 0x0000 }, /* R18 - ALC2 */ | 132 | |
132 | { 19, 0x1C32 }, /* R19 - ALC3 */ | 133 | { 19, 0x1C32 }, /* R19 - ALC3 */ |
133 | { 20, 0x3200 }, /* R20 - Noise Gate */ | 134 | { 20, 0x3200 }, /* R20 - Noise Gate */ |
134 | { 21, 0x00C0 }, /* R21 - Left ADC volume */ | 135 | { 21, 0x00C0 }, /* R21 - Left ADC volume */ |
@@ -152,10 +153,6 @@ static struct reg_default wm8962_reg[] = { | |||
152 | { 40, 0x0000 }, /* R40 - SPKOUTL volume */ | 153 | { 40, 0x0000 }, /* R40 - SPKOUTL volume */ |
153 | { 41, 0x0000 }, /* R41 - SPKOUTR volume */ | 154 | { 41, 0x0000 }, /* R41 - SPKOUTR volume */ |
154 | 155 | ||
155 | { 47, 0x0000 }, /* R47 - Thermal Shutdown Status */ | ||
156 | { 48, 0x8027 }, /* R48 - Additional Control (4) */ | ||
157 | { 49, 0x0010 }, /* R49 - Class D Control 1 */ | ||
158 | |||
159 | { 51, 0x0003 }, /* R51 - Class D Control 2 */ | 156 | { 51, 0x0003 }, /* R51 - Class D Control 2 */ |
160 | 157 | ||
161 | { 56, 0x0506 }, /* R56 - Clocking 4 */ | 158 | { 56, 0x0506 }, /* R56 - Clocking 4 */ |
@@ -167,8 +164,6 @@ static struct reg_default wm8962_reg[] = { | |||
167 | 164 | ||
168 | { 64, 0x0810 }, /* R64 - DC Servo 4 */ | 165 | { 64, 0x0810 }, /* R64 - DC Servo 4 */ |
169 | 166 | ||
170 | { 66, 0x0000 }, /* R66 - DC Servo 6 */ | ||
171 | |||
172 | { 68, 0x001B }, /* R68 - Analogue PGA Bias */ | 167 | { 68, 0x001B }, /* R68 - Analogue PGA Bias */ |
173 | { 69, 0x0000 }, /* R69 - Analogue HP 0 */ | 168 | { 69, 0x0000 }, /* R69 - Analogue HP 0 */ |
174 | 169 | ||
@@ -207,8 +202,6 @@ static struct reg_default wm8962_reg[] = { | |||
207 | { 126, 0x000D }, /* R126 - Analogue Clocking3 */ | 202 | { 126, 0x000D }, /* R126 - Analogue Clocking3 */ |
208 | { 127, 0x0000 }, /* R127 - PLL Software Reset */ | 203 | { 127, 0x0000 }, /* R127 - PLL Software Reset */ |
209 | 204 | ||
210 | { 129, 0x0000 }, /* R129 - PLL2 */ | ||
211 | |||
212 | { 131, 0x0000 }, /* R131 - PLL 4 */ | 205 | { 131, 0x0000 }, /* R131 - PLL 4 */ |
213 | 206 | ||
214 | { 136, 0x0067 }, /* R136 - PLL 9 */ | 207 | { 136, 0x0067 }, /* R136 - PLL 9 */ |
@@ -303,9 +296,6 @@ static struct reg_default wm8962_reg[] = { | |||
303 | { 516, 0x8100 }, /* R516 - GPIO 5 */ | 296 | { 516, 0x8100 }, /* R516 - GPIO 5 */ |
304 | { 517, 0x8100 }, /* R517 - GPIO 6 */ | 297 | { 517, 0x8100 }, /* R517 - GPIO 6 */ |
305 | 298 | ||
306 | { 560, 0x0000 }, /* R560 - Interrupt Status 1 */ | ||
307 | { 561, 0x0000 }, /* R561 - Interrupt Status 2 */ | ||
308 | |||
309 | { 568, 0x0030 }, /* R568 - Interrupt Status 1 Mask */ | 299 | { 568, 0x0030 }, /* R568 - Interrupt Status 1 Mask */ |
310 | { 569, 0xFFED }, /* R569 - Interrupt Status 2 Mask */ | 300 | { 569, 0xFFED }, /* R569 - Interrupt Status 2 Mask */ |
311 | 301 | ||
@@ -317,8 +307,6 @@ static struct reg_default wm8962_reg[] = { | |||
317 | 307 | ||
318 | { 768, 0x1C00 }, /* R768 - DSP2 Power Management */ | 308 | { 768, 0x1C00 }, /* R768 - DSP2 Power Management */ |
319 | 309 | ||
320 | { 1037, 0x0000 }, /* R1037 - DSP2_ExecControl */ | ||
321 | |||
322 | { 8192, 0x0000 }, /* R8192 - DSP2 Instruction RAM 0 */ | 310 | { 8192, 0x0000 }, /* R8192 - DSP2 Instruction RAM 0 */ |
323 | 311 | ||
324 | { 9216, 0x0030 }, /* R9216 - DSP2 Address RAM 2 */ | 312 | { 9216, 0x0030 }, /* R9216 - DSP2 Address RAM 2 */ |
@@ -797,1167 +785,660 @@ static struct reg_default wm8962_reg[] = { | |||
797 | { 21139, 0x8580 }, /* R21139 - VSS_XTS32_0 */ | 785 | { 21139, 0x8580 }, /* R21139 - VSS_XTS32_0 */ |
798 | }; | 786 | }; |
799 | 787 | ||
800 | static const struct wm8962_reg_access { | ||
801 | u16 read; | ||
802 | u16 write; | ||
803 | u16 vol; | ||
804 | } wm8962_reg_access[WM8962_MAX_REGISTER + 1] = { | ||
805 | [0] = { 0x00FF, 0x01FF, 0x0000 }, /* R0 - Left Input volume */ | ||
806 | [1] = { 0xFEFF, 0x01FF, 0x0000 }, /* R1 - Right Input volume */ | ||
807 | [2] = { 0x00FF, 0x01FF, 0x0000 }, /* R2 - HPOUTL volume */ | ||
808 | [3] = { 0x00FF, 0x01FF, 0x0000 }, /* R3 - HPOUTR volume */ | ||
809 | [4] = { 0x07FE, 0x07FE, 0xFFFF }, /* R4 - Clocking1 */ | ||
810 | [5] = { 0x007F, 0x007F, 0x0000 }, /* R5 - ADC & DAC Control 1 */ | ||
811 | [6] = { 0x37ED, 0x37ED, 0x0000 }, /* R6 - ADC & DAC Control 2 */ | ||
812 | [7] = { 0x1FFF, 0x1FFF, 0x0000 }, /* R7 - Audio Interface 0 */ | ||
813 | [8] = { 0x0FEF, 0x0FEF, 0xFFFF }, /* R8 - Clocking2 */ | ||
814 | [9] = { 0x0B9F, 0x039F, 0x0000 }, /* R9 - Audio Interface 1 */ | ||
815 | [10] = { 0x00FF, 0x01FF, 0x0000 }, /* R10 - Left DAC volume */ | ||
816 | [11] = { 0x00FF, 0x01FF, 0x0000 }, /* R11 - Right DAC volume */ | ||
817 | [14] = { 0x07FF, 0x07FF, 0x0000 }, /* R14 - Audio Interface 2 */ | ||
818 | [15] = { 0xFFFF, 0xFFFF, 0xFFFF }, /* R15 - Software Reset */ | ||
819 | [17] = { 0x07FF, 0x07FF, 0x0000 }, /* R17 - ALC1 */ | ||
820 | [18] = { 0xF8FF, 0x00FF, 0xFFFF }, /* R18 - ALC2 */ | ||
821 | [19] = { 0x1DFF, 0x1DFF, 0x0000 }, /* R19 - ALC3 */ | ||
822 | [20] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20 - Noise Gate */ | ||
823 | [21] = { 0x00FF, 0x01FF, 0x0000 }, /* R21 - Left ADC volume */ | ||
824 | [22] = { 0x00FF, 0x01FF, 0x0000 }, /* R22 - Right ADC volume */ | ||
825 | [23] = { 0x0161, 0x0161, 0x0000 }, /* R23 - Additional control(1) */ | ||
826 | [24] = { 0x0008, 0x0008, 0x0000 }, /* R24 - Additional control(2) */ | ||
827 | [25] = { 0x07FE, 0x07FE, 0x0000 }, /* R25 - Pwr Mgmt (1) */ | ||
828 | [26] = { 0x01FB, 0x01FB, 0x0000 }, /* R26 - Pwr Mgmt (2) */ | ||
829 | [27] = { 0x0017, 0x0017, 0x0000 }, /* R27 - Additional Control (3) */ | ||
830 | [28] = { 0x001C, 0x001C, 0x0000 }, /* R28 - Anti-pop */ | ||
831 | |||
832 | [30] = { 0xFFFE, 0xFFFE, 0x0000 }, /* R30 - Clocking 3 */ | ||
833 | [31] = { 0x000F, 0x000F, 0x0000 }, /* R31 - Input mixer control (1) */ | ||
834 | [32] = { 0x01FF, 0x01FF, 0x0000 }, /* R32 - Left input mixer volume */ | ||
835 | [33] = { 0x01FF, 0x01FF, 0x0000 }, /* R33 - Right input mixer volume */ | ||
836 | [34] = { 0x003F, 0x003F, 0x0000 }, /* R34 - Input mixer control (2) */ | ||
837 | [35] = { 0x003F, 0x003F, 0x0000 }, /* R35 - Input bias control */ | ||
838 | [37] = { 0x001F, 0x001F, 0x0000 }, /* R37 - Left input PGA control */ | ||
839 | [38] = { 0x001F, 0x001F, 0x0000 }, /* R38 - Right input PGA control */ | ||
840 | [40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40 - SPKOUTL volume */ | ||
841 | [41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41 - SPKOUTR volume */ | ||
842 | |||
843 | [47] = { 0x000F, 0x0000, 0xFFFF }, /* R47 - Thermal Shutdown Status */ | ||
844 | [48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48 - Additional Control (4) */ | ||
845 | [49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49 - Class D Control 1 */ | ||
846 | [51] = { 0x0047, 0x0047, 0x0000 }, /* R51 - Class D Control 2 */ | ||
847 | [56] = { 0x001E, 0x001E, 0x0000 }, /* R56 - Clocking 4 */ | ||
848 | [57] = { 0x02FC, 0x02FC, 0x0000 }, /* R57 - DAC DSP Mixing (1) */ | ||
849 | [58] = { 0x00FC, 0x00FC, 0x0000 }, /* R58 - DAC DSP Mixing (2) */ | ||
850 | [60] = { 0x00CC, 0x00CC, 0x0000 }, /* R60 - DC Servo 0 */ | ||
851 | [61] = { 0x00DD, 0x00DD, 0x0000 }, /* R61 - DC Servo 1 */ | ||
852 | [64] = { 0x3F80, 0x3F80, 0x0000 }, /* R64 - DC Servo 4 */ | ||
853 | [66] = { 0x0780, 0x0000, 0xFFFF }, /* R66 - DC Servo 6 */ | ||
854 | [68] = { 0x0007, 0x0007, 0x0000 }, /* R68 - Analogue PGA Bias */ | ||
855 | [69] = { 0x00FF, 0x00FF, 0x0000 }, /* R69 - Analogue HP 0 */ | ||
856 | [71] = { 0x01FF, 0x01FF, 0x0000 }, /* R71 - Analogue HP 2 */ | ||
857 | [72] = { 0x0001, 0x0001, 0x0000 }, /* R72 - Charge Pump 1 */ | ||
858 | [82] = { 0x0001, 0x0001, 0x0000 }, /* R82 - Charge Pump B */ | ||
859 | [87] = { 0x00A0, 0x00A0, 0x0000 }, /* R87 - Write Sequencer Control 1 */ | ||
860 | [90] = { 0x007F, 0x01FF, 0x0000 }, /* R90 - Write Sequencer Control 2 */ | ||
861 | [93] = { 0x03F9, 0x0000, 0x0000 }, /* R93 - Write Sequencer Control 3 */ | ||
862 | [94] = { 0x0070, 0x0070, 0x0000 }, /* R94 - Control Interface */ | ||
863 | [99] = { 0x000F, 0x000F, 0x0000 }, /* R99 - Mixer Enables */ | ||
864 | [100] = { 0x00BF, 0x00BF, 0x0000 }, /* R100 - Headphone Mixer (1) */ | ||
865 | [101] = { 0x00BF, 0x00BF, 0x0000 }, /* R101 - Headphone Mixer (2) */ | ||
866 | [102] = { 0x01FF, 0x01FF, 0x0000 }, /* R102 - Headphone Mixer (3) */ | ||
867 | [103] = { 0x01FF, 0x01FF, 0x0000 }, /* R103 - Headphone Mixer (4) */ | ||
868 | [105] = { 0x00BF, 0x00BF, 0x0000 }, /* R105 - Speaker Mixer (1) */ | ||
869 | [106] = { 0x00BF, 0x00BF, 0x0000 }, /* R106 - Speaker Mixer (2) */ | ||
870 | [107] = { 0x01FF, 0x01FF, 0x0000 }, /* R107 - Speaker Mixer (3) */ | ||
871 | [108] = { 0x01FF, 0x01FF, 0x0000 }, /* R108 - Speaker Mixer (4) */ | ||
872 | [109] = { 0x00F0, 0x00F0, 0x0000 }, /* R109 - Speaker Mixer (5) */ | ||
873 | [110] = { 0x00F7, 0x00F7, 0x0000 }, /* R110 - Beep Generator (1) */ | ||
874 | [115] = { 0x001F, 0x001F, 0x0000 }, /* R115 - Oscillator Trim (3) */ | ||
875 | [116] = { 0x001F, 0x001F, 0x0000 }, /* R116 - Oscillator Trim (4) */ | ||
876 | [119] = { 0x00FF, 0x00FF, 0x0000 }, /* R119 - Oscillator Trim (7) */ | ||
877 | [124] = { 0x0079, 0x0079, 0x0000 }, /* R124 - Analogue Clocking1 */ | ||
878 | [125] = { 0x00DF, 0x00DF, 0x0000 }, /* R125 - Analogue Clocking2 */ | ||
879 | [126] = { 0x000D, 0x000D, 0x0000 }, /* R126 - Analogue Clocking3 */ | ||
880 | [127] = { 0x0000, 0xFFFF, 0x0000 }, /* R127 - PLL Software Reset */ | ||
881 | [129] = { 0x00B0, 0x00B0, 0x0000 }, /* R129 - PLL2 */ | ||
882 | [131] = { 0x0003, 0x0003, 0x0000 }, /* R131 - PLL 4 */ | ||
883 | [136] = { 0x005F, 0x005F, 0x0000 }, /* R136 - PLL 9 */ | ||
884 | [137] = { 0x00FF, 0x00FF, 0x0000 }, /* R137 - PLL 10 */ | ||
885 | [138] = { 0x00FF, 0x00FF, 0x0000 }, /* R138 - PLL 11 */ | ||
886 | [139] = { 0x00FF, 0x00FF, 0x0000 }, /* R139 - PLL 12 */ | ||
887 | [140] = { 0x005F, 0x005F, 0x0000 }, /* R140 - PLL 13 */ | ||
888 | [141] = { 0x00FF, 0x00FF, 0x0000 }, /* R141 - PLL 14 */ | ||
889 | [142] = { 0x00FF, 0x00FF, 0x0000 }, /* R142 - PLL 15 */ | ||
890 | [143] = { 0x00FF, 0x00FF, 0x0000 }, /* R143 - PLL 16 */ | ||
891 | [155] = { 0x0067, 0x0067, 0x0000 }, /* R155 - FLL Control (1) */ | ||
892 | [156] = { 0x01FB, 0x01FB, 0x0000 }, /* R156 - FLL Control (2) */ | ||
893 | [157] = { 0x0007, 0x0007, 0x0000 }, /* R157 - FLL Control (3) */ | ||
894 | [159] = { 0x007F, 0x007F, 0x0000 }, /* R159 - FLL Control (5) */ | ||
895 | [160] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R160 - FLL Control (6) */ | ||
896 | [161] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R161 - FLL Control (7) */ | ||
897 | [162] = { 0x03FF, 0x03FF, 0x0000 }, /* R162 - FLL Control (8) */ | ||
898 | [252] = { 0x0005, 0x0005, 0x0000 }, /* R252 - General test 1 */ | ||
899 | [256] = { 0x000F, 0x000F, 0x0000 }, /* R256 - DF1 */ | ||
900 | [257] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R257 - DF2 */ | ||
901 | [258] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R258 - DF3 */ | ||
902 | [259] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R259 - DF4 */ | ||
903 | [260] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R260 - DF5 */ | ||
904 | [261] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R261 - DF6 */ | ||
905 | [262] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R262 - DF7 */ | ||
906 | [264] = { 0x0003, 0x0003, 0x0000 }, /* R264 - LHPF1 */ | ||
907 | [265] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R265 - LHPF2 */ | ||
908 | [268] = { 0x0077, 0x0077, 0x0000 }, /* R268 - THREED1 */ | ||
909 | [269] = { 0xFFFC, 0xFFFC, 0x0000 }, /* R269 - THREED2 */ | ||
910 | [270] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R270 - THREED3 */ | ||
911 | [271] = { 0xFFFC, 0xFFFC, 0x0000 }, /* R271 - THREED4 */ | ||
912 | [276] = { 0x7FFF, 0x7FFF, 0x0000 }, /* R276 - DRC 1 */ | ||
913 | [277] = { 0x1FFF, 0x1FFF, 0x0000 }, /* R277 - DRC 2 */ | ||
914 | [278] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R278 - DRC 3 */ | ||
915 | [279] = { 0x07FF, 0x07FF, 0x0000 }, /* R279 - DRC 4 */ | ||
916 | [280] = { 0x03FF, 0x03FF, 0x0000 }, /* R280 - DRC 5 */ | ||
917 | [285] = { 0x0003, 0x0003, 0x0000 }, /* R285 - Tloopback */ | ||
918 | [335] = { 0x0007, 0x0007, 0x0000 }, /* R335 - EQ1 */ | ||
919 | [336] = { 0xFFFE, 0xFFFE, 0x0000 }, /* R336 - EQ2 */ | ||
920 | [337] = { 0xFFC0, 0xFFC0, 0x0000 }, /* R337 - EQ3 */ | ||
921 | [338] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R338 - EQ4 */ | ||
922 | [339] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R339 - EQ5 */ | ||
923 | [340] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R340 - EQ6 */ | ||
924 | [341] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R341 - EQ7 */ | ||
925 | [342] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R342 - EQ8 */ | ||
926 | [343] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R343 - EQ9 */ | ||
927 | [344] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R344 - EQ10 */ | ||
928 | [345] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R345 - EQ11 */ | ||
929 | [346] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R346 - EQ12 */ | ||
930 | [347] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R347 - EQ13 */ | ||
931 | [348] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R348 - EQ14 */ | ||
932 | [349] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R349 - EQ15 */ | ||
933 | [350] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R350 - EQ16 */ | ||
934 | [351] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R351 - EQ17 */ | ||
935 | [352] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R352 - EQ18 */ | ||
936 | [353] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R353 - EQ19 */ | ||
937 | [354] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R354 - EQ20 */ | ||
938 | [355] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R355 - EQ21 */ | ||
939 | [356] = { 0xFFFE, 0xFFFE, 0x0000 }, /* R356 - EQ22 */ | ||
940 | [357] = { 0xFFC0, 0xFFC0, 0x0000 }, /* R357 - EQ23 */ | ||
941 | [358] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R358 - EQ24 */ | ||
942 | [359] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R359 - EQ25 */ | ||
943 | [360] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R360 - EQ26 */ | ||
944 | [361] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R361 - EQ27 */ | ||
945 | [362] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R362 - EQ28 */ | ||
946 | [363] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R363 - EQ29 */ | ||
947 | [364] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R364 - EQ30 */ | ||
948 | [365] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R365 - EQ31 */ | ||
949 | [366] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R366 - EQ32 */ | ||
950 | [367] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R367 - EQ33 */ | ||
951 | [368] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R368 - EQ34 */ | ||
952 | [369] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R369 - EQ35 */ | ||
953 | [370] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R370 - EQ36 */ | ||
954 | [371] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R371 - EQ37 */ | ||
955 | [372] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R372 - EQ38 */ | ||
956 | [373] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R373 - EQ39 */ | ||
957 | [374] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R374 - EQ40 */ | ||
958 | [375] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R375 - EQ41 */ | ||
959 | [513] = { 0x045F, 0x045F, 0x0000 }, /* R513 - GPIO 2 */ | ||
960 | [514] = { 0x045F, 0x045F, 0x0000 }, /* R514 - GPIO 3 */ | ||
961 | [516] = { 0xE75F, 0xE75F, 0x0000 }, /* R516 - GPIO 5 */ | ||
962 | [517] = { 0xE75F, 0xE75F, 0x0000 }, /* R517 - GPIO 6 */ | ||
963 | [560] = { 0x0030, 0x0030, 0xFFFF }, /* R560 - Interrupt Status 1 */ | ||
964 | [561] = { 0xFFED, 0xFFED, 0xFFFF }, /* R561 - Interrupt Status 2 */ | ||
965 | [568] = { 0x0030, 0x0030, 0x0000 }, /* R568 - Interrupt Status 1 Mask */ | ||
966 | [569] = { 0xFFED, 0xFFED, 0x0000 }, /* R569 - Interrupt Status 2 Mask */ | ||
967 | [576] = { 0x0001, 0x0001, 0x0000 }, /* R576 - Interrupt Control */ | ||
968 | [584] = { 0x002D, 0x002D, 0x0000 }, /* R584 - IRQ Debounce */ | ||
969 | [586] = { 0xC000, 0xC000, 0x0000 }, /* R586 - MICINT Source Pol */ | ||
970 | [768] = { 0x0001, 0x0001, 0x0000 }, /* R768 - DSP2 Power Management */ | ||
971 | [1037] = { 0x0000, 0x003F, 0xFFFF }, /* R1037 - DSP2_ExecControl */ | ||
972 | [4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096 - Write Sequencer 0 */ | ||
973 | [4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097 - Write Sequencer 1 */ | ||
974 | [4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098 - Write Sequencer 2 */ | ||
975 | [4099] = { 0x010F, 0x010F, 0x0000 }, /* R4099 - Write Sequencer 3 */ | ||
976 | [4100] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4100 - Write Sequencer 4 */ | ||
977 | [4101] = { 0x00FF, 0x00FF, 0x0000 }, /* R4101 - Write Sequencer 5 */ | ||
978 | [4102] = { 0x070F, 0x070F, 0x0000 }, /* R4102 - Write Sequencer 6 */ | ||
979 | [4103] = { 0x010F, 0x010F, 0x0000 }, /* R4103 - Write Sequencer 7 */ | ||
980 | [4104] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4104 - Write Sequencer 8 */ | ||
981 | [4105] = { 0x00FF, 0x00FF, 0x0000 }, /* R4105 - Write Sequencer 9 */ | ||
982 | [4106] = { 0x070F, 0x070F, 0x0000 }, /* R4106 - Write Sequencer 10 */ | ||
983 | [4107] = { 0x010F, 0x010F, 0x0000 }, /* R4107 - Write Sequencer 11 */ | ||
984 | [4108] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4108 - Write Sequencer 12 */ | ||
985 | [4109] = { 0x00FF, 0x00FF, 0x0000 }, /* R4109 - Write Sequencer 13 */ | ||
986 | [4110] = { 0x070F, 0x070F, 0x0000 }, /* R4110 - Write Sequencer 14 */ | ||
987 | [4111] = { 0x010F, 0x010F, 0x0000 }, /* R4111 - Write Sequencer 15 */ | ||
988 | [4112] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4112 - Write Sequencer 16 */ | ||
989 | [4113] = { 0x00FF, 0x00FF, 0x0000 }, /* R4113 - Write Sequencer 17 */ | ||
990 | [4114] = { 0x070F, 0x070F, 0x0000 }, /* R4114 - Write Sequencer 18 */ | ||
991 | [4115] = { 0x010F, 0x010F, 0x0000 }, /* R4115 - Write Sequencer 19 */ | ||
992 | [4116] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4116 - Write Sequencer 20 */ | ||
993 | [4117] = { 0x00FF, 0x00FF, 0x0000 }, /* R4117 - Write Sequencer 21 */ | ||
994 | [4118] = { 0x070F, 0x070F, 0x0000 }, /* R4118 - Write Sequencer 22 */ | ||
995 | [4119] = { 0x010F, 0x010F, 0x0000 }, /* R4119 - Write Sequencer 23 */ | ||
996 | [4120] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4120 - Write Sequencer 24 */ | ||
997 | [4121] = { 0x00FF, 0x00FF, 0x0000 }, /* R4121 - Write Sequencer 25 */ | ||
998 | [4122] = { 0x070F, 0x070F, 0x0000 }, /* R4122 - Write Sequencer 26 */ | ||
999 | [4123] = { 0x010F, 0x010F, 0x0000 }, /* R4123 - Write Sequencer 27 */ | ||
1000 | [4124] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4124 - Write Sequencer 28 */ | ||
1001 | [4125] = { 0x00FF, 0x00FF, 0x0000 }, /* R4125 - Write Sequencer 29 */ | ||
1002 | [4126] = { 0x070F, 0x070F, 0x0000 }, /* R4126 - Write Sequencer 30 */ | ||
1003 | [4127] = { 0x010F, 0x010F, 0x0000 }, /* R4127 - Write Sequencer 31 */ | ||
1004 | [4128] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4128 - Write Sequencer 32 */ | ||
1005 | [4129] = { 0x00FF, 0x00FF, 0x0000 }, /* R4129 - Write Sequencer 33 */ | ||
1006 | [4130] = { 0x070F, 0x070F, 0x0000 }, /* R4130 - Write Sequencer 34 */ | ||
1007 | [4131] = { 0x010F, 0x010F, 0x0000 }, /* R4131 - Write Sequencer 35 */ | ||
1008 | [4132] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4132 - Write Sequencer 36 */ | ||
1009 | [4133] = { 0x00FF, 0x00FF, 0x0000 }, /* R4133 - Write Sequencer 37 */ | ||
1010 | [4134] = { 0x070F, 0x070F, 0x0000 }, /* R4134 - Write Sequencer 38 */ | ||
1011 | [4135] = { 0x010F, 0x010F, 0x0000 }, /* R4135 - Write Sequencer 39 */ | ||
1012 | [4136] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4136 - Write Sequencer 40 */ | ||
1013 | [4137] = { 0x00FF, 0x00FF, 0x0000 }, /* R4137 - Write Sequencer 41 */ | ||
1014 | [4138] = { 0x070F, 0x070F, 0x0000 }, /* R4138 - Write Sequencer 42 */ | ||
1015 | [4139] = { 0x010F, 0x010F, 0x0000 }, /* R4139 - Write Sequencer 43 */ | ||
1016 | [4140] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4140 - Write Sequencer 44 */ | ||
1017 | [4141] = { 0x00FF, 0x00FF, 0x0000 }, /* R4141 - Write Sequencer 45 */ | ||
1018 | [4142] = { 0x070F, 0x070F, 0x0000 }, /* R4142 - Write Sequencer 46 */ | ||
1019 | [4143] = { 0x010F, 0x010F, 0x0000 }, /* R4143 - Write Sequencer 47 */ | ||
1020 | [4144] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4144 - Write Sequencer 48 */ | ||
1021 | [4145] = { 0x00FF, 0x00FF, 0x0000 }, /* R4145 - Write Sequencer 49 */ | ||
1022 | [4146] = { 0x070F, 0x070F, 0x0000 }, /* R4146 - Write Sequencer 50 */ | ||
1023 | [4147] = { 0x010F, 0x010F, 0x0000 }, /* R4147 - Write Sequencer 51 */ | ||
1024 | [4148] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4148 - Write Sequencer 52 */ | ||
1025 | [4149] = { 0x00FF, 0x00FF, 0x0000 }, /* R4149 - Write Sequencer 53 */ | ||
1026 | [4150] = { 0x070F, 0x070F, 0x0000 }, /* R4150 - Write Sequencer 54 */ | ||
1027 | [4151] = { 0x010F, 0x010F, 0x0000 }, /* R4151 - Write Sequencer 55 */ | ||
1028 | [4152] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4152 - Write Sequencer 56 */ | ||
1029 | [4153] = { 0x00FF, 0x00FF, 0x0000 }, /* R4153 - Write Sequencer 57 */ | ||
1030 | [4154] = { 0x070F, 0x070F, 0x0000 }, /* R4154 - Write Sequencer 58 */ | ||
1031 | [4155] = { 0x010F, 0x010F, 0x0000 }, /* R4155 - Write Sequencer 59 */ | ||
1032 | [4156] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4156 - Write Sequencer 60 */ | ||
1033 | [4157] = { 0x00FF, 0x00FF, 0x0000 }, /* R4157 - Write Sequencer 61 */ | ||
1034 | [4158] = { 0x070F, 0x070F, 0x0000 }, /* R4158 - Write Sequencer 62 */ | ||
1035 | [4159] = { 0x010F, 0x010F, 0x0000 }, /* R4159 - Write Sequencer 63 */ | ||
1036 | [4160] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4160 - Write Sequencer 64 */ | ||
1037 | [4161] = { 0x00FF, 0x00FF, 0x0000 }, /* R4161 - Write Sequencer 65 */ | ||
1038 | [4162] = { 0x070F, 0x070F, 0x0000 }, /* R4162 - Write Sequencer 66 */ | ||
1039 | [4163] = { 0x010F, 0x010F, 0x0000 }, /* R4163 - Write Sequencer 67 */ | ||
1040 | [4164] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4164 - Write Sequencer 68 */ | ||
1041 | [4165] = { 0x00FF, 0x00FF, 0x0000 }, /* R4165 - Write Sequencer 69 */ | ||
1042 | [4166] = { 0x070F, 0x070F, 0x0000 }, /* R4166 - Write Sequencer 70 */ | ||
1043 | [4167] = { 0x010F, 0x010F, 0x0000 }, /* R4167 - Write Sequencer 71 */ | ||
1044 | [4168] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4168 - Write Sequencer 72 */ | ||
1045 | [4169] = { 0x00FF, 0x00FF, 0x0000 }, /* R4169 - Write Sequencer 73 */ | ||
1046 | [4170] = { 0x070F, 0x070F, 0x0000 }, /* R4170 - Write Sequencer 74 */ | ||
1047 | [4171] = { 0x010F, 0x010F, 0x0000 }, /* R4171 - Write Sequencer 75 */ | ||
1048 | [4172] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4172 - Write Sequencer 76 */ | ||
1049 | [4173] = { 0x00FF, 0x00FF, 0x0000 }, /* R4173 - Write Sequencer 77 */ | ||
1050 | [4174] = { 0x070F, 0x070F, 0x0000 }, /* R4174 - Write Sequencer 78 */ | ||
1051 | [4175] = { 0x010F, 0x010F, 0x0000 }, /* R4175 - Write Sequencer 79 */ | ||
1052 | [4176] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4176 - Write Sequencer 80 */ | ||
1053 | [4177] = { 0x00FF, 0x00FF, 0x0000 }, /* R4177 - Write Sequencer 81 */ | ||
1054 | [4178] = { 0x070F, 0x070F, 0x0000 }, /* R4178 - Write Sequencer 82 */ | ||
1055 | [4179] = { 0x010F, 0x010F, 0x0000 }, /* R4179 - Write Sequencer 83 */ | ||
1056 | [4180] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4180 - Write Sequencer 84 */ | ||
1057 | [4181] = { 0x00FF, 0x00FF, 0x0000 }, /* R4181 - Write Sequencer 85 */ | ||
1058 | [4182] = { 0x070F, 0x070F, 0x0000 }, /* R4182 - Write Sequencer 86 */ | ||
1059 | [4183] = { 0x010F, 0x010F, 0x0000 }, /* R4183 - Write Sequencer 87 */ | ||
1060 | [4184] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4184 - Write Sequencer 88 */ | ||
1061 | [4185] = { 0x00FF, 0x00FF, 0x0000 }, /* R4185 - Write Sequencer 89 */ | ||
1062 | [4186] = { 0x070F, 0x070F, 0x0000 }, /* R4186 - Write Sequencer 90 */ | ||
1063 | [4187] = { 0x010F, 0x010F, 0x0000 }, /* R4187 - Write Sequencer 91 */ | ||
1064 | [4188] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4188 - Write Sequencer 92 */ | ||
1065 | [4189] = { 0x00FF, 0x00FF, 0x0000 }, /* R4189 - Write Sequencer 93 */ | ||
1066 | [4190] = { 0x070F, 0x070F, 0x0000 }, /* R4190 - Write Sequencer 94 */ | ||
1067 | [4191] = { 0x010F, 0x010F, 0x0000 }, /* R4191 - Write Sequencer 95 */ | ||
1068 | [4192] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4192 - Write Sequencer 96 */ | ||
1069 | [4193] = { 0x00FF, 0x00FF, 0x0000 }, /* R4193 - Write Sequencer 97 */ | ||
1070 | [4194] = { 0x070F, 0x070F, 0x0000 }, /* R4194 - Write Sequencer 98 */ | ||
1071 | [4195] = { 0x010F, 0x010F, 0x0000 }, /* R4195 - Write Sequencer 99 */ | ||
1072 | [4196] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4196 - Write Sequencer 100 */ | ||
1073 | [4197] = { 0x00FF, 0x00FF, 0x0000 }, /* R4197 - Write Sequencer 101 */ | ||
1074 | [4198] = { 0x070F, 0x070F, 0x0000 }, /* R4198 - Write Sequencer 102 */ | ||
1075 | [4199] = { 0x010F, 0x010F, 0x0000 }, /* R4199 - Write Sequencer 103 */ | ||
1076 | [4200] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4200 - Write Sequencer 104 */ | ||
1077 | [4201] = { 0x00FF, 0x00FF, 0x0000 }, /* R4201 - Write Sequencer 105 */ | ||
1078 | [4202] = { 0x070F, 0x070F, 0x0000 }, /* R4202 - Write Sequencer 106 */ | ||
1079 | [4203] = { 0x010F, 0x010F, 0x0000 }, /* R4203 - Write Sequencer 107 */ | ||
1080 | [4204] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4204 - Write Sequencer 108 */ | ||
1081 | [4205] = { 0x00FF, 0x00FF, 0x0000 }, /* R4205 - Write Sequencer 109 */ | ||
1082 | [4206] = { 0x070F, 0x070F, 0x0000 }, /* R4206 - Write Sequencer 110 */ | ||
1083 | [4207] = { 0x010F, 0x010F, 0x0000 }, /* R4207 - Write Sequencer 111 */ | ||
1084 | [4208] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4208 - Write Sequencer 112 */ | ||
1085 | [4209] = { 0x00FF, 0x00FF, 0x0000 }, /* R4209 - Write Sequencer 113 */ | ||
1086 | [4210] = { 0x070F, 0x070F, 0x0000 }, /* R4210 - Write Sequencer 114 */ | ||
1087 | [4211] = { 0x010F, 0x010F, 0x0000 }, /* R4211 - Write Sequencer 115 */ | ||
1088 | [4212] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4212 - Write Sequencer 116 */ | ||
1089 | [4213] = { 0x00FF, 0x00FF, 0x0000 }, /* R4213 - Write Sequencer 117 */ | ||
1090 | [4214] = { 0x070F, 0x070F, 0x0000 }, /* R4214 - Write Sequencer 118 */ | ||
1091 | [4215] = { 0x010F, 0x010F, 0x0000 }, /* R4215 - Write Sequencer 119 */ | ||
1092 | [4216] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4216 - Write Sequencer 120 */ | ||
1093 | [4217] = { 0x00FF, 0x00FF, 0x0000 }, /* R4217 - Write Sequencer 121 */ | ||
1094 | [4218] = { 0x070F, 0x070F, 0x0000 }, /* R4218 - Write Sequencer 122 */ | ||
1095 | [4219] = { 0x010F, 0x010F, 0x0000 }, /* R4219 - Write Sequencer 123 */ | ||
1096 | [4220] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4220 - Write Sequencer 124 */ | ||
1097 | [4221] = { 0x00FF, 0x00FF, 0x0000 }, /* R4221 - Write Sequencer 125 */ | ||
1098 | [4222] = { 0x070F, 0x070F, 0x0000 }, /* R4222 - Write Sequencer 126 */ | ||
1099 | [4223] = { 0x010F, 0x010F, 0x0000 }, /* R4223 - Write Sequencer 127 */ | ||
1100 | [4224] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4224 - Write Sequencer 128 */ | ||
1101 | [4225] = { 0x00FF, 0x00FF, 0x0000 }, /* R4225 - Write Sequencer 129 */ | ||
1102 | [4226] = { 0x070F, 0x070F, 0x0000 }, /* R4226 - Write Sequencer 130 */ | ||
1103 | [4227] = { 0x010F, 0x010F, 0x0000 }, /* R4227 - Write Sequencer 131 */ | ||
1104 | [4228] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4228 - Write Sequencer 132 */ | ||
1105 | [4229] = { 0x00FF, 0x00FF, 0x0000 }, /* R4229 - Write Sequencer 133 */ | ||
1106 | [4230] = { 0x070F, 0x070F, 0x0000 }, /* R4230 - Write Sequencer 134 */ | ||
1107 | [4231] = { 0x010F, 0x010F, 0x0000 }, /* R4231 - Write Sequencer 135 */ | ||
1108 | [4232] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4232 - Write Sequencer 136 */ | ||
1109 | [4233] = { 0x00FF, 0x00FF, 0x0000 }, /* R4233 - Write Sequencer 137 */ | ||
1110 | [4234] = { 0x070F, 0x070F, 0x0000 }, /* R4234 - Write Sequencer 138 */ | ||
1111 | [4235] = { 0x010F, 0x010F, 0x0000 }, /* R4235 - Write Sequencer 139 */ | ||
1112 | [4236] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4236 - Write Sequencer 140 */ | ||
1113 | [4237] = { 0x00FF, 0x00FF, 0x0000 }, /* R4237 - Write Sequencer 141 */ | ||
1114 | [4238] = { 0x070F, 0x070F, 0x0000 }, /* R4238 - Write Sequencer 142 */ | ||
1115 | [4239] = { 0x010F, 0x010F, 0x0000 }, /* R4239 - Write Sequencer 143 */ | ||
1116 | [4240] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4240 - Write Sequencer 144 */ | ||
1117 | [4241] = { 0x00FF, 0x00FF, 0x0000 }, /* R4241 - Write Sequencer 145 */ | ||
1118 | [4242] = { 0x070F, 0x070F, 0x0000 }, /* R4242 - Write Sequencer 146 */ | ||
1119 | [4243] = { 0x010F, 0x010F, 0x0000 }, /* R4243 - Write Sequencer 147 */ | ||
1120 | [4244] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4244 - Write Sequencer 148 */ | ||
1121 | [4245] = { 0x00FF, 0x00FF, 0x0000 }, /* R4245 - Write Sequencer 149 */ | ||
1122 | [4246] = { 0x070F, 0x070F, 0x0000 }, /* R4246 - Write Sequencer 150 */ | ||
1123 | [4247] = { 0x010F, 0x010F, 0x0000 }, /* R4247 - Write Sequencer 151 */ | ||
1124 | [4248] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4248 - Write Sequencer 152 */ | ||
1125 | [4249] = { 0x00FF, 0x00FF, 0x0000 }, /* R4249 - Write Sequencer 153 */ | ||
1126 | [4250] = { 0x070F, 0x070F, 0x0000 }, /* R4250 - Write Sequencer 154 */ | ||
1127 | [4251] = { 0x010F, 0x010F, 0x0000 }, /* R4251 - Write Sequencer 155 */ | ||
1128 | [4252] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4252 - Write Sequencer 156 */ | ||
1129 | [4253] = { 0x00FF, 0x00FF, 0x0000 }, /* R4253 - Write Sequencer 157 */ | ||
1130 | [4254] = { 0x070F, 0x070F, 0x0000 }, /* R4254 - Write Sequencer 158 */ | ||
1131 | [4255] = { 0x010F, 0x010F, 0x0000 }, /* R4255 - Write Sequencer 159 */ | ||
1132 | [4256] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4256 - Write Sequencer 160 */ | ||
1133 | [4257] = { 0x00FF, 0x00FF, 0x0000 }, /* R4257 - Write Sequencer 161 */ | ||
1134 | [4258] = { 0x070F, 0x070F, 0x0000 }, /* R4258 - Write Sequencer 162 */ | ||
1135 | [4259] = { 0x010F, 0x010F, 0x0000 }, /* R4259 - Write Sequencer 163 */ | ||
1136 | [4260] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4260 - Write Sequencer 164 */ | ||
1137 | [4261] = { 0x00FF, 0x00FF, 0x0000 }, /* R4261 - Write Sequencer 165 */ | ||
1138 | [4262] = { 0x070F, 0x070F, 0x0000 }, /* R4262 - Write Sequencer 166 */ | ||
1139 | [4263] = { 0x010F, 0x010F, 0x0000 }, /* R4263 - Write Sequencer 167 */ | ||
1140 | [4264] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4264 - Write Sequencer 168 */ | ||
1141 | [4265] = { 0x00FF, 0x00FF, 0x0000 }, /* R4265 - Write Sequencer 169 */ | ||
1142 | [4266] = { 0x070F, 0x070F, 0x0000 }, /* R4266 - Write Sequencer 170 */ | ||
1143 | [4267] = { 0x010F, 0x010F, 0x0000 }, /* R4267 - Write Sequencer 171 */ | ||
1144 | [4268] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4268 - Write Sequencer 172 */ | ||
1145 | [4269] = { 0x00FF, 0x00FF, 0x0000 }, /* R4269 - Write Sequencer 173 */ | ||
1146 | [4270] = { 0x070F, 0x070F, 0x0000 }, /* R4270 - Write Sequencer 174 */ | ||
1147 | [4271] = { 0x010F, 0x010F, 0x0000 }, /* R4271 - Write Sequencer 175 */ | ||
1148 | [4272] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4272 - Write Sequencer 176 */ | ||
1149 | [4273] = { 0x00FF, 0x00FF, 0x0000 }, /* R4273 - Write Sequencer 177 */ | ||
1150 | [4274] = { 0x070F, 0x070F, 0x0000 }, /* R4274 - Write Sequencer 178 */ | ||
1151 | [4275] = { 0x010F, 0x010F, 0x0000 }, /* R4275 - Write Sequencer 179 */ | ||
1152 | [4276] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4276 - Write Sequencer 180 */ | ||
1153 | [4277] = { 0x00FF, 0x00FF, 0x0000 }, /* R4277 - Write Sequencer 181 */ | ||
1154 | [4278] = { 0x070F, 0x070F, 0x0000 }, /* R4278 - Write Sequencer 182 */ | ||
1155 | [4279] = { 0x010F, 0x010F, 0x0000 }, /* R4279 - Write Sequencer 183 */ | ||
1156 | [4280] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4280 - Write Sequencer 184 */ | ||
1157 | [4281] = { 0x00FF, 0x00FF, 0x0000 }, /* R4281 - Write Sequencer 185 */ | ||
1158 | [4282] = { 0x070F, 0x070F, 0x0000 }, /* R4282 - Write Sequencer 186 */ | ||
1159 | [4283] = { 0x010F, 0x010F, 0x0000 }, /* R4283 - Write Sequencer 187 */ | ||
1160 | [4284] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4284 - Write Sequencer 188 */ | ||
1161 | [4285] = { 0x00FF, 0x00FF, 0x0000 }, /* R4285 - Write Sequencer 189 */ | ||
1162 | [4286] = { 0x070F, 0x070F, 0x0000 }, /* R4286 - Write Sequencer 190 */ | ||
1163 | [4287] = { 0x010F, 0x010F, 0x0000 }, /* R4287 - Write Sequencer 191 */ | ||
1164 | [4288] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4288 - Write Sequencer 192 */ | ||
1165 | [4289] = { 0x00FF, 0x00FF, 0x0000 }, /* R4289 - Write Sequencer 193 */ | ||
1166 | [4290] = { 0x070F, 0x070F, 0x0000 }, /* R4290 - Write Sequencer 194 */ | ||
1167 | [4291] = { 0x010F, 0x010F, 0x0000 }, /* R4291 - Write Sequencer 195 */ | ||
1168 | [4292] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4292 - Write Sequencer 196 */ | ||
1169 | [4293] = { 0x00FF, 0x00FF, 0x0000 }, /* R4293 - Write Sequencer 197 */ | ||
1170 | [4294] = { 0x070F, 0x070F, 0x0000 }, /* R4294 - Write Sequencer 198 */ | ||
1171 | [4295] = { 0x010F, 0x010F, 0x0000 }, /* R4295 - Write Sequencer 199 */ | ||
1172 | [4296] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4296 - Write Sequencer 200 */ | ||
1173 | [4297] = { 0x00FF, 0x00FF, 0x0000 }, /* R4297 - Write Sequencer 201 */ | ||
1174 | [4298] = { 0x070F, 0x070F, 0x0000 }, /* R4298 - Write Sequencer 202 */ | ||
1175 | [4299] = { 0x010F, 0x010F, 0x0000 }, /* R4299 - Write Sequencer 203 */ | ||
1176 | [4300] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4300 - Write Sequencer 204 */ | ||
1177 | [4301] = { 0x00FF, 0x00FF, 0x0000 }, /* R4301 - Write Sequencer 205 */ | ||
1178 | [4302] = { 0x070F, 0x070F, 0x0000 }, /* R4302 - Write Sequencer 206 */ | ||
1179 | [4303] = { 0x010F, 0x010F, 0x0000 }, /* R4303 - Write Sequencer 207 */ | ||
1180 | [4304] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4304 - Write Sequencer 208 */ | ||
1181 | [4305] = { 0x00FF, 0x00FF, 0x0000 }, /* R4305 - Write Sequencer 209 */ | ||
1182 | [4306] = { 0x070F, 0x070F, 0x0000 }, /* R4306 - Write Sequencer 210 */ | ||
1183 | [4307] = { 0x010F, 0x010F, 0x0000 }, /* R4307 - Write Sequencer 211 */ | ||
1184 | [4308] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4308 - Write Sequencer 212 */ | ||
1185 | [4309] = { 0x00FF, 0x00FF, 0x0000 }, /* R4309 - Write Sequencer 213 */ | ||
1186 | [4310] = { 0x070F, 0x070F, 0x0000 }, /* R4310 - Write Sequencer 214 */ | ||
1187 | [4311] = { 0x010F, 0x010F, 0x0000 }, /* R4311 - Write Sequencer 215 */ | ||
1188 | [4312] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4312 - Write Sequencer 216 */ | ||
1189 | [4313] = { 0x00FF, 0x00FF, 0x0000 }, /* R4313 - Write Sequencer 217 */ | ||
1190 | [4314] = { 0x070F, 0x070F, 0x0000 }, /* R4314 - Write Sequencer 218 */ | ||
1191 | [4315] = { 0x010F, 0x010F, 0x0000 }, /* R4315 - Write Sequencer 219 */ | ||
1192 | [4316] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4316 - Write Sequencer 220 */ | ||
1193 | [4317] = { 0x00FF, 0x00FF, 0x0000 }, /* R4317 - Write Sequencer 221 */ | ||
1194 | [4318] = { 0x070F, 0x070F, 0x0000 }, /* R4318 - Write Sequencer 222 */ | ||
1195 | [4319] = { 0x010F, 0x010F, 0x0000 }, /* R4319 - Write Sequencer 223 */ | ||
1196 | [4320] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4320 - Write Sequencer 224 */ | ||
1197 | [4321] = { 0x00FF, 0x00FF, 0x0000 }, /* R4321 - Write Sequencer 225 */ | ||
1198 | [4322] = { 0x070F, 0x070F, 0x0000 }, /* R4322 - Write Sequencer 226 */ | ||
1199 | [4323] = { 0x010F, 0x010F, 0x0000 }, /* R4323 - Write Sequencer 227 */ | ||
1200 | [4324] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4324 - Write Sequencer 228 */ | ||
1201 | [4325] = { 0x00FF, 0x00FF, 0x0000 }, /* R4325 - Write Sequencer 229 */ | ||
1202 | [4326] = { 0x070F, 0x070F, 0x0000 }, /* R4326 - Write Sequencer 230 */ | ||
1203 | [4327] = { 0x010F, 0x010F, 0x0000 }, /* R4327 - Write Sequencer 231 */ | ||
1204 | [4328] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4328 - Write Sequencer 232 */ | ||
1205 | [4329] = { 0x00FF, 0x00FF, 0x0000 }, /* R4329 - Write Sequencer 233 */ | ||
1206 | [4330] = { 0x070F, 0x070F, 0x0000 }, /* R4330 - Write Sequencer 234 */ | ||
1207 | [4331] = { 0x010F, 0x010F, 0x0000 }, /* R4331 - Write Sequencer 235 */ | ||
1208 | [4332] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4332 - Write Sequencer 236 */ | ||
1209 | [4333] = { 0x00FF, 0x00FF, 0x0000 }, /* R4333 - Write Sequencer 237 */ | ||
1210 | [4334] = { 0x070F, 0x070F, 0x0000 }, /* R4334 - Write Sequencer 238 */ | ||
1211 | [4335] = { 0x010F, 0x010F, 0x0000 }, /* R4335 - Write Sequencer 239 */ | ||
1212 | [4336] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4336 - Write Sequencer 240 */ | ||
1213 | [4337] = { 0x00FF, 0x00FF, 0x0000 }, /* R4337 - Write Sequencer 241 */ | ||
1214 | [4338] = { 0x070F, 0x070F, 0x0000 }, /* R4338 - Write Sequencer 242 */ | ||
1215 | [4339] = { 0x010F, 0x010F, 0x0000 }, /* R4339 - Write Sequencer 243 */ | ||
1216 | [4340] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4340 - Write Sequencer 244 */ | ||
1217 | [4341] = { 0x00FF, 0x00FF, 0x0000 }, /* R4341 - Write Sequencer 245 */ | ||
1218 | [4342] = { 0x070F, 0x070F, 0x0000 }, /* R4342 - Write Sequencer 246 */ | ||
1219 | [4343] = { 0x010F, 0x010F, 0x0000 }, /* R4343 - Write Sequencer 247 */ | ||
1220 | [4344] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4344 - Write Sequencer 248 */ | ||
1221 | [4345] = { 0x00FF, 0x00FF, 0x0000 }, /* R4345 - Write Sequencer 249 */ | ||
1222 | [4346] = { 0x070F, 0x070F, 0x0000 }, /* R4346 - Write Sequencer 250 */ | ||
1223 | [4347] = { 0x010F, 0x010F, 0x0000 }, /* R4347 - Write Sequencer 251 */ | ||
1224 | [4348] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4348 - Write Sequencer 252 */ | ||
1225 | [4349] = { 0x00FF, 0x00FF, 0x0000 }, /* R4349 - Write Sequencer 253 */ | ||
1226 | [4350] = { 0x070F, 0x070F, 0x0000 }, /* R4350 - Write Sequencer 254 */ | ||
1227 | [4351] = { 0x010F, 0x010F, 0x0000 }, /* R4351 - Write Sequencer 255 */ | ||
1228 | [4352] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4352 - Write Sequencer 256 */ | ||
1229 | [4353] = { 0x00FF, 0x00FF, 0x0000 }, /* R4353 - Write Sequencer 257 */ | ||
1230 | [4354] = { 0x070F, 0x070F, 0x0000 }, /* R4354 - Write Sequencer 258 */ | ||
1231 | [4355] = { 0x010F, 0x010F, 0x0000 }, /* R4355 - Write Sequencer 259 */ | ||
1232 | [4356] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4356 - Write Sequencer 260 */ | ||
1233 | [4357] = { 0x00FF, 0x00FF, 0x0000 }, /* R4357 - Write Sequencer 261 */ | ||
1234 | [4358] = { 0x070F, 0x070F, 0x0000 }, /* R4358 - Write Sequencer 262 */ | ||
1235 | [4359] = { 0x010F, 0x010F, 0x0000 }, /* R4359 - Write Sequencer 263 */ | ||
1236 | [4360] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4360 - Write Sequencer 264 */ | ||
1237 | [4361] = { 0x00FF, 0x00FF, 0x0000 }, /* R4361 - Write Sequencer 265 */ | ||
1238 | [4362] = { 0x070F, 0x070F, 0x0000 }, /* R4362 - Write Sequencer 266 */ | ||
1239 | [4363] = { 0x010F, 0x010F, 0x0000 }, /* R4363 - Write Sequencer 267 */ | ||
1240 | [4364] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4364 - Write Sequencer 268 */ | ||
1241 | [4365] = { 0x00FF, 0x00FF, 0x0000 }, /* R4365 - Write Sequencer 269 */ | ||
1242 | [4366] = { 0x070F, 0x070F, 0x0000 }, /* R4366 - Write Sequencer 270 */ | ||
1243 | [4367] = { 0x010F, 0x010F, 0x0000 }, /* R4367 - Write Sequencer 271 */ | ||
1244 | [4368] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4368 - Write Sequencer 272 */ | ||
1245 | [4369] = { 0x00FF, 0x00FF, 0x0000 }, /* R4369 - Write Sequencer 273 */ | ||
1246 | [4370] = { 0x070F, 0x070F, 0x0000 }, /* R4370 - Write Sequencer 274 */ | ||
1247 | [4371] = { 0x010F, 0x010F, 0x0000 }, /* R4371 - Write Sequencer 275 */ | ||
1248 | [4372] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4372 - Write Sequencer 276 */ | ||
1249 | [4373] = { 0x00FF, 0x00FF, 0x0000 }, /* R4373 - Write Sequencer 277 */ | ||
1250 | [4374] = { 0x070F, 0x070F, 0x0000 }, /* R4374 - Write Sequencer 278 */ | ||
1251 | [4375] = { 0x010F, 0x010F, 0x0000 }, /* R4375 - Write Sequencer 279 */ | ||
1252 | [4376] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4376 - Write Sequencer 280 */ | ||
1253 | [4377] = { 0x00FF, 0x00FF, 0x0000 }, /* R4377 - Write Sequencer 281 */ | ||
1254 | [4378] = { 0x070F, 0x070F, 0x0000 }, /* R4378 - Write Sequencer 282 */ | ||
1255 | [4379] = { 0x010F, 0x010F, 0x0000 }, /* R4379 - Write Sequencer 283 */ | ||
1256 | [4380] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4380 - Write Sequencer 284 */ | ||
1257 | [4381] = { 0x00FF, 0x00FF, 0x0000 }, /* R4381 - Write Sequencer 285 */ | ||
1258 | [4382] = { 0x070F, 0x070F, 0x0000 }, /* R4382 - Write Sequencer 286 */ | ||
1259 | [4383] = { 0x010F, 0x010F, 0x0000 }, /* R4383 - Write Sequencer 287 */ | ||
1260 | [4384] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4384 - Write Sequencer 288 */ | ||
1261 | [4385] = { 0x00FF, 0x00FF, 0x0000 }, /* R4385 - Write Sequencer 289 */ | ||
1262 | [4386] = { 0x070F, 0x070F, 0x0000 }, /* R4386 - Write Sequencer 290 */ | ||
1263 | [4387] = { 0x010F, 0x010F, 0x0000 }, /* R4387 - Write Sequencer 291 */ | ||
1264 | [4388] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4388 - Write Sequencer 292 */ | ||
1265 | [4389] = { 0x00FF, 0x00FF, 0x0000 }, /* R4389 - Write Sequencer 293 */ | ||
1266 | [4390] = { 0x070F, 0x070F, 0x0000 }, /* R4390 - Write Sequencer 294 */ | ||
1267 | [4391] = { 0x010F, 0x010F, 0x0000 }, /* R4391 - Write Sequencer 295 */ | ||
1268 | [4392] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4392 - Write Sequencer 296 */ | ||
1269 | [4393] = { 0x00FF, 0x00FF, 0x0000 }, /* R4393 - Write Sequencer 297 */ | ||
1270 | [4394] = { 0x070F, 0x070F, 0x0000 }, /* R4394 - Write Sequencer 298 */ | ||
1271 | [4395] = { 0x010F, 0x010F, 0x0000 }, /* R4395 - Write Sequencer 299 */ | ||
1272 | [4396] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4396 - Write Sequencer 300 */ | ||
1273 | [4397] = { 0x00FF, 0x00FF, 0x0000 }, /* R4397 - Write Sequencer 301 */ | ||
1274 | [4398] = { 0x070F, 0x070F, 0x0000 }, /* R4398 - Write Sequencer 302 */ | ||
1275 | [4399] = { 0x010F, 0x010F, 0x0000 }, /* R4399 - Write Sequencer 303 */ | ||
1276 | [4400] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4400 - Write Sequencer 304 */ | ||
1277 | [4401] = { 0x00FF, 0x00FF, 0x0000 }, /* R4401 - Write Sequencer 305 */ | ||
1278 | [4402] = { 0x070F, 0x070F, 0x0000 }, /* R4402 - Write Sequencer 306 */ | ||
1279 | [4403] = { 0x010F, 0x010F, 0x0000 }, /* R4403 - Write Sequencer 307 */ | ||
1280 | [4404] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4404 - Write Sequencer 308 */ | ||
1281 | [4405] = { 0x00FF, 0x00FF, 0x0000 }, /* R4405 - Write Sequencer 309 */ | ||
1282 | [4406] = { 0x070F, 0x070F, 0x0000 }, /* R4406 - Write Sequencer 310 */ | ||
1283 | [4407] = { 0x010F, 0x010F, 0x0000 }, /* R4407 - Write Sequencer 311 */ | ||
1284 | [4408] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4408 - Write Sequencer 312 */ | ||
1285 | [4409] = { 0x00FF, 0x00FF, 0x0000 }, /* R4409 - Write Sequencer 313 */ | ||
1286 | [4410] = { 0x070F, 0x070F, 0x0000 }, /* R4410 - Write Sequencer 314 */ | ||
1287 | [4411] = { 0x010F, 0x010F, 0x0000 }, /* R4411 - Write Sequencer 315 */ | ||
1288 | [4412] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4412 - Write Sequencer 316 */ | ||
1289 | [4413] = { 0x00FF, 0x00FF, 0x0000 }, /* R4413 - Write Sequencer 317 */ | ||
1290 | [4414] = { 0x070F, 0x070F, 0x0000 }, /* R4414 - Write Sequencer 318 */ | ||
1291 | [4415] = { 0x010F, 0x010F, 0x0000 }, /* R4415 - Write Sequencer 319 */ | ||
1292 | [4416] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4416 - Write Sequencer 320 */ | ||
1293 | [4417] = { 0x00FF, 0x00FF, 0x0000 }, /* R4417 - Write Sequencer 321 */ | ||
1294 | [4418] = { 0x070F, 0x070F, 0x0000 }, /* R4418 - Write Sequencer 322 */ | ||
1295 | [4419] = { 0x010F, 0x010F, 0x0000 }, /* R4419 - Write Sequencer 323 */ | ||
1296 | [4420] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4420 - Write Sequencer 324 */ | ||
1297 | [4421] = { 0x00FF, 0x00FF, 0x0000 }, /* R4421 - Write Sequencer 325 */ | ||
1298 | [4422] = { 0x070F, 0x070F, 0x0000 }, /* R4422 - Write Sequencer 326 */ | ||
1299 | [4423] = { 0x010F, 0x010F, 0x0000 }, /* R4423 - Write Sequencer 327 */ | ||
1300 | [4424] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4424 - Write Sequencer 328 */ | ||
1301 | [4425] = { 0x00FF, 0x00FF, 0x0000 }, /* R4425 - Write Sequencer 329 */ | ||
1302 | [4426] = { 0x070F, 0x070F, 0x0000 }, /* R4426 - Write Sequencer 330 */ | ||
1303 | [4427] = { 0x010F, 0x010F, 0x0000 }, /* R4427 - Write Sequencer 331 */ | ||
1304 | [4428] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4428 - Write Sequencer 332 */ | ||
1305 | [4429] = { 0x00FF, 0x00FF, 0x0000 }, /* R4429 - Write Sequencer 333 */ | ||
1306 | [4430] = { 0x070F, 0x070F, 0x0000 }, /* R4430 - Write Sequencer 334 */ | ||
1307 | [4431] = { 0x010F, 0x010F, 0x0000 }, /* R4431 - Write Sequencer 335 */ | ||
1308 | [4432] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4432 - Write Sequencer 336 */ | ||
1309 | [4433] = { 0x00FF, 0x00FF, 0x0000 }, /* R4433 - Write Sequencer 337 */ | ||
1310 | [4434] = { 0x070F, 0x070F, 0x0000 }, /* R4434 - Write Sequencer 338 */ | ||
1311 | [4435] = { 0x010F, 0x010F, 0x0000 }, /* R4435 - Write Sequencer 339 */ | ||
1312 | [4436] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4436 - Write Sequencer 340 */ | ||
1313 | [4437] = { 0x00FF, 0x00FF, 0x0000 }, /* R4437 - Write Sequencer 341 */ | ||
1314 | [4438] = { 0x070F, 0x070F, 0x0000 }, /* R4438 - Write Sequencer 342 */ | ||
1315 | [4439] = { 0x010F, 0x010F, 0x0000 }, /* R4439 - Write Sequencer 343 */ | ||
1316 | [4440] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4440 - Write Sequencer 344 */ | ||
1317 | [4441] = { 0x00FF, 0x00FF, 0x0000 }, /* R4441 - Write Sequencer 345 */ | ||
1318 | [4442] = { 0x070F, 0x070F, 0x0000 }, /* R4442 - Write Sequencer 346 */ | ||
1319 | [4443] = { 0x010F, 0x010F, 0x0000 }, /* R4443 - Write Sequencer 347 */ | ||
1320 | [4444] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4444 - Write Sequencer 348 */ | ||
1321 | [4445] = { 0x00FF, 0x00FF, 0x0000 }, /* R4445 - Write Sequencer 349 */ | ||
1322 | [4446] = { 0x070F, 0x070F, 0x0000 }, /* R4446 - Write Sequencer 350 */ | ||
1323 | [4447] = { 0x010F, 0x010F, 0x0000 }, /* R4447 - Write Sequencer 351 */ | ||
1324 | [4448] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4448 - Write Sequencer 352 */ | ||
1325 | [4449] = { 0x00FF, 0x00FF, 0x0000 }, /* R4449 - Write Sequencer 353 */ | ||
1326 | [4450] = { 0x070F, 0x070F, 0x0000 }, /* R4450 - Write Sequencer 354 */ | ||
1327 | [4451] = { 0x010F, 0x010F, 0x0000 }, /* R4451 - Write Sequencer 355 */ | ||
1328 | [4452] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4452 - Write Sequencer 356 */ | ||
1329 | [4453] = { 0x00FF, 0x00FF, 0x0000 }, /* R4453 - Write Sequencer 357 */ | ||
1330 | [4454] = { 0x070F, 0x070F, 0x0000 }, /* R4454 - Write Sequencer 358 */ | ||
1331 | [4455] = { 0x010F, 0x010F, 0x0000 }, /* R4455 - Write Sequencer 359 */ | ||
1332 | [4456] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4456 - Write Sequencer 360 */ | ||
1333 | [4457] = { 0x00FF, 0x00FF, 0x0000 }, /* R4457 - Write Sequencer 361 */ | ||
1334 | [4458] = { 0x070F, 0x070F, 0x0000 }, /* R4458 - Write Sequencer 362 */ | ||
1335 | [4459] = { 0x010F, 0x010F, 0x0000 }, /* R4459 - Write Sequencer 363 */ | ||
1336 | [4460] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4460 - Write Sequencer 364 */ | ||
1337 | [4461] = { 0x00FF, 0x00FF, 0x0000 }, /* R4461 - Write Sequencer 365 */ | ||
1338 | [4462] = { 0x070F, 0x070F, 0x0000 }, /* R4462 - Write Sequencer 366 */ | ||
1339 | [4463] = { 0x010F, 0x010F, 0x0000 }, /* R4463 - Write Sequencer 367 */ | ||
1340 | [4464] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4464 - Write Sequencer 368 */ | ||
1341 | [4465] = { 0x00FF, 0x00FF, 0x0000 }, /* R4465 - Write Sequencer 369 */ | ||
1342 | [4466] = { 0x070F, 0x070F, 0x0000 }, /* R4466 - Write Sequencer 370 */ | ||
1343 | [4467] = { 0x010F, 0x010F, 0x0000 }, /* R4467 - Write Sequencer 371 */ | ||
1344 | [4468] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4468 - Write Sequencer 372 */ | ||
1345 | [4469] = { 0x00FF, 0x00FF, 0x0000 }, /* R4469 - Write Sequencer 373 */ | ||
1346 | [4470] = { 0x070F, 0x070F, 0x0000 }, /* R4470 - Write Sequencer 374 */ | ||
1347 | [4471] = { 0x010F, 0x010F, 0x0000 }, /* R4471 - Write Sequencer 375 */ | ||
1348 | [4472] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4472 - Write Sequencer 376 */ | ||
1349 | [4473] = { 0x00FF, 0x00FF, 0x0000 }, /* R4473 - Write Sequencer 377 */ | ||
1350 | [4474] = { 0x070F, 0x070F, 0x0000 }, /* R4474 - Write Sequencer 378 */ | ||
1351 | [4475] = { 0x010F, 0x010F, 0x0000 }, /* R4475 - Write Sequencer 379 */ | ||
1352 | [4476] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4476 - Write Sequencer 380 */ | ||
1353 | [4477] = { 0x00FF, 0x00FF, 0x0000 }, /* R4477 - Write Sequencer 381 */ | ||
1354 | [4478] = { 0x070F, 0x070F, 0x0000 }, /* R4478 - Write Sequencer 382 */ | ||
1355 | [4479] = { 0x010F, 0x010F, 0x0000 }, /* R4479 - Write Sequencer 383 */ | ||
1356 | [4480] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4480 - Write Sequencer 384 */ | ||
1357 | [4481] = { 0x00FF, 0x00FF, 0x0000 }, /* R4481 - Write Sequencer 385 */ | ||
1358 | [4482] = { 0x070F, 0x070F, 0x0000 }, /* R4482 - Write Sequencer 386 */ | ||
1359 | [4483] = { 0x010F, 0x010F, 0x0000 }, /* R4483 - Write Sequencer 387 */ | ||
1360 | [4484] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4484 - Write Sequencer 388 */ | ||
1361 | [4485] = { 0x00FF, 0x00FF, 0x0000 }, /* R4485 - Write Sequencer 389 */ | ||
1362 | [4486] = { 0x070F, 0x070F, 0x0000 }, /* R4486 - Write Sequencer 390 */ | ||
1363 | [4487] = { 0x010F, 0x010F, 0x0000 }, /* R4487 - Write Sequencer 391 */ | ||
1364 | [4488] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4488 - Write Sequencer 392 */ | ||
1365 | [4489] = { 0x00FF, 0x00FF, 0x0000 }, /* R4489 - Write Sequencer 393 */ | ||
1366 | [4490] = { 0x070F, 0x070F, 0x0000 }, /* R4490 - Write Sequencer 394 */ | ||
1367 | [4491] = { 0x010F, 0x010F, 0x0000 }, /* R4491 - Write Sequencer 395 */ | ||
1368 | [4492] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4492 - Write Sequencer 396 */ | ||
1369 | [4493] = { 0x00FF, 0x00FF, 0x0000 }, /* R4493 - Write Sequencer 397 */ | ||
1370 | [4494] = { 0x070F, 0x070F, 0x0000 }, /* R4494 - Write Sequencer 398 */ | ||
1371 | [4495] = { 0x010F, 0x010F, 0x0000 }, /* R4495 - Write Sequencer 399 */ | ||
1372 | [4496] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4496 - Write Sequencer 400 */ | ||
1373 | [4497] = { 0x00FF, 0x00FF, 0x0000 }, /* R4497 - Write Sequencer 401 */ | ||
1374 | [4498] = { 0x070F, 0x070F, 0x0000 }, /* R4498 - Write Sequencer 402 */ | ||
1375 | [4499] = { 0x010F, 0x010F, 0x0000 }, /* R4499 - Write Sequencer 403 */ | ||
1376 | [4500] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4500 - Write Sequencer 404 */ | ||
1377 | [4501] = { 0x00FF, 0x00FF, 0x0000 }, /* R4501 - Write Sequencer 405 */ | ||
1378 | [4502] = { 0x070F, 0x070F, 0x0000 }, /* R4502 - Write Sequencer 406 */ | ||
1379 | [4503] = { 0x010F, 0x010F, 0x0000 }, /* R4503 - Write Sequencer 407 */ | ||
1380 | [4504] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4504 - Write Sequencer 408 */ | ||
1381 | [4505] = { 0x00FF, 0x00FF, 0x0000 }, /* R4505 - Write Sequencer 409 */ | ||
1382 | [4506] = { 0x070F, 0x070F, 0x0000 }, /* R4506 - Write Sequencer 410 */ | ||
1383 | [4507] = { 0x010F, 0x010F, 0x0000 }, /* R4507 - Write Sequencer 411 */ | ||
1384 | [4508] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4508 - Write Sequencer 412 */ | ||
1385 | [4509] = { 0x00FF, 0x00FF, 0x0000 }, /* R4509 - Write Sequencer 413 */ | ||
1386 | [4510] = { 0x070F, 0x070F, 0x0000 }, /* R4510 - Write Sequencer 414 */ | ||
1387 | [4511] = { 0x010F, 0x010F, 0x0000 }, /* R4511 - Write Sequencer 415 */ | ||
1388 | [4512] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4512 - Write Sequencer 416 */ | ||
1389 | [4513] = { 0x00FF, 0x00FF, 0x0000 }, /* R4513 - Write Sequencer 417 */ | ||
1390 | [4514] = { 0x070F, 0x070F, 0x0000 }, /* R4514 - Write Sequencer 418 */ | ||
1391 | [4515] = { 0x010F, 0x010F, 0x0000 }, /* R4515 - Write Sequencer 419 */ | ||
1392 | [4516] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4516 - Write Sequencer 420 */ | ||
1393 | [4517] = { 0x00FF, 0x00FF, 0x0000 }, /* R4517 - Write Sequencer 421 */ | ||
1394 | [4518] = { 0x070F, 0x070F, 0x0000 }, /* R4518 - Write Sequencer 422 */ | ||
1395 | [4519] = { 0x010F, 0x010F, 0x0000 }, /* R4519 - Write Sequencer 423 */ | ||
1396 | [4520] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4520 - Write Sequencer 424 */ | ||
1397 | [4521] = { 0x00FF, 0x00FF, 0x0000 }, /* R4521 - Write Sequencer 425 */ | ||
1398 | [4522] = { 0x070F, 0x070F, 0x0000 }, /* R4522 - Write Sequencer 426 */ | ||
1399 | [4523] = { 0x010F, 0x010F, 0x0000 }, /* R4523 - Write Sequencer 427 */ | ||
1400 | [4524] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4524 - Write Sequencer 428 */ | ||
1401 | [4525] = { 0x00FF, 0x00FF, 0x0000 }, /* R4525 - Write Sequencer 429 */ | ||
1402 | [4526] = { 0x070F, 0x070F, 0x0000 }, /* R4526 - Write Sequencer 430 */ | ||
1403 | [4527] = { 0x010F, 0x010F, 0x0000 }, /* R4527 - Write Sequencer 431 */ | ||
1404 | [4528] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4528 - Write Sequencer 432 */ | ||
1405 | [4529] = { 0x00FF, 0x00FF, 0x0000 }, /* R4529 - Write Sequencer 433 */ | ||
1406 | [4530] = { 0x070F, 0x070F, 0x0000 }, /* R4530 - Write Sequencer 434 */ | ||
1407 | [4531] = { 0x010F, 0x010F, 0x0000 }, /* R4531 - Write Sequencer 435 */ | ||
1408 | [4532] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4532 - Write Sequencer 436 */ | ||
1409 | [4533] = { 0x00FF, 0x00FF, 0x0000 }, /* R4533 - Write Sequencer 437 */ | ||
1410 | [4534] = { 0x070F, 0x070F, 0x0000 }, /* R4534 - Write Sequencer 438 */ | ||
1411 | [4535] = { 0x010F, 0x010F, 0x0000 }, /* R4535 - Write Sequencer 439 */ | ||
1412 | [4536] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4536 - Write Sequencer 440 */ | ||
1413 | [4537] = { 0x00FF, 0x00FF, 0x0000 }, /* R4537 - Write Sequencer 441 */ | ||
1414 | [4538] = { 0x070F, 0x070F, 0x0000 }, /* R4538 - Write Sequencer 442 */ | ||
1415 | [4539] = { 0x010F, 0x010F, 0x0000 }, /* R4539 - Write Sequencer 443 */ | ||
1416 | [4540] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4540 - Write Sequencer 444 */ | ||
1417 | [4541] = { 0x00FF, 0x00FF, 0x0000 }, /* R4541 - Write Sequencer 445 */ | ||
1418 | [4542] = { 0x070F, 0x070F, 0x0000 }, /* R4542 - Write Sequencer 446 */ | ||
1419 | [4543] = { 0x010F, 0x010F, 0x0000 }, /* R4543 - Write Sequencer 447 */ | ||
1420 | [4544] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4544 - Write Sequencer 448 */ | ||
1421 | [4545] = { 0x00FF, 0x00FF, 0x0000 }, /* R4545 - Write Sequencer 449 */ | ||
1422 | [4546] = { 0x070F, 0x070F, 0x0000 }, /* R4546 - Write Sequencer 450 */ | ||
1423 | [4547] = { 0x010F, 0x010F, 0x0000 }, /* R4547 - Write Sequencer 451 */ | ||
1424 | [4548] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4548 - Write Sequencer 452 */ | ||
1425 | [4549] = { 0x00FF, 0x00FF, 0x0000 }, /* R4549 - Write Sequencer 453 */ | ||
1426 | [4550] = { 0x070F, 0x070F, 0x0000 }, /* R4550 - Write Sequencer 454 */ | ||
1427 | [4551] = { 0x010F, 0x010F, 0x0000 }, /* R4551 - Write Sequencer 455 */ | ||
1428 | [4552] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4552 - Write Sequencer 456 */ | ||
1429 | [4553] = { 0x00FF, 0x00FF, 0x0000 }, /* R4553 - Write Sequencer 457 */ | ||
1430 | [4554] = { 0x070F, 0x070F, 0x0000 }, /* R4554 - Write Sequencer 458 */ | ||
1431 | [4555] = { 0x010F, 0x010F, 0x0000 }, /* R4555 - Write Sequencer 459 */ | ||
1432 | [4556] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4556 - Write Sequencer 460 */ | ||
1433 | [4557] = { 0x00FF, 0x00FF, 0x0000 }, /* R4557 - Write Sequencer 461 */ | ||
1434 | [4558] = { 0x070F, 0x070F, 0x0000 }, /* R4558 - Write Sequencer 462 */ | ||
1435 | [4559] = { 0x010F, 0x010F, 0x0000 }, /* R4559 - Write Sequencer 463 */ | ||
1436 | [4560] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4560 - Write Sequencer 464 */ | ||
1437 | [4561] = { 0x00FF, 0x00FF, 0x0000 }, /* R4561 - Write Sequencer 465 */ | ||
1438 | [4562] = { 0x070F, 0x070F, 0x0000 }, /* R4562 - Write Sequencer 466 */ | ||
1439 | [4563] = { 0x010F, 0x010F, 0x0000 }, /* R4563 - Write Sequencer 467 */ | ||
1440 | [4564] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4564 - Write Sequencer 468 */ | ||
1441 | [4565] = { 0x00FF, 0x00FF, 0x0000 }, /* R4565 - Write Sequencer 469 */ | ||
1442 | [4566] = { 0x070F, 0x070F, 0x0000 }, /* R4566 - Write Sequencer 470 */ | ||
1443 | [4567] = { 0x010F, 0x010F, 0x0000 }, /* R4567 - Write Sequencer 471 */ | ||
1444 | [4568] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4568 - Write Sequencer 472 */ | ||
1445 | [4569] = { 0x00FF, 0x00FF, 0x0000 }, /* R4569 - Write Sequencer 473 */ | ||
1446 | [4570] = { 0x070F, 0x070F, 0x0000 }, /* R4570 - Write Sequencer 474 */ | ||
1447 | [4571] = { 0x010F, 0x010F, 0x0000 }, /* R4571 - Write Sequencer 475 */ | ||
1448 | [4572] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4572 - Write Sequencer 476 */ | ||
1449 | [4573] = { 0x00FF, 0x00FF, 0x0000 }, /* R4573 - Write Sequencer 477 */ | ||
1450 | [4574] = { 0x070F, 0x070F, 0x0000 }, /* R4574 - Write Sequencer 478 */ | ||
1451 | [4575] = { 0x010F, 0x010F, 0x0000 }, /* R4575 - Write Sequencer 479 */ | ||
1452 | [4576] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4576 - Write Sequencer 480 */ | ||
1453 | [4577] = { 0x00FF, 0x00FF, 0x0000 }, /* R4577 - Write Sequencer 481 */ | ||
1454 | [4578] = { 0x070F, 0x070F, 0x0000 }, /* R4578 - Write Sequencer 482 */ | ||
1455 | [4579] = { 0x010F, 0x010F, 0x0000 }, /* R4579 - Write Sequencer 483 */ | ||
1456 | [4580] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4580 - Write Sequencer 484 */ | ||
1457 | [4581] = { 0x00FF, 0x00FF, 0x0000 }, /* R4581 - Write Sequencer 485 */ | ||
1458 | [4582] = { 0x070F, 0x070F, 0x0000 }, /* R4582 - Write Sequencer 486 */ | ||
1459 | [4583] = { 0x010F, 0x010F, 0x0000 }, /* R4583 - Write Sequencer 487 */ | ||
1460 | [4584] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4584 - Write Sequencer 488 */ | ||
1461 | [4585] = { 0x00FF, 0x00FF, 0x0000 }, /* R4585 - Write Sequencer 489 */ | ||
1462 | [4586] = { 0x070F, 0x070F, 0x0000 }, /* R4586 - Write Sequencer 490 */ | ||
1463 | [4587] = { 0x010F, 0x010F, 0x0000 }, /* R4587 - Write Sequencer 491 */ | ||
1464 | [4588] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4588 - Write Sequencer 492 */ | ||
1465 | [4589] = { 0x00FF, 0x00FF, 0x0000 }, /* R4589 - Write Sequencer 493 */ | ||
1466 | [4590] = { 0x070F, 0x070F, 0x0000 }, /* R4590 - Write Sequencer 494 */ | ||
1467 | [4591] = { 0x010F, 0x010F, 0x0000 }, /* R4591 - Write Sequencer 495 */ | ||
1468 | [4592] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4592 - Write Sequencer 496 */ | ||
1469 | [4593] = { 0x00FF, 0x00FF, 0x0000 }, /* R4593 - Write Sequencer 497 */ | ||
1470 | [4594] = { 0x070F, 0x070F, 0x0000 }, /* R4594 - Write Sequencer 498 */ | ||
1471 | [4595] = { 0x010F, 0x010F, 0x0000 }, /* R4595 - Write Sequencer 499 */ | ||
1472 | [4596] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4596 - Write Sequencer 500 */ | ||
1473 | [4597] = { 0x00FF, 0x00FF, 0x0000 }, /* R4597 - Write Sequencer 501 */ | ||
1474 | [4598] = { 0x070F, 0x070F, 0x0000 }, /* R4598 - Write Sequencer 502 */ | ||
1475 | [4599] = { 0x010F, 0x010F, 0x0000 }, /* R4599 - Write Sequencer 503 */ | ||
1476 | [4600] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4600 - Write Sequencer 504 */ | ||
1477 | [4601] = { 0x00FF, 0x00FF, 0x0000 }, /* R4601 - Write Sequencer 505 */ | ||
1478 | [4602] = { 0x070F, 0x070F, 0x0000 }, /* R4602 - Write Sequencer 506 */ | ||
1479 | [4603] = { 0x010F, 0x010F, 0x0000 }, /* R4603 - Write Sequencer 507 */ | ||
1480 | [4604] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4604 - Write Sequencer 508 */ | ||
1481 | [4605] = { 0x00FF, 0x00FF, 0x0000 }, /* R4605 - Write Sequencer 509 */ | ||
1482 | [4606] = { 0x070F, 0x070F, 0x0000 }, /* R4606 - Write Sequencer 510 */ | ||
1483 | [4607] = { 0x010F, 0x010F, 0x0000 }, /* R4607 - Write Sequencer 511 */ | ||
1484 | [8192] = { 0x03FF, 0x03FF, 0x0000 }, /* R8192 - DSP2 Instruction RAM 0 */ | ||
1485 | [9216] = { 0x003F, 0x003F, 0x0000 }, /* R9216 - DSP2 Address RAM 2 */ | ||
1486 | [9217] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R9217 - DSP2 Address RAM 1 */ | ||
1487 | [9218] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R9218 - DSP2 Address RAM 0 */ | ||
1488 | [12288] = { 0x00FF, 0x00FF, 0x0000 }, /* R12288 - DSP2 Data1 RAM 1 */ | ||
1489 | [12289] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R12289 - DSP2 Data1 RAM 0 */ | ||
1490 | [13312] = { 0x00FF, 0x00FF, 0x0000 }, /* R13312 - DSP2 Data2 RAM 1 */ | ||
1491 | [13313] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R13313 - DSP2 Data2 RAM 0 */ | ||
1492 | [14336] = { 0x00FF, 0x00FF, 0x0000 }, /* R14336 - DSP2 Data3 RAM 1 */ | ||
1493 | [14337] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R14337 - DSP2 Data3 RAM 0 */ | ||
1494 | [15360] = { 0x07FF, 0x07FF, 0x0000 }, /* R15360 - DSP2 Coeff RAM 0 */ | ||
1495 | [16384] = { 0x00FF, 0x00FF, 0x0000 }, /* R16384 - RETUNEADC_SHARED_COEFF_1 */ | ||
1496 | [16385] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16385 - RETUNEADC_SHARED_COEFF_0 */ | ||
1497 | [16386] = { 0x00FF, 0x00FF, 0x0000 }, /* R16386 - RETUNEDAC_SHARED_COEFF_1 */ | ||
1498 | [16387] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16387 - RETUNEDAC_SHARED_COEFF_0 */ | ||
1499 | [16388] = { 0x00FF, 0x00FF, 0x0000 }, /* R16388 - SOUNDSTAGE_ENABLES_1 */ | ||
1500 | [16389] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16389 - SOUNDSTAGE_ENABLES_0 */ | ||
1501 | [16896] = { 0x00FF, 0x00FF, 0x0000 }, /* R16896 - HDBASS_AI_1 */ | ||
1502 | [16897] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16897 - HDBASS_AI_0 */ | ||
1503 | [16898] = { 0x00FF, 0x00FF, 0x0000 }, /* R16898 - HDBASS_AR_1 */ | ||
1504 | [16899] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16899 - HDBASS_AR_0 */ | ||
1505 | [16900] = { 0x00FF, 0x00FF, 0x0000 }, /* R16900 - HDBASS_B_1 */ | ||
1506 | [16901] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16901 - HDBASS_B_0 */ | ||
1507 | [16902] = { 0x00FF, 0x00FF, 0x0000 }, /* R16902 - HDBASS_K_1 */ | ||
1508 | [16903] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16903 - HDBASS_K_0 */ | ||
1509 | [16904] = { 0x00FF, 0x00FF, 0x0000 }, /* R16904 - HDBASS_N1_1 */ | ||
1510 | [16905] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16905 - HDBASS_N1_0 */ | ||
1511 | [16906] = { 0x00FF, 0x00FF, 0x0000 }, /* R16906 - HDBASS_N2_1 */ | ||
1512 | [16907] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16907 - HDBASS_N2_0 */ | ||
1513 | [16908] = { 0x00FF, 0x00FF, 0x0000 }, /* R16908 - HDBASS_N3_1 */ | ||
1514 | [16909] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16909 - HDBASS_N3_0 */ | ||
1515 | [16910] = { 0x00FF, 0x00FF, 0x0000 }, /* R16910 - HDBASS_N4_1 */ | ||
1516 | [16911] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16911 - HDBASS_N4_0 */ | ||
1517 | [16912] = { 0x00FF, 0x00FF, 0x0000 }, /* R16912 - HDBASS_N5_1 */ | ||
1518 | [16913] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16913 - HDBASS_N5_0 */ | ||
1519 | [16914] = { 0x00FF, 0x00FF, 0x0000 }, /* R16914 - HDBASS_X1_1 */ | ||
1520 | [16915] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16915 - HDBASS_X1_0 */ | ||
1521 | [16916] = { 0x00FF, 0x00FF, 0x0000 }, /* R16916 - HDBASS_X2_1 */ | ||
1522 | [16917] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16917 - HDBASS_X2_0 */ | ||
1523 | [16918] = { 0x00FF, 0x00FF, 0x0000 }, /* R16918 - HDBASS_X3_1 */ | ||
1524 | [16919] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16919 - HDBASS_X3_0 */ | ||
1525 | [16920] = { 0x00FF, 0x00FF, 0x0000 }, /* R16920 - HDBASS_ATK_1 */ | ||
1526 | [16921] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16921 - HDBASS_ATK_0 */ | ||
1527 | [16922] = { 0x00FF, 0x00FF, 0x0000 }, /* R16922 - HDBASS_DCY_1 */ | ||
1528 | [16923] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16923 - HDBASS_DCY_0 */ | ||
1529 | [16924] = { 0x00FF, 0x00FF, 0x0000 }, /* R16924 - HDBASS_PG_1 */ | ||
1530 | [16925] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R16925 - HDBASS_PG_0 */ | ||
1531 | [17408] = { 0x00FF, 0x00FF, 0x0000 }, /* R17408 - HPF_C_1 */ | ||
1532 | [17409] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17409 - HPF_C_0 */ | ||
1533 | [17920] = { 0x00FF, 0x00FF, 0x0000 }, /* R17920 - ADCL_RETUNE_C1_1 */ | ||
1534 | [17921] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17921 - ADCL_RETUNE_C1_0 */ | ||
1535 | [17922] = { 0x00FF, 0x00FF, 0x0000 }, /* R17922 - ADCL_RETUNE_C2_1 */ | ||
1536 | [17923] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17923 - ADCL_RETUNE_C2_0 */ | ||
1537 | [17924] = { 0x00FF, 0x00FF, 0x0000 }, /* R17924 - ADCL_RETUNE_C3_1 */ | ||
1538 | [17925] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17925 - ADCL_RETUNE_C3_0 */ | ||
1539 | [17926] = { 0x00FF, 0x00FF, 0x0000 }, /* R17926 - ADCL_RETUNE_C4_1 */ | ||
1540 | [17927] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17927 - ADCL_RETUNE_C4_0 */ | ||
1541 | [17928] = { 0x00FF, 0x00FF, 0x0000 }, /* R17928 - ADCL_RETUNE_C5_1 */ | ||
1542 | [17929] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17929 - ADCL_RETUNE_C5_0 */ | ||
1543 | [17930] = { 0x00FF, 0x00FF, 0x0000 }, /* R17930 - ADCL_RETUNE_C6_1 */ | ||
1544 | [17931] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17931 - ADCL_RETUNE_C6_0 */ | ||
1545 | [17932] = { 0x00FF, 0x00FF, 0x0000 }, /* R17932 - ADCL_RETUNE_C7_1 */ | ||
1546 | [17933] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17933 - ADCL_RETUNE_C7_0 */ | ||
1547 | [17934] = { 0x00FF, 0x00FF, 0x0000 }, /* R17934 - ADCL_RETUNE_C8_1 */ | ||
1548 | [17935] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17935 - ADCL_RETUNE_C8_0 */ | ||
1549 | [17936] = { 0x00FF, 0x00FF, 0x0000 }, /* R17936 - ADCL_RETUNE_C9_1 */ | ||
1550 | [17937] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17937 - ADCL_RETUNE_C9_0 */ | ||
1551 | [17938] = { 0x00FF, 0x00FF, 0x0000 }, /* R17938 - ADCL_RETUNE_C10_1 */ | ||
1552 | [17939] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17939 - ADCL_RETUNE_C10_0 */ | ||
1553 | [17940] = { 0x00FF, 0x00FF, 0x0000 }, /* R17940 - ADCL_RETUNE_C11_1 */ | ||
1554 | [17941] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17941 - ADCL_RETUNE_C11_0 */ | ||
1555 | [17942] = { 0x00FF, 0x00FF, 0x0000 }, /* R17942 - ADCL_RETUNE_C12_1 */ | ||
1556 | [17943] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17943 - ADCL_RETUNE_C12_0 */ | ||
1557 | [17944] = { 0x00FF, 0x00FF, 0x0000 }, /* R17944 - ADCL_RETUNE_C13_1 */ | ||
1558 | [17945] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17945 - ADCL_RETUNE_C13_0 */ | ||
1559 | [17946] = { 0x00FF, 0x00FF, 0x0000 }, /* R17946 - ADCL_RETUNE_C14_1 */ | ||
1560 | [17947] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17947 - ADCL_RETUNE_C14_0 */ | ||
1561 | [17948] = { 0x00FF, 0x00FF, 0x0000 }, /* R17948 - ADCL_RETUNE_C15_1 */ | ||
1562 | [17949] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17949 - ADCL_RETUNE_C15_0 */ | ||
1563 | [17950] = { 0x00FF, 0x00FF, 0x0000 }, /* R17950 - ADCL_RETUNE_C16_1 */ | ||
1564 | [17951] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17951 - ADCL_RETUNE_C16_0 */ | ||
1565 | [17952] = { 0x00FF, 0x00FF, 0x0000 }, /* R17952 - ADCL_RETUNE_C17_1 */ | ||
1566 | [17953] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17953 - ADCL_RETUNE_C17_0 */ | ||
1567 | [17954] = { 0x00FF, 0x00FF, 0x0000 }, /* R17954 - ADCL_RETUNE_C18_1 */ | ||
1568 | [17955] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17955 - ADCL_RETUNE_C18_0 */ | ||
1569 | [17956] = { 0x00FF, 0x00FF, 0x0000 }, /* R17956 - ADCL_RETUNE_C19_1 */ | ||
1570 | [17957] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17957 - ADCL_RETUNE_C19_0 */ | ||
1571 | [17958] = { 0x00FF, 0x00FF, 0x0000 }, /* R17958 - ADCL_RETUNE_C20_1 */ | ||
1572 | [17959] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17959 - ADCL_RETUNE_C20_0 */ | ||
1573 | [17960] = { 0x00FF, 0x00FF, 0x0000 }, /* R17960 - ADCL_RETUNE_C21_1 */ | ||
1574 | [17961] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17961 - ADCL_RETUNE_C21_0 */ | ||
1575 | [17962] = { 0x00FF, 0x00FF, 0x0000 }, /* R17962 - ADCL_RETUNE_C22_1 */ | ||
1576 | [17963] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17963 - ADCL_RETUNE_C22_0 */ | ||
1577 | [17964] = { 0x00FF, 0x00FF, 0x0000 }, /* R17964 - ADCL_RETUNE_C23_1 */ | ||
1578 | [17965] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17965 - ADCL_RETUNE_C23_0 */ | ||
1579 | [17966] = { 0x00FF, 0x00FF, 0x0000 }, /* R17966 - ADCL_RETUNE_C24_1 */ | ||
1580 | [17967] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17967 - ADCL_RETUNE_C24_0 */ | ||
1581 | [17968] = { 0x00FF, 0x00FF, 0x0000 }, /* R17968 - ADCL_RETUNE_C25_1 */ | ||
1582 | [17969] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17969 - ADCL_RETUNE_C25_0 */ | ||
1583 | [17970] = { 0x00FF, 0x00FF, 0x0000 }, /* R17970 - ADCL_RETUNE_C26_1 */ | ||
1584 | [17971] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17971 - ADCL_RETUNE_C26_0 */ | ||
1585 | [17972] = { 0x00FF, 0x00FF, 0x0000 }, /* R17972 - ADCL_RETUNE_C27_1 */ | ||
1586 | [17973] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17973 - ADCL_RETUNE_C27_0 */ | ||
1587 | [17974] = { 0x00FF, 0x00FF, 0x0000 }, /* R17974 - ADCL_RETUNE_C28_1 */ | ||
1588 | [17975] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17975 - ADCL_RETUNE_C28_0 */ | ||
1589 | [17976] = { 0x00FF, 0x00FF, 0x0000 }, /* R17976 - ADCL_RETUNE_C29_1 */ | ||
1590 | [17977] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17977 - ADCL_RETUNE_C29_0 */ | ||
1591 | [17978] = { 0x00FF, 0x00FF, 0x0000 }, /* R17978 - ADCL_RETUNE_C30_1 */ | ||
1592 | [17979] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17979 - ADCL_RETUNE_C30_0 */ | ||
1593 | [17980] = { 0x00FF, 0x00FF, 0x0000 }, /* R17980 - ADCL_RETUNE_C31_1 */ | ||
1594 | [17981] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17981 - ADCL_RETUNE_C31_0 */ | ||
1595 | [17982] = { 0x00FF, 0x00FF, 0x0000 }, /* R17982 - ADCL_RETUNE_C32_1 */ | ||
1596 | [17983] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R17983 - ADCL_RETUNE_C32_0 */ | ||
1597 | [18432] = { 0x00FF, 0x00FF, 0x0000 }, /* R18432 - RETUNEADC_PG2_1 */ | ||
1598 | [18433] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18433 - RETUNEADC_PG2_0 */ | ||
1599 | [18434] = { 0x00FF, 0x00FF, 0x0000 }, /* R18434 - RETUNEADC_PG_1 */ | ||
1600 | [18435] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18435 - RETUNEADC_PG_0 */ | ||
1601 | [18944] = { 0x00FF, 0x00FF, 0x0000 }, /* R18944 - ADCR_RETUNE_C1_1 */ | ||
1602 | [18945] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18945 - ADCR_RETUNE_C1_0 */ | ||
1603 | [18946] = { 0x00FF, 0x00FF, 0x0000 }, /* R18946 - ADCR_RETUNE_C2_1 */ | ||
1604 | [18947] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18947 - ADCR_RETUNE_C2_0 */ | ||
1605 | [18948] = { 0x00FF, 0x00FF, 0x0000 }, /* R18948 - ADCR_RETUNE_C3_1 */ | ||
1606 | [18949] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18949 - ADCR_RETUNE_C3_0 */ | ||
1607 | [18950] = { 0x00FF, 0x00FF, 0x0000 }, /* R18950 - ADCR_RETUNE_C4_1 */ | ||
1608 | [18951] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18951 - ADCR_RETUNE_C4_0 */ | ||
1609 | [18952] = { 0x00FF, 0x00FF, 0x0000 }, /* R18952 - ADCR_RETUNE_C5_1 */ | ||
1610 | [18953] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18953 - ADCR_RETUNE_C5_0 */ | ||
1611 | [18954] = { 0x00FF, 0x00FF, 0x0000 }, /* R18954 - ADCR_RETUNE_C6_1 */ | ||
1612 | [18955] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18955 - ADCR_RETUNE_C6_0 */ | ||
1613 | [18956] = { 0x00FF, 0x00FF, 0x0000 }, /* R18956 - ADCR_RETUNE_C7_1 */ | ||
1614 | [18957] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18957 - ADCR_RETUNE_C7_0 */ | ||
1615 | [18958] = { 0x00FF, 0x00FF, 0x0000 }, /* R18958 - ADCR_RETUNE_C8_1 */ | ||
1616 | [18959] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18959 - ADCR_RETUNE_C8_0 */ | ||
1617 | [18960] = { 0x00FF, 0x00FF, 0x0000 }, /* R18960 - ADCR_RETUNE_C9_1 */ | ||
1618 | [18961] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18961 - ADCR_RETUNE_C9_0 */ | ||
1619 | [18962] = { 0x00FF, 0x00FF, 0x0000 }, /* R18962 - ADCR_RETUNE_C10_1 */ | ||
1620 | [18963] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18963 - ADCR_RETUNE_C10_0 */ | ||
1621 | [18964] = { 0x00FF, 0x00FF, 0x0000 }, /* R18964 - ADCR_RETUNE_C11_1 */ | ||
1622 | [18965] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18965 - ADCR_RETUNE_C11_0 */ | ||
1623 | [18966] = { 0x00FF, 0x00FF, 0x0000 }, /* R18966 - ADCR_RETUNE_C12_1 */ | ||
1624 | [18967] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18967 - ADCR_RETUNE_C12_0 */ | ||
1625 | [18968] = { 0x00FF, 0x00FF, 0x0000 }, /* R18968 - ADCR_RETUNE_C13_1 */ | ||
1626 | [18969] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18969 - ADCR_RETUNE_C13_0 */ | ||
1627 | [18970] = { 0x00FF, 0x00FF, 0x0000 }, /* R18970 - ADCR_RETUNE_C14_1 */ | ||
1628 | [18971] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18971 - ADCR_RETUNE_C14_0 */ | ||
1629 | [18972] = { 0x00FF, 0x00FF, 0x0000 }, /* R18972 - ADCR_RETUNE_C15_1 */ | ||
1630 | [18973] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18973 - ADCR_RETUNE_C15_0 */ | ||
1631 | [18974] = { 0x00FF, 0x00FF, 0x0000 }, /* R18974 - ADCR_RETUNE_C16_1 */ | ||
1632 | [18975] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18975 - ADCR_RETUNE_C16_0 */ | ||
1633 | [18976] = { 0x00FF, 0x00FF, 0x0000 }, /* R18976 - ADCR_RETUNE_C17_1 */ | ||
1634 | [18977] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18977 - ADCR_RETUNE_C17_0 */ | ||
1635 | [18978] = { 0x00FF, 0x00FF, 0x0000 }, /* R18978 - ADCR_RETUNE_C18_1 */ | ||
1636 | [18979] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18979 - ADCR_RETUNE_C18_0 */ | ||
1637 | [18980] = { 0x00FF, 0x00FF, 0x0000 }, /* R18980 - ADCR_RETUNE_C19_1 */ | ||
1638 | [18981] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18981 - ADCR_RETUNE_C19_0 */ | ||
1639 | [18982] = { 0x00FF, 0x00FF, 0x0000 }, /* R18982 - ADCR_RETUNE_C20_1 */ | ||
1640 | [18983] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18983 - ADCR_RETUNE_C20_0 */ | ||
1641 | [18984] = { 0x00FF, 0x00FF, 0x0000 }, /* R18984 - ADCR_RETUNE_C21_1 */ | ||
1642 | [18985] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18985 - ADCR_RETUNE_C21_0 */ | ||
1643 | [18986] = { 0x00FF, 0x00FF, 0x0000 }, /* R18986 - ADCR_RETUNE_C22_1 */ | ||
1644 | [18987] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18987 - ADCR_RETUNE_C22_0 */ | ||
1645 | [18988] = { 0x00FF, 0x00FF, 0x0000 }, /* R18988 - ADCR_RETUNE_C23_1 */ | ||
1646 | [18989] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18989 - ADCR_RETUNE_C23_0 */ | ||
1647 | [18990] = { 0x00FF, 0x00FF, 0x0000 }, /* R18990 - ADCR_RETUNE_C24_1 */ | ||
1648 | [18991] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18991 - ADCR_RETUNE_C24_0 */ | ||
1649 | [18992] = { 0x00FF, 0x00FF, 0x0000 }, /* R18992 - ADCR_RETUNE_C25_1 */ | ||
1650 | [18993] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18993 - ADCR_RETUNE_C25_0 */ | ||
1651 | [18994] = { 0x00FF, 0x00FF, 0x0000 }, /* R18994 - ADCR_RETUNE_C26_1 */ | ||
1652 | [18995] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18995 - ADCR_RETUNE_C26_0 */ | ||
1653 | [18996] = { 0x00FF, 0x00FF, 0x0000 }, /* R18996 - ADCR_RETUNE_C27_1 */ | ||
1654 | [18997] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18997 - ADCR_RETUNE_C27_0 */ | ||
1655 | [18998] = { 0x00FF, 0x00FF, 0x0000 }, /* R18998 - ADCR_RETUNE_C28_1 */ | ||
1656 | [18999] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R18999 - ADCR_RETUNE_C28_0 */ | ||
1657 | [19000] = { 0x00FF, 0x00FF, 0x0000 }, /* R19000 - ADCR_RETUNE_C29_1 */ | ||
1658 | [19001] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19001 - ADCR_RETUNE_C29_0 */ | ||
1659 | [19002] = { 0x00FF, 0x00FF, 0x0000 }, /* R19002 - ADCR_RETUNE_C30_1 */ | ||
1660 | [19003] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19003 - ADCR_RETUNE_C30_0 */ | ||
1661 | [19004] = { 0x00FF, 0x00FF, 0x0000 }, /* R19004 - ADCR_RETUNE_C31_1 */ | ||
1662 | [19005] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19005 - ADCR_RETUNE_C31_0 */ | ||
1663 | [19006] = { 0x00FF, 0x00FF, 0x0000 }, /* R19006 - ADCR_RETUNE_C32_1 */ | ||
1664 | [19007] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19007 - ADCR_RETUNE_C32_0 */ | ||
1665 | [19456] = { 0x00FF, 0x00FF, 0x0000 }, /* R19456 - DACL_RETUNE_C1_1 */ | ||
1666 | [19457] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19457 - DACL_RETUNE_C1_0 */ | ||
1667 | [19458] = { 0x00FF, 0x00FF, 0x0000 }, /* R19458 - DACL_RETUNE_C2_1 */ | ||
1668 | [19459] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19459 - DACL_RETUNE_C2_0 */ | ||
1669 | [19460] = { 0x00FF, 0x00FF, 0x0000 }, /* R19460 - DACL_RETUNE_C3_1 */ | ||
1670 | [19461] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19461 - DACL_RETUNE_C3_0 */ | ||
1671 | [19462] = { 0x00FF, 0x00FF, 0x0000 }, /* R19462 - DACL_RETUNE_C4_1 */ | ||
1672 | [19463] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19463 - DACL_RETUNE_C4_0 */ | ||
1673 | [19464] = { 0x00FF, 0x00FF, 0x0000 }, /* R19464 - DACL_RETUNE_C5_1 */ | ||
1674 | [19465] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19465 - DACL_RETUNE_C5_0 */ | ||
1675 | [19466] = { 0x00FF, 0x00FF, 0x0000 }, /* R19466 - DACL_RETUNE_C6_1 */ | ||
1676 | [19467] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19467 - DACL_RETUNE_C6_0 */ | ||
1677 | [19468] = { 0x00FF, 0x00FF, 0x0000 }, /* R19468 - DACL_RETUNE_C7_1 */ | ||
1678 | [19469] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19469 - DACL_RETUNE_C7_0 */ | ||
1679 | [19470] = { 0x00FF, 0x00FF, 0x0000 }, /* R19470 - DACL_RETUNE_C8_1 */ | ||
1680 | [19471] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19471 - DACL_RETUNE_C8_0 */ | ||
1681 | [19472] = { 0x00FF, 0x00FF, 0x0000 }, /* R19472 - DACL_RETUNE_C9_1 */ | ||
1682 | [19473] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19473 - DACL_RETUNE_C9_0 */ | ||
1683 | [19474] = { 0x00FF, 0x00FF, 0x0000 }, /* R19474 - DACL_RETUNE_C10_1 */ | ||
1684 | [19475] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19475 - DACL_RETUNE_C10_0 */ | ||
1685 | [19476] = { 0x00FF, 0x00FF, 0x0000 }, /* R19476 - DACL_RETUNE_C11_1 */ | ||
1686 | [19477] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19477 - DACL_RETUNE_C11_0 */ | ||
1687 | [19478] = { 0x00FF, 0x00FF, 0x0000 }, /* R19478 - DACL_RETUNE_C12_1 */ | ||
1688 | [19479] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19479 - DACL_RETUNE_C12_0 */ | ||
1689 | [19480] = { 0x00FF, 0x00FF, 0x0000 }, /* R19480 - DACL_RETUNE_C13_1 */ | ||
1690 | [19481] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19481 - DACL_RETUNE_C13_0 */ | ||
1691 | [19482] = { 0x00FF, 0x00FF, 0x0000 }, /* R19482 - DACL_RETUNE_C14_1 */ | ||
1692 | [19483] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19483 - DACL_RETUNE_C14_0 */ | ||
1693 | [19484] = { 0x00FF, 0x00FF, 0x0000 }, /* R19484 - DACL_RETUNE_C15_1 */ | ||
1694 | [19485] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19485 - DACL_RETUNE_C15_0 */ | ||
1695 | [19486] = { 0x00FF, 0x00FF, 0x0000 }, /* R19486 - DACL_RETUNE_C16_1 */ | ||
1696 | [19487] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19487 - DACL_RETUNE_C16_0 */ | ||
1697 | [19488] = { 0x00FF, 0x00FF, 0x0000 }, /* R19488 - DACL_RETUNE_C17_1 */ | ||
1698 | [19489] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19489 - DACL_RETUNE_C17_0 */ | ||
1699 | [19490] = { 0x00FF, 0x00FF, 0x0000 }, /* R19490 - DACL_RETUNE_C18_1 */ | ||
1700 | [19491] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19491 - DACL_RETUNE_C18_0 */ | ||
1701 | [19492] = { 0x00FF, 0x00FF, 0x0000 }, /* R19492 - DACL_RETUNE_C19_1 */ | ||
1702 | [19493] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19493 - DACL_RETUNE_C19_0 */ | ||
1703 | [19494] = { 0x00FF, 0x00FF, 0x0000 }, /* R19494 - DACL_RETUNE_C20_1 */ | ||
1704 | [19495] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19495 - DACL_RETUNE_C20_0 */ | ||
1705 | [19496] = { 0x00FF, 0x00FF, 0x0000 }, /* R19496 - DACL_RETUNE_C21_1 */ | ||
1706 | [19497] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19497 - DACL_RETUNE_C21_0 */ | ||
1707 | [19498] = { 0x00FF, 0x00FF, 0x0000 }, /* R19498 - DACL_RETUNE_C22_1 */ | ||
1708 | [19499] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19499 - DACL_RETUNE_C22_0 */ | ||
1709 | [19500] = { 0x00FF, 0x00FF, 0x0000 }, /* R19500 - DACL_RETUNE_C23_1 */ | ||
1710 | [19501] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19501 - DACL_RETUNE_C23_0 */ | ||
1711 | [19502] = { 0x00FF, 0x00FF, 0x0000 }, /* R19502 - DACL_RETUNE_C24_1 */ | ||
1712 | [19503] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19503 - DACL_RETUNE_C24_0 */ | ||
1713 | [19504] = { 0x00FF, 0x00FF, 0x0000 }, /* R19504 - DACL_RETUNE_C25_1 */ | ||
1714 | [19505] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19505 - DACL_RETUNE_C25_0 */ | ||
1715 | [19506] = { 0x00FF, 0x00FF, 0x0000 }, /* R19506 - DACL_RETUNE_C26_1 */ | ||
1716 | [19507] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19507 - DACL_RETUNE_C26_0 */ | ||
1717 | [19508] = { 0x00FF, 0x00FF, 0x0000 }, /* R19508 - DACL_RETUNE_C27_1 */ | ||
1718 | [19509] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19509 - DACL_RETUNE_C27_0 */ | ||
1719 | [19510] = { 0x00FF, 0x00FF, 0x0000 }, /* R19510 - DACL_RETUNE_C28_1 */ | ||
1720 | [19511] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19511 - DACL_RETUNE_C28_0 */ | ||
1721 | [19512] = { 0x00FF, 0x00FF, 0x0000 }, /* R19512 - DACL_RETUNE_C29_1 */ | ||
1722 | [19513] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19513 - DACL_RETUNE_C29_0 */ | ||
1723 | [19514] = { 0x00FF, 0x00FF, 0x0000 }, /* R19514 - DACL_RETUNE_C30_1 */ | ||
1724 | [19515] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19515 - DACL_RETUNE_C30_0 */ | ||
1725 | [19516] = { 0x00FF, 0x00FF, 0x0000 }, /* R19516 - DACL_RETUNE_C31_1 */ | ||
1726 | [19517] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19517 - DACL_RETUNE_C31_0 */ | ||
1727 | [19518] = { 0x00FF, 0x00FF, 0x0000 }, /* R19518 - DACL_RETUNE_C32_1 */ | ||
1728 | [19519] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19519 - DACL_RETUNE_C32_0 */ | ||
1729 | [19968] = { 0x00FF, 0x00FF, 0x0000 }, /* R19968 - RETUNEDAC_PG2_1 */ | ||
1730 | [19969] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19969 - RETUNEDAC_PG2_0 */ | ||
1731 | [19970] = { 0x00FF, 0x00FF, 0x0000 }, /* R19970 - RETUNEDAC_PG_1 */ | ||
1732 | [19971] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R19971 - RETUNEDAC_PG_0 */ | ||
1733 | [20480] = { 0x00FF, 0x00FF, 0x0000 }, /* R20480 - DACR_RETUNE_C1_1 */ | ||
1734 | [20481] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20481 - DACR_RETUNE_C1_0 */ | ||
1735 | [20482] = { 0x00FF, 0x00FF, 0x0000 }, /* R20482 - DACR_RETUNE_C2_1 */ | ||
1736 | [20483] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20483 - DACR_RETUNE_C2_0 */ | ||
1737 | [20484] = { 0x00FF, 0x00FF, 0x0000 }, /* R20484 - DACR_RETUNE_C3_1 */ | ||
1738 | [20485] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20485 - DACR_RETUNE_C3_0 */ | ||
1739 | [20486] = { 0x00FF, 0x00FF, 0x0000 }, /* R20486 - DACR_RETUNE_C4_1 */ | ||
1740 | [20487] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20487 - DACR_RETUNE_C4_0 */ | ||
1741 | [20488] = { 0x00FF, 0x00FF, 0x0000 }, /* R20488 - DACR_RETUNE_C5_1 */ | ||
1742 | [20489] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20489 - DACR_RETUNE_C5_0 */ | ||
1743 | [20490] = { 0x00FF, 0x00FF, 0x0000 }, /* R20490 - DACR_RETUNE_C6_1 */ | ||
1744 | [20491] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20491 - DACR_RETUNE_C6_0 */ | ||
1745 | [20492] = { 0x00FF, 0x00FF, 0x0000 }, /* R20492 - DACR_RETUNE_C7_1 */ | ||
1746 | [20493] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20493 - DACR_RETUNE_C7_0 */ | ||
1747 | [20494] = { 0x00FF, 0x00FF, 0x0000 }, /* R20494 - DACR_RETUNE_C8_1 */ | ||
1748 | [20495] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20495 - DACR_RETUNE_C8_0 */ | ||
1749 | [20496] = { 0x00FF, 0x00FF, 0x0000 }, /* R20496 - DACR_RETUNE_C9_1 */ | ||
1750 | [20497] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20497 - DACR_RETUNE_C9_0 */ | ||
1751 | [20498] = { 0x00FF, 0x00FF, 0x0000 }, /* R20498 - DACR_RETUNE_C10_1 */ | ||
1752 | [20499] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20499 - DACR_RETUNE_C10_0 */ | ||
1753 | [20500] = { 0x00FF, 0x00FF, 0x0000 }, /* R20500 - DACR_RETUNE_C11_1 */ | ||
1754 | [20501] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20501 - DACR_RETUNE_C11_0 */ | ||
1755 | [20502] = { 0x00FF, 0x00FF, 0x0000 }, /* R20502 - DACR_RETUNE_C12_1 */ | ||
1756 | [20503] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20503 - DACR_RETUNE_C12_0 */ | ||
1757 | [20504] = { 0x00FF, 0x00FF, 0x0000 }, /* R20504 - DACR_RETUNE_C13_1 */ | ||
1758 | [20505] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20505 - DACR_RETUNE_C13_0 */ | ||
1759 | [20506] = { 0x00FF, 0x00FF, 0x0000 }, /* R20506 - DACR_RETUNE_C14_1 */ | ||
1760 | [20507] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20507 - DACR_RETUNE_C14_0 */ | ||
1761 | [20508] = { 0x00FF, 0x00FF, 0x0000 }, /* R20508 - DACR_RETUNE_C15_1 */ | ||
1762 | [20509] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20509 - DACR_RETUNE_C15_0 */ | ||
1763 | [20510] = { 0x00FF, 0x00FF, 0x0000 }, /* R20510 - DACR_RETUNE_C16_1 */ | ||
1764 | [20511] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20511 - DACR_RETUNE_C16_0 */ | ||
1765 | [20512] = { 0x00FF, 0x00FF, 0x0000 }, /* R20512 - DACR_RETUNE_C17_1 */ | ||
1766 | [20513] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20513 - DACR_RETUNE_C17_0 */ | ||
1767 | [20514] = { 0x00FF, 0x00FF, 0x0000 }, /* R20514 - DACR_RETUNE_C18_1 */ | ||
1768 | [20515] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20515 - DACR_RETUNE_C18_0 */ | ||
1769 | [20516] = { 0x00FF, 0x00FF, 0x0000 }, /* R20516 - DACR_RETUNE_C19_1 */ | ||
1770 | [20517] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20517 - DACR_RETUNE_C19_0 */ | ||
1771 | [20518] = { 0x00FF, 0x00FF, 0x0000 }, /* R20518 - DACR_RETUNE_C20_1 */ | ||
1772 | [20519] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20519 - DACR_RETUNE_C20_0 */ | ||
1773 | [20520] = { 0x00FF, 0x00FF, 0x0000 }, /* R20520 - DACR_RETUNE_C21_1 */ | ||
1774 | [20521] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20521 - DACR_RETUNE_C21_0 */ | ||
1775 | [20522] = { 0x00FF, 0x00FF, 0x0000 }, /* R20522 - DACR_RETUNE_C22_1 */ | ||
1776 | [20523] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20523 - DACR_RETUNE_C22_0 */ | ||
1777 | [20524] = { 0x00FF, 0x00FF, 0x0000 }, /* R20524 - DACR_RETUNE_C23_1 */ | ||
1778 | [20525] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20525 - DACR_RETUNE_C23_0 */ | ||
1779 | [20526] = { 0x00FF, 0x00FF, 0x0000 }, /* R20526 - DACR_RETUNE_C24_1 */ | ||
1780 | [20527] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20527 - DACR_RETUNE_C24_0 */ | ||
1781 | [20528] = { 0x00FF, 0x00FF, 0x0000 }, /* R20528 - DACR_RETUNE_C25_1 */ | ||
1782 | [20529] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20529 - DACR_RETUNE_C25_0 */ | ||
1783 | [20530] = { 0x00FF, 0x00FF, 0x0000 }, /* R20530 - DACR_RETUNE_C26_1 */ | ||
1784 | [20531] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20531 - DACR_RETUNE_C26_0 */ | ||
1785 | [20532] = { 0x00FF, 0x00FF, 0x0000 }, /* R20532 - DACR_RETUNE_C27_1 */ | ||
1786 | [20533] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20533 - DACR_RETUNE_C27_0 */ | ||
1787 | [20534] = { 0x00FF, 0x00FF, 0x0000 }, /* R20534 - DACR_RETUNE_C28_1 */ | ||
1788 | [20535] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20535 - DACR_RETUNE_C28_0 */ | ||
1789 | [20536] = { 0x00FF, 0x00FF, 0x0000 }, /* R20536 - DACR_RETUNE_C29_1 */ | ||
1790 | [20537] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20537 - DACR_RETUNE_C29_0 */ | ||
1791 | [20538] = { 0x00FF, 0x00FF, 0x0000 }, /* R20538 - DACR_RETUNE_C30_1 */ | ||
1792 | [20539] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20539 - DACR_RETUNE_C30_0 */ | ||
1793 | [20540] = { 0x00FF, 0x00FF, 0x0000 }, /* R20540 - DACR_RETUNE_C31_1 */ | ||
1794 | [20541] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20541 - DACR_RETUNE_C31_0 */ | ||
1795 | [20542] = { 0x00FF, 0x00FF, 0x0000 }, /* R20542 - DACR_RETUNE_C32_1 */ | ||
1796 | [20543] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20543 - DACR_RETUNE_C32_0 */ | ||
1797 | [20992] = { 0x00FF, 0x00FF, 0x0000 }, /* R20992 - VSS_XHD2_1 */ | ||
1798 | [20993] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20993 - VSS_XHD2_0 */ | ||
1799 | [20994] = { 0x00FF, 0x00FF, 0x0000 }, /* R20994 - VSS_XHD3_1 */ | ||
1800 | [20995] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20995 - VSS_XHD3_0 */ | ||
1801 | [20996] = { 0x00FF, 0x00FF, 0x0000 }, /* R20996 - VSS_XHN1_1 */ | ||
1802 | [20997] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20997 - VSS_XHN1_0 */ | ||
1803 | [20998] = { 0x00FF, 0x00FF, 0x0000 }, /* R20998 - VSS_XHN2_1 */ | ||
1804 | [20999] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R20999 - VSS_XHN2_0 */ | ||
1805 | [21000] = { 0x00FF, 0x00FF, 0x0000 }, /* R21000 - VSS_XHN3_1 */ | ||
1806 | [21001] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21001 - VSS_XHN3_0 */ | ||
1807 | [21002] = { 0x00FF, 0x00FF, 0x0000 }, /* R21002 - VSS_XLA_1 */ | ||
1808 | [21003] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21003 - VSS_XLA_0 */ | ||
1809 | [21004] = { 0x00FF, 0x00FF, 0x0000 }, /* R21004 - VSS_XLB_1 */ | ||
1810 | [21005] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21005 - VSS_XLB_0 */ | ||
1811 | [21006] = { 0x00FF, 0x00FF, 0x0000 }, /* R21006 - VSS_XLG_1 */ | ||
1812 | [21007] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21007 - VSS_XLG_0 */ | ||
1813 | [21008] = { 0x00FF, 0x00FF, 0x0000 }, /* R21008 - VSS_PG2_1 */ | ||
1814 | [21009] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21009 - VSS_PG2_0 */ | ||
1815 | [21010] = { 0x00FF, 0x00FF, 0x0000 }, /* R21010 - VSS_PG_1 */ | ||
1816 | [21011] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21011 - VSS_PG_0 */ | ||
1817 | [21012] = { 0x00FF, 0x00FF, 0x0000 }, /* R21012 - VSS_XTD1_1 */ | ||
1818 | [21013] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21013 - VSS_XTD1_0 */ | ||
1819 | [21014] = { 0x00FF, 0x00FF, 0x0000 }, /* R21014 - VSS_XTD2_1 */ | ||
1820 | [21015] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21015 - VSS_XTD2_0 */ | ||
1821 | [21016] = { 0x00FF, 0x00FF, 0x0000 }, /* R21016 - VSS_XTD3_1 */ | ||
1822 | [21017] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21017 - VSS_XTD3_0 */ | ||
1823 | [21018] = { 0x00FF, 0x00FF, 0x0000 }, /* R21018 - VSS_XTD4_1 */ | ||
1824 | [21019] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21019 - VSS_XTD4_0 */ | ||
1825 | [21020] = { 0x00FF, 0x00FF, 0x0000 }, /* R21020 - VSS_XTD5_1 */ | ||
1826 | [21021] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21021 - VSS_XTD5_0 */ | ||
1827 | [21022] = { 0x00FF, 0x00FF, 0x0000 }, /* R21022 - VSS_XTD6_1 */ | ||
1828 | [21023] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21023 - VSS_XTD6_0 */ | ||
1829 | [21024] = { 0x00FF, 0x00FF, 0x0000 }, /* R21024 - VSS_XTD7_1 */ | ||
1830 | [21025] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21025 - VSS_XTD7_0 */ | ||
1831 | [21026] = { 0x00FF, 0x00FF, 0x0000 }, /* R21026 - VSS_XTD8_1 */ | ||
1832 | [21027] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21027 - VSS_XTD8_0 */ | ||
1833 | [21028] = { 0x00FF, 0x00FF, 0x0000 }, /* R21028 - VSS_XTD9_1 */ | ||
1834 | [21029] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21029 - VSS_XTD9_0 */ | ||
1835 | [21030] = { 0x00FF, 0x00FF, 0x0000 }, /* R21030 - VSS_XTD10_1 */ | ||
1836 | [21031] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21031 - VSS_XTD10_0 */ | ||
1837 | [21032] = { 0x00FF, 0x00FF, 0x0000 }, /* R21032 - VSS_XTD11_1 */ | ||
1838 | [21033] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21033 - VSS_XTD11_0 */ | ||
1839 | [21034] = { 0x00FF, 0x00FF, 0x0000 }, /* R21034 - VSS_XTD12_1 */ | ||
1840 | [21035] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21035 - VSS_XTD12_0 */ | ||
1841 | [21036] = { 0x00FF, 0x00FF, 0x0000 }, /* R21036 - VSS_XTD13_1 */ | ||
1842 | [21037] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21037 - VSS_XTD13_0 */ | ||
1843 | [21038] = { 0x00FF, 0x00FF, 0x0000 }, /* R21038 - VSS_XTD14_1 */ | ||
1844 | [21039] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21039 - VSS_XTD14_0 */ | ||
1845 | [21040] = { 0x00FF, 0x00FF, 0x0000 }, /* R21040 - VSS_XTD15_1 */ | ||
1846 | [21041] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21041 - VSS_XTD15_0 */ | ||
1847 | [21042] = { 0x00FF, 0x00FF, 0x0000 }, /* R21042 - VSS_XTD16_1 */ | ||
1848 | [21043] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21043 - VSS_XTD16_0 */ | ||
1849 | [21044] = { 0x00FF, 0x00FF, 0x0000 }, /* R21044 - VSS_XTD17_1 */ | ||
1850 | [21045] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21045 - VSS_XTD17_0 */ | ||
1851 | [21046] = { 0x00FF, 0x00FF, 0x0000 }, /* R21046 - VSS_XTD18_1 */ | ||
1852 | [21047] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21047 - VSS_XTD18_0 */ | ||
1853 | [21048] = { 0x00FF, 0x00FF, 0x0000 }, /* R21048 - VSS_XTD19_1 */ | ||
1854 | [21049] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21049 - VSS_XTD19_0 */ | ||
1855 | [21050] = { 0x00FF, 0x00FF, 0x0000 }, /* R21050 - VSS_XTD20_1 */ | ||
1856 | [21051] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21051 - VSS_XTD20_0 */ | ||
1857 | [21052] = { 0x00FF, 0x00FF, 0x0000 }, /* R21052 - VSS_XTD21_1 */ | ||
1858 | [21053] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21053 - VSS_XTD21_0 */ | ||
1859 | [21054] = { 0x00FF, 0x00FF, 0x0000 }, /* R21054 - VSS_XTD22_1 */ | ||
1860 | [21055] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21055 - VSS_XTD22_0 */ | ||
1861 | [21056] = { 0x00FF, 0x00FF, 0x0000 }, /* R21056 - VSS_XTD23_1 */ | ||
1862 | [21057] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21057 - VSS_XTD23_0 */ | ||
1863 | [21058] = { 0x00FF, 0x00FF, 0x0000 }, /* R21058 - VSS_XTD24_1 */ | ||
1864 | [21059] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21059 - VSS_XTD24_0 */ | ||
1865 | [21060] = { 0x00FF, 0x00FF, 0x0000 }, /* R21060 - VSS_XTD25_1 */ | ||
1866 | [21061] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21061 - VSS_XTD25_0 */ | ||
1867 | [21062] = { 0x00FF, 0x00FF, 0x0000 }, /* R21062 - VSS_XTD26_1 */ | ||
1868 | [21063] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21063 - VSS_XTD26_0 */ | ||
1869 | [21064] = { 0x00FF, 0x00FF, 0x0000 }, /* R21064 - VSS_XTD27_1 */ | ||
1870 | [21065] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21065 - VSS_XTD27_0 */ | ||
1871 | [21066] = { 0x00FF, 0x00FF, 0x0000 }, /* R21066 - VSS_XTD28_1 */ | ||
1872 | [21067] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21067 - VSS_XTD28_0 */ | ||
1873 | [21068] = { 0x00FF, 0x00FF, 0x0000 }, /* R21068 - VSS_XTD29_1 */ | ||
1874 | [21069] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21069 - VSS_XTD29_0 */ | ||
1875 | [21070] = { 0x00FF, 0x00FF, 0x0000 }, /* R21070 - VSS_XTD30_1 */ | ||
1876 | [21071] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21071 - VSS_XTD30_0 */ | ||
1877 | [21072] = { 0x00FF, 0x00FF, 0x0000 }, /* R21072 - VSS_XTD31_1 */ | ||
1878 | [21073] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21073 - VSS_XTD31_0 */ | ||
1879 | [21074] = { 0x00FF, 0x00FF, 0x0000 }, /* R21074 - VSS_XTD32_1 */ | ||
1880 | [21075] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21075 - VSS_XTD32_0 */ | ||
1881 | [21076] = { 0x00FF, 0x00FF, 0x0000 }, /* R21076 - VSS_XTS1_1 */ | ||
1882 | [21077] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21077 - VSS_XTS1_0 */ | ||
1883 | [21078] = { 0x00FF, 0x00FF, 0x0000 }, /* R21078 - VSS_XTS2_1 */ | ||
1884 | [21079] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21079 - VSS_XTS2_0 */ | ||
1885 | [21080] = { 0x00FF, 0x00FF, 0x0000 }, /* R21080 - VSS_XTS3_1 */ | ||
1886 | [21081] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21081 - VSS_XTS3_0 */ | ||
1887 | [21082] = { 0x00FF, 0x00FF, 0x0000 }, /* R21082 - VSS_XTS4_1 */ | ||
1888 | [21083] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21083 - VSS_XTS4_0 */ | ||
1889 | [21084] = { 0x00FF, 0x00FF, 0x0000 }, /* R21084 - VSS_XTS5_1 */ | ||
1890 | [21085] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21085 - VSS_XTS5_0 */ | ||
1891 | [21086] = { 0x00FF, 0x00FF, 0x0000 }, /* R21086 - VSS_XTS6_1 */ | ||
1892 | [21087] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21087 - VSS_XTS6_0 */ | ||
1893 | [21088] = { 0x00FF, 0x00FF, 0x0000 }, /* R21088 - VSS_XTS7_1 */ | ||
1894 | [21089] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21089 - VSS_XTS7_0 */ | ||
1895 | [21090] = { 0x00FF, 0x00FF, 0x0000 }, /* R21090 - VSS_XTS8_1 */ | ||
1896 | [21091] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21091 - VSS_XTS8_0 */ | ||
1897 | [21092] = { 0x00FF, 0x00FF, 0x0000 }, /* R21092 - VSS_XTS9_1 */ | ||
1898 | [21093] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21093 - VSS_XTS9_0 */ | ||
1899 | [21094] = { 0x00FF, 0x00FF, 0x0000 }, /* R21094 - VSS_XTS10_1 */ | ||
1900 | [21095] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21095 - VSS_XTS10_0 */ | ||
1901 | [21096] = { 0x00FF, 0x00FF, 0x0000 }, /* R21096 - VSS_XTS11_1 */ | ||
1902 | [21097] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21097 - VSS_XTS11_0 */ | ||
1903 | [21098] = { 0x00FF, 0x00FF, 0x0000 }, /* R21098 - VSS_XTS12_1 */ | ||
1904 | [21099] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21099 - VSS_XTS12_0 */ | ||
1905 | [21100] = { 0x00FF, 0x00FF, 0x0000 }, /* R21100 - VSS_XTS13_1 */ | ||
1906 | [21101] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21101 - VSS_XTS13_0 */ | ||
1907 | [21102] = { 0x00FF, 0x00FF, 0x0000 }, /* R21102 - VSS_XTS14_1 */ | ||
1908 | [21103] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21103 - VSS_XTS14_0 */ | ||
1909 | [21104] = { 0x00FF, 0x00FF, 0x0000 }, /* R21104 - VSS_XTS15_1 */ | ||
1910 | [21105] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21105 - VSS_XTS15_0 */ | ||
1911 | [21106] = { 0x00FF, 0x00FF, 0x0000 }, /* R21106 - VSS_XTS16_1 */ | ||
1912 | [21107] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21107 - VSS_XTS16_0 */ | ||
1913 | [21108] = { 0x00FF, 0x00FF, 0x0000 }, /* R21108 - VSS_XTS17_1 */ | ||
1914 | [21109] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21109 - VSS_XTS17_0 */ | ||
1915 | [21110] = { 0x00FF, 0x00FF, 0x0000 }, /* R21110 - VSS_XTS18_1 */ | ||
1916 | [21111] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21111 - VSS_XTS18_0 */ | ||
1917 | [21112] = { 0x00FF, 0x00FF, 0x0000 }, /* R21112 - VSS_XTS19_1 */ | ||
1918 | [21113] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21113 - VSS_XTS19_0 */ | ||
1919 | [21114] = { 0x00FF, 0x00FF, 0x0000 }, /* R21114 - VSS_XTS20_1 */ | ||
1920 | [21115] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21115 - VSS_XTS20_0 */ | ||
1921 | [21116] = { 0x00FF, 0x00FF, 0x0000 }, /* R21116 - VSS_XTS21_1 */ | ||
1922 | [21117] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21117 - VSS_XTS21_0 */ | ||
1923 | [21118] = { 0x00FF, 0x00FF, 0x0000 }, /* R21118 - VSS_XTS22_1 */ | ||
1924 | [21119] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21119 - VSS_XTS22_0 */ | ||
1925 | [21120] = { 0x00FF, 0x00FF, 0x0000 }, /* R21120 - VSS_XTS23_1 */ | ||
1926 | [21121] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21121 - VSS_XTS23_0 */ | ||
1927 | [21122] = { 0x00FF, 0x00FF, 0x0000 }, /* R21122 - VSS_XTS24_1 */ | ||
1928 | [21123] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21123 - VSS_XTS24_0 */ | ||
1929 | [21124] = { 0x00FF, 0x00FF, 0x0000 }, /* R21124 - VSS_XTS25_1 */ | ||
1930 | [21125] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21125 - VSS_XTS25_0 */ | ||
1931 | [21126] = { 0x00FF, 0x00FF, 0x0000 }, /* R21126 - VSS_XTS26_1 */ | ||
1932 | [21127] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21127 - VSS_XTS26_0 */ | ||
1933 | [21128] = { 0x00FF, 0x00FF, 0x0000 }, /* R21128 - VSS_XTS27_1 */ | ||
1934 | [21129] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21129 - VSS_XTS27_0 */ | ||
1935 | [21130] = { 0x00FF, 0x00FF, 0x0000 }, /* R21130 - VSS_XTS28_1 */ | ||
1936 | [21131] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21131 - VSS_XTS28_0 */ | ||
1937 | [21132] = { 0x00FF, 0x00FF, 0x0000 }, /* R21132 - VSS_XTS29_1 */ | ||
1938 | [21133] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21133 - VSS_XTS29_0 */ | ||
1939 | [21134] = { 0x00FF, 0x00FF, 0x0000 }, /* R21134 - VSS_XTS30_1 */ | ||
1940 | [21135] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21135 - VSS_XTS30_0 */ | ||
1941 | [21136] = { 0x00FF, 0x00FF, 0x0000 }, /* R21136 - VSS_XTS31_1 */ | ||
1942 | [21137] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21137 - VSS_XTS31_0 */ | ||
1943 | [21138] = { 0x00FF, 0x00FF, 0x0000 }, /* R21138 - VSS_XTS32_1 */ | ||
1944 | [21139] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21139 - VSS_XTS32_0 */ | ||
1945 | }; | ||
1946 | |||
1947 | static bool wm8962_volatile_register(struct device *dev, unsigned int reg) | 788 | static bool wm8962_volatile_register(struct device *dev, unsigned int reg) |
1948 | { | 789 | { |
1949 | if (wm8962_reg_access[reg].vol) | 790 | switch (reg) { |
1950 | return 1; | 791 | case WM8962_CLOCKING1: |
1951 | else | 792 | case WM8962_CLOCKING2: |
1952 | return 0; | 793 | case WM8962_SOFTWARE_RESET: |
794 | case WM8962_ALC2: | ||
795 | case WM8962_THERMAL_SHUTDOWN_STATUS: | ||
796 | case WM8962_ADDITIONAL_CONTROL_4: | ||
797 | case WM8962_CLASS_D_CONTROL_1: | ||
798 | case WM8962_DC_SERVO_6: | ||
799 | case WM8962_INTERRUPT_STATUS_1: | ||
800 | case WM8962_INTERRUPT_STATUS_2: | ||
801 | case WM8962_DSP2_EXECCONTROL: | ||
802 | return true; | ||
803 | default: | ||
804 | return false; | ||
805 | } | ||
1953 | } | 806 | } |
1954 | 807 | ||
1955 | static bool wm8962_readable_register(struct device *dev, unsigned int reg) | 808 | static bool wm8962_readable_register(struct device *dev, unsigned int reg) |
1956 | { | 809 | { |
1957 | if (wm8962_reg_access[reg].read) | 810 | switch (reg) { |
1958 | return 1; | 811 | case WM8962_LEFT_INPUT_VOLUME: |
1959 | else | 812 | case WM8962_RIGHT_INPUT_VOLUME: |
1960 | return 0; | 813 | case WM8962_HPOUTL_VOLUME: |
814 | case WM8962_HPOUTR_VOLUME: | ||
815 | case WM8962_CLOCKING1: | ||
816 | case WM8962_ADC_DAC_CONTROL_1: | ||
817 | case WM8962_ADC_DAC_CONTROL_2: | ||
818 | case WM8962_AUDIO_INTERFACE_0: | ||
819 | case WM8962_CLOCKING2: | ||
820 | case WM8962_AUDIO_INTERFACE_1: | ||
821 | case WM8962_LEFT_DAC_VOLUME: | ||
822 | case WM8962_RIGHT_DAC_VOLUME: | ||
823 | case WM8962_AUDIO_INTERFACE_2: | ||
824 | case WM8962_SOFTWARE_RESET: | ||
825 | case WM8962_ALC1: | ||
826 | case WM8962_ALC2: | ||
827 | case WM8962_ALC3: | ||
828 | case WM8962_NOISE_GATE: | ||
829 | case WM8962_LEFT_ADC_VOLUME: | ||
830 | case WM8962_RIGHT_ADC_VOLUME: | ||
831 | case WM8962_ADDITIONAL_CONTROL_1: | ||
832 | case WM8962_ADDITIONAL_CONTROL_2: | ||
833 | case WM8962_PWR_MGMT_1: | ||
834 | case WM8962_PWR_MGMT_2: | ||
835 | case WM8962_ADDITIONAL_CONTROL_3: | ||
836 | case WM8962_ANTI_POP: | ||
837 | case WM8962_CLOCKING_3: | ||
838 | case WM8962_INPUT_MIXER_CONTROL_1: | ||
839 | case WM8962_LEFT_INPUT_MIXER_VOLUME: | ||
840 | case WM8962_RIGHT_INPUT_MIXER_VOLUME: | ||
841 | case WM8962_INPUT_MIXER_CONTROL_2: | ||
842 | case WM8962_INPUT_BIAS_CONTROL: | ||
843 | case WM8962_LEFT_INPUT_PGA_CONTROL: | ||
844 | case WM8962_RIGHT_INPUT_PGA_CONTROL: | ||
845 | case WM8962_SPKOUTL_VOLUME: | ||
846 | case WM8962_SPKOUTR_VOLUME: | ||
847 | case WM8962_THERMAL_SHUTDOWN_STATUS: | ||
848 | case WM8962_ADDITIONAL_CONTROL_4: | ||
849 | case WM8962_CLASS_D_CONTROL_1: | ||
850 | case WM8962_CLASS_D_CONTROL_2: | ||
851 | case WM8962_CLOCKING_4: | ||
852 | case WM8962_DAC_DSP_MIXING_1: | ||
853 | case WM8962_DAC_DSP_MIXING_2: | ||
854 | case WM8962_DC_SERVO_0: | ||
855 | case WM8962_DC_SERVO_1: | ||
856 | case WM8962_DC_SERVO_4: | ||
857 | case WM8962_DC_SERVO_6: | ||
858 | case WM8962_ANALOGUE_PGA_BIAS: | ||
859 | case WM8962_ANALOGUE_HP_0: | ||
860 | case WM8962_ANALOGUE_HP_2: | ||
861 | case WM8962_CHARGE_PUMP_1: | ||
862 | case WM8962_CHARGE_PUMP_B: | ||
863 | case WM8962_WRITE_SEQUENCER_CONTROL_1: | ||
864 | case WM8962_WRITE_SEQUENCER_CONTROL_2: | ||
865 | case WM8962_WRITE_SEQUENCER_CONTROL_3: | ||
866 | case WM8962_CONTROL_INTERFACE: | ||
867 | case WM8962_MIXER_ENABLES: | ||
868 | case WM8962_HEADPHONE_MIXER_1: | ||
869 | case WM8962_HEADPHONE_MIXER_2: | ||
870 | case WM8962_HEADPHONE_MIXER_3: | ||
871 | case WM8962_HEADPHONE_MIXER_4: | ||
872 | case WM8962_SPEAKER_MIXER_1: | ||
873 | case WM8962_SPEAKER_MIXER_2: | ||
874 | case WM8962_SPEAKER_MIXER_3: | ||
875 | case WM8962_SPEAKER_MIXER_4: | ||
876 | case WM8962_SPEAKER_MIXER_5: | ||
877 | case WM8962_BEEP_GENERATOR_1: | ||
878 | case WM8962_OSCILLATOR_TRIM_3: | ||
879 | case WM8962_OSCILLATOR_TRIM_4: | ||
880 | case WM8962_OSCILLATOR_TRIM_7: | ||
881 | case WM8962_ANALOGUE_CLOCKING1: | ||
882 | case WM8962_ANALOGUE_CLOCKING2: | ||
883 | case WM8962_ANALOGUE_CLOCKING3: | ||
884 | case WM8962_PLL_SOFTWARE_RESET: | ||
885 | case WM8962_PLL2: | ||
886 | case WM8962_PLL_4: | ||
887 | case WM8962_PLL_9: | ||
888 | case WM8962_PLL_10: | ||
889 | case WM8962_PLL_11: | ||
890 | case WM8962_PLL_12: | ||
891 | case WM8962_PLL_13: | ||
892 | case WM8962_PLL_14: | ||
893 | case WM8962_PLL_15: | ||
894 | case WM8962_PLL_16: | ||
895 | case WM8962_FLL_CONTROL_1: | ||
896 | case WM8962_FLL_CONTROL_2: | ||
897 | case WM8962_FLL_CONTROL_3: | ||
898 | case WM8962_FLL_CONTROL_5: | ||
899 | case WM8962_FLL_CONTROL_6: | ||
900 | case WM8962_FLL_CONTROL_7: | ||
901 | case WM8962_FLL_CONTROL_8: | ||
902 | case WM8962_GENERAL_TEST_1: | ||
903 | case WM8962_DF1: | ||
904 | case WM8962_DF2: | ||
905 | case WM8962_DF3: | ||
906 | case WM8962_DF4: | ||
907 | case WM8962_DF5: | ||
908 | case WM8962_DF6: | ||
909 | case WM8962_DF7: | ||
910 | case WM8962_LHPF1: | ||
911 | case WM8962_LHPF2: | ||
912 | case WM8962_THREED1: | ||
913 | case WM8962_THREED2: | ||
914 | case WM8962_THREED3: | ||
915 | case WM8962_THREED4: | ||
916 | case WM8962_DRC_1: | ||
917 | case WM8962_DRC_2: | ||
918 | case WM8962_DRC_3: | ||
919 | case WM8962_DRC_4: | ||
920 | case WM8962_DRC_5: | ||
921 | case WM8962_TLOOPBACK: | ||
922 | case WM8962_EQ1: | ||
923 | case WM8962_EQ2: | ||
924 | case WM8962_EQ3: | ||
925 | case WM8962_EQ4: | ||
926 | case WM8962_EQ5: | ||
927 | case WM8962_EQ6: | ||
928 | case WM8962_EQ7: | ||
929 | case WM8962_EQ8: | ||
930 | case WM8962_EQ9: | ||
931 | case WM8962_EQ10: | ||
932 | case WM8962_EQ11: | ||
933 | case WM8962_EQ12: | ||
934 | case WM8962_EQ13: | ||
935 | case WM8962_EQ14: | ||
936 | case WM8962_EQ15: | ||
937 | case WM8962_EQ16: | ||
938 | case WM8962_EQ17: | ||
939 | case WM8962_EQ18: | ||
940 | case WM8962_EQ19: | ||
941 | case WM8962_EQ20: | ||
942 | case WM8962_EQ21: | ||
943 | case WM8962_EQ22: | ||
944 | case WM8962_EQ23: | ||
945 | case WM8962_EQ24: | ||
946 | case WM8962_EQ25: | ||
947 | case WM8962_EQ26: | ||
948 | case WM8962_EQ27: | ||
949 | case WM8962_EQ28: | ||
950 | case WM8962_EQ29: | ||
951 | case WM8962_EQ30: | ||
952 | case WM8962_EQ31: | ||
953 | case WM8962_EQ32: | ||
954 | case WM8962_EQ33: | ||
955 | case WM8962_EQ34: | ||
956 | case WM8962_EQ35: | ||
957 | case WM8962_EQ36: | ||
958 | case WM8962_EQ37: | ||
959 | case WM8962_EQ38: | ||
960 | case WM8962_EQ39: | ||
961 | case WM8962_EQ40: | ||
962 | case WM8962_EQ41: | ||
963 | case WM8962_GPIO_BASE: | ||
964 | case WM8962_GPIO_2: | ||
965 | case WM8962_GPIO_3: | ||
966 | case WM8962_GPIO_5: | ||
967 | case WM8962_GPIO_6: | ||
968 | case WM8962_INTERRUPT_STATUS_1: | ||
969 | case WM8962_INTERRUPT_STATUS_2: | ||
970 | case WM8962_INTERRUPT_STATUS_1_MASK: | ||
971 | case WM8962_INTERRUPT_STATUS_2_MASK: | ||
972 | case WM8962_INTERRUPT_CONTROL: | ||
973 | case WM8962_IRQ_DEBOUNCE: | ||
974 | case WM8962_MICINT_SOURCE_POL: | ||
975 | case WM8962_DSP2_POWER_MANAGEMENT: | ||
976 | case WM8962_DSP2_EXECCONTROL: | ||
977 | case WM8962_DSP2_INSTRUCTION_RAM_0: | ||
978 | case WM8962_DSP2_ADDRESS_RAM_2: | ||
979 | case WM8962_DSP2_ADDRESS_RAM_1: | ||
980 | case WM8962_DSP2_ADDRESS_RAM_0: | ||
981 | case WM8962_DSP2_DATA1_RAM_1: | ||
982 | case WM8962_DSP2_DATA1_RAM_0: | ||
983 | case WM8962_DSP2_DATA2_RAM_1: | ||
984 | case WM8962_DSP2_DATA2_RAM_0: | ||
985 | case WM8962_DSP2_DATA3_RAM_1: | ||
986 | case WM8962_DSP2_DATA3_RAM_0: | ||
987 | case WM8962_DSP2_COEFF_RAM_0: | ||
988 | case WM8962_RETUNEADC_SHARED_COEFF_1: | ||
989 | case WM8962_RETUNEADC_SHARED_COEFF_0: | ||
990 | case WM8962_RETUNEDAC_SHARED_COEFF_1: | ||
991 | case WM8962_RETUNEDAC_SHARED_COEFF_0: | ||
992 | case WM8962_SOUNDSTAGE_ENABLES_1: | ||
993 | case WM8962_SOUNDSTAGE_ENABLES_0: | ||
994 | case WM8962_HDBASS_AI_1: | ||
995 | case WM8962_HDBASS_AI_0: | ||
996 | case WM8962_HDBASS_AR_1: | ||
997 | case WM8962_HDBASS_AR_0: | ||
998 | case WM8962_HDBASS_B_1: | ||
999 | case WM8962_HDBASS_B_0: | ||
1000 | case WM8962_HDBASS_K_1: | ||
1001 | case WM8962_HDBASS_K_0: | ||
1002 | case WM8962_HDBASS_N1_1: | ||
1003 | case WM8962_HDBASS_N1_0: | ||
1004 | case WM8962_HDBASS_N2_1: | ||
1005 | case WM8962_HDBASS_N2_0: | ||
1006 | case WM8962_HDBASS_N3_1: | ||
1007 | case WM8962_HDBASS_N3_0: | ||
1008 | case WM8962_HDBASS_N4_1: | ||
1009 | case WM8962_HDBASS_N4_0: | ||
1010 | case WM8962_HDBASS_N5_1: | ||
1011 | case WM8962_HDBASS_N5_0: | ||
1012 | case WM8962_HDBASS_X1_1: | ||
1013 | case WM8962_HDBASS_X1_0: | ||
1014 | case WM8962_HDBASS_X2_1: | ||
1015 | case WM8962_HDBASS_X2_0: | ||
1016 | case WM8962_HDBASS_X3_1: | ||
1017 | case WM8962_HDBASS_X3_0: | ||
1018 | case WM8962_HDBASS_ATK_1: | ||
1019 | case WM8962_HDBASS_ATK_0: | ||
1020 | case WM8962_HDBASS_DCY_1: | ||
1021 | case WM8962_HDBASS_DCY_0: | ||
1022 | case WM8962_HDBASS_PG_1: | ||
1023 | case WM8962_HDBASS_PG_0: | ||
1024 | case WM8962_HPF_C_1: | ||
1025 | case WM8962_HPF_C_0: | ||
1026 | case WM8962_ADCL_RETUNE_C1_1: | ||
1027 | case WM8962_ADCL_RETUNE_C1_0: | ||
1028 | case WM8962_ADCL_RETUNE_C2_1: | ||
1029 | case WM8962_ADCL_RETUNE_C2_0: | ||
1030 | case WM8962_ADCL_RETUNE_C3_1: | ||
1031 | case WM8962_ADCL_RETUNE_C3_0: | ||
1032 | case WM8962_ADCL_RETUNE_C4_1: | ||
1033 | case WM8962_ADCL_RETUNE_C4_0: | ||
1034 | case WM8962_ADCL_RETUNE_C5_1: | ||
1035 | case WM8962_ADCL_RETUNE_C5_0: | ||
1036 | case WM8962_ADCL_RETUNE_C6_1: | ||
1037 | case WM8962_ADCL_RETUNE_C6_0: | ||
1038 | case WM8962_ADCL_RETUNE_C7_1: | ||
1039 | case WM8962_ADCL_RETUNE_C7_0: | ||
1040 | case WM8962_ADCL_RETUNE_C8_1: | ||
1041 | case WM8962_ADCL_RETUNE_C8_0: | ||
1042 | case WM8962_ADCL_RETUNE_C9_1: | ||
1043 | case WM8962_ADCL_RETUNE_C9_0: | ||
1044 | case WM8962_ADCL_RETUNE_C10_1: | ||
1045 | case WM8962_ADCL_RETUNE_C10_0: | ||
1046 | case WM8962_ADCL_RETUNE_C11_1: | ||
1047 | case WM8962_ADCL_RETUNE_C11_0: | ||
1048 | case WM8962_ADCL_RETUNE_C12_1: | ||
1049 | case WM8962_ADCL_RETUNE_C12_0: | ||
1050 | case WM8962_ADCL_RETUNE_C13_1: | ||
1051 | case WM8962_ADCL_RETUNE_C13_0: | ||
1052 | case WM8962_ADCL_RETUNE_C14_1: | ||
1053 | case WM8962_ADCL_RETUNE_C14_0: | ||
1054 | case WM8962_ADCL_RETUNE_C15_1: | ||
1055 | case WM8962_ADCL_RETUNE_C15_0: | ||
1056 | case WM8962_ADCL_RETUNE_C16_1: | ||
1057 | case WM8962_ADCL_RETUNE_C16_0: | ||
1058 | case WM8962_ADCL_RETUNE_C17_1: | ||
1059 | case WM8962_ADCL_RETUNE_C17_0: | ||
1060 | case WM8962_ADCL_RETUNE_C18_1: | ||
1061 | case WM8962_ADCL_RETUNE_C18_0: | ||
1062 | case WM8962_ADCL_RETUNE_C19_1: | ||
1063 | case WM8962_ADCL_RETUNE_C19_0: | ||
1064 | case WM8962_ADCL_RETUNE_C20_1: | ||
1065 | case WM8962_ADCL_RETUNE_C20_0: | ||
1066 | case WM8962_ADCL_RETUNE_C21_1: | ||
1067 | case WM8962_ADCL_RETUNE_C21_0: | ||
1068 | case WM8962_ADCL_RETUNE_C22_1: | ||
1069 | case WM8962_ADCL_RETUNE_C22_0: | ||
1070 | case WM8962_ADCL_RETUNE_C23_1: | ||
1071 | case WM8962_ADCL_RETUNE_C23_0: | ||
1072 | case WM8962_ADCL_RETUNE_C24_1: | ||
1073 | case WM8962_ADCL_RETUNE_C24_0: | ||
1074 | case WM8962_ADCL_RETUNE_C25_1: | ||
1075 | case WM8962_ADCL_RETUNE_C25_0: | ||
1076 | case WM8962_ADCL_RETUNE_C26_1: | ||
1077 | case WM8962_ADCL_RETUNE_C26_0: | ||
1078 | case WM8962_ADCL_RETUNE_C27_1: | ||
1079 | case WM8962_ADCL_RETUNE_C27_0: | ||
1080 | case WM8962_ADCL_RETUNE_C28_1: | ||
1081 | case WM8962_ADCL_RETUNE_C28_0: | ||
1082 | case WM8962_ADCL_RETUNE_C29_1: | ||
1083 | case WM8962_ADCL_RETUNE_C29_0: | ||
1084 | case WM8962_ADCL_RETUNE_C30_1: | ||
1085 | case WM8962_ADCL_RETUNE_C30_0: | ||
1086 | case WM8962_ADCL_RETUNE_C31_1: | ||
1087 | case WM8962_ADCL_RETUNE_C31_0: | ||
1088 | case WM8962_ADCL_RETUNE_C32_1: | ||
1089 | case WM8962_ADCL_RETUNE_C32_0: | ||
1090 | case WM8962_RETUNEADC_PG2_1: | ||
1091 | case WM8962_RETUNEADC_PG2_0: | ||
1092 | case WM8962_RETUNEADC_PG_1: | ||
1093 | case WM8962_RETUNEADC_PG_0: | ||
1094 | case WM8962_ADCR_RETUNE_C1_1: | ||
1095 | case WM8962_ADCR_RETUNE_C1_0: | ||
1096 | case WM8962_ADCR_RETUNE_C2_1: | ||
1097 | case WM8962_ADCR_RETUNE_C2_0: | ||
1098 | case WM8962_ADCR_RETUNE_C3_1: | ||
1099 | case WM8962_ADCR_RETUNE_C3_0: | ||
1100 | case WM8962_ADCR_RETUNE_C4_1: | ||
1101 | case WM8962_ADCR_RETUNE_C4_0: | ||
1102 | case WM8962_ADCR_RETUNE_C5_1: | ||
1103 | case WM8962_ADCR_RETUNE_C5_0: | ||
1104 | case WM8962_ADCR_RETUNE_C6_1: | ||
1105 | case WM8962_ADCR_RETUNE_C6_0: | ||
1106 | case WM8962_ADCR_RETUNE_C7_1: | ||
1107 | case WM8962_ADCR_RETUNE_C7_0: | ||
1108 | case WM8962_ADCR_RETUNE_C8_1: | ||
1109 | case WM8962_ADCR_RETUNE_C8_0: | ||
1110 | case WM8962_ADCR_RETUNE_C9_1: | ||
1111 | case WM8962_ADCR_RETUNE_C9_0: | ||
1112 | case WM8962_ADCR_RETUNE_C10_1: | ||
1113 | case WM8962_ADCR_RETUNE_C10_0: | ||
1114 | case WM8962_ADCR_RETUNE_C11_1: | ||
1115 | case WM8962_ADCR_RETUNE_C11_0: | ||
1116 | case WM8962_ADCR_RETUNE_C12_1: | ||
1117 | case WM8962_ADCR_RETUNE_C12_0: | ||
1118 | case WM8962_ADCR_RETUNE_C13_1: | ||
1119 | case WM8962_ADCR_RETUNE_C13_0: | ||
1120 | case WM8962_ADCR_RETUNE_C14_1: | ||
1121 | case WM8962_ADCR_RETUNE_C14_0: | ||
1122 | case WM8962_ADCR_RETUNE_C15_1: | ||
1123 | case WM8962_ADCR_RETUNE_C15_0: | ||
1124 | case WM8962_ADCR_RETUNE_C16_1: | ||
1125 | case WM8962_ADCR_RETUNE_C16_0: | ||
1126 | case WM8962_ADCR_RETUNE_C17_1: | ||
1127 | case WM8962_ADCR_RETUNE_C17_0: | ||
1128 | case WM8962_ADCR_RETUNE_C18_1: | ||
1129 | case WM8962_ADCR_RETUNE_C18_0: | ||
1130 | case WM8962_ADCR_RETUNE_C19_1: | ||
1131 | case WM8962_ADCR_RETUNE_C19_0: | ||
1132 | case WM8962_ADCR_RETUNE_C20_1: | ||
1133 | case WM8962_ADCR_RETUNE_C20_0: | ||
1134 | case WM8962_ADCR_RETUNE_C21_1: | ||
1135 | case WM8962_ADCR_RETUNE_C21_0: | ||
1136 | case WM8962_ADCR_RETUNE_C22_1: | ||
1137 | case WM8962_ADCR_RETUNE_C22_0: | ||
1138 | case WM8962_ADCR_RETUNE_C23_1: | ||
1139 | case WM8962_ADCR_RETUNE_C23_0: | ||
1140 | case WM8962_ADCR_RETUNE_C24_1: | ||
1141 | case WM8962_ADCR_RETUNE_C24_0: | ||
1142 | case WM8962_ADCR_RETUNE_C25_1: | ||
1143 | case WM8962_ADCR_RETUNE_C25_0: | ||
1144 | case WM8962_ADCR_RETUNE_C26_1: | ||
1145 | case WM8962_ADCR_RETUNE_C26_0: | ||
1146 | case WM8962_ADCR_RETUNE_C27_1: | ||
1147 | case WM8962_ADCR_RETUNE_C27_0: | ||
1148 | case WM8962_ADCR_RETUNE_C28_1: | ||
1149 | case WM8962_ADCR_RETUNE_C28_0: | ||
1150 | case WM8962_ADCR_RETUNE_C29_1: | ||
1151 | case WM8962_ADCR_RETUNE_C29_0: | ||
1152 | case WM8962_ADCR_RETUNE_C30_1: | ||
1153 | case WM8962_ADCR_RETUNE_C30_0: | ||
1154 | case WM8962_ADCR_RETUNE_C31_1: | ||
1155 | case WM8962_ADCR_RETUNE_C31_0: | ||
1156 | case WM8962_ADCR_RETUNE_C32_1: | ||
1157 | case WM8962_ADCR_RETUNE_C32_0: | ||
1158 | case WM8962_DACL_RETUNE_C1_1: | ||
1159 | case WM8962_DACL_RETUNE_C1_0: | ||
1160 | case WM8962_DACL_RETUNE_C2_1: | ||
1161 | case WM8962_DACL_RETUNE_C2_0: | ||
1162 | case WM8962_DACL_RETUNE_C3_1: | ||
1163 | case WM8962_DACL_RETUNE_C3_0: | ||
1164 | case WM8962_DACL_RETUNE_C4_1: | ||
1165 | case WM8962_DACL_RETUNE_C4_0: | ||
1166 | case WM8962_DACL_RETUNE_C5_1: | ||
1167 | case WM8962_DACL_RETUNE_C5_0: | ||
1168 | case WM8962_DACL_RETUNE_C6_1: | ||
1169 | case WM8962_DACL_RETUNE_C6_0: | ||
1170 | case WM8962_DACL_RETUNE_C7_1: | ||
1171 | case WM8962_DACL_RETUNE_C7_0: | ||
1172 | case WM8962_DACL_RETUNE_C8_1: | ||
1173 | case WM8962_DACL_RETUNE_C8_0: | ||
1174 | case WM8962_DACL_RETUNE_C9_1: | ||
1175 | case WM8962_DACL_RETUNE_C9_0: | ||
1176 | case WM8962_DACL_RETUNE_C10_1: | ||
1177 | case WM8962_DACL_RETUNE_C10_0: | ||
1178 | case WM8962_DACL_RETUNE_C11_1: | ||
1179 | case WM8962_DACL_RETUNE_C11_0: | ||
1180 | case WM8962_DACL_RETUNE_C12_1: | ||
1181 | case WM8962_DACL_RETUNE_C12_0: | ||
1182 | case WM8962_DACL_RETUNE_C13_1: | ||
1183 | case WM8962_DACL_RETUNE_C13_0: | ||
1184 | case WM8962_DACL_RETUNE_C14_1: | ||
1185 | case WM8962_DACL_RETUNE_C14_0: | ||
1186 | case WM8962_DACL_RETUNE_C15_1: | ||
1187 | case WM8962_DACL_RETUNE_C15_0: | ||
1188 | case WM8962_DACL_RETUNE_C16_1: | ||
1189 | case WM8962_DACL_RETUNE_C16_0: | ||
1190 | case WM8962_DACL_RETUNE_C17_1: | ||
1191 | case WM8962_DACL_RETUNE_C17_0: | ||
1192 | case WM8962_DACL_RETUNE_C18_1: | ||
1193 | case WM8962_DACL_RETUNE_C18_0: | ||
1194 | case WM8962_DACL_RETUNE_C19_1: | ||
1195 | case WM8962_DACL_RETUNE_C19_0: | ||
1196 | case WM8962_DACL_RETUNE_C20_1: | ||
1197 | case WM8962_DACL_RETUNE_C20_0: | ||
1198 | case WM8962_DACL_RETUNE_C21_1: | ||
1199 | case WM8962_DACL_RETUNE_C21_0: | ||
1200 | case WM8962_DACL_RETUNE_C22_1: | ||
1201 | case WM8962_DACL_RETUNE_C22_0: | ||
1202 | case WM8962_DACL_RETUNE_C23_1: | ||
1203 | case WM8962_DACL_RETUNE_C23_0: | ||
1204 | case WM8962_DACL_RETUNE_C24_1: | ||
1205 | case WM8962_DACL_RETUNE_C24_0: | ||
1206 | case WM8962_DACL_RETUNE_C25_1: | ||
1207 | case WM8962_DACL_RETUNE_C25_0: | ||
1208 | case WM8962_DACL_RETUNE_C26_1: | ||
1209 | case WM8962_DACL_RETUNE_C26_0: | ||
1210 | case WM8962_DACL_RETUNE_C27_1: | ||
1211 | case WM8962_DACL_RETUNE_C27_0: | ||
1212 | case WM8962_DACL_RETUNE_C28_1: | ||
1213 | case WM8962_DACL_RETUNE_C28_0: | ||
1214 | case WM8962_DACL_RETUNE_C29_1: | ||
1215 | case WM8962_DACL_RETUNE_C29_0: | ||
1216 | case WM8962_DACL_RETUNE_C30_1: | ||
1217 | case WM8962_DACL_RETUNE_C30_0: | ||
1218 | case WM8962_DACL_RETUNE_C31_1: | ||
1219 | case WM8962_DACL_RETUNE_C31_0: | ||
1220 | case WM8962_DACL_RETUNE_C32_1: | ||
1221 | case WM8962_DACL_RETUNE_C32_0: | ||
1222 | case WM8962_RETUNEDAC_PG2_1: | ||
1223 | case WM8962_RETUNEDAC_PG2_0: | ||
1224 | case WM8962_RETUNEDAC_PG_1: | ||
1225 | case WM8962_RETUNEDAC_PG_0: | ||
1226 | case WM8962_DACR_RETUNE_C1_1: | ||
1227 | case WM8962_DACR_RETUNE_C1_0: | ||
1228 | case WM8962_DACR_RETUNE_C2_1: | ||
1229 | case WM8962_DACR_RETUNE_C2_0: | ||
1230 | case WM8962_DACR_RETUNE_C3_1: | ||
1231 | case WM8962_DACR_RETUNE_C3_0: | ||
1232 | case WM8962_DACR_RETUNE_C4_1: | ||
1233 | case WM8962_DACR_RETUNE_C4_0: | ||
1234 | case WM8962_DACR_RETUNE_C5_1: | ||
1235 | case WM8962_DACR_RETUNE_C5_0: | ||
1236 | case WM8962_DACR_RETUNE_C6_1: | ||
1237 | case WM8962_DACR_RETUNE_C6_0: | ||
1238 | case WM8962_DACR_RETUNE_C7_1: | ||
1239 | case WM8962_DACR_RETUNE_C7_0: | ||
1240 | case WM8962_DACR_RETUNE_C8_1: | ||
1241 | case WM8962_DACR_RETUNE_C8_0: | ||
1242 | case WM8962_DACR_RETUNE_C9_1: | ||
1243 | case WM8962_DACR_RETUNE_C9_0: | ||
1244 | case WM8962_DACR_RETUNE_C10_1: | ||
1245 | case WM8962_DACR_RETUNE_C10_0: | ||
1246 | case WM8962_DACR_RETUNE_C11_1: | ||
1247 | case WM8962_DACR_RETUNE_C11_0: | ||
1248 | case WM8962_DACR_RETUNE_C12_1: | ||
1249 | case WM8962_DACR_RETUNE_C12_0: | ||
1250 | case WM8962_DACR_RETUNE_C13_1: | ||
1251 | case WM8962_DACR_RETUNE_C13_0: | ||
1252 | case WM8962_DACR_RETUNE_C14_1: | ||
1253 | case WM8962_DACR_RETUNE_C14_0: | ||
1254 | case WM8962_DACR_RETUNE_C15_1: | ||
1255 | case WM8962_DACR_RETUNE_C15_0: | ||
1256 | case WM8962_DACR_RETUNE_C16_1: | ||
1257 | case WM8962_DACR_RETUNE_C16_0: | ||
1258 | case WM8962_DACR_RETUNE_C17_1: | ||
1259 | case WM8962_DACR_RETUNE_C17_0: | ||
1260 | case WM8962_DACR_RETUNE_C18_1: | ||
1261 | case WM8962_DACR_RETUNE_C18_0: | ||
1262 | case WM8962_DACR_RETUNE_C19_1: | ||
1263 | case WM8962_DACR_RETUNE_C19_0: | ||
1264 | case WM8962_DACR_RETUNE_C20_1: | ||
1265 | case WM8962_DACR_RETUNE_C20_0: | ||
1266 | case WM8962_DACR_RETUNE_C21_1: | ||
1267 | case WM8962_DACR_RETUNE_C21_0: | ||
1268 | case WM8962_DACR_RETUNE_C22_1: | ||
1269 | case WM8962_DACR_RETUNE_C22_0: | ||
1270 | case WM8962_DACR_RETUNE_C23_1: | ||
1271 | case WM8962_DACR_RETUNE_C23_0: | ||
1272 | case WM8962_DACR_RETUNE_C24_1: | ||
1273 | case WM8962_DACR_RETUNE_C24_0: | ||
1274 | case WM8962_DACR_RETUNE_C25_1: | ||
1275 | case WM8962_DACR_RETUNE_C25_0: | ||
1276 | case WM8962_DACR_RETUNE_C26_1: | ||
1277 | case WM8962_DACR_RETUNE_C26_0: | ||
1278 | case WM8962_DACR_RETUNE_C27_1: | ||
1279 | case WM8962_DACR_RETUNE_C27_0: | ||
1280 | case WM8962_DACR_RETUNE_C28_1: | ||
1281 | case WM8962_DACR_RETUNE_C28_0: | ||
1282 | case WM8962_DACR_RETUNE_C29_1: | ||
1283 | case WM8962_DACR_RETUNE_C29_0: | ||
1284 | case WM8962_DACR_RETUNE_C30_1: | ||
1285 | case WM8962_DACR_RETUNE_C30_0: | ||
1286 | case WM8962_DACR_RETUNE_C31_1: | ||
1287 | case WM8962_DACR_RETUNE_C31_0: | ||
1288 | case WM8962_DACR_RETUNE_C32_1: | ||
1289 | case WM8962_DACR_RETUNE_C32_0: | ||
1290 | case WM8962_VSS_XHD2_1: | ||
1291 | case WM8962_VSS_XHD2_0: | ||
1292 | case WM8962_VSS_XHD3_1: | ||
1293 | case WM8962_VSS_XHD3_0: | ||
1294 | case WM8962_VSS_XHN1_1: | ||
1295 | case WM8962_VSS_XHN1_0: | ||
1296 | case WM8962_VSS_XHN2_1: | ||
1297 | case WM8962_VSS_XHN2_0: | ||
1298 | case WM8962_VSS_XHN3_1: | ||
1299 | case WM8962_VSS_XHN3_0: | ||
1300 | case WM8962_VSS_XLA_1: | ||
1301 | case WM8962_VSS_XLA_0: | ||
1302 | case WM8962_VSS_XLB_1: | ||
1303 | case WM8962_VSS_XLB_0: | ||
1304 | case WM8962_VSS_XLG_1: | ||
1305 | case WM8962_VSS_XLG_0: | ||
1306 | case WM8962_VSS_PG2_1: | ||
1307 | case WM8962_VSS_PG2_0: | ||
1308 | case WM8962_VSS_PG_1: | ||
1309 | case WM8962_VSS_PG_0: | ||
1310 | case WM8962_VSS_XTD1_1: | ||
1311 | case WM8962_VSS_XTD1_0: | ||
1312 | case WM8962_VSS_XTD2_1: | ||
1313 | case WM8962_VSS_XTD2_0: | ||
1314 | case WM8962_VSS_XTD3_1: | ||
1315 | case WM8962_VSS_XTD3_0: | ||
1316 | case WM8962_VSS_XTD4_1: | ||
1317 | case WM8962_VSS_XTD4_0: | ||
1318 | case WM8962_VSS_XTD5_1: | ||
1319 | case WM8962_VSS_XTD5_0: | ||
1320 | case WM8962_VSS_XTD6_1: | ||
1321 | case WM8962_VSS_XTD6_0: | ||
1322 | case WM8962_VSS_XTD7_1: | ||
1323 | case WM8962_VSS_XTD7_0: | ||
1324 | case WM8962_VSS_XTD8_1: | ||
1325 | case WM8962_VSS_XTD8_0: | ||
1326 | case WM8962_VSS_XTD9_1: | ||
1327 | case WM8962_VSS_XTD9_0: | ||
1328 | case WM8962_VSS_XTD10_1: | ||
1329 | case WM8962_VSS_XTD10_0: | ||
1330 | case WM8962_VSS_XTD11_1: | ||
1331 | case WM8962_VSS_XTD11_0: | ||
1332 | case WM8962_VSS_XTD12_1: | ||
1333 | case WM8962_VSS_XTD12_0: | ||
1334 | case WM8962_VSS_XTD13_1: | ||
1335 | case WM8962_VSS_XTD13_0: | ||
1336 | case WM8962_VSS_XTD14_1: | ||
1337 | case WM8962_VSS_XTD14_0: | ||
1338 | case WM8962_VSS_XTD15_1: | ||
1339 | case WM8962_VSS_XTD15_0: | ||
1340 | case WM8962_VSS_XTD16_1: | ||
1341 | case WM8962_VSS_XTD16_0: | ||
1342 | case WM8962_VSS_XTD17_1: | ||
1343 | case WM8962_VSS_XTD17_0: | ||
1344 | case WM8962_VSS_XTD18_1: | ||
1345 | case WM8962_VSS_XTD18_0: | ||
1346 | case WM8962_VSS_XTD19_1: | ||
1347 | case WM8962_VSS_XTD19_0: | ||
1348 | case WM8962_VSS_XTD20_1: | ||
1349 | case WM8962_VSS_XTD20_0: | ||
1350 | case WM8962_VSS_XTD21_1: | ||
1351 | case WM8962_VSS_XTD21_0: | ||
1352 | case WM8962_VSS_XTD22_1: | ||
1353 | case WM8962_VSS_XTD22_0: | ||
1354 | case WM8962_VSS_XTD23_1: | ||
1355 | case WM8962_VSS_XTD23_0: | ||
1356 | case WM8962_VSS_XTD24_1: | ||
1357 | case WM8962_VSS_XTD24_0: | ||
1358 | case WM8962_VSS_XTD25_1: | ||
1359 | case WM8962_VSS_XTD25_0: | ||
1360 | case WM8962_VSS_XTD26_1: | ||
1361 | case WM8962_VSS_XTD26_0: | ||
1362 | case WM8962_VSS_XTD27_1: | ||
1363 | case WM8962_VSS_XTD27_0: | ||
1364 | case WM8962_VSS_XTD28_1: | ||
1365 | case WM8962_VSS_XTD28_0: | ||
1366 | case WM8962_VSS_XTD29_1: | ||
1367 | case WM8962_VSS_XTD29_0: | ||
1368 | case WM8962_VSS_XTD30_1: | ||
1369 | case WM8962_VSS_XTD30_0: | ||
1370 | case WM8962_VSS_XTD31_1: | ||
1371 | case WM8962_VSS_XTD31_0: | ||
1372 | case WM8962_VSS_XTD32_1: | ||
1373 | case WM8962_VSS_XTD32_0: | ||
1374 | case WM8962_VSS_XTS1_1: | ||
1375 | case WM8962_VSS_XTS1_0: | ||
1376 | case WM8962_VSS_XTS2_1: | ||
1377 | case WM8962_VSS_XTS2_0: | ||
1378 | case WM8962_VSS_XTS3_1: | ||
1379 | case WM8962_VSS_XTS3_0: | ||
1380 | case WM8962_VSS_XTS4_1: | ||
1381 | case WM8962_VSS_XTS4_0: | ||
1382 | case WM8962_VSS_XTS5_1: | ||
1383 | case WM8962_VSS_XTS5_0: | ||
1384 | case WM8962_VSS_XTS6_1: | ||
1385 | case WM8962_VSS_XTS6_0: | ||
1386 | case WM8962_VSS_XTS7_1: | ||
1387 | case WM8962_VSS_XTS7_0: | ||
1388 | case WM8962_VSS_XTS8_1: | ||
1389 | case WM8962_VSS_XTS8_0: | ||
1390 | case WM8962_VSS_XTS9_1: | ||
1391 | case WM8962_VSS_XTS9_0: | ||
1392 | case WM8962_VSS_XTS10_1: | ||
1393 | case WM8962_VSS_XTS10_0: | ||
1394 | case WM8962_VSS_XTS11_1: | ||
1395 | case WM8962_VSS_XTS11_0: | ||
1396 | case WM8962_VSS_XTS12_1: | ||
1397 | case WM8962_VSS_XTS12_0: | ||
1398 | case WM8962_VSS_XTS13_1: | ||
1399 | case WM8962_VSS_XTS13_0: | ||
1400 | case WM8962_VSS_XTS14_1: | ||
1401 | case WM8962_VSS_XTS14_0: | ||
1402 | case WM8962_VSS_XTS15_1: | ||
1403 | case WM8962_VSS_XTS15_0: | ||
1404 | case WM8962_VSS_XTS16_1: | ||
1405 | case WM8962_VSS_XTS16_0: | ||
1406 | case WM8962_VSS_XTS17_1: | ||
1407 | case WM8962_VSS_XTS17_0: | ||
1408 | case WM8962_VSS_XTS18_1: | ||
1409 | case WM8962_VSS_XTS18_0: | ||
1410 | case WM8962_VSS_XTS19_1: | ||
1411 | case WM8962_VSS_XTS19_0: | ||
1412 | case WM8962_VSS_XTS20_1: | ||
1413 | case WM8962_VSS_XTS20_0: | ||
1414 | case WM8962_VSS_XTS21_1: | ||
1415 | case WM8962_VSS_XTS21_0: | ||
1416 | case WM8962_VSS_XTS22_1: | ||
1417 | case WM8962_VSS_XTS22_0: | ||
1418 | case WM8962_VSS_XTS23_1: | ||
1419 | case WM8962_VSS_XTS23_0: | ||
1420 | case WM8962_VSS_XTS24_1: | ||
1421 | case WM8962_VSS_XTS24_0: | ||
1422 | case WM8962_VSS_XTS25_1: | ||
1423 | case WM8962_VSS_XTS25_0: | ||
1424 | case WM8962_VSS_XTS26_1: | ||
1425 | case WM8962_VSS_XTS26_0: | ||
1426 | case WM8962_VSS_XTS27_1: | ||
1427 | case WM8962_VSS_XTS27_0: | ||
1428 | case WM8962_VSS_XTS28_1: | ||
1429 | case WM8962_VSS_XTS28_0: | ||
1430 | case WM8962_VSS_XTS29_1: | ||
1431 | case WM8962_VSS_XTS29_0: | ||
1432 | case WM8962_VSS_XTS30_1: | ||
1433 | case WM8962_VSS_XTS30_0: | ||
1434 | case WM8962_VSS_XTS31_1: | ||
1435 | case WM8962_VSS_XTS31_0: | ||
1436 | case WM8962_VSS_XTS32_1: | ||
1437 | case WM8962_VSS_XTS32_0: | ||
1438 | return true; | ||
1439 | default: | ||
1440 | return false; | ||
1441 | } | ||
1961 | } | 1442 | } |
1962 | 1443 | ||
1963 | static int wm8962_reset(struct wm8962_priv *wm8962) | 1444 | static int wm8962_reset(struct wm8962_priv *wm8962) |
@@ -2221,6 +1702,8 @@ SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1, | |||
2221 | SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8962_LEFT_DAC_VOLUME, | 1702 | SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8962_LEFT_DAC_VOLUME, |
2222 | WM8962_RIGHT_DAC_VOLUME, 1, 127, 0, digital_tlv), | 1703 | WM8962_RIGHT_DAC_VOLUME, 1, 127, 0, digital_tlv), |
2223 | SOC_SINGLE("DAC High Performance Switch", WM8962_ADC_DAC_CONTROL_2, 0, 1, 0), | 1704 | SOC_SINGLE("DAC High Performance Switch", WM8962_ADC_DAC_CONTROL_2, 0, 1, 0), |
1705 | SOC_SINGLE("DAC L/R Swap Switch", WM8962_AUDIO_INTERFACE_0, 5, 1, 0), | ||
1706 | SOC_SINGLE("ADC L/R Swap Switch", WM8962_AUDIO_INTERFACE_0, 8, 1, 0), | ||
2224 | 1707 | ||
2225 | SOC_SINGLE("ADC High Performance Switch", WM8962_ADDITIONAL_CONTROL_1, | 1708 | SOC_SINGLE("ADC High Performance Switch", WM8962_ADDITIONAL_CONTROL_1, |
2226 | 5, 1, 0), | 1709 | 5, 1, 0), |
@@ -2337,65 +1820,6 @@ SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5, | |||
2337 | 4, 1, 0, inmix_tlv), | 1820 | 4, 1, 0, inmix_tlv), |
2338 | }; | 1821 | }; |
2339 | 1822 | ||
2340 | static int sysclk_event(struct snd_soc_dapm_widget *w, | ||
2341 | struct snd_kcontrol *kcontrol, int event) | ||
2342 | { | ||
2343 | struct snd_soc_codec *codec = w->codec; | ||
2344 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
2345 | unsigned long timeout; | ||
2346 | int src; | ||
2347 | int fll; | ||
2348 | |||
2349 | /* Ignore attempts to run the event during startup */ | ||
2350 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) | ||
2351 | return 0; | ||
2352 | |||
2353 | src = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_SRC_MASK; | ||
2354 | |||
2355 | switch (src) { | ||
2356 | case 0: /* MCLK */ | ||
2357 | fll = 0; | ||
2358 | break; | ||
2359 | case 0x200: /* FLL */ | ||
2360 | fll = 1; | ||
2361 | break; | ||
2362 | default: | ||
2363 | dev_err(codec->dev, "Unknown SYSCLK source %x\n", src); | ||
2364 | return -EINVAL; | ||
2365 | } | ||
2366 | |||
2367 | switch (event) { | ||
2368 | case SND_SOC_DAPM_PRE_PMU: | ||
2369 | if (fll) { | ||
2370 | try_wait_for_completion(&wm8962->fll_lock); | ||
2371 | |||
2372 | snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, | ||
2373 | WM8962_FLL_ENA, WM8962_FLL_ENA); | ||
2374 | |||
2375 | timeout = msecs_to_jiffies(5); | ||
2376 | timeout = wait_for_completion_timeout(&wm8962->fll_lock, | ||
2377 | timeout); | ||
2378 | |||
2379 | if (wm8962->irq && timeout == 0) | ||
2380 | dev_err(codec->dev, | ||
2381 | "Timed out starting FLL\n"); | ||
2382 | } | ||
2383 | break; | ||
2384 | |||
2385 | case SND_SOC_DAPM_POST_PMD: | ||
2386 | if (fll) | ||
2387 | snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, | ||
2388 | WM8962_FLL_ENA, 0); | ||
2389 | break; | ||
2390 | |||
2391 | default: | ||
2392 | BUG(); | ||
2393 | return -EINVAL; | ||
2394 | } | ||
2395 | |||
2396 | return 0; | ||
2397 | } | ||
2398 | |||
2399 | static int cp_event(struct snd_soc_dapm_widget *w, | 1823 | static int cp_event(struct snd_soc_dapm_widget *w, |
2400 | struct snd_kcontrol *kcontrol, int event) | 1824 | struct snd_kcontrol *kcontrol, int event) |
2401 | { | 1825 | { |
@@ -2564,7 +1988,7 @@ static int dsp2_event(struct snd_soc_dapm_widget *w, | |||
2564 | return 0; | 1988 | return 0; |
2565 | } | 1989 | } |
2566 | 1990 | ||
2567 | static const char *st_text[] = { "None", "Right", "Left" }; | 1991 | static const char *st_text[] = { "None", "Left", "Right" }; |
2568 | 1992 | ||
2569 | static const struct soc_enum str_enum = | 1993 | static const struct soc_enum str_enum = |
2570 | SOC_ENUM_SINGLE(WM8962_DAC_DSP_MIXING_1, 2, 3, st_text); | 1994 | SOC_ENUM_SINGLE(WM8962_DAC_DSP_MIXING_1, 2, 3, st_text); |
@@ -2681,8 +2105,7 @@ SND_SOC_DAPM_INPUT("DMICDAT"), | |||
2681 | SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0), | 2105 | SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0), |
2682 | 2106 | ||
2683 | SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0), | 2107 | SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0), |
2684 | SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event, | 2108 | SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, NULL, 0), |
2685 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
2686 | SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event, | 2109 | SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event, |
2687 | SND_SOC_DAPM_POST_PMU), | 2110 | SND_SOC_DAPM_POST_PMU), |
2688 | SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), | 2111 | SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), |
@@ -2796,9 +2219,11 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = { | |||
2796 | 2219 | ||
2797 | { "STL", "Left", "ADCL" }, | 2220 | { "STL", "Left", "ADCL" }, |
2798 | { "STL", "Right", "ADCR" }, | 2221 | { "STL", "Right", "ADCR" }, |
2222 | { "STL", NULL, "Class G" }, | ||
2799 | 2223 | ||
2800 | { "STR", "Left", "ADCL" }, | 2224 | { "STR", "Left", "ADCL" }, |
2801 | { "STR", "Right", "ADCR" }, | 2225 | { "STR", "Right", "ADCR" }, |
2226 | { "STR", NULL, "Class G" }, | ||
2802 | 2227 | ||
2803 | { "DACL", NULL, "SYSCLK" }, | 2228 | { "DACL", NULL, "SYSCLK" }, |
2804 | { "DACL", NULL, "TOCLK" }, | 2229 | { "DACL", NULL, "TOCLK" }, |
@@ -2910,13 +2335,13 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec) | |||
2910 | struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); | 2335 | struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); |
2911 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 2336 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
2912 | 2337 | ||
2913 | snd_soc_add_controls(codec, wm8962_snd_controls, | 2338 | snd_soc_add_codec_controls(codec, wm8962_snd_controls, |
2914 | ARRAY_SIZE(wm8962_snd_controls)); | 2339 | ARRAY_SIZE(wm8962_snd_controls)); |
2915 | if (pdata && pdata->spk_mono) | 2340 | if (pdata && pdata->spk_mono) |
2916 | snd_soc_add_controls(codec, wm8962_spk_mono_controls, | 2341 | snd_soc_add_codec_controls(codec, wm8962_spk_mono_controls, |
2917 | ARRAY_SIZE(wm8962_spk_mono_controls)); | 2342 | ARRAY_SIZE(wm8962_spk_mono_controls)); |
2918 | else | 2343 | else |
2919 | snd_soc_add_controls(codec, wm8962_spk_stereo_controls, | 2344 | snd_soc_add_codec_controls(codec, wm8962_spk_stereo_controls, |
2920 | ARRAY_SIZE(wm8962_spk_stereo_controls)); | 2345 | ARRAY_SIZE(wm8962_spk_stereo_controls)); |
2921 | 2346 | ||
2922 | 2347 | ||
@@ -2950,7 +2375,7 @@ static const int bclk_divs[] = { | |||
2950 | }; | 2375 | }; |
2951 | 2376 | ||
2952 | static const int sysclk_rates[] = { | 2377 | static const int sysclk_rates[] = { |
2953 | 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536, | 2378 | 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536, 3072, 6144 |
2954 | }; | 2379 | }; |
2955 | 2380 | ||
2956 | static void wm8962_configure_bclk(struct snd_soc_codec *codec) | 2381 | static void wm8962_configure_bclk(struct snd_soc_codec *codec) |
@@ -2984,6 +2409,8 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec) | |||
2984 | return; | 2409 | return; |
2985 | } | 2410 | } |
2986 | 2411 | ||
2412 | dev_dbg(codec->dev, "Selected sysclk ratio %d\n", sysclk_rates[i]); | ||
2413 | |||
2987 | snd_soc_update_bits(codec, WM8962_CLOCKING_4, | 2414 | snd_soc_update_bits(codec, WM8962_CLOCKING_4, |
2988 | WM8962_SYSCLK_RATE_MASK, clocking4); | 2415 | WM8962_SYSCLK_RATE_MASK, clocking4); |
2989 | 2416 | ||
@@ -3042,9 +2469,6 @@ static void wm8962_configure_bclk(struct snd_soc_codec *codec) | |||
3042 | static int wm8962_set_bias_level(struct snd_soc_codec *codec, | 2469 | static int wm8962_set_bias_level(struct snd_soc_codec *codec, |
3043 | enum snd_soc_bias_level level) | 2470 | enum snd_soc_bias_level level) |
3044 | { | 2471 | { |
3045 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
3046 | int ret; | ||
3047 | |||
3048 | if (level == codec->dapm.bias_level) | 2472 | if (level == codec->dapm.bias_level) |
3049 | return 0; | 2473 | return 0; |
3050 | 2474 | ||
@@ -3061,51 +2485,15 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec, | |||
3061 | break; | 2485 | break; |
3062 | 2486 | ||
3063 | case SND_SOC_BIAS_STANDBY: | 2487 | case SND_SOC_BIAS_STANDBY: |
3064 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
3065 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies), | ||
3066 | wm8962->supplies); | ||
3067 | if (ret != 0) { | ||
3068 | dev_err(codec->dev, | ||
3069 | "Failed to enable supplies: %d\n", | ||
3070 | ret); | ||
3071 | return ret; | ||
3072 | } | ||
3073 | |||
3074 | regcache_cache_only(wm8962->regmap, false); | ||
3075 | regcache_sync(wm8962->regmap); | ||
3076 | |||
3077 | snd_soc_update_bits(codec, WM8962_ANTI_POP, | ||
3078 | WM8962_STARTUP_BIAS_ENA | | ||
3079 | WM8962_VMID_BUF_ENA, | ||
3080 | WM8962_STARTUP_BIAS_ENA | | ||
3081 | WM8962_VMID_BUF_ENA); | ||
3082 | |||
3083 | /* Bias enable at 2*50k for ramp */ | ||
3084 | snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, | ||
3085 | WM8962_VMID_SEL_MASK | | ||
3086 | WM8962_BIAS_ENA, | ||
3087 | WM8962_BIAS_ENA | 0x180); | ||
3088 | |||
3089 | msleep(5); | ||
3090 | } | ||
3091 | |||
3092 | /* VMID 2*250k */ | 2488 | /* VMID 2*250k */ |
3093 | snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, | 2489 | snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, |
3094 | WM8962_VMID_SEL_MASK, 0x100); | 2490 | WM8962_VMID_SEL_MASK, 0x100); |
3095 | break; | 2491 | break; |
3096 | 2492 | ||
3097 | case SND_SOC_BIAS_OFF: | 2493 | case SND_SOC_BIAS_OFF: |
3098 | snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, | ||
3099 | WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0); | ||
3100 | |||
3101 | snd_soc_update_bits(codec, WM8962_ANTI_POP, | ||
3102 | WM8962_STARTUP_BIAS_ENA | | ||
3103 | WM8962_VMID_BUF_ENA, 0); | ||
3104 | |||
3105 | regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), | ||
3106 | wm8962->supplies); | ||
3107 | break; | 2494 | break; |
3108 | } | 2495 | } |
2496 | |||
3109 | codec->dapm.bias_level = level; | 2497 | codec->dapm.bias_level = level; |
3110 | return 0; | 2498 | return 0; |
3111 | } | 2499 | } |
@@ -3139,6 +2527,9 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream, | |||
3139 | int adctl3 = 0; | 2527 | int adctl3 = 0; |
3140 | 2528 | ||
3141 | wm8962->bclk = snd_soc_params_to_bclk(params); | 2529 | wm8962->bclk = snd_soc_params_to_bclk(params); |
2530 | if (params_channels(params) == 1) | ||
2531 | wm8962->bclk *= 2; | ||
2532 | |||
3142 | wm8962->lrclk = params_rate(params); | 2533 | wm8962->lrclk = params_rate(params); |
3143 | 2534 | ||
3144 | for (i = 0; i < ARRAY_SIZE(sr_vals); i++) { | 2535 | for (i = 0; i < ARRAY_SIZE(sr_vals); i++) { |
@@ -3159,13 +2550,13 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream, | |||
3159 | case SNDRV_PCM_FORMAT_S16_LE: | 2550 | case SNDRV_PCM_FORMAT_S16_LE: |
3160 | break; | 2551 | break; |
3161 | case SNDRV_PCM_FORMAT_S20_3LE: | 2552 | case SNDRV_PCM_FORMAT_S20_3LE: |
3162 | aif0 |= 0x40; | 2553 | aif0 |= 0x4; |
3163 | break; | 2554 | break; |
3164 | case SNDRV_PCM_FORMAT_S24_LE: | 2555 | case SNDRV_PCM_FORMAT_S24_LE: |
3165 | aif0 |= 0x80; | 2556 | aif0 |= 0x8; |
3166 | break; | 2557 | break; |
3167 | case SNDRV_PCM_FORMAT_S32_LE: | 2558 | case SNDRV_PCM_FORMAT_S32_LE: |
3168 | aif0 |= 0xc0; | 2559 | aif0 |= 0xc; |
3169 | break; | 2560 | break; |
3170 | default: | 2561 | default: |
3171 | return -EINVAL; | 2562 | return -EINVAL; |
@@ -3177,7 +2568,8 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream, | |||
3177 | WM8962_SAMPLE_RATE_INT_MODE | | 2568 | WM8962_SAMPLE_RATE_INT_MODE | |
3178 | WM8962_SAMPLE_RATE_MASK, adctl3); | 2569 | WM8962_SAMPLE_RATE_MASK, adctl3); |
3179 | 2570 | ||
3180 | wm8962_configure_bclk(codec); | 2571 | if (codec->dapm.bias_level == SND_SOC_BIAS_ON) |
2572 | wm8962_configure_bclk(codec); | ||
3181 | 2573 | ||
3182 | return 0; | 2574 | return 0; |
3183 | } | 2575 | } |
@@ -3207,6 +2599,8 @@ static int wm8962_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, | |||
3207 | 2599 | ||
3208 | wm8962->sysclk_rate = freq; | 2600 | wm8962->sysclk_rate = freq; |
3209 | 2601 | ||
2602 | wm8962_configure_bclk(codec); | ||
2603 | |||
3210 | return 0; | 2604 | return 0; |
3211 | } | 2605 | } |
3212 | 2606 | ||
@@ -3385,8 +2779,7 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
3385 | struct _fll_div fll_div; | 2779 | struct _fll_div fll_div; |
3386 | unsigned long timeout; | 2780 | unsigned long timeout; |
3387 | int ret; | 2781 | int ret; |
3388 | int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1) & WM8962_FLL_ENA; | 2782 | int fll1 = 0; |
3389 | int sysclk = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_ENA; | ||
3390 | 2783 | ||
3391 | /* Any change? */ | 2784 | /* Any change? */ |
3392 | if (source == wm8962->fll_src && Fref == wm8962->fll_fref && | 2785 | if (source == wm8962->fll_src && Fref == wm8962->fll_fref && |
@@ -3402,6 +2795,8 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
3402 | snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, | 2795 | snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, |
3403 | WM8962_FLL_ENA, 0); | 2796 | WM8962_FLL_ENA, 0); |
3404 | 2797 | ||
2798 | pm_runtime_put(codec->dev); | ||
2799 | |||
3405 | return 0; | 2800 | return 0; |
3406 | } | 2801 | } |
3407 | 2802 | ||
@@ -3409,6 +2804,9 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
3409 | if (ret != 0) | 2804 | if (ret != 0) |
3410 | return ret; | 2805 | return ret; |
3411 | 2806 | ||
2807 | /* Parameters good, disable so we can reprogram */ | ||
2808 | snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0); | ||
2809 | |||
3412 | switch (fll_id) { | 2810 | switch (fll_id) { |
3413 | case WM8962_FLL_MCLK: | 2811 | case WM8962_FLL_MCLK: |
3414 | case WM8962_FLL_BCLK: | 2812 | case WM8962_FLL_BCLK: |
@@ -3447,12 +2845,11 @@ static int wm8962_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
3447 | 2845 | ||
3448 | try_wait_for_completion(&wm8962->fll_lock); | 2846 | try_wait_for_completion(&wm8962->fll_lock); |
3449 | 2847 | ||
3450 | if (sysclk) | 2848 | pm_runtime_get_sync(codec->dev); |
3451 | fll1 |= WM8962_FLL_ENA; | ||
3452 | 2849 | ||
3453 | snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, | 2850 | snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, |
3454 | WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK | | 2851 | WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK | |
3455 | WM8962_FLL_ENA, fll1); | 2852 | WM8962_FLL_ENA, fll1 | WM8962_FLL_ENA); |
3456 | 2853 | ||
3457 | dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); | 2854 | dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); |
3458 | 2855 | ||
@@ -3513,14 +2910,14 @@ static struct snd_soc_dai_driver wm8962_dai = { | |||
3513 | .name = "wm8962", | 2910 | .name = "wm8962", |
3514 | .playback = { | 2911 | .playback = { |
3515 | .stream_name = "Playback", | 2912 | .stream_name = "Playback", |
3516 | .channels_min = 2, | 2913 | .channels_min = 1, |
3517 | .channels_max = 2, | 2914 | .channels_max = 2, |
3518 | .rates = WM8962_RATES, | 2915 | .rates = WM8962_RATES, |
3519 | .formats = WM8962_FORMATS, | 2916 | .formats = WM8962_FORMATS, |
3520 | }, | 2917 | }, |
3521 | .capture = { | 2918 | .capture = { |
3522 | .stream_name = "Capture", | 2919 | .stream_name = "Capture", |
3523 | .channels_min = 2, | 2920 | .channels_min = 1, |
3524 | .channels_max = 2, | 2921 | .channels_max = 2, |
3525 | .rates = WM8962_RATES, | 2922 | .rates = WM8962_RATES, |
3526 | .formats = WM8962_FORMATS, | 2923 | .formats = WM8962_FORMATS, |
@@ -3561,54 +2958,73 @@ static void wm8962_mic_work(struct work_struct *work) | |||
3561 | 2958 | ||
3562 | static irqreturn_t wm8962_irq(int irq, void *data) | 2959 | static irqreturn_t wm8962_irq(int irq, void *data) |
3563 | { | 2960 | { |
3564 | struct snd_soc_codec *codec = data; | 2961 | struct device *dev = data; |
3565 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 2962 | struct wm8962_priv *wm8962 = dev_get_drvdata(dev); |
3566 | int mask; | 2963 | unsigned int mask; |
3567 | int active; | 2964 | unsigned int active; |
3568 | int reg; | 2965 | int reg, ret; |
3569 | 2966 | ||
3570 | mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK); | 2967 | ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2_MASK, |
2968 | &mask); | ||
2969 | if (ret != 0) { | ||
2970 | dev_err(dev, "Failed to read interrupt mask: %d\n", | ||
2971 | ret); | ||
2972 | return IRQ_NONE; | ||
2973 | } | ||
2974 | |||
2975 | ret = regmap_read(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, &active); | ||
2976 | if (ret != 0) { | ||
2977 | dev_err(dev, "Failed to read interrupt: %d\n", ret); | ||
2978 | return IRQ_NONE; | ||
2979 | } | ||
3571 | 2980 | ||
3572 | active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); | ||
3573 | active &= ~mask; | 2981 | active &= ~mask; |
3574 | 2982 | ||
3575 | if (!active) | 2983 | if (!active) |
3576 | return IRQ_NONE; | 2984 | return IRQ_NONE; |
3577 | 2985 | ||
3578 | /* Acknowledge the interrupts */ | 2986 | /* Acknowledge the interrupts */ |
3579 | snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); | 2987 | ret = regmap_write(wm8962->regmap, WM8962_INTERRUPT_STATUS_2, active); |
2988 | if (ret != 0) | ||
2989 | dev_warn(dev, "Failed to ack interrupt: %d\n", ret); | ||
3580 | 2990 | ||
3581 | if (active & WM8962_FLL_LOCK_EINT) { | 2991 | if (active & WM8962_FLL_LOCK_EINT) { |
3582 | dev_dbg(codec->dev, "FLL locked\n"); | 2992 | dev_dbg(dev, "FLL locked\n"); |
3583 | complete(&wm8962->fll_lock); | 2993 | complete(&wm8962->fll_lock); |
3584 | } | 2994 | } |
3585 | 2995 | ||
3586 | if (active & WM8962_FIFOS_ERR_EINT) | 2996 | if (active & WM8962_FIFOS_ERR_EINT) |
3587 | dev_err(codec->dev, "FIFO error\n"); | 2997 | dev_err(dev, "FIFO error\n"); |
3588 | 2998 | ||
3589 | if (active & WM8962_TEMP_SHUT_EINT) { | 2999 | if (active & WM8962_TEMP_SHUT_EINT) { |
3590 | dev_crit(codec->dev, "Thermal shutdown\n"); | 3000 | dev_crit(dev, "Thermal shutdown\n"); |
3591 | 3001 | ||
3592 | reg = snd_soc_read(codec, WM8962_THERMAL_SHUTDOWN_STATUS); | 3002 | ret = regmap_read(wm8962->regmap, |
3003 | WM8962_THERMAL_SHUTDOWN_STATUS, ®); | ||
3004 | if (ret != 0) { | ||
3005 | dev_warn(dev, "Failed to read thermal status: %d\n", | ||
3006 | ret); | ||
3007 | reg = 0; | ||
3008 | } | ||
3593 | 3009 | ||
3594 | if (reg & WM8962_TEMP_ERR_HP) | 3010 | if (reg & WM8962_TEMP_ERR_HP) |
3595 | dev_crit(codec->dev, "Headphone thermal error\n"); | 3011 | dev_crit(dev, "Headphone thermal error\n"); |
3596 | if (reg & WM8962_TEMP_WARN_HP) | 3012 | if (reg & WM8962_TEMP_WARN_HP) |
3597 | dev_crit(codec->dev, "Headphone thermal warning\n"); | 3013 | dev_crit(dev, "Headphone thermal warning\n"); |
3598 | if (reg & WM8962_TEMP_ERR_SPK) | 3014 | if (reg & WM8962_TEMP_ERR_SPK) |
3599 | dev_crit(codec->dev, "Speaker thermal error\n"); | 3015 | dev_crit(dev, "Speaker thermal error\n"); |
3600 | if (reg & WM8962_TEMP_WARN_SPK) | 3016 | if (reg & WM8962_TEMP_WARN_SPK) |
3601 | dev_crit(codec->dev, "Speaker thermal warning\n"); | 3017 | dev_crit(dev, "Speaker thermal warning\n"); |
3602 | } | 3018 | } |
3603 | 3019 | ||
3604 | if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { | 3020 | if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { |
3605 | dev_dbg(codec->dev, "Microphone event detected\n"); | 3021 | dev_dbg(dev, "Microphone event detected\n"); |
3606 | 3022 | ||
3607 | #ifndef CONFIG_SND_SOC_WM8962_MODULE | 3023 | #ifndef CONFIG_SND_SOC_WM8962_MODULE |
3608 | trace_snd_soc_jack_irq(dev_name(codec->dev)); | 3024 | trace_snd_soc_jack_irq(dev_name(dev)); |
3609 | #endif | 3025 | #endif |
3610 | 3026 | ||
3611 | pm_wakeup_event(codec->dev, 300); | 3027 | pm_wakeup_event(dev, 300); |
3612 | 3028 | ||
3613 | schedule_delayed_work(&wm8962->mic_work, | 3029 | schedule_delayed_work(&wm8962->mic_work, |
3614 | msecs_to_jiffies(250)); | 3030 | msecs_to_jiffies(250)); |
@@ -4089,7 +3505,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) | |||
4089 | 3505 | ||
4090 | ret = request_threaded_irq(wm8962->irq, NULL, wm8962_irq, | 3506 | ret = request_threaded_irq(wm8962->irq, NULL, wm8962_irq, |
4091 | trigger | IRQF_ONESHOT, | 3507 | trigger | IRQF_ONESHOT, |
4092 | "wm8962", codec); | 3508 | "wm8962", codec->dev); |
4093 | if (ret != 0) { | 3509 | if (ret != 0) { |
4094 | dev_err(codec->dev, "Failed to request IRQ %d: %d\n", | 3510 | dev_err(codec->dev, "Failed to request IRQ %d: %d\n", |
4095 | wm8962->irq, ret); | 3511 | wm8962->irq, ret); |
@@ -4127,20 +3543,19 @@ static int wm8962_remove(struct snd_soc_codec *codec) | |||
4127 | return 0; | 3543 | return 0; |
4128 | } | 3544 | } |
4129 | 3545 | ||
4130 | static int wm8962_soc_volatile(struct snd_soc_codec *codec, | ||
4131 | unsigned int reg) | ||
4132 | { | ||
4133 | return true; | ||
4134 | } | ||
4135 | |||
4136 | |||
4137 | static struct snd_soc_codec_driver soc_codec_dev_wm8962 = { | 3546 | static struct snd_soc_codec_driver soc_codec_dev_wm8962 = { |
4138 | .probe = wm8962_probe, | 3547 | .probe = wm8962_probe, |
4139 | .remove = wm8962_remove, | 3548 | .remove = wm8962_remove, |
4140 | .set_bias_level = wm8962_set_bias_level, | 3549 | .set_bias_level = wm8962_set_bias_level, |
4141 | .set_pll = wm8962_set_fll, | 3550 | .set_pll = wm8962_set_fll, |
4142 | .reg_cache_size = WM8962_MAX_REGISTER, | 3551 | .idle_bias_off = true, |
4143 | .volatile_register = wm8962_soc_volatile, | 3552 | }; |
3553 | |||
3554 | /* Improve power consumption for IN4 DC measurement mode */ | ||
3555 | static const struct reg_default wm8962_dc_measure[] = { | ||
3556 | { 0xfd, 0x1 }, | ||
3557 | { 0xcc, 0x40 }, | ||
3558 | { 0xfd, 0 }, | ||
4144 | }; | 3559 | }; |
4145 | 3560 | ||
4146 | static const struct regmap_config wm8962_regmap = { | 3561 | static const struct regmap_config wm8962_regmap = { |
@@ -4155,10 +3570,10 @@ static const struct regmap_config wm8962_regmap = { | |||
4155 | .cache_type = REGCACHE_RBTREE, | 3570 | .cache_type = REGCACHE_RBTREE, |
4156 | }; | 3571 | }; |
4157 | 3572 | ||
4158 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
4159 | static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, | 3573 | static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, |
4160 | const struct i2c_device_id *id) | 3574 | const struct i2c_device_id *id) |
4161 | { | 3575 | { |
3576 | struct wm8962_pdata *pdata = dev_get_platdata(&i2c->dev); | ||
4162 | struct wm8962_priv *wm8962; | 3577 | struct wm8962_priv *wm8962; |
4163 | unsigned int reg; | 3578 | unsigned int reg; |
4164 | int ret, i; | 3579 | int ret, i; |
@@ -4212,7 +3627,7 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, | |||
4212 | } | 3627 | } |
4213 | if (reg != 0x6243) { | 3628 | if (reg != 0x6243) { |
4214 | dev_err(&i2c->dev, | 3629 | dev_err(&i2c->dev, |
4215 | "Device is not a WM8962, ID %x != 0x6243\n", ret); | 3630 | "Device is not a WM8962, ID %x != 0x6243\n", reg); |
4216 | ret = -EINVAL; | 3631 | ret = -EINVAL; |
4217 | goto err_regmap; | 3632 | goto err_regmap; |
4218 | } | 3633 | } |
@@ -4237,7 +3652,18 @@ static __devinit int wm8962_i2c_probe(struct i2c_client *i2c, | |||
4237 | goto err_regmap; | 3652 | goto err_regmap; |
4238 | } | 3653 | } |
4239 | 3654 | ||
4240 | regcache_cache_only(wm8962->regmap, true); | 3655 | if (pdata && pdata->in4_dc_measure) { |
3656 | ret = regmap_register_patch(wm8962->regmap, | ||
3657 | wm8962_dc_measure, | ||
3658 | ARRAY_SIZE(wm8962_dc_measure)); | ||
3659 | if (ret != 0) | ||
3660 | dev_err(&i2c->dev, | ||
3661 | "Failed to configure for DC mesurement: %d\n", | ||
3662 | ret); | ||
3663 | } | ||
3664 | |||
3665 | pm_runtime_enable(&i2c->dev); | ||
3666 | pm_request_idle(&i2c->dev); | ||
4241 | 3667 | ||
4242 | ret = snd_soc_register_codec(&i2c->dev, | 3668 | ret = snd_soc_register_codec(&i2c->dev, |
4243 | &soc_codec_dev_wm8962, &wm8962_dai, 1); | 3669 | &soc_codec_dev_wm8962, &wm8962_dai, 1); |
@@ -4269,6 +3695,65 @@ static __devexit int wm8962_i2c_remove(struct i2c_client *client) | |||
4269 | return 0; | 3695 | return 0; |
4270 | } | 3696 | } |
4271 | 3697 | ||
3698 | #ifdef CONFIG_PM_RUNTIME | ||
3699 | static int wm8962_runtime_resume(struct device *dev) | ||
3700 | { | ||
3701 | struct wm8962_priv *wm8962 = dev_get_drvdata(dev); | ||
3702 | int ret; | ||
3703 | |||
3704 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies), | ||
3705 | wm8962->supplies); | ||
3706 | if (ret != 0) { | ||
3707 | dev_err(dev, | ||
3708 | "Failed to enable supplies: %d\n", ret); | ||
3709 | return ret; | ||
3710 | } | ||
3711 | |||
3712 | regcache_cache_only(wm8962->regmap, false); | ||
3713 | regcache_sync(wm8962->regmap); | ||
3714 | |||
3715 | regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP, | ||
3716 | WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA, | ||
3717 | WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA); | ||
3718 | |||
3719 | /* Bias enable at 2*50k for ramp */ | ||
3720 | regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1, | ||
3721 | WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, | ||
3722 | WM8962_BIAS_ENA | 0x180); | ||
3723 | |||
3724 | msleep(5); | ||
3725 | |||
3726 | /* VMID back to 2x250k for standby */ | ||
3727 | regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1, | ||
3728 | WM8962_VMID_SEL_MASK, 0x100); | ||
3729 | |||
3730 | return 0; | ||
3731 | } | ||
3732 | |||
3733 | static int wm8962_runtime_suspend(struct device *dev) | ||
3734 | { | ||
3735 | struct wm8962_priv *wm8962 = dev_get_drvdata(dev); | ||
3736 | |||
3737 | regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1, | ||
3738 | WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0); | ||
3739 | |||
3740 | regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP, | ||
3741 | WM8962_STARTUP_BIAS_ENA | | ||
3742 | WM8962_VMID_BUF_ENA, 0); | ||
3743 | |||
3744 | regcache_cache_only(wm8962->regmap, true); | ||
3745 | |||
3746 | regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), | ||
3747 | wm8962->supplies); | ||
3748 | |||
3749 | return 0; | ||
3750 | } | ||
3751 | #endif | ||
3752 | |||
3753 | static struct dev_pm_ops wm8962_pm = { | ||
3754 | SET_RUNTIME_PM_OPS(wm8962_runtime_suspend, wm8962_runtime_resume, NULL) | ||
3755 | }; | ||
3756 | |||
4272 | static const struct i2c_device_id wm8962_i2c_id[] = { | 3757 | static const struct i2c_device_id wm8962_i2c_id[] = { |
4273 | { "wm8962", 0 }, | 3758 | { "wm8962", 0 }, |
4274 | { } | 3759 | { } |
@@ -4279,34 +3764,14 @@ static struct i2c_driver wm8962_i2c_driver = { | |||
4279 | .driver = { | 3764 | .driver = { |
4280 | .name = "wm8962", | 3765 | .name = "wm8962", |
4281 | .owner = THIS_MODULE, | 3766 | .owner = THIS_MODULE, |
3767 | .pm = &wm8962_pm, | ||
4282 | }, | 3768 | }, |
4283 | .probe = wm8962_i2c_probe, | 3769 | .probe = wm8962_i2c_probe, |
4284 | .remove = __devexit_p(wm8962_i2c_remove), | 3770 | .remove = __devexit_p(wm8962_i2c_remove), |
4285 | .id_table = wm8962_i2c_id, | 3771 | .id_table = wm8962_i2c_id, |
4286 | }; | 3772 | }; |
4287 | #endif | ||
4288 | |||
4289 | static int __init wm8962_modinit(void) | ||
4290 | { | ||
4291 | int ret; | ||
4292 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
4293 | ret = i2c_add_driver(&wm8962_i2c_driver); | ||
4294 | if (ret != 0) { | ||
4295 | printk(KERN_ERR "Failed to register WM8962 I2C driver: %d\n", | ||
4296 | ret); | ||
4297 | } | ||
4298 | #endif | ||
4299 | return 0; | ||
4300 | } | ||
4301 | module_init(wm8962_modinit); | ||
4302 | 3773 | ||
4303 | static void __exit wm8962_exit(void) | 3774 | module_i2c_driver(wm8962_i2c_driver); |
4304 | { | ||
4305 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
4306 | i2c_del_driver(&wm8962_i2c_driver); | ||
4307 | #endif | ||
4308 | } | ||
4309 | module_exit(wm8962_exit); | ||
4310 | 3775 | ||
4311 | MODULE_DESCRIPTION("ASoC WM8962 driver"); | 3776 | MODULE_DESCRIPTION("ASoC WM8962 driver"); |
4312 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 3777 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 4af893601f00..28fe59e3ce01 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c | |||
@@ -252,7 +252,7 @@ static const struct snd_soc_dapm_widget wm8971_dapm_widgets[] = { | |||
252 | SND_SOC_DAPM_INPUT("MIC"), | 252 | SND_SOC_DAPM_INPUT("MIC"), |
253 | }; | 253 | }; |
254 | 254 | ||
255 | static const struct snd_soc_dapm_route audio_map[] = { | 255 | static const struct snd_soc_dapm_route wm8971_dapm_routes[] = { |
256 | /* left mixer */ | 256 | /* left mixer */ |
257 | {"Left Mixer", "Playback Switch", "Left DAC"}, | 257 | {"Left Mixer", "Playback Switch", "Left DAC"}, |
258 | {"Left Mixer", "Left Bypass Switch", "Left Line Mux"}, | 258 | {"Left Mixer", "Left Bypass Switch", "Left Line Mux"}, |
@@ -329,17 +329,6 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
329 | {"Right ADC", NULL, "Right ADC Mux"}, | 329 | {"Right ADC", NULL, "Right ADC Mux"}, |
330 | }; | 330 | }; |
331 | 331 | ||
332 | static int wm8971_add_widgets(struct snd_soc_codec *codec) | ||
333 | { | ||
334 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
335 | |||
336 | snd_soc_dapm_new_controls(dapm, wm8971_dapm_widgets, | ||
337 | ARRAY_SIZE(wm8971_dapm_widgets)); | ||
338 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | struct _coeff_div { | 332 | struct _coeff_div { |
344 | u32 mclk; | 333 | u32 mclk; |
345 | u32 rate; | 334 | u32 rate; |
@@ -659,10 +648,6 @@ static int wm8971_probe(struct snd_soc_codec *codec) | |||
659 | snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100); | 648 | snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100); |
660 | snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100); | 649 | snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100); |
661 | 650 | ||
662 | snd_soc_add_controls(codec, wm8971_snd_controls, | ||
663 | ARRAY_SIZE(wm8971_snd_controls)); | ||
664 | wm8971_add_widgets(codec); | ||
665 | |||
666 | return ret; | 651 | return ret; |
667 | } | 652 | } |
668 | 653 | ||
@@ -686,16 +671,23 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8971 = { | |||
686 | .reg_cache_size = ARRAY_SIZE(wm8971_reg), | 671 | .reg_cache_size = ARRAY_SIZE(wm8971_reg), |
687 | .reg_word_size = sizeof(u16), | 672 | .reg_word_size = sizeof(u16), |
688 | .reg_cache_default = wm8971_reg, | 673 | .reg_cache_default = wm8971_reg, |
674 | |||
675 | .controls = wm8971_snd_controls, | ||
676 | .num_controls = ARRAY_SIZE(wm8971_snd_controls), | ||
677 | .dapm_widgets = wm8971_dapm_widgets, | ||
678 | .num_dapm_widgets = ARRAY_SIZE(wm8971_dapm_widgets), | ||
679 | .dapm_routes = wm8971_dapm_routes, | ||
680 | .num_dapm_routes = ARRAY_SIZE(wm8971_dapm_routes), | ||
689 | }; | 681 | }; |
690 | 682 | ||
691 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
692 | static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, | 683 | static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, |
693 | const struct i2c_device_id *id) | 684 | const struct i2c_device_id *id) |
694 | { | 685 | { |
695 | struct wm8971_priv *wm8971; | 686 | struct wm8971_priv *wm8971; |
696 | int ret; | 687 | int ret; |
697 | 688 | ||
698 | wm8971 = kzalloc(sizeof(struct wm8971_priv), GFP_KERNEL); | 689 | wm8971 = devm_kzalloc(&i2c->dev, sizeof(struct wm8971_priv), |
690 | GFP_KERNEL); | ||
699 | if (wm8971 == NULL) | 691 | if (wm8971 == NULL) |
700 | return -ENOMEM; | 692 | return -ENOMEM; |
701 | 693 | ||
@@ -704,15 +696,13 @@ static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, | |||
704 | 696 | ||
705 | ret = snd_soc_register_codec(&i2c->dev, | 697 | ret = snd_soc_register_codec(&i2c->dev, |
706 | &soc_codec_dev_wm8971, &wm8971_dai, 1); | 698 | &soc_codec_dev_wm8971, &wm8971_dai, 1); |
707 | if (ret < 0) | 699 | |
708 | kfree(wm8971); | ||
709 | return ret; | 700 | return ret; |
710 | } | 701 | } |
711 | 702 | ||
712 | static __devexit int wm8971_i2c_remove(struct i2c_client *client) | 703 | static __devexit int wm8971_i2c_remove(struct i2c_client *client) |
713 | { | 704 | { |
714 | snd_soc_unregister_codec(&client->dev); | 705 | snd_soc_unregister_codec(&client->dev); |
715 | kfree(i2c_get_clientdata(client)); | ||
716 | return 0; | 706 | return 0; |
717 | } | 707 | } |
718 | 708 | ||
@@ -731,27 +721,22 @@ static struct i2c_driver wm8971_i2c_driver = { | |||
731 | .remove = __devexit_p(wm8971_i2c_remove), | 721 | .remove = __devexit_p(wm8971_i2c_remove), |
732 | .id_table = wm8971_i2c_id, | 722 | .id_table = wm8971_i2c_id, |
733 | }; | 723 | }; |
734 | #endif | ||
735 | 724 | ||
736 | static int __init wm8971_modinit(void) | 725 | static int __init wm8971_modinit(void) |
737 | { | 726 | { |
738 | int ret = 0; | 727 | int ret = 0; |
739 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
740 | ret = i2c_add_driver(&wm8971_i2c_driver); | 728 | ret = i2c_add_driver(&wm8971_i2c_driver); |
741 | if (ret != 0) { | 729 | if (ret != 0) { |
742 | printk(KERN_ERR "Failed to register WM8971 I2C driver: %d\n", | 730 | printk(KERN_ERR "Failed to register WM8971 I2C driver: %d\n", |
743 | ret); | 731 | ret); |
744 | } | 732 | } |
745 | #endif | ||
746 | return ret; | 733 | return ret; |
747 | } | 734 | } |
748 | module_init(wm8971_modinit); | 735 | module_init(wm8971_modinit); |
749 | 736 | ||
750 | static void __exit wm8971_exit(void) | 737 | static void __exit wm8971_exit(void) |
751 | { | 738 | { |
752 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
753 | i2c_del_driver(&wm8971_i2c_driver); | 739 | i2c_del_driver(&wm8971_i2c_driver); |
754 | #endif | ||
755 | } | 740 | } |
756 | module_exit(wm8971_exit); | 741 | module_exit(wm8971_exit); |
757 | 742 | ||
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 4a6a7b5a61ba..d93c03f820c9 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c | |||
@@ -48,10 +48,6 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = { | |||
48 | #define WM8974_POWER1_BIASEN 0x08 | 48 | #define WM8974_POWER1_BIASEN 0x08 |
49 | #define WM8974_POWER1_BUFIOEN 0x04 | 49 | #define WM8974_POWER1_BUFIOEN 0x04 |
50 | 50 | ||
51 | struct wm8974_priv { | ||
52 | enum snd_soc_control_type control_type; | ||
53 | }; | ||
54 | |||
55 | #define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0) | 51 | #define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0) |
56 | 52 | ||
57 | static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" }; | 53 | static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" }; |
@@ -235,7 +231,7 @@ SND_SOC_DAPM_OUTPUT("SPKOUTP"), | |||
235 | SND_SOC_DAPM_OUTPUT("SPKOUTN"), | 231 | SND_SOC_DAPM_OUTPUT("SPKOUTN"), |
236 | }; | 232 | }; |
237 | 233 | ||
238 | static const struct snd_soc_dapm_route audio_map[] = { | 234 | static const struct snd_soc_dapm_route wm8974_dapm_routes[] = { |
239 | /* Mono output mixer */ | 235 | /* Mono output mixer */ |
240 | {"Mono Mixer", "PCM Playback Switch", "DAC"}, | 236 | {"Mono Mixer", "PCM Playback Switch", "DAC"}, |
241 | {"Mono Mixer", "Aux Playback Switch", "Aux Input"}, | 237 | {"Mono Mixer", "Aux Playback Switch", "Aux Input"}, |
@@ -269,17 +265,6 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
269 | {"Aux Input", NULL, "AUX"}, | 265 | {"Aux Input", NULL, "AUX"}, |
270 | }; | 266 | }; |
271 | 267 | ||
272 | static int wm8974_add_widgets(struct snd_soc_codec *codec) | ||
273 | { | ||
274 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
275 | |||
276 | snd_soc_dapm_new_controls(dapm, wm8974_dapm_widgets, | ||
277 | ARRAY_SIZE(wm8974_dapm_widgets)); | ||
278 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | struct pll_ { | 268 | struct pll_ { |
284 | unsigned int pre_div:1; | 269 | unsigned int pre_div:1; |
285 | unsigned int n:4; | 270 | unsigned int n:4; |
@@ -611,9 +596,6 @@ static int wm8974_probe(struct snd_soc_codec *codec) | |||
611 | } | 596 | } |
612 | 597 | ||
613 | wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 598 | wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
614 | snd_soc_add_controls(codec, wm8974_snd_controls, | ||
615 | ARRAY_SIZE(wm8974_snd_controls)); | ||
616 | wm8974_add_widgets(codec); | ||
617 | 599 | ||
618 | return ret; | 600 | return ret; |
619 | } | 601 | } |
@@ -634,32 +616,30 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8974 = { | |||
634 | .reg_cache_size = ARRAY_SIZE(wm8974_reg), | 616 | .reg_cache_size = ARRAY_SIZE(wm8974_reg), |
635 | .reg_word_size = sizeof(u16), | 617 | .reg_word_size = sizeof(u16), |
636 | .reg_cache_default = wm8974_reg, | 618 | .reg_cache_default = wm8974_reg, |
619 | |||
620 | .controls = wm8974_snd_controls, | ||
621 | .num_controls = ARRAY_SIZE(wm8974_snd_controls), | ||
622 | .dapm_widgets = wm8974_dapm_widgets, | ||
623 | .num_dapm_widgets = ARRAY_SIZE(wm8974_dapm_widgets), | ||
624 | .dapm_routes = wm8974_dapm_routes, | ||
625 | .num_dapm_routes = ARRAY_SIZE(wm8974_dapm_routes), | ||
637 | }; | 626 | }; |
638 | 627 | ||
639 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
640 | static __devinit int wm8974_i2c_probe(struct i2c_client *i2c, | 628 | static __devinit int wm8974_i2c_probe(struct i2c_client *i2c, |
641 | const struct i2c_device_id *id) | 629 | const struct i2c_device_id *id) |
642 | { | 630 | { |
643 | struct wm8974_priv *wm8974; | ||
644 | int ret; | 631 | int ret; |
645 | 632 | ||
646 | wm8974 = kzalloc(sizeof(struct wm8974_priv), GFP_KERNEL); | ||
647 | if (wm8974 == NULL) | ||
648 | return -ENOMEM; | ||
649 | |||
650 | i2c_set_clientdata(i2c, wm8974); | ||
651 | |||
652 | ret = snd_soc_register_codec(&i2c->dev, | 633 | ret = snd_soc_register_codec(&i2c->dev, |
653 | &soc_codec_dev_wm8974, &wm8974_dai, 1); | 634 | &soc_codec_dev_wm8974, &wm8974_dai, 1); |
654 | if (ret < 0) | 635 | |
655 | kfree(wm8974); | ||
656 | return ret; | 636 | return ret; |
657 | } | 637 | } |
658 | 638 | ||
659 | static __devexit int wm8974_i2c_remove(struct i2c_client *client) | 639 | static __devexit int wm8974_i2c_remove(struct i2c_client *client) |
660 | { | 640 | { |
661 | snd_soc_unregister_codec(&client->dev); | 641 | snd_soc_unregister_codec(&client->dev); |
662 | kfree(i2c_get_clientdata(client)); | 642 | |
663 | return 0; | 643 | return 0; |
664 | } | 644 | } |
665 | 645 | ||
@@ -678,27 +658,22 @@ static struct i2c_driver wm8974_i2c_driver = { | |||
678 | .remove = __devexit_p(wm8974_i2c_remove), | 658 | .remove = __devexit_p(wm8974_i2c_remove), |
679 | .id_table = wm8974_i2c_id, | 659 | .id_table = wm8974_i2c_id, |
680 | }; | 660 | }; |
681 | #endif | ||
682 | 661 | ||
683 | static int __init wm8974_modinit(void) | 662 | static int __init wm8974_modinit(void) |
684 | { | 663 | { |
685 | int ret = 0; | 664 | int ret = 0; |
686 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
687 | ret = i2c_add_driver(&wm8974_i2c_driver); | 665 | ret = i2c_add_driver(&wm8974_i2c_driver); |
688 | if (ret != 0) { | 666 | if (ret != 0) { |
689 | printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n", | 667 | printk(KERN_ERR "Failed to register wm8974 I2C driver: %d\n", |
690 | ret); | 668 | ret); |
691 | } | 669 | } |
692 | #endif | ||
693 | return ret; | 670 | return ret; |
694 | } | 671 | } |
695 | module_init(wm8974_modinit); | 672 | module_init(wm8974_modinit); |
696 | 673 | ||
697 | static void __exit wm8974_exit(void) | 674 | static void __exit wm8974_exit(void) |
698 | { | 675 | { |
699 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
700 | i2c_del_driver(&wm8974_i2c_driver); | 676 | i2c_del_driver(&wm8974_i2c_driver); |
701 | #endif | ||
702 | } | 677 | } |
703 | module_exit(wm8974_exit); | 678 | module_exit(wm8974_exit); |
704 | 679 | ||
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 85d514d63a4c..72d5fdcd3cc2 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/pm.h> | 19 | #include <linux/pm.h> |
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/regmap.h> | ||
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
22 | #include <sound/core.h> | 23 | #include <sound/core.h> |
23 | #include <sound/pcm.h> | 24 | #include <sound/pcm.h> |
@@ -29,28 +30,74 @@ | |||
29 | 30 | ||
30 | #include "wm8978.h" | 31 | #include "wm8978.h" |
31 | 32 | ||
32 | /* wm8978 register cache. Note that register 0 is not included in the cache. */ | 33 | static const struct reg_default wm8978_reg_defaults[] = { |
33 | static const u16 wm8978_reg[WM8978_CACHEREGNUM] = { | 34 | { 1, 0x0000 }, |
34 | 0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */ | 35 | { 2, 0x0000 }, |
35 | 0x0050, 0x0000, 0x0140, 0x0000, /* 0x04...0x07 */ | 36 | { 3, 0x0000 }, |
36 | 0x0000, 0x0000, 0x0000, 0x00ff, /* 0x08...0x0b */ | 37 | { 4, 0x0050 }, |
37 | 0x00ff, 0x0000, 0x0100, 0x00ff, /* 0x0c...0x0f */ | 38 | { 5, 0x0000 }, |
38 | 0x00ff, 0x0000, 0x012c, 0x002c, /* 0x10...0x13 */ | 39 | { 6, 0x0140 }, |
39 | 0x002c, 0x002c, 0x002c, 0x0000, /* 0x14...0x17 */ | 40 | { 7, 0x0000 }, |
40 | 0x0032, 0x0000, 0x0000, 0x0000, /* 0x18...0x1b */ | 41 | { 8, 0x0000 }, |
41 | 0x0000, 0x0000, 0x0000, 0x0000, /* 0x1c...0x1f */ | 42 | { 9, 0x0000 }, |
42 | 0x0038, 0x000b, 0x0032, 0x0000, /* 0x20...0x23 */ | 43 | { 10, 0x0000 }, |
43 | 0x0008, 0x000c, 0x0093, 0x00e9, /* 0x24...0x27 */ | 44 | { 11, 0x00ff }, |
44 | 0x0000, 0x0000, 0x0000, 0x0000, /* 0x28...0x2b */ | 45 | { 12, 0x00ff }, |
45 | 0x0033, 0x0010, 0x0010, 0x0100, /* 0x2c...0x2f */ | 46 | { 13, 0x0000 }, |
46 | 0x0100, 0x0002, 0x0001, 0x0001, /* 0x30...0x33 */ | 47 | { 14, 0x0100 }, |
47 | 0x0039, 0x0039, 0x0039, 0x0039, /* 0x34...0x37 */ | 48 | { 15, 0x00ff }, |
48 | 0x0001, 0x0001, /* 0x38...0x3b */ | 49 | { 16, 0x00ff }, |
50 | { 17, 0x0000 }, | ||
51 | { 18, 0x012c }, | ||
52 | { 19, 0x002c }, | ||
53 | { 20, 0x002c }, | ||
54 | { 21, 0x002c }, | ||
55 | { 22, 0x002c }, | ||
56 | { 23, 0x0000 }, | ||
57 | { 24, 0x0032 }, | ||
58 | { 25, 0x0000 }, | ||
59 | { 26, 0x0000 }, | ||
60 | { 27, 0x0000 }, | ||
61 | { 28, 0x0000 }, | ||
62 | { 29, 0x0000 }, | ||
63 | { 30, 0x0000 }, | ||
64 | { 31, 0x0000 }, | ||
65 | { 32, 0x0038 }, | ||
66 | { 33, 0x000b }, | ||
67 | { 34, 0x0032 }, | ||
68 | { 35, 0x0000 }, | ||
69 | { 36, 0x0008 }, | ||
70 | { 37, 0x000c }, | ||
71 | { 38, 0x0093 }, | ||
72 | { 39, 0x00e9 }, | ||
73 | { 40, 0x0000 }, | ||
74 | { 41, 0x0000 }, | ||
75 | { 42, 0x0000 }, | ||
76 | { 43, 0x0000 }, | ||
77 | { 44, 0x0033 }, | ||
78 | { 45, 0x0010 }, | ||
79 | { 46, 0x0010 }, | ||
80 | { 47, 0x0100 }, | ||
81 | { 48, 0x0100 }, | ||
82 | { 49, 0x0002 }, | ||
83 | { 50, 0x0001 }, | ||
84 | { 51, 0x0001 }, | ||
85 | { 52, 0x0039 }, | ||
86 | { 53, 0x0039 }, | ||
87 | { 54, 0x0039 }, | ||
88 | { 55, 0x0039 }, | ||
89 | { 56, 0x0001 }, | ||
90 | { 57, 0x0001 }, | ||
49 | }; | 91 | }; |
50 | 92 | ||
93 | static bool wm8978_volatile(struct device *dev, unsigned int reg) | ||
94 | { | ||
95 | return reg == WM8978_RESET; | ||
96 | } | ||
97 | |||
51 | /* codec private data */ | 98 | /* codec private data */ |
52 | struct wm8978_priv { | 99 | struct wm8978_priv { |
53 | enum snd_soc_control_type control_type; | 100 | struct regmap *regmap; |
54 | unsigned int f_pllout; | 101 | unsigned int f_pllout; |
55 | unsigned int f_mclk; | 102 | unsigned int f_mclk; |
56 | unsigned int f_256fs; | 103 | unsigned int f_256fs; |
@@ -303,7 +350,7 @@ static const struct snd_soc_dapm_widget wm8978_dapm_widgets[] = { | |||
303 | SND_SOC_DAPM_OUTPUT("RSPK"), | 350 | SND_SOC_DAPM_OUTPUT("RSPK"), |
304 | }; | 351 | }; |
305 | 352 | ||
306 | static const struct snd_soc_dapm_route audio_map[] = { | 353 | static const struct snd_soc_dapm_route wm8978_dapm_routes[] = { |
307 | /* Output mixer */ | 354 | /* Output mixer */ |
308 | {"Right Output Mixer", "PCM Playback Switch", "Right DAC"}, | 355 | {"Right Output Mixer", "PCM Playback Switch", "Right DAC"}, |
309 | {"Right Output Mixer", "Aux Playback Switch", "RAUX"}, | 356 | {"Right Output Mixer", "Aux Playback Switch", "RAUX"}, |
@@ -352,18 +399,6 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
352 | {"Left Input Mixer", "MicP Switch", "LMICP"}, | 399 | {"Left Input Mixer", "MicP Switch", "LMICP"}, |
353 | }; | 400 | }; |
354 | 401 | ||
355 | static int wm8978_add_widgets(struct snd_soc_codec *codec) | ||
356 | { | ||
357 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
358 | |||
359 | snd_soc_dapm_new_controls(dapm, wm8978_dapm_widgets, | ||
360 | ARRAY_SIZE(wm8978_dapm_widgets)); | ||
361 | /* set up the WM8978 audio map */ | ||
362 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
363 | |||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | /* PLL divisors */ | 402 | /* PLL divisors */ |
368 | struct wm8978_pll_div { | 403 | struct wm8978_pll_div { |
369 | u32 k; | 404 | u32 k; |
@@ -894,26 +929,23 @@ static struct snd_soc_dai_driver wm8978_dai = { | |||
894 | 929 | ||
895 | static int wm8978_suspend(struct snd_soc_codec *codec) | 930 | static int wm8978_suspend(struct snd_soc_codec *codec) |
896 | { | 931 | { |
932 | struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec); | ||
933 | |||
897 | wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF); | 934 | wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF); |
898 | /* Also switch PLL off */ | 935 | /* Also switch PLL off */ |
899 | snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0); | 936 | snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0); |
900 | 937 | ||
938 | regcache_mark_dirty(wm8978->regmap); | ||
939 | |||
901 | return 0; | 940 | return 0; |
902 | } | 941 | } |
903 | 942 | ||
904 | static int wm8978_resume(struct snd_soc_codec *codec) | 943 | static int wm8978_resume(struct snd_soc_codec *codec) |
905 | { | 944 | { |
906 | struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec); | 945 | struct wm8978_priv *wm8978 = snd_soc_codec_get_drvdata(codec); |
907 | int i; | ||
908 | u16 *cache = codec->reg_cache; | ||
909 | 946 | ||
910 | /* Sync reg_cache with the hardware */ | 947 | /* Sync reg_cache with the hardware */ |
911 | for (i = 0; i < ARRAY_SIZE(wm8978_reg); i++) { | 948 | regcache_sync(wm8978->regmap); |
912 | if (i == WM8978_RESET) | ||
913 | continue; | ||
914 | if (cache[i] != wm8978_reg[i]) | ||
915 | snd_soc_write(codec, i, cache[i]); | ||
916 | } | ||
917 | 949 | ||
918 | wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 950 | wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
919 | 951 | ||
@@ -953,7 +985,8 @@ static int wm8978_probe(struct snd_soc_codec *codec) | |||
953 | * default hardware setting | 985 | * default hardware setting |
954 | */ | 986 | */ |
955 | wm8978->sysclk = WM8978_PLL; | 987 | wm8978->sysclk = WM8978_PLL; |
956 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C); | 988 | codec->control_data = wm8978->regmap; |
989 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
957 | if (ret < 0) { | 990 | if (ret < 0) { |
958 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 991 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
959 | return ret; | 992 | return ret; |
@@ -967,19 +1000,8 @@ static int wm8978_probe(struct snd_soc_codec *codec) | |||
967 | for (i = 0; i < ARRAY_SIZE(update_reg); i++) | 1000 | for (i = 0; i < ARRAY_SIZE(update_reg); i++) |
968 | snd_soc_update_bits(codec, update_reg[i], 0x100, 0x100); | 1001 | snd_soc_update_bits(codec, update_reg[i], 0x100, 0x100); |
969 | 1002 | ||
970 | /* Reset the codec */ | ||
971 | ret = snd_soc_write(codec, WM8978_RESET, 0); | ||
972 | if (ret < 0) { | ||
973 | dev_err(codec->dev, "Failed to issue reset\n"); | ||
974 | return ret; | ||
975 | } | ||
976 | |||
977 | wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1003 | wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
978 | 1004 | ||
979 | snd_soc_add_controls(codec, wm8978_snd_controls, | ||
980 | ARRAY_SIZE(wm8978_snd_controls)); | ||
981 | wm8978_add_widgets(codec); | ||
982 | |||
983 | return 0; | 1005 | return 0; |
984 | } | 1006 | } |
985 | 1007 | ||
@@ -996,35 +1018,75 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8978 = { | |||
996 | .suspend = wm8978_suspend, | 1018 | .suspend = wm8978_suspend, |
997 | .resume = wm8978_resume, | 1019 | .resume = wm8978_resume, |
998 | .set_bias_level = wm8978_set_bias_level, | 1020 | .set_bias_level = wm8978_set_bias_level, |
999 | .reg_cache_size = ARRAY_SIZE(wm8978_reg), | 1021 | |
1000 | .reg_word_size = sizeof(u16), | 1022 | .controls = wm8978_snd_controls, |
1001 | .reg_cache_default = wm8978_reg, | 1023 | .num_controls = ARRAY_SIZE(wm8978_snd_controls), |
1024 | .dapm_widgets = wm8978_dapm_widgets, | ||
1025 | .num_dapm_widgets = ARRAY_SIZE(wm8978_dapm_widgets), | ||
1026 | .dapm_routes = wm8978_dapm_routes, | ||
1027 | .num_dapm_routes = ARRAY_SIZE(wm8978_dapm_routes), | ||
1028 | }; | ||
1029 | |||
1030 | static const struct regmap_config wm8978_regmap_config = { | ||
1031 | .reg_bits = 7, | ||
1032 | .val_bits = 9, | ||
1033 | |||
1034 | .max_register = WM8978_MAX_REGISTER, | ||
1035 | .volatile_reg = wm8978_volatile, | ||
1036 | |||
1037 | .cache_type = REGCACHE_RBTREE, | ||
1038 | .reg_defaults = wm8978_reg_defaults, | ||
1039 | .num_reg_defaults = ARRAY_SIZE(wm8978_reg_defaults), | ||
1002 | }; | 1040 | }; |
1003 | 1041 | ||
1004 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1005 | static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, | 1042 | static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, |
1006 | const struct i2c_device_id *id) | 1043 | const struct i2c_device_id *id) |
1007 | { | 1044 | { |
1008 | struct wm8978_priv *wm8978; | 1045 | struct wm8978_priv *wm8978; |
1009 | int ret; | 1046 | int ret; |
1010 | 1047 | ||
1011 | wm8978 = kzalloc(sizeof(struct wm8978_priv), GFP_KERNEL); | 1048 | wm8978 = devm_kzalloc(&i2c->dev, sizeof(struct wm8978_priv), |
1049 | GFP_KERNEL); | ||
1012 | if (wm8978 == NULL) | 1050 | if (wm8978 == NULL) |
1013 | return -ENOMEM; | 1051 | return -ENOMEM; |
1014 | 1052 | ||
1053 | wm8978->regmap = regmap_init_i2c(i2c, &wm8978_regmap_config); | ||
1054 | if (IS_ERR(wm8978->regmap)) { | ||
1055 | ret = PTR_ERR(wm8978->regmap); | ||
1056 | dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); | ||
1057 | return ret; | ||
1058 | } | ||
1059 | |||
1015 | i2c_set_clientdata(i2c, wm8978); | 1060 | i2c_set_clientdata(i2c, wm8978); |
1016 | 1061 | ||
1062 | /* Reset the codec */ | ||
1063 | ret = regmap_write(wm8978->regmap, WM8978_RESET, 0); | ||
1064 | if (ret != 0) { | ||
1065 | dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret); | ||
1066 | goto err; | ||
1067 | } | ||
1068 | |||
1017 | ret = snd_soc_register_codec(&i2c->dev, | 1069 | ret = snd_soc_register_codec(&i2c->dev, |
1018 | &soc_codec_dev_wm8978, &wm8978_dai, 1); | 1070 | &soc_codec_dev_wm8978, &wm8978_dai, 1); |
1019 | if (ret < 0) | 1071 | if (ret != 0) { |
1020 | kfree(wm8978); | 1072 | dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); |
1073 | goto err; | ||
1074 | } | ||
1075 | |||
1076 | return 0; | ||
1077 | |||
1078 | err: | ||
1079 | regmap_exit(wm8978->regmap); | ||
1021 | return ret; | 1080 | return ret; |
1022 | } | 1081 | } |
1023 | 1082 | ||
1024 | static __devexit int wm8978_i2c_remove(struct i2c_client *client) | 1083 | static __devexit int wm8978_i2c_remove(struct i2c_client *client) |
1025 | { | 1084 | { |
1085 | struct wm8978_priv *wm8978 = i2c_get_clientdata(client); | ||
1086 | |||
1026 | snd_soc_unregister_codec(&client->dev); | 1087 | snd_soc_unregister_codec(&client->dev); |
1027 | kfree(i2c_get_clientdata(client)); | 1088 | regmap_exit(wm8978->regmap); |
1089 | |||
1028 | return 0; | 1090 | return 0; |
1029 | } | 1091 | } |
1030 | 1092 | ||
@@ -1043,27 +1105,22 @@ static struct i2c_driver wm8978_i2c_driver = { | |||
1043 | .remove = __devexit_p(wm8978_i2c_remove), | 1105 | .remove = __devexit_p(wm8978_i2c_remove), |
1044 | .id_table = wm8978_i2c_id, | 1106 | .id_table = wm8978_i2c_id, |
1045 | }; | 1107 | }; |
1046 | #endif | ||
1047 | 1108 | ||
1048 | static int __init wm8978_modinit(void) | 1109 | static int __init wm8978_modinit(void) |
1049 | { | 1110 | { |
1050 | int ret = 0; | 1111 | int ret = 0; |
1051 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1052 | ret = i2c_add_driver(&wm8978_i2c_driver); | 1112 | ret = i2c_add_driver(&wm8978_i2c_driver); |
1053 | if (ret != 0) { | 1113 | if (ret != 0) { |
1054 | printk(KERN_ERR "Failed to register WM8978 I2C driver: %d\n", | 1114 | printk(KERN_ERR "Failed to register WM8978 I2C driver: %d\n", |
1055 | ret); | 1115 | ret); |
1056 | } | 1116 | } |
1057 | #endif | ||
1058 | return ret; | 1117 | return ret; |
1059 | } | 1118 | } |
1060 | module_init(wm8978_modinit); | 1119 | module_init(wm8978_modinit); |
1061 | 1120 | ||
1062 | static void __exit wm8978_exit(void) | 1121 | static void __exit wm8978_exit(void) |
1063 | { | 1122 | { |
1064 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1065 | i2c_del_driver(&wm8978_i2c_driver); | 1123 | i2c_del_driver(&wm8978_i2c_driver); |
1066 | #endif | ||
1067 | } | 1124 | } |
1068 | module_exit(wm8978_exit); | 1125 | module_exit(wm8978_exit); |
1069 | 1126 | ||
diff --git a/sound/soc/codecs/wm8978.h b/sound/soc/codecs/wm8978.h index c75525b7f154..6ae43495b7cf 100644 --- a/sound/soc/codecs/wm8978.h +++ b/sound/soc/codecs/wm8978.h | |||
@@ -67,6 +67,8 @@ | |||
67 | #define WM8978_OUT3_MIXER_CONTROL 0x38 | 67 | #define WM8978_OUT3_MIXER_CONTROL 0x38 |
68 | #define WM8978_OUT4_MIXER_CONTROL 0x39 | 68 | #define WM8978_OUT4_MIXER_CONTROL 0x39 |
69 | 69 | ||
70 | #define WM8978_MAX_REGISTER 0x39 | ||
71 | |||
70 | #define WM8978_CACHEREGNUM 58 | 72 | #define WM8978_CACHEREGNUM 58 |
71 | 73 | ||
72 | /* Clock divider Id's */ | 74 | /* Clock divider Id's */ |
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index cebde568d191..367388fdc486 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c | |||
@@ -249,9 +249,6 @@ static const char *eq5_cutoff_text[] = { | |||
249 | static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5, | 249 | static const SOC_ENUM_SINGLE_DECL(eq5_cutoff, WM8983_EQ5_HIGH_SHELF, 5, |
250 | eq5_cutoff_text); | 250 | eq5_cutoff_text); |
251 | 251 | ||
252 | static const char *speaker_mode_text[] = { "Class A/B", "Class D" }; | ||
253 | static const SOC_ENUM_SINGLE_DECL(speaker_mode, 0x17, 8, speaker_mode_text); | ||
254 | |||
255 | static const char *depth_3d_text[] = { | 252 | static const char *depth_3d_text[] = { |
256 | "Off", | 253 | "Off", |
257 | "6.67%", | 254 | "6.67%", |
@@ -369,8 +366,6 @@ static const struct snd_kcontrol_new wm8983_snd_controls[] = { | |||
369 | SOC_SINGLE_TLV("EQ5 Volume", WM8983_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv), | 366 | SOC_SINGLE_TLV("EQ5 Volume", WM8983_EQ5_HIGH_SHELF, 0, 24, 1, eq_tlv), |
370 | 367 | ||
371 | SOC_ENUM("3D Depth", depth_3d), | 368 | SOC_ENUM("3D Depth", depth_3d), |
372 | |||
373 | SOC_ENUM("Speaker Mode", speaker_mode) | ||
374 | }; | 369 | }; |
375 | 370 | ||
376 | static const struct snd_kcontrol_new left_out_mixer[] = { | 371 | static const struct snd_kcontrol_new left_out_mixer[] = { |
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index c0c86b3c6adf..14f666398d0c 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/pm.h> | 20 | #include <linux/pm.h> |
21 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
22 | #include <linux/regmap.h> | ||
22 | #include <linux/regulator/consumer.h> | 23 | #include <linux/regulator/consumer.h> |
23 | #include <linux/spi/spi.h> | 24 | #include <linux/spi/spi.h> |
24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
@@ -39,73 +40,127 @@ static const char *wm8985_supply_names[WM8985_NUM_SUPPLIES] = { | |||
39 | "AVDD2" | 40 | "AVDD2" |
40 | }; | 41 | }; |
41 | 42 | ||
42 | static const u16 wm8985_reg_defs[] = { | 43 | static const struct reg_default wm8985_reg_defaults[] = { |
43 | 0x0000, /* R0 - Software Reset */ | 44 | { 1, 0x0000 }, /* R1 - Power management 1 */ |
44 | 0x0000, /* R1 - Power management 1 */ | 45 | { 2, 0x0000 }, /* R2 - Power management 2 */ |
45 | 0x0000, /* R2 - Power management 2 */ | 46 | { 3, 0x0000 }, /* R3 - Power management 3 */ |
46 | 0x0000, /* R3 - Power management 3 */ | 47 | { 4, 0x0050 }, /* R4 - Audio Interface */ |
47 | 0x0050, /* R4 - Audio Interface */ | 48 | { 5, 0x0000 }, /* R5 - Companding control */ |
48 | 0x0000, /* R5 - Companding control */ | 49 | { 6, 0x0140 }, /* R6 - Clock Gen control */ |
49 | 0x0140, /* R6 - Clock Gen control */ | 50 | { 7, 0x0000 }, /* R7 - Additional control */ |
50 | 0x0000, /* R7 - Additional control */ | 51 | { 8, 0x0000 }, /* R8 - GPIO Control */ |
51 | 0x0000, /* R8 - GPIO Control */ | 52 | { 9, 0x0000 }, /* R9 - Jack Detect Control 1 */ |
52 | 0x0000, /* R9 - Jack Detect Control 1 */ | 53 | { 10, 0x0000 }, /* R10 - DAC Control */ |
53 | 0x0000, /* R10 - DAC Control */ | 54 | { 11, 0x00FF }, /* R11 - Left DAC digital Vol */ |
54 | 0x00FF, /* R11 - Left DAC digital Vol */ | 55 | { 12, 0x00FF }, /* R12 - Right DAC digital vol */ |
55 | 0x00FF, /* R12 - Right DAC digital vol */ | 56 | { 13, 0x0000 }, /* R13 - Jack Detect Control 2 */ |
56 | 0x0000, /* R13 - Jack Detect Control 2 */ | 57 | { 14, 0x0100 }, /* R14 - ADC Control */ |
57 | 0x0100, /* R14 - ADC Control */ | 58 | { 15, 0x00FF }, /* R15 - Left ADC Digital Vol */ |
58 | 0x00FF, /* R15 - Left ADC Digital Vol */ | 59 | { 16, 0x00FF }, /* R16 - Right ADC Digital Vol */ |
59 | 0x00FF, /* R16 - Right ADC Digital Vol */ | 60 | { 18, 0x012C }, /* R18 - EQ1 - low shelf */ |
60 | 0x0000, /* R17 */ | 61 | { 19, 0x002C }, /* R19 - EQ2 - peak 1 */ |
61 | 0x012C, /* R18 - EQ1 - low shelf */ | 62 | { 20, 0x002C }, /* R20 - EQ3 - peak 2 */ |
62 | 0x002C, /* R19 - EQ2 - peak 1 */ | 63 | { 21, 0x002C }, /* R21 - EQ4 - peak 3 */ |
63 | 0x002C, /* R20 - EQ3 - peak 2 */ | 64 | { 22, 0x002C }, /* R22 - EQ5 - high shelf */ |
64 | 0x002C, /* R21 - EQ4 - peak 3 */ | 65 | { 24, 0x0032 }, /* R24 - DAC Limiter 1 */ |
65 | 0x002C, /* R22 - EQ5 - high shelf */ | 66 | { 25, 0x0000 }, /* R25 - DAC Limiter 2 */ |
66 | 0x0000, /* R23 */ | 67 | { 27, 0x0000 }, /* R27 - Notch Filter 1 */ |
67 | 0x0032, /* R24 - DAC Limiter 1 */ | 68 | { 28, 0x0000 }, /* R28 - Notch Filter 2 */ |
68 | 0x0000, /* R25 - DAC Limiter 2 */ | 69 | { 29, 0x0000 }, /* R29 - Notch Filter 3 */ |
69 | 0x0000, /* R26 */ | 70 | { 30, 0x0000 }, /* R30 - Notch Filter 4 */ |
70 | 0x0000, /* R27 - Notch Filter 1 */ | 71 | { 32, 0x0038 }, /* R32 - ALC control 1 */ |
71 | 0x0000, /* R28 - Notch Filter 2 */ | 72 | { 33, 0x000B }, /* R33 - ALC control 2 */ |
72 | 0x0000, /* R29 - Notch Filter 3 */ | 73 | { 34, 0x0032 }, /* R34 - ALC control 3 */ |
73 | 0x0000, /* R30 - Notch Filter 4 */ | 74 | { 35, 0x0000 }, /* R35 - Noise Gate */ |
74 | 0x0000, /* R31 */ | 75 | { 36, 0x0008 }, /* R36 - PLL N */ |
75 | 0x0038, /* R32 - ALC control 1 */ | 76 | { 37, 0x000C }, /* R37 - PLL K 1 */ |
76 | 0x000B, /* R33 - ALC control 2 */ | 77 | { 38, 0x0093 }, /* R38 - PLL K 2 */ |
77 | 0x0032, /* R34 - ALC control 3 */ | 78 | { 39, 0x00E9 }, /* R39 - PLL K 3 */ |
78 | 0x0000, /* R35 - Noise Gate */ | 79 | { 41, 0x0000 }, /* R41 - 3D control */ |
79 | 0x0008, /* R36 - PLL N */ | 80 | { 42, 0x0000 }, /* R42 - OUT4 to ADC */ |
80 | 0x000C, /* R37 - PLL K 1 */ | 81 | { 43, 0x0000 }, /* R43 - Beep control */ |
81 | 0x0093, /* R38 - PLL K 2 */ | 82 | { 44, 0x0033 }, /* R44 - Input ctrl */ |
82 | 0x00E9, /* R39 - PLL K 3 */ | 83 | { 45, 0x0010 }, /* R45 - Left INP PGA gain ctrl */ |
83 | 0x0000, /* R40 */ | 84 | { 46, 0x0010 }, /* R46 - Right INP PGA gain ctrl */ |
84 | 0x0000, /* R41 - 3D control */ | 85 | { 47, 0x0100 }, /* R47 - Left ADC BOOST ctrl */ |
85 | 0x0000, /* R42 - OUT4 to ADC */ | 86 | { 48, 0x0100 }, /* R48 - Right ADC BOOST ctrl */ |
86 | 0x0000, /* R43 - Beep control */ | 87 | { 49, 0x0002 }, /* R49 - Output ctrl */ |
87 | 0x0033, /* R44 - Input ctrl */ | 88 | { 50, 0x0001 }, /* R50 - Left mixer ctrl */ |
88 | 0x0010, /* R45 - Left INP PGA gain ctrl */ | 89 | { 51, 0x0001 }, /* R51 - Right mixer ctrl */ |
89 | 0x0010, /* R46 - Right INP PGA gain ctrl */ | 90 | { 52, 0x0039 }, /* R52 - LOUT1 (HP) volume ctrl */ |
90 | 0x0100, /* R47 - Left ADC BOOST ctrl */ | 91 | { 53, 0x0039 }, /* R53 - ROUT1 (HP) volume ctrl */ |
91 | 0x0100, /* R48 - Right ADC BOOST ctrl */ | 92 | { 54, 0x0039 }, /* R54 - LOUT2 (SPK) volume ctrl */ |
92 | 0x0002, /* R49 - Output ctrl */ | 93 | { 55, 0x0039 }, /* R55 - ROUT2 (SPK) volume ctrl */ |
93 | 0x0001, /* R50 - Left mixer ctrl */ | 94 | { 56, 0x0001 }, /* R56 - OUT3 mixer ctrl */ |
94 | 0x0001, /* R51 - Right mixer ctrl */ | 95 | { 57, 0x0001 }, /* R57 - OUT4 (MONO) mix ctrl */ |
95 | 0x0039, /* R52 - LOUT1 (HP) volume ctrl */ | 96 | { 60, 0x0004 }, /* R60 - OUTPUT ctrl */ |
96 | 0x0039, /* R53 - ROUT1 (HP) volume ctrl */ | 97 | { 61, 0x0000 }, /* R61 - BIAS CTRL */ |
97 | 0x0039, /* R54 - LOUT2 (SPK) volume ctrl */ | ||
98 | 0x0039, /* R55 - ROUT2 (SPK) volume ctrl */ | ||
99 | 0x0001, /* R56 - OUT3 mixer ctrl */ | ||
100 | 0x0001, /* R57 - OUT4 (MONO) mix ctrl */ | ||
101 | 0x0001, /* R58 */ | ||
102 | 0x0000, /* R59 */ | ||
103 | 0x0004, /* R60 - OUTPUT ctrl */ | ||
104 | 0x0000, /* R61 - BIAS CTRL */ | ||
105 | 0x0180, /* R62 */ | ||
106 | 0x0000 /* R63 */ | ||
107 | }; | 98 | }; |
108 | 99 | ||
100 | static bool wm8985_writeable(struct device *dev, unsigned int reg) | ||
101 | { | ||
102 | switch (reg) { | ||
103 | case WM8985_SOFTWARE_RESET: | ||
104 | case WM8985_POWER_MANAGEMENT_1: | ||
105 | case WM8985_POWER_MANAGEMENT_2: | ||
106 | case WM8985_POWER_MANAGEMENT_3: | ||
107 | case WM8985_AUDIO_INTERFACE: | ||
108 | case WM8985_COMPANDING_CONTROL: | ||
109 | case WM8985_CLOCK_GEN_CONTROL: | ||
110 | case WM8985_ADDITIONAL_CONTROL: | ||
111 | case WM8985_GPIO_CONTROL: | ||
112 | case WM8985_JACK_DETECT_CONTROL_1: | ||
113 | case WM8985_DAC_CONTROL: | ||
114 | case WM8985_LEFT_DAC_DIGITAL_VOL: | ||
115 | case WM8985_RIGHT_DAC_DIGITAL_VOL: | ||
116 | case WM8985_JACK_DETECT_CONTROL_2: | ||
117 | case WM8985_ADC_CONTROL: | ||
118 | case WM8985_LEFT_ADC_DIGITAL_VOL: | ||
119 | case WM8985_RIGHT_ADC_DIGITAL_VOL: | ||
120 | case WM8985_EQ1_LOW_SHELF: | ||
121 | case WM8985_EQ2_PEAK_1: | ||
122 | case WM8985_EQ3_PEAK_2: | ||
123 | case WM8985_EQ4_PEAK_3: | ||
124 | case WM8985_EQ5_HIGH_SHELF: | ||
125 | case WM8985_DAC_LIMITER_1: | ||
126 | case WM8985_DAC_LIMITER_2: | ||
127 | case WM8985_NOTCH_FILTER_1: | ||
128 | case WM8985_NOTCH_FILTER_2: | ||
129 | case WM8985_NOTCH_FILTER_3: | ||
130 | case WM8985_NOTCH_FILTER_4: | ||
131 | case WM8985_ALC_CONTROL_1: | ||
132 | case WM8985_ALC_CONTROL_2: | ||
133 | case WM8985_ALC_CONTROL_3: | ||
134 | case WM8985_NOISE_GATE: | ||
135 | case WM8985_PLL_N: | ||
136 | case WM8985_PLL_K_1: | ||
137 | case WM8985_PLL_K_2: | ||
138 | case WM8985_PLL_K_3: | ||
139 | case WM8985_3D_CONTROL: | ||
140 | case WM8985_OUT4_TO_ADC: | ||
141 | case WM8985_BEEP_CONTROL: | ||
142 | case WM8985_INPUT_CTRL: | ||
143 | case WM8985_LEFT_INP_PGA_GAIN_CTRL: | ||
144 | case WM8985_RIGHT_INP_PGA_GAIN_CTRL: | ||
145 | case WM8985_LEFT_ADC_BOOST_CTRL: | ||
146 | case WM8985_RIGHT_ADC_BOOST_CTRL: | ||
147 | case WM8985_OUTPUT_CTRL0: | ||
148 | case WM8985_LEFT_MIXER_CTRL: | ||
149 | case WM8985_RIGHT_MIXER_CTRL: | ||
150 | case WM8985_LOUT1_HP_VOLUME_CTRL: | ||
151 | case WM8985_ROUT1_HP_VOLUME_CTRL: | ||
152 | case WM8985_LOUT2_SPK_VOLUME_CTRL: | ||
153 | case WM8985_ROUT2_SPK_VOLUME_CTRL: | ||
154 | case WM8985_OUT3_MIXER_CTRL: | ||
155 | case WM8985_OUT4_MONO_MIX_CTRL: | ||
156 | case WM8985_OUTPUT_CTRL1: | ||
157 | case WM8985_BIAS_CTRL: | ||
158 | return true; | ||
159 | default: | ||
160 | return false; | ||
161 | } | ||
162 | } | ||
163 | |||
109 | /* | 164 | /* |
110 | * latch bit 8 of these registers to ensure instant | 165 | * latch bit 8 of these registers to ensure instant |
111 | * volume updates | 166 | * volume updates |
@@ -124,7 +179,7 @@ static const int volume_update_regs[] = { | |||
124 | }; | 179 | }; |
125 | 180 | ||
126 | struct wm8985_priv { | 181 | struct wm8985_priv { |
127 | enum snd_soc_control_type control_type; | 182 | struct regmap *regmap; |
128 | struct regulator_bulk_data supplies[WM8985_NUM_SUPPLIES]; | 183 | struct regulator_bulk_data supplies[WM8985_NUM_SUPPLIES]; |
129 | unsigned int sysclk; | 184 | unsigned int sysclk; |
130 | unsigned int bclk; | 185 | unsigned int bclk; |
@@ -428,7 +483,7 @@ static const struct snd_soc_dapm_widget wm8985_dapm_widgets[] = { | |||
428 | SND_SOC_DAPM_OUTPUT("SPKR") | 483 | SND_SOC_DAPM_OUTPUT("SPKR") |
429 | }; | 484 | }; |
430 | 485 | ||
431 | static const struct snd_soc_dapm_route audio_map[] = { | 486 | static const struct snd_soc_dapm_route wm8985_dapm_routes[] = { |
432 | { "Right Output Mixer", "PCM Switch", "Right DAC" }, | 487 | { "Right Output Mixer", "PCM Switch", "Right DAC" }, |
433 | { "Right Output Mixer", "Aux Switch", "AUXR" }, | 488 | { "Right Output Mixer", "Aux Switch", "AUXR" }, |
434 | { "Right Output Mixer", "Line Switch", "Right Boost Mixer" }, | 489 | { "Right Output Mixer", "Line Switch", "Right Boost Mixer" }, |
@@ -531,17 +586,6 @@ static int eqmode_put(struct snd_kcontrol *kcontrol, | |||
531 | return 0; | 586 | return 0; |
532 | } | 587 | } |
533 | 588 | ||
534 | static int wm8985_add_widgets(struct snd_soc_codec *codec) | ||
535 | { | ||
536 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
537 | |||
538 | snd_soc_dapm_new_controls(dapm, wm8985_dapm_widgets, | ||
539 | ARRAY_SIZE(wm8985_dapm_widgets)); | ||
540 | snd_soc_dapm_add_routes(dapm, audio_map, | ||
541 | ARRAY_SIZE(audio_map)); | ||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | static int wm8985_reset(struct snd_soc_codec *codec) | 589 | static int wm8985_reset(struct snd_soc_codec *codec) |
546 | { | 590 | { |
547 | return snd_soc_write(codec, WM8985_SOFTWARE_RESET, 0x0); | 591 | return snd_soc_write(codec, WM8985_SOFTWARE_RESET, 0x0); |
@@ -845,25 +889,6 @@ static int wm8985_set_sysclk(struct snd_soc_dai *dai, | |||
845 | return 0; | 889 | return 0; |
846 | } | 890 | } |
847 | 891 | ||
848 | static void wm8985_sync_cache(struct snd_soc_codec *codec) | ||
849 | { | ||
850 | short i; | ||
851 | u16 *cache; | ||
852 | |||
853 | if (!codec->cache_sync) | ||
854 | return; | ||
855 | codec->cache_only = 0; | ||
856 | /* restore cache */ | ||
857 | cache = codec->reg_cache; | ||
858 | for (i = 0; i < codec->driver->reg_cache_size; i++) { | ||
859 | if (i == WM8985_SOFTWARE_RESET | ||
860 | || cache[i] == wm8985_reg_defs[i]) | ||
861 | continue; | ||
862 | snd_soc_write(codec, i, cache[i]); | ||
863 | } | ||
864 | codec->cache_sync = 0; | ||
865 | } | ||
866 | |||
867 | static int wm8985_set_bias_level(struct snd_soc_codec *codec, | 892 | static int wm8985_set_bias_level(struct snd_soc_codec *codec, |
868 | enum snd_soc_bias_level level) | 893 | enum snd_soc_bias_level level) |
869 | { | 894 | { |
@@ -890,7 +915,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec, | |||
890 | return ret; | 915 | return ret; |
891 | } | 916 | } |
892 | 917 | ||
893 | wm8985_sync_cache(codec); | 918 | regcache_sync(wm8985->regmap); |
894 | 919 | ||
895 | /* enable anti-pop features */ | 920 | /* enable anti-pop features */ |
896 | snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC, | 921 | snd_soc_update_bits(codec, WM8985_OUT4_TO_ADC, |
@@ -933,7 +958,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec, | |||
933 | snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, 0); | 958 | snd_soc_write(codec, WM8985_POWER_MANAGEMENT_2, 0); |
934 | snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, 0); | 959 | snd_soc_write(codec, WM8985_POWER_MANAGEMENT_3, 0); |
935 | 960 | ||
936 | codec->cache_sync = 1; | 961 | regcache_mark_dirty(wm8985->regmap); |
937 | 962 | ||
938 | regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies), | 963 | regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies), |
939 | wm8985->supplies); | 964 | wm8985->supplies); |
@@ -976,11 +1001,11 @@ static int wm8985_probe(struct snd_soc_codec *codec) | |||
976 | size_t i; | 1001 | size_t i; |
977 | struct wm8985_priv *wm8985; | 1002 | struct wm8985_priv *wm8985; |
978 | int ret; | 1003 | int ret; |
979 | u16 *cache; | ||
980 | 1004 | ||
981 | wm8985 = snd_soc_codec_get_drvdata(codec); | 1005 | wm8985 = snd_soc_codec_get_drvdata(codec); |
1006 | codec->control_data = wm8985->regmap; | ||
982 | 1007 | ||
983 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8985->control_type); | 1008 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); |
984 | if (ret < 0) { | 1009 | if (ret < 0) { |
985 | dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); | 1010 | dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); |
986 | return ret; | 1011 | return ret; |
@@ -1009,17 +1034,13 @@ static int wm8985_probe(struct snd_soc_codec *codec) | |||
1009 | goto err_reg_enable; | 1034 | goto err_reg_enable; |
1010 | } | 1035 | } |
1011 | 1036 | ||
1012 | cache = codec->reg_cache; | ||
1013 | /* latch volume update bits */ | 1037 | /* latch volume update bits */ |
1014 | for (i = 0; i < ARRAY_SIZE(volume_update_regs); ++i) | 1038 | for (i = 0; i < ARRAY_SIZE(volume_update_regs); ++i) |
1015 | cache[volume_update_regs[i]] |= 0x100; | 1039 | snd_soc_update_bits(codec, volume_update_regs[i], |
1040 | 0x100, 0x100); | ||
1016 | /* enable BIASCUT */ | 1041 | /* enable BIASCUT */ |
1017 | cache[WM8985_BIAS_CTRL] |= WM8985_BIASCUT; | 1042 | snd_soc_update_bits(codec, WM8985_BIAS_CTRL, WM8985_BIASCUT, |
1018 | codec->cache_sync = 1; | 1043 | WM8985_BIASCUT); |
1019 | |||
1020 | snd_soc_add_controls(codec, wm8985_snd_controls, | ||
1021 | ARRAY_SIZE(wm8985_snd_controls)); | ||
1022 | wm8985_add_widgets(codec); | ||
1023 | 1044 | ||
1024 | wm8985_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1045 | wm8985_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1025 | return 0; | 1046 | return 0; |
@@ -1068,9 +1089,25 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8985 = { | |||
1068 | .suspend = wm8985_suspend, | 1089 | .suspend = wm8985_suspend, |
1069 | .resume = wm8985_resume, | 1090 | .resume = wm8985_resume, |
1070 | .set_bias_level = wm8985_set_bias_level, | 1091 | .set_bias_level = wm8985_set_bias_level, |
1071 | .reg_cache_size = ARRAY_SIZE(wm8985_reg_defs), | 1092 | |
1072 | .reg_word_size = sizeof(u16), | 1093 | .controls = wm8985_snd_controls, |
1073 | .reg_cache_default = wm8985_reg_defs | 1094 | .num_controls = ARRAY_SIZE(wm8985_snd_controls), |
1095 | .dapm_widgets = wm8985_dapm_widgets, | ||
1096 | .num_dapm_widgets = ARRAY_SIZE(wm8985_dapm_widgets), | ||
1097 | .dapm_routes = wm8985_dapm_routes, | ||
1098 | .num_dapm_routes = ARRAY_SIZE(wm8985_dapm_routes), | ||
1099 | }; | ||
1100 | |||
1101 | static const struct regmap_config wm8985_regmap = { | ||
1102 | .reg_bits = 7, | ||
1103 | .val_bits = 9, | ||
1104 | |||
1105 | .max_register = WM8985_MAX_REGISTER, | ||
1106 | .writeable_reg = wm8985_writeable, | ||
1107 | |||
1108 | .cache_type = REGCACHE_RBTREE, | ||
1109 | .reg_defaults = wm8985_reg_defaults, | ||
1110 | .num_reg_defaults = ARRAY_SIZE(wm8985_reg_defaults), | ||
1074 | }; | 1111 | }; |
1075 | 1112 | ||
1076 | #if defined(CONFIG_SPI_MASTER) | 1113 | #if defined(CONFIG_SPI_MASTER) |
@@ -1079,24 +1116,39 @@ static int __devinit wm8985_spi_probe(struct spi_device *spi) | |||
1079 | struct wm8985_priv *wm8985; | 1116 | struct wm8985_priv *wm8985; |
1080 | int ret; | 1117 | int ret; |
1081 | 1118 | ||
1082 | wm8985 = kzalloc(sizeof *wm8985, GFP_KERNEL); | 1119 | wm8985 = devm_kzalloc(&spi->dev, sizeof *wm8985, GFP_KERNEL); |
1083 | if (!wm8985) | 1120 | if (!wm8985) |
1084 | return -ENOMEM; | 1121 | return -ENOMEM; |
1085 | 1122 | ||
1086 | wm8985->control_type = SND_SOC_SPI; | ||
1087 | spi_set_drvdata(spi, wm8985); | 1123 | spi_set_drvdata(spi, wm8985); |
1088 | 1124 | ||
1125 | wm8985->regmap = regmap_init_spi(spi, &wm8985_regmap); | ||
1126 | if (IS_ERR(wm8985->regmap)) { | ||
1127 | ret = PTR_ERR(wm8985->regmap); | ||
1128 | dev_err(&spi->dev, "Failed to allocate register map: %d\n", | ||
1129 | ret); | ||
1130 | goto err; | ||
1131 | } | ||
1132 | |||
1089 | ret = snd_soc_register_codec(&spi->dev, | 1133 | ret = snd_soc_register_codec(&spi->dev, |
1090 | &soc_codec_dev_wm8985, &wm8985_dai, 1); | 1134 | &soc_codec_dev_wm8985, &wm8985_dai, 1); |
1091 | if (ret < 0) | 1135 | if (ret != 0) |
1092 | kfree(wm8985); | 1136 | goto err; |
1137 | |||
1138 | return 0; | ||
1139 | |||
1140 | err: | ||
1141 | regmap_exit(wm8985->regmap); | ||
1093 | return ret; | 1142 | return ret; |
1094 | } | 1143 | } |
1095 | 1144 | ||
1096 | static int __devexit wm8985_spi_remove(struct spi_device *spi) | 1145 | static int __devexit wm8985_spi_remove(struct spi_device *spi) |
1097 | { | 1146 | { |
1147 | struct wm8985_priv *wm8985 = spi_get_drvdata(spi); | ||
1148 | |||
1098 | snd_soc_unregister_codec(&spi->dev); | 1149 | snd_soc_unregister_codec(&spi->dev); |
1099 | kfree(spi_get_drvdata(spi)); | 1150 | regmap_exit(wm8985->regmap); |
1151 | |||
1100 | return 0; | 1152 | return 0; |
1101 | } | 1153 | } |
1102 | 1154 | ||
@@ -1117,24 +1169,39 @@ static __devinit int wm8985_i2c_probe(struct i2c_client *i2c, | |||
1117 | struct wm8985_priv *wm8985; | 1169 | struct wm8985_priv *wm8985; |
1118 | int ret; | 1170 | int ret; |
1119 | 1171 | ||
1120 | wm8985 = kzalloc(sizeof *wm8985, GFP_KERNEL); | 1172 | wm8985 = devm_kzalloc(&i2c->dev, sizeof *wm8985, GFP_KERNEL); |
1121 | if (!wm8985) | 1173 | if (!wm8985) |
1122 | return -ENOMEM; | 1174 | return -ENOMEM; |
1123 | 1175 | ||
1124 | wm8985->control_type = SND_SOC_I2C; | ||
1125 | i2c_set_clientdata(i2c, wm8985); | 1176 | i2c_set_clientdata(i2c, wm8985); |
1126 | 1177 | ||
1178 | wm8985->regmap = regmap_init_i2c(i2c, &wm8985_regmap); | ||
1179 | if (IS_ERR(wm8985->regmap)) { | ||
1180 | ret = PTR_ERR(wm8985->regmap); | ||
1181 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
1182 | ret); | ||
1183 | goto err; | ||
1184 | } | ||
1185 | |||
1127 | ret = snd_soc_register_codec(&i2c->dev, | 1186 | ret = snd_soc_register_codec(&i2c->dev, |
1128 | &soc_codec_dev_wm8985, &wm8985_dai, 1); | 1187 | &soc_codec_dev_wm8985, &wm8985_dai, 1); |
1129 | if (ret < 0) | 1188 | if (ret != 0) |
1130 | kfree(wm8985); | 1189 | goto err; |
1190 | |||
1191 | return 0; | ||
1192 | |||
1193 | err: | ||
1194 | regmap_exit(wm8985->regmap); | ||
1131 | return ret; | 1195 | return ret; |
1132 | } | 1196 | } |
1133 | 1197 | ||
1134 | static __devexit int wm8985_i2c_remove(struct i2c_client *client) | 1198 | static __devexit int wm8985_i2c_remove(struct i2c_client *i2c) |
1135 | { | 1199 | { |
1136 | snd_soc_unregister_codec(&client->dev); | 1200 | struct wm8985_priv *wm8985 = i2c_get_clientdata(i2c); |
1137 | kfree(i2c_get_clientdata(client)); | 1201 | |
1202 | snd_soc_unregister_codec(&i2c->dev); | ||
1203 | regmap_exit(wm8985->regmap); | ||
1204 | |||
1138 | return 0; | 1205 | return 0; |
1139 | } | 1206 | } |
1140 | 1207 | ||
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index ab52963dd04c..6cdf6a2bc283 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c | |||
@@ -33,24 +33,89 @@ | |||
33 | * We can't read the WM8988 register space when we | 33 | * We can't read the WM8988 register space when we |
34 | * are using 2 wire for device control, so we cache them instead. | 34 | * are using 2 wire for device control, so we cache them instead. |
35 | */ | 35 | */ |
36 | static const u16 wm8988_reg[] = { | 36 | static const struct reg_default wm8988_reg_defaults[] = { |
37 | 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ | 37 | { 0, 0x0097 }, |
38 | 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ | 38 | { 1, 0x0097 }, |
39 | 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ | 39 | { 2, 0x0079 }, |
40 | 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ | 40 | { 3, 0x0079 }, |
41 | 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ | 41 | { 5, 0x0008 }, |
42 | 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ | 42 | { 7, 0x000a }, |
43 | 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ | 43 | { 8, 0x0000 }, |
44 | 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ | 44 | { 10, 0x00ff }, |
45 | 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ | 45 | { 11, 0x00ff }, |
46 | 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ | 46 | { 12, 0x000f }, |
47 | 0x0079, 0x0079, 0x0079, /* 40 */ | 47 | { 13, 0x000f }, |
48 | { 16, 0x0000 }, | ||
49 | { 17, 0x007b }, | ||
50 | { 18, 0x0000 }, | ||
51 | { 19, 0x0032 }, | ||
52 | { 20, 0x0000 }, | ||
53 | { 21, 0x00c3 }, | ||
54 | { 22, 0x00c3 }, | ||
55 | { 23, 0x00c0 }, | ||
56 | { 24, 0x0000 }, | ||
57 | { 25, 0x0000 }, | ||
58 | { 26, 0x0000 }, | ||
59 | { 27, 0x0000 }, | ||
60 | { 31, 0x0000 }, | ||
61 | { 32, 0x0000 }, | ||
62 | { 33, 0x0000 }, | ||
63 | { 34, 0x0050 }, | ||
64 | { 35, 0x0050 }, | ||
65 | { 36, 0x0050 }, | ||
66 | { 37, 0x0050 }, | ||
67 | { 40, 0x0079 }, | ||
68 | { 41, 0x0079 }, | ||
69 | { 42, 0x0079 }, | ||
48 | }; | 70 | }; |
49 | 71 | ||
72 | static bool wm8988_writeable(struct device *dev, unsigned int reg) | ||
73 | { | ||
74 | switch (reg) { | ||
75 | case WM8988_LINVOL: | ||
76 | case WM8988_RINVOL: | ||
77 | case WM8988_LOUT1V: | ||
78 | case WM8988_ROUT1V: | ||
79 | case WM8988_ADCDAC: | ||
80 | case WM8988_IFACE: | ||
81 | case WM8988_SRATE: | ||
82 | case WM8988_LDAC: | ||
83 | case WM8988_RDAC: | ||
84 | case WM8988_BASS: | ||
85 | case WM8988_TREBLE: | ||
86 | case WM8988_RESET: | ||
87 | case WM8988_3D: | ||
88 | case WM8988_ALC1: | ||
89 | case WM8988_ALC2: | ||
90 | case WM8988_ALC3: | ||
91 | case WM8988_NGATE: | ||
92 | case WM8988_LADC: | ||
93 | case WM8988_RADC: | ||
94 | case WM8988_ADCTL1: | ||
95 | case WM8988_ADCTL2: | ||
96 | case WM8988_PWR1: | ||
97 | case WM8988_PWR2: | ||
98 | case WM8988_ADCTL3: | ||
99 | case WM8988_ADCIN: | ||
100 | case WM8988_LADCIN: | ||
101 | case WM8988_RADCIN: | ||
102 | case WM8988_LOUTM1: | ||
103 | case WM8988_LOUTM2: | ||
104 | case WM8988_ROUTM1: | ||
105 | case WM8988_ROUTM2: | ||
106 | case WM8988_LOUT2V: | ||
107 | case WM8988_ROUT2V: | ||
108 | case WM8988_LPPB: | ||
109 | return true; | ||
110 | default: | ||
111 | return false; | ||
112 | } | ||
113 | } | ||
114 | |||
50 | /* codec private data */ | 115 | /* codec private data */ |
51 | struct wm8988_priv { | 116 | struct wm8988_priv { |
117 | struct regmap *regmap; | ||
52 | unsigned int sysclk; | 118 | unsigned int sysclk; |
53 | enum snd_soc_control_type control_type; | ||
54 | struct snd_pcm_hw_constraint_list *sysclk_constraints; | 119 | struct snd_pcm_hw_constraint_list *sysclk_constraints; |
55 | }; | 120 | }; |
56 | 121 | ||
@@ -317,7 +382,7 @@ static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = { | |||
317 | SND_SOC_DAPM_INPUT("RINPUT2"), | 382 | SND_SOC_DAPM_INPUT("RINPUT2"), |
318 | }; | 383 | }; |
319 | 384 | ||
320 | static const struct snd_soc_dapm_route audio_map[] = { | 385 | static const struct snd_soc_dapm_route wm8988_dapm_routes[] = { |
321 | 386 | ||
322 | { "Left Line Mux", "Line 1", "LINPUT1" }, | 387 | { "Left Line Mux", "Line 1", "LINPUT1" }, |
323 | { "Left Line Mux", "Line 2", "LINPUT2" }, | 388 | { "Left Line Mux", "Line 2", "LINPUT2" }, |
@@ -661,6 +726,7 @@ static int wm8988_mute(struct snd_soc_dai *dai, int mute) | |||
661 | static int wm8988_set_bias_level(struct snd_soc_codec *codec, | 726 | static int wm8988_set_bias_level(struct snd_soc_codec *codec, |
662 | enum snd_soc_bias_level level) | 727 | enum snd_soc_bias_level level) |
663 | { | 728 | { |
729 | struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); | ||
664 | u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1; | 730 | u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1; |
665 | 731 | ||
666 | switch (level) { | 732 | switch (level) { |
@@ -674,7 +740,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec, | |||
674 | 740 | ||
675 | case SND_SOC_BIAS_STANDBY: | 741 | case SND_SOC_BIAS_STANDBY: |
676 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 742 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
677 | snd_soc_cache_sync(codec); | 743 | regcache_sync(wm8988->regmap); |
678 | 744 | ||
679 | /* VREF, VMID=2x5k */ | 745 | /* VREF, VMID=2x5k */ |
680 | snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); | 746 | snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); |
@@ -730,7 +796,10 @@ static struct snd_soc_dai_driver wm8988_dai = { | |||
730 | 796 | ||
731 | static int wm8988_suspend(struct snd_soc_codec *codec) | 797 | static int wm8988_suspend(struct snd_soc_codec *codec) |
732 | { | 798 | { |
799 | struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); | ||
800 | |||
733 | wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); | 801 | wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); |
802 | regcache_mark_dirty(wm8988->regmap); | ||
734 | return 0; | 803 | return 0; |
735 | } | 804 | } |
736 | 805 | ||
@@ -743,10 +812,10 @@ static int wm8988_resume(struct snd_soc_codec *codec) | |||
743 | static int wm8988_probe(struct snd_soc_codec *codec) | 812 | static int wm8988_probe(struct snd_soc_codec *codec) |
744 | { | 813 | { |
745 | struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); | 814 | struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); |
746 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
747 | int ret = 0; | 815 | int ret = 0; |
748 | 816 | ||
749 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type); | 817 | codec->control_data = wm8988->regmap; |
818 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP); | ||
750 | if (ret < 0) { | 819 | if (ret < 0) { |
751 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 820 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
752 | return ret; | 821 | return ret; |
@@ -767,12 +836,6 @@ static int wm8988_probe(struct snd_soc_codec *codec) | |||
767 | 836 | ||
768 | wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 837 | wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
769 | 838 | ||
770 | snd_soc_add_controls(codec, wm8988_snd_controls, | ||
771 | ARRAY_SIZE(wm8988_snd_controls)); | ||
772 | snd_soc_dapm_new_controls(dapm, wm8988_dapm_widgets, | ||
773 | ARRAY_SIZE(wm8988_dapm_widgets)); | ||
774 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
775 | |||
776 | return 0; | 839 | return 0; |
777 | } | 840 | } |
778 | 841 | ||
@@ -788,9 +851,25 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8988 = { | |||
788 | .suspend = wm8988_suspend, | 851 | .suspend = wm8988_suspend, |
789 | .resume = wm8988_resume, | 852 | .resume = wm8988_resume, |
790 | .set_bias_level = wm8988_set_bias_level, | 853 | .set_bias_level = wm8988_set_bias_level, |
791 | .reg_cache_size = ARRAY_SIZE(wm8988_reg), | 854 | |
792 | .reg_word_size = sizeof(u16), | 855 | .controls = wm8988_snd_controls, |
793 | .reg_cache_default = wm8988_reg, | 856 | .num_controls = ARRAY_SIZE(wm8988_snd_controls), |
857 | .dapm_widgets = wm8988_dapm_widgets, | ||
858 | .num_dapm_widgets = ARRAY_SIZE(wm8988_dapm_widgets), | ||
859 | .dapm_routes = wm8988_dapm_routes, | ||
860 | .num_dapm_routes = ARRAY_SIZE(wm8988_dapm_routes), | ||
861 | }; | ||
862 | |||
863 | static struct regmap_config wm8988_regmap = { | ||
864 | .reg_bits = 7, | ||
865 | .val_bits = 9, | ||
866 | |||
867 | .max_register = WM8988_LPPB, | ||
868 | .writeable_reg = wm8988_writeable, | ||
869 | |||
870 | .cache_type = REGCACHE_RBTREE, | ||
871 | .reg_defaults = wm8988_reg_defaults, | ||
872 | .num_reg_defaults = ARRAY_SIZE(wm8988_reg_defaults), | ||
794 | }; | 873 | }; |
795 | 874 | ||
796 | #if defined(CONFIG_SPI_MASTER) | 875 | #if defined(CONFIG_SPI_MASTER) |
@@ -799,24 +878,33 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi) | |||
799 | struct wm8988_priv *wm8988; | 878 | struct wm8988_priv *wm8988; |
800 | int ret; | 879 | int ret; |
801 | 880 | ||
802 | wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); | 881 | wm8988 = devm_kzalloc(&spi->dev, sizeof(struct wm8988_priv), |
882 | GFP_KERNEL); | ||
803 | if (wm8988 == NULL) | 883 | if (wm8988 == NULL) |
804 | return -ENOMEM; | 884 | return -ENOMEM; |
805 | 885 | ||
806 | wm8988->control_type = SND_SOC_SPI; | 886 | wm8988->regmap = regmap_init_spi(spi, &wm8988_regmap); |
887 | if (IS_ERR(wm8988->regmap)) { | ||
888 | ret = PTR_ERR(wm8988->regmap); | ||
889 | dev_err(&spi->dev, "Failed to init regmap: %d\n", ret); | ||
890 | return ret; | ||
891 | } | ||
892 | |||
807 | spi_set_drvdata(spi, wm8988); | 893 | spi_set_drvdata(spi, wm8988); |
808 | 894 | ||
809 | ret = snd_soc_register_codec(&spi->dev, | 895 | ret = snd_soc_register_codec(&spi->dev, |
810 | &soc_codec_dev_wm8988, &wm8988_dai, 1); | 896 | &soc_codec_dev_wm8988, &wm8988_dai, 1); |
811 | if (ret < 0) | 897 | if (ret != 0) |
812 | kfree(wm8988); | 898 | regmap_exit(wm8988->regmap); |
899 | |||
813 | return ret; | 900 | return ret; |
814 | } | 901 | } |
815 | 902 | ||
816 | static int __devexit wm8988_spi_remove(struct spi_device *spi) | 903 | static int __devexit wm8988_spi_remove(struct spi_device *spi) |
817 | { | 904 | { |
905 | struct wm8988_priv *wm8988 = spi_get_drvdata(spi); | ||
818 | snd_soc_unregister_codec(&spi->dev); | 906 | snd_soc_unregister_codec(&spi->dev); |
819 | kfree(spi_get_drvdata(spi)); | 907 | regmap_exit(wm8988->regmap); |
820 | return 0; | 908 | return 0; |
821 | } | 909 | } |
822 | 910 | ||
@@ -837,24 +925,33 @@ static __devinit int wm8988_i2c_probe(struct i2c_client *i2c, | |||
837 | struct wm8988_priv *wm8988; | 925 | struct wm8988_priv *wm8988; |
838 | int ret; | 926 | int ret; |
839 | 927 | ||
840 | wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); | 928 | wm8988 = devm_kzalloc(&i2c->dev, sizeof(struct wm8988_priv), |
929 | GFP_KERNEL); | ||
841 | if (wm8988 == NULL) | 930 | if (wm8988 == NULL) |
842 | return -ENOMEM; | 931 | return -ENOMEM; |
843 | 932 | ||
844 | i2c_set_clientdata(i2c, wm8988); | 933 | i2c_set_clientdata(i2c, wm8988); |
845 | wm8988->control_type = SND_SOC_I2C; | 934 | |
935 | wm8988->regmap = regmap_init_i2c(i2c, &wm8988_regmap); | ||
936 | if (IS_ERR(wm8988->regmap)) { | ||
937 | ret = PTR_ERR(wm8988->regmap); | ||
938 | dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret); | ||
939 | return ret; | ||
940 | } | ||
846 | 941 | ||
847 | ret = snd_soc_register_codec(&i2c->dev, | 942 | ret = snd_soc_register_codec(&i2c->dev, |
848 | &soc_codec_dev_wm8988, &wm8988_dai, 1); | 943 | &soc_codec_dev_wm8988, &wm8988_dai, 1); |
849 | if (ret < 0) | 944 | if (ret != 0) |
850 | kfree(wm8988); | 945 | regmap_exit(wm8988->regmap); |
946 | |||
851 | return ret; | 947 | return ret; |
852 | } | 948 | } |
853 | 949 | ||
854 | static __devexit int wm8988_i2c_remove(struct i2c_client *client) | 950 | static __devexit int wm8988_i2c_remove(struct i2c_client *client) |
855 | { | 951 | { |
952 | struct wm8988_priv *wm8988 = i2c_get_clientdata(client); | ||
856 | snd_soc_unregister_codec(&client->dev); | 953 | snd_soc_unregister_codec(&client->dev); |
857 | kfree(i2c_get_clientdata(client)); | 954 | regmap_exit(wm8988->regmap); |
858 | return 0; | 955 | return 0; |
859 | } | 956 | } |
860 | 957 | ||
@@ -866,7 +963,7 @@ MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id); | |||
866 | 963 | ||
867 | static struct i2c_driver wm8988_i2c_driver = { | 964 | static struct i2c_driver wm8988_i2c_driver = { |
868 | .driver = { | 965 | .driver = { |
869 | .name = "wm8988-codec", | 966 | .name = "wm8988", |
870 | .owner = THIS_MODULE, | 967 | .owner = THIS_MODULE, |
871 | }, | 968 | }, |
872 | .probe = wm8988_i2c_probe, | 969 | .probe = wm8988_i2c_probe, |
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index e538edaae1f0..9d242351e6e8 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c | |||
@@ -1356,7 +1356,7 @@ static int wm8990_probe(struct snd_soc_codec *codec) | |||
1356 | snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); | 1356 | snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); |
1357 | snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); | 1357 | snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); |
1358 | 1358 | ||
1359 | snd_soc_add_controls(codec, wm8990_snd_controls, | 1359 | snd_soc_add_codec_controls(codec, wm8990_snd_controls, |
1360 | ARRAY_SIZE(wm8990_snd_controls)); | 1360 | ARRAY_SIZE(wm8990_snd_controls)); |
1361 | wm8990_add_widgets(codec); | 1361 | wm8990_add_widgets(codec); |
1362 | 1362 | ||
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index 7ee40da8dbb5..9ac31ba9b82e 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c | |||
@@ -1297,7 +1297,7 @@ static int wm8991_probe(struct snd_soc_codec *codec) | |||
1297 | snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); | 1297 | snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); |
1298 | snd_soc_write(codec, WM8991_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); | 1298 | snd_soc_write(codec, WM8991_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); |
1299 | 1299 | ||
1300 | snd_soc_add_controls(codec, wm8991_snd_controls, | 1300 | snd_soc_add_codec_controls(codec, wm8991_snd_controls, |
1301 | ARRAY_SIZE(wm8991_snd_controls)); | 1301 | ARRAY_SIZE(wm8991_snd_controls)); |
1302 | 1302 | ||
1303 | snd_soc_dapm_new_controls(&codec->dapm, wm8991_dapm_widgets, | 1303 | snd_soc_dapm_new_controls(&codec->dapm, wm8991_dapm_widgets, |
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 7c7fd925db8d..d256a9340644 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <linux/regmap.h> | ||
19 | #include <linux/regulator/consumer.h> | 20 | #include <linux/regulator/consumer.h> |
20 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
@@ -40,134 +41,113 @@ static const char *wm8993_supply_names[WM8993_NUM_SUPPLIES] = { | |||
40 | "SPKVDD", | 41 | "SPKVDD", |
41 | }; | 42 | }; |
42 | 43 | ||
43 | static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = { | 44 | static struct reg_default wm8993_reg_defaults[] = { |
44 | 0x8993, /* R0 - Software Reset */ | 45 | { 1, 0x0000 }, /* R1 - Power Management (1) */ |
45 | 0x0000, /* R1 - Power Management (1) */ | 46 | { 2, 0x6000 }, /* R2 - Power Management (2) */ |
46 | 0x6000, /* R2 - Power Management (2) */ | 47 | { 3, 0x0000 }, /* R3 - Power Management (3) */ |
47 | 0x0000, /* R3 - Power Management (3) */ | 48 | { 4, 0x4050 }, /* R4 - Audio Interface (1) */ |
48 | 0x4050, /* R4 - Audio Interface (1) */ | 49 | { 5, 0x4000 }, /* R5 - Audio Interface (2) */ |
49 | 0x4000, /* R5 - Audio Interface (2) */ | 50 | { 6, 0x01C8 }, /* R6 - Clocking 1 */ |
50 | 0x01C8, /* R6 - Clocking 1 */ | 51 | { 7, 0x0000 }, /* R7 - Clocking 2 */ |
51 | 0x0000, /* R7 - Clocking 2 */ | 52 | { 8, 0x0000 }, /* R8 - Audio Interface (3) */ |
52 | 0x0000, /* R8 - Audio Interface (3) */ | 53 | { 9, 0x0040 }, /* R9 - Audio Interface (4) */ |
53 | 0x0040, /* R9 - Audio Interface (4) */ | 54 | { 10, 0x0004 }, /* R10 - DAC CTRL */ |
54 | 0x0004, /* R10 - DAC CTRL */ | 55 | { 11, 0x00C0 }, /* R11 - Left DAC Digital Volume */ |
55 | 0x00C0, /* R11 - Left DAC Digital Volume */ | 56 | { 12, 0x00C0 }, /* R12 - Right DAC Digital Volume */ |
56 | 0x00C0, /* R12 - Right DAC Digital Volume */ | 57 | { 13, 0x0000 }, /* R13 - Digital Side Tone */ |
57 | 0x0000, /* R13 - Digital Side Tone */ | 58 | { 14, 0x0300 }, /* R14 - ADC CTRL */ |
58 | 0x0300, /* R14 - ADC CTRL */ | 59 | { 15, 0x00C0 }, /* R15 - Left ADC Digital Volume */ |
59 | 0x00C0, /* R15 - Left ADC Digital Volume */ | 60 | { 16, 0x00C0 }, /* R16 - Right ADC Digital Volume */ |
60 | 0x00C0, /* R16 - Right ADC Digital Volume */ | 61 | { 18, 0x0000 }, /* R18 - GPIO CTRL 1 */ |
61 | 0x0000, /* R17 */ | 62 | { 19, 0x0010 }, /* R19 - GPIO1 */ |
62 | 0x0000, /* R18 - GPIO CTRL 1 */ | 63 | { 20, 0x0000 }, /* R20 - IRQ_DEBOUNCE */ |
63 | 0x0010, /* R19 - GPIO1 */ | 64 | { 21, 0x0000 }, /* R21 - Inputs Clamp */ |
64 | 0x0000, /* R20 - IRQ_DEBOUNCE */ | 65 | { 22, 0x8000 }, /* R22 - GPIOCTRL 2 */ |
65 | 0x0000, /* R21 */ | 66 | { 23, 0x0800 }, /* R23 - GPIO_POL */ |
66 | 0x8000, /* R22 - GPIOCTRL 2 */ | 67 | { 24, 0x008B }, /* R24 - Left Line Input 1&2 Volume */ |
67 | 0x0800, /* R23 - GPIO_POL */ | 68 | { 25, 0x008B }, /* R25 - Left Line Input 3&4 Volume */ |
68 | 0x008B, /* R24 - Left Line Input 1&2 Volume */ | 69 | { 26, 0x008B }, /* R26 - Right Line Input 1&2 Volume */ |
69 | 0x008B, /* R25 - Left Line Input 3&4 Volume */ | 70 | { 27, 0x008B }, /* R27 - Right Line Input 3&4 Volume */ |
70 | 0x008B, /* R26 - Right Line Input 1&2 Volume */ | 71 | { 28, 0x006D }, /* R28 - Left Output Volume */ |
71 | 0x008B, /* R27 - Right Line Input 3&4 Volume */ | 72 | { 29, 0x006D }, /* R29 - Right Output Volume */ |
72 | 0x006D, /* R28 - Left Output Volume */ | 73 | { 30, 0x0066 }, /* R30 - Line Outputs Volume */ |
73 | 0x006D, /* R29 - Right Output Volume */ | 74 | { 31, 0x0020 }, /* R31 - HPOUT2 Volume */ |
74 | 0x0066, /* R30 - Line Outputs Volume */ | 75 | { 32, 0x0079 }, /* R32 - Left OPGA Volume */ |
75 | 0x0020, /* R31 - HPOUT2 Volume */ | 76 | { 33, 0x0079 }, /* R33 - Right OPGA Volume */ |
76 | 0x0079, /* R32 - Left OPGA Volume */ | 77 | { 34, 0x0003 }, /* R34 - SPKMIXL Attenuation */ |
77 | 0x0079, /* R33 - Right OPGA Volume */ | 78 | { 35, 0x0003 }, /* R35 - SPKMIXR Attenuation */ |
78 | 0x0003, /* R34 - SPKMIXL Attenuation */ | 79 | { 36, 0x0011 }, /* R36 - SPKOUT Mixers */ |
79 | 0x0003, /* R35 - SPKMIXR Attenuation */ | 80 | { 37, 0x0100 }, /* R37 - SPKOUT Boost */ |
80 | 0x0011, /* R36 - SPKOUT Mixers */ | 81 | { 38, 0x0079 }, /* R38 - Speaker Volume Left */ |
81 | 0x0100, /* R37 - SPKOUT Boost */ | 82 | { 39, 0x0079 }, /* R39 - Speaker Volume Right */ |
82 | 0x0079, /* R38 - Speaker Volume Left */ | 83 | { 40, 0x0000 }, /* R40 - Input Mixer2 */ |
83 | 0x0079, /* R39 - Speaker Volume Right */ | 84 | { 41, 0x0000 }, /* R41 - Input Mixer3 */ |
84 | 0x0000, /* R40 - Input Mixer2 */ | 85 | { 42, 0x0000 }, /* R42 - Input Mixer4 */ |
85 | 0x0000, /* R41 - Input Mixer3 */ | 86 | { 43, 0x0000 }, /* R43 - Input Mixer5 */ |
86 | 0x0000, /* R42 - Input Mixer4 */ | 87 | { 44, 0x0000 }, /* R44 - Input Mixer6 */ |
87 | 0x0000, /* R43 - Input Mixer5 */ | 88 | { 45, 0x0000 }, /* R45 - Output Mixer1 */ |
88 | 0x0000, /* R44 - Input Mixer6 */ | 89 | { 46, 0x0000 }, /* R46 - Output Mixer2 */ |
89 | 0x0000, /* R45 - Output Mixer1 */ | 90 | { 47, 0x0000 }, /* R47 - Output Mixer3 */ |
90 | 0x0000, /* R46 - Output Mixer2 */ | 91 | { 48, 0x0000 }, /* R48 - Output Mixer4 */ |
91 | 0x0000, /* R47 - Output Mixer3 */ | 92 | { 49, 0x0000 }, /* R49 - Output Mixer5 */ |
92 | 0x0000, /* R48 - Output Mixer4 */ | 93 | { 50, 0x0000 }, /* R50 - Output Mixer6 */ |
93 | 0x0000, /* R49 - Output Mixer5 */ | 94 | { 51, 0x0000 }, /* R51 - HPOUT2 Mixer */ |
94 | 0x0000, /* R50 - Output Mixer6 */ | 95 | { 52, 0x0000 }, /* R52 - Line Mixer1 */ |
95 | 0x0000, /* R51 - HPOUT2 Mixer */ | 96 | { 53, 0x0000 }, /* R53 - Line Mixer2 */ |
96 | 0x0000, /* R52 - Line Mixer1 */ | 97 | { 54, 0x0000 }, /* R54 - Speaker Mixer */ |
97 | 0x0000, /* R53 - Line Mixer2 */ | 98 | { 55, 0x0000 }, /* R55 - Additional Control */ |
98 | 0x0000, /* R54 - Speaker Mixer */ | 99 | { 56, 0x0000 }, /* R56 - AntiPOP1 */ |
99 | 0x0000, /* R55 - Additional Control */ | 100 | { 57, 0x0000 }, /* R57 - AntiPOP2 */ |
100 | 0x0000, /* R56 - AntiPOP1 */ | 101 | { 58, 0x0000 }, /* R58 - MICBIAS */ |
101 | 0x0000, /* R57 - AntiPOP2 */ | 102 | { 60, 0x0000 }, /* R60 - FLL Control 1 */ |
102 | 0x0000, /* R58 - MICBIAS */ | 103 | { 61, 0x0000 }, /* R61 - FLL Control 2 */ |
103 | 0x0000, /* R59 */ | 104 | { 62, 0x0000 }, /* R62 - FLL Control 3 */ |
104 | 0x0000, /* R60 - FLL Control 1 */ | 105 | { 63, 0x2EE0 }, /* R63 - FLL Control 4 */ |
105 | 0x0000, /* R61 - FLL Control 2 */ | 106 | { 64, 0x0002 }, /* R64 - FLL Control 5 */ |
106 | 0x0000, /* R62 - FLL Control 3 */ | 107 | { 65, 0x2287 }, /* R65 - Clocking 3 */ |
107 | 0x2EE0, /* R63 - FLL Control 4 */ | 108 | { 66, 0x025F }, /* R66 - Clocking 4 */ |
108 | 0x0002, /* R64 - FLL Control 5 */ | 109 | { 67, 0x0000 }, /* R67 - MW Slave Control */ |
109 | 0x2287, /* R65 - Clocking 3 */ | 110 | { 69, 0x0002 }, /* R69 - Bus Control 1 */ |
110 | 0x025F, /* R66 - Clocking 4 */ | 111 | { 70, 0x0000 }, /* R70 - Write Sequencer 0 */ |
111 | 0x0000, /* R67 - MW Slave Control */ | 112 | { 71, 0x0000 }, /* R71 - Write Sequencer 1 */ |
112 | 0x0000, /* R68 */ | 113 | { 72, 0x0000 }, /* R72 - Write Sequencer 2 */ |
113 | 0x0002, /* R69 - Bus Control 1 */ | 114 | { 73, 0x0000 }, /* R73 - Write Sequencer 3 */ |
114 | 0x0000, /* R70 - Write Sequencer 0 */ | 115 | { 74, 0x0000 }, /* R74 - Write Sequencer 4 */ |
115 | 0x0000, /* R71 - Write Sequencer 1 */ | 116 | { 75, 0x0000 }, /* R75 - Write Sequencer 5 */ |
116 | 0x0000, /* R72 - Write Sequencer 2 */ | 117 | { 76, 0x1F25 }, /* R76 - Charge Pump 1 */ |
117 | 0x0000, /* R73 - Write Sequencer 3 */ | 118 | { 81, 0x0000 }, /* R81 - Class W 0 */ |
118 | 0x0000, /* R74 - Write Sequencer 4 */ | 119 | { 85, 0x054A }, /* R85 - DC Servo 1 */ |
119 | 0x0000, /* R75 - Write Sequencer 5 */ | 120 | { 87, 0x0000 }, /* R87 - DC Servo 3 */ |
120 | 0x1F25, /* R76 - Charge Pump 1 */ | 121 | { 96, 0x0100 }, /* R96 - Analogue HP 0 */ |
121 | 0x0000, /* R77 */ | 122 | { 98, 0x0000 }, /* R98 - EQ1 */ |
122 | 0x0000, /* R78 */ | 123 | { 99, 0x000C }, /* R99 - EQ2 */ |
123 | 0x0000, /* R79 */ | 124 | { 100, 0x000C }, /* R100 - EQ3 */ |
124 | 0x0000, /* R80 */ | 125 | { 101, 0x000C }, /* R101 - EQ4 */ |
125 | 0x0000, /* R81 - Class W 0 */ | 126 | { 102, 0x000C }, /* R102 - EQ5 */ |
126 | 0x0000, /* R82 */ | 127 | { 103, 0x000C }, /* R103 - EQ6 */ |
127 | 0x0000, /* R83 */ | 128 | { 104, 0x0FCA }, /* R104 - EQ7 */ |
128 | 0x0000, /* R84 - DC Servo 0 */ | 129 | { 105, 0x0400 }, /* R105 - EQ8 */ |
129 | 0x054A, /* R85 - DC Servo 1 */ | 130 | { 106, 0x00D8 }, /* R106 - EQ9 */ |
130 | 0x0000, /* R86 */ | 131 | { 107, 0x1EB5 }, /* R107 - EQ10 */ |
131 | 0x0000, /* R87 - DC Servo 3 */ | 132 | { 108, 0xF145 }, /* R108 - EQ11 */ |
132 | 0x0000, /* R88 - DC Servo Readback 0 */ | 133 | { 109, 0x0B75 }, /* R109 - EQ12 */ |
133 | 0x0000, /* R89 - DC Servo Readback 1 */ | 134 | { 110, 0x01C5 }, /* R110 - EQ13 */ |
134 | 0x0000, /* R90 - DC Servo Readback 2 */ | 135 | { 111, 0x1C58 }, /* R111 - EQ14 */ |
135 | 0x0000, /* R91 */ | 136 | { 112, 0xF373 }, /* R112 - EQ15 */ |
136 | 0x0000, /* R92 */ | 137 | { 113, 0x0A54 }, /* R113 - EQ16 */ |
137 | 0x0000, /* R93 */ | 138 | { 114, 0x0558 }, /* R114 - EQ17 */ |
138 | 0x0000, /* R94 */ | 139 | { 115, 0x168E }, /* R115 - EQ18 */ |
139 | 0x0000, /* R95 */ | 140 | { 116, 0xF829 }, /* R116 - EQ19 */ |
140 | 0x0100, /* R96 - Analogue HP 0 */ | 141 | { 117, 0x07AD }, /* R117 - EQ20 */ |
141 | 0x0000, /* R97 */ | 142 | { 118, 0x1103 }, /* R118 - EQ21 */ |
142 | 0x0000, /* R98 - EQ1 */ | 143 | { 119, 0x0564 }, /* R119 - EQ22 */ |
143 | 0x000C, /* R99 - EQ2 */ | 144 | { 120, 0x0559 }, /* R120 - EQ23 */ |
144 | 0x000C, /* R100 - EQ3 */ | 145 | { 121, 0x4000 }, /* R121 - EQ24 */ |
145 | 0x000C, /* R101 - EQ4 */ | 146 | { 122, 0x0000 }, /* R122 - Digital Pulls */ |
146 | 0x000C, /* R102 - EQ5 */ | 147 | { 123, 0x0F08 }, /* R123 - DRC Control 1 */ |
147 | 0x000C, /* R103 - EQ6 */ | 148 | { 124, 0x0000 }, /* R124 - DRC Control 2 */ |
148 | 0x0FCA, /* R104 - EQ7 */ | 149 | { 125, 0x0080 }, /* R125 - DRC Control 3 */ |
149 | 0x0400, /* R105 - EQ8 */ | 150 | { 126, 0x0000 }, /* R126 - DRC Control 4 */ |
150 | 0x00D8, /* R106 - EQ9 */ | ||
151 | 0x1EB5, /* R107 - EQ10 */ | ||
152 | 0xF145, /* R108 - EQ11 */ | ||
153 | 0x0B75, /* R109 - EQ12 */ | ||
154 | 0x01C5, /* R110 - EQ13 */ | ||
155 | 0x1C58, /* R111 - EQ14 */ | ||
156 | 0xF373, /* R112 - EQ15 */ | ||
157 | 0x0A54, /* R113 - EQ16 */ | ||
158 | 0x0558, /* R114 - EQ17 */ | ||
159 | 0x168E, /* R115 - EQ18 */ | ||
160 | 0xF829, /* R116 - EQ19 */ | ||
161 | 0x07AD, /* R117 - EQ20 */ | ||
162 | 0x1103, /* R118 - EQ21 */ | ||
163 | 0x0564, /* R119 - EQ22 */ | ||
164 | 0x0559, /* R120 - EQ23 */ | ||
165 | 0x4000, /* R121 - EQ24 */ | ||
166 | 0x0000, /* R122 - Digital Pulls */ | ||
167 | 0x0F08, /* R123 - DRC Control 1 */ | ||
168 | 0x0000, /* R124 - DRC Control 2 */ | ||
169 | 0x0080, /* R125 - DRC Control 3 */ | ||
170 | 0x0000, /* R126 - DRC Control 4 */ | ||
171 | }; | 151 | }; |
172 | 152 | ||
173 | static struct { | 153 | static struct { |
@@ -225,9 +205,11 @@ static struct { | |||
225 | 205 | ||
226 | struct wm8993_priv { | 206 | struct wm8993_priv { |
227 | struct wm_hubs_data hubs_data; | 207 | struct wm_hubs_data hubs_data; |
208 | struct device *dev; | ||
209 | struct regmap *regmap; | ||
228 | struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES]; | 210 | struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES]; |
229 | struct wm8993_platform_data pdata; | 211 | struct wm8993_platform_data pdata; |
230 | enum snd_soc_control_type control_type; | 212 | struct completion fll_lock; |
231 | int master; | 213 | int master; |
232 | int sysclk_source; | 214 | int sysclk_source; |
233 | int tdm_slots; | 215 | int tdm_slots; |
@@ -242,17 +224,137 @@ struct wm8993_priv { | |||
242 | int fll_src; | 224 | int fll_src; |
243 | }; | 225 | }; |
244 | 226 | ||
245 | static int wm8993_volatile(struct snd_soc_codec *codec, unsigned int reg) | 227 | static bool wm8993_volatile(struct device *dev, unsigned int reg) |
246 | { | 228 | { |
247 | switch (reg) { | 229 | switch (reg) { |
248 | case WM8993_SOFTWARE_RESET: | 230 | case WM8993_SOFTWARE_RESET: |
231 | case WM8993_GPIO_CTRL_1: | ||
249 | case WM8993_DC_SERVO_0: | 232 | case WM8993_DC_SERVO_0: |
250 | case WM8993_DC_SERVO_READBACK_0: | 233 | case WM8993_DC_SERVO_READBACK_0: |
251 | case WM8993_DC_SERVO_READBACK_1: | 234 | case WM8993_DC_SERVO_READBACK_1: |
252 | case WM8993_DC_SERVO_READBACK_2: | 235 | case WM8993_DC_SERVO_READBACK_2: |
253 | return 1; | 236 | return true; |
254 | default: | 237 | default: |
255 | return 0; | 238 | return false; |
239 | } | ||
240 | } | ||
241 | |||
242 | static bool wm8993_readable(struct device *dev, unsigned int reg) | ||
243 | { | ||
244 | switch (reg) { | ||
245 | case WM8993_SOFTWARE_RESET: | ||
246 | case WM8993_POWER_MANAGEMENT_1: | ||
247 | case WM8993_POWER_MANAGEMENT_2: | ||
248 | case WM8993_POWER_MANAGEMENT_3: | ||
249 | case WM8993_AUDIO_INTERFACE_1: | ||
250 | case WM8993_AUDIO_INTERFACE_2: | ||
251 | case WM8993_CLOCKING_1: | ||
252 | case WM8993_CLOCKING_2: | ||
253 | case WM8993_AUDIO_INTERFACE_3: | ||
254 | case WM8993_AUDIO_INTERFACE_4: | ||
255 | case WM8993_DAC_CTRL: | ||
256 | case WM8993_LEFT_DAC_DIGITAL_VOLUME: | ||
257 | case WM8993_RIGHT_DAC_DIGITAL_VOLUME: | ||
258 | case WM8993_DIGITAL_SIDE_TONE: | ||
259 | case WM8993_ADC_CTRL: | ||
260 | case WM8993_LEFT_ADC_DIGITAL_VOLUME: | ||
261 | case WM8993_RIGHT_ADC_DIGITAL_VOLUME: | ||
262 | case WM8993_GPIO_CTRL_1: | ||
263 | case WM8993_GPIO1: | ||
264 | case WM8993_IRQ_DEBOUNCE: | ||
265 | case WM8993_GPIOCTRL_2: | ||
266 | case WM8993_GPIO_POL: | ||
267 | case WM8993_LEFT_LINE_INPUT_1_2_VOLUME: | ||
268 | case WM8993_LEFT_LINE_INPUT_3_4_VOLUME: | ||
269 | case WM8993_RIGHT_LINE_INPUT_1_2_VOLUME: | ||
270 | case WM8993_RIGHT_LINE_INPUT_3_4_VOLUME: | ||
271 | case WM8993_LEFT_OUTPUT_VOLUME: | ||
272 | case WM8993_RIGHT_OUTPUT_VOLUME: | ||
273 | case WM8993_LINE_OUTPUTS_VOLUME: | ||
274 | case WM8993_HPOUT2_VOLUME: | ||
275 | case WM8993_LEFT_OPGA_VOLUME: | ||
276 | case WM8993_RIGHT_OPGA_VOLUME: | ||
277 | case WM8993_SPKMIXL_ATTENUATION: | ||
278 | case WM8993_SPKMIXR_ATTENUATION: | ||
279 | case WM8993_SPKOUT_MIXERS: | ||
280 | case WM8993_SPKOUT_BOOST: | ||
281 | case WM8993_SPEAKER_VOLUME_LEFT: | ||
282 | case WM8993_SPEAKER_VOLUME_RIGHT: | ||
283 | case WM8993_INPUT_MIXER2: | ||
284 | case WM8993_INPUT_MIXER3: | ||
285 | case WM8993_INPUT_MIXER4: | ||
286 | case WM8993_INPUT_MIXER5: | ||
287 | case WM8993_INPUT_MIXER6: | ||
288 | case WM8993_OUTPUT_MIXER1: | ||
289 | case WM8993_OUTPUT_MIXER2: | ||
290 | case WM8993_OUTPUT_MIXER3: | ||
291 | case WM8993_OUTPUT_MIXER4: | ||
292 | case WM8993_OUTPUT_MIXER5: | ||
293 | case WM8993_OUTPUT_MIXER6: | ||
294 | case WM8993_HPOUT2_MIXER: | ||
295 | case WM8993_LINE_MIXER1: | ||
296 | case WM8993_LINE_MIXER2: | ||
297 | case WM8993_SPEAKER_MIXER: | ||
298 | case WM8993_ADDITIONAL_CONTROL: | ||
299 | case WM8993_ANTIPOP1: | ||
300 | case WM8993_ANTIPOP2: | ||
301 | case WM8993_MICBIAS: | ||
302 | case WM8993_FLL_CONTROL_1: | ||
303 | case WM8993_FLL_CONTROL_2: | ||
304 | case WM8993_FLL_CONTROL_3: | ||
305 | case WM8993_FLL_CONTROL_4: | ||
306 | case WM8993_FLL_CONTROL_5: | ||
307 | case WM8993_CLOCKING_3: | ||
308 | case WM8993_CLOCKING_4: | ||
309 | case WM8993_MW_SLAVE_CONTROL: | ||
310 | case WM8993_BUS_CONTROL_1: | ||
311 | case WM8993_WRITE_SEQUENCER_0: | ||
312 | case WM8993_WRITE_SEQUENCER_1: | ||
313 | case WM8993_WRITE_SEQUENCER_2: | ||
314 | case WM8993_WRITE_SEQUENCER_3: | ||
315 | case WM8993_WRITE_SEQUENCER_4: | ||
316 | case WM8993_WRITE_SEQUENCER_5: | ||
317 | case WM8993_CHARGE_PUMP_1: | ||
318 | case WM8993_CLASS_W_0: | ||
319 | case WM8993_DC_SERVO_0: | ||
320 | case WM8993_DC_SERVO_1: | ||
321 | case WM8993_DC_SERVO_3: | ||
322 | case WM8993_DC_SERVO_READBACK_0: | ||
323 | case WM8993_DC_SERVO_READBACK_1: | ||
324 | case WM8993_DC_SERVO_READBACK_2: | ||
325 | case WM8993_ANALOGUE_HP_0: | ||
326 | case WM8993_EQ1: | ||
327 | case WM8993_EQ2: | ||
328 | case WM8993_EQ3: | ||
329 | case WM8993_EQ4: | ||
330 | case WM8993_EQ5: | ||
331 | case WM8993_EQ6: | ||
332 | case WM8993_EQ7: | ||
333 | case WM8993_EQ8: | ||
334 | case WM8993_EQ9: | ||
335 | case WM8993_EQ10: | ||
336 | case WM8993_EQ11: | ||
337 | case WM8993_EQ12: | ||
338 | case WM8993_EQ13: | ||
339 | case WM8993_EQ14: | ||
340 | case WM8993_EQ15: | ||
341 | case WM8993_EQ16: | ||
342 | case WM8993_EQ17: | ||
343 | case WM8993_EQ18: | ||
344 | case WM8993_EQ19: | ||
345 | case WM8993_EQ20: | ||
346 | case WM8993_EQ21: | ||
347 | case WM8993_EQ22: | ||
348 | case WM8993_EQ23: | ||
349 | case WM8993_EQ24: | ||
350 | case WM8993_DIGITAL_PULLS: | ||
351 | case WM8993_DRC_CONTROL_1: | ||
352 | case WM8993_DRC_CONTROL_2: | ||
353 | case WM8993_DRC_CONTROL_3: | ||
354 | case WM8993_DRC_CONTROL_4: | ||
355 | return true; | ||
356 | default: | ||
357 | return false; | ||
256 | } | 358 | } |
257 | } | 359 | } |
258 | 360 | ||
@@ -369,8 +471,10 @@ static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
369 | unsigned int Fref, unsigned int Fout) | 471 | unsigned int Fref, unsigned int Fout) |
370 | { | 472 | { |
371 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); | 473 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
474 | struct i2c_client *i2c = to_i2c_client(codec->dev); | ||
372 | u16 reg1, reg4, reg5; | 475 | u16 reg1, reg4, reg5; |
373 | struct _fll_div fll_div; | 476 | struct _fll_div fll_div; |
477 | unsigned int timeout; | ||
374 | int ret; | 478 | int ret; |
375 | 479 | ||
376 | /* Any change? */ | 480 | /* Any change? */ |
@@ -441,14 +545,22 @@ static int _wm8993_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
441 | reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT; | 545 | reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT; |
442 | snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5); | 546 | snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5); |
443 | 547 | ||
548 | /* If we've got an interrupt wired up make sure we get it */ | ||
549 | if (i2c->irq) | ||
550 | timeout = msecs_to_jiffies(20); | ||
551 | else if (Fref < 1000000) | ||
552 | timeout = msecs_to_jiffies(3); | ||
553 | else | ||
554 | timeout = msecs_to_jiffies(1); | ||
555 | |||
556 | try_wait_for_completion(&wm8993->fll_lock); | ||
557 | |||
444 | /* Enable the FLL */ | 558 | /* Enable the FLL */ |
445 | snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA); | 559 | snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA); |
446 | 560 | ||
447 | /* Both overestimates */ | 561 | timeout = wait_for_completion_timeout(&wm8993->fll_lock, timeout); |
448 | if (Fref < 1000000) | 562 | if (i2c->irq && !timeout) |
449 | msleep(3); | 563 | dev_warn(codec->dev, "Timed out waiting for FLL\n"); |
450 | else | ||
451 | msleep(1); | ||
452 | 564 | ||
453 | dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); | 565 | dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); |
454 | 566 | ||
@@ -946,6 +1058,8 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, | |||
946 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); | 1058 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
947 | int ret; | 1059 | int ret; |
948 | 1060 | ||
1061 | wm_hubs_set_bias_level(codec, level); | ||
1062 | |||
949 | switch (level) { | 1063 | switch (level) { |
950 | case SND_SOC_BIAS_ON: | 1064 | case SND_SOC_BIAS_ON: |
951 | case SND_SOC_BIAS_PREPARE: | 1065 | case SND_SOC_BIAS_PREPARE: |
@@ -963,12 +1077,10 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, | |||
963 | if (ret != 0) | 1077 | if (ret != 0) |
964 | return ret; | 1078 | return ret; |
965 | 1079 | ||
966 | snd_soc_cache_sync(codec); | 1080 | regcache_cache_only(wm8993->regmap, false); |
1081 | regcache_sync(wm8993->regmap); | ||
967 | 1082 | ||
968 | /* Tune DC servo configuration */ | 1083 | wm_hubs_vmid_ena(codec); |
969 | snd_soc_write(codec, 0x44, 3); | ||
970 | snd_soc_write(codec, 0x56, 3); | ||
971 | snd_soc_write(codec, 0x44, 0); | ||
972 | 1084 | ||
973 | /* Bring up VMID with fast soft start */ | 1085 | /* Bring up VMID with fast soft start */ |
974 | snd_soc_update_bits(codec, WM8993_ANTIPOP2, | 1086 | snd_soc_update_bits(codec, WM8993_ANTIPOP2, |
@@ -1024,14 +1136,8 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, | |||
1024 | WM8993_VMID_RAMP_MASK | | 1136 | WM8993_VMID_RAMP_MASK | |
1025 | WM8993_BIAS_SRC, 0); | 1137 | WM8993_BIAS_SRC, 0); |
1026 | 1138 | ||
1027 | #ifdef CONFIG_REGULATOR | 1139 | regcache_cache_only(wm8993->regmap, true); |
1028 | /* Post 2.6.34 we will be able to get a callback when | 1140 | regcache_mark_dirty(wm8993->regmap); |
1029 | * the regulators are disabled which we can use but | ||
1030 | * for now just assume that the power will be cut if | ||
1031 | * the regulator API is in use. | ||
1032 | */ | ||
1033 | codec->cache_sync = 1; | ||
1034 | #endif | ||
1035 | 1141 | ||
1036 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), | 1142 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), |
1037 | wm8993->supplies); | 1143 | wm8993->supplies); |
@@ -1378,6 +1484,45 @@ out: | |||
1378 | return 0; | 1484 | return 0; |
1379 | } | 1485 | } |
1380 | 1486 | ||
1487 | static irqreturn_t wm8993_irq(int irq, void *data) | ||
1488 | { | ||
1489 | struct wm8993_priv *wm8993 = data; | ||
1490 | int mask, val, ret; | ||
1491 | |||
1492 | ret = regmap_read(wm8993->regmap, WM8993_GPIO_CTRL_1, &val); | ||
1493 | if (ret != 0) { | ||
1494 | dev_err(wm8993->dev, "Failed to read interrupt status: %d\n", | ||
1495 | ret); | ||
1496 | return IRQ_NONE; | ||
1497 | } | ||
1498 | |||
1499 | ret = regmap_read(wm8993->regmap, WM8993_GPIOCTRL_2, &mask); | ||
1500 | if (ret != 0) { | ||
1501 | dev_err(wm8993->dev, "Failed to read interrupt mask: %d\n", | ||
1502 | ret); | ||
1503 | return IRQ_NONE; | ||
1504 | } | ||
1505 | |||
1506 | /* The IRQ pin status is visible in the register too */ | ||
1507 | val &= ~(mask | WM8993_IRQ); | ||
1508 | if (!val) | ||
1509 | return IRQ_NONE; | ||
1510 | |||
1511 | if (val & WM8993_TEMPOK_EINT) | ||
1512 | dev_crit(wm8993->dev, "Thermal warning\n"); | ||
1513 | |||
1514 | if (val & WM8993_FLL_LOCK_EINT) { | ||
1515 | dev_dbg(wm8993->dev, "FLL locked\n"); | ||
1516 | complete(&wm8993->fll_lock); | ||
1517 | } | ||
1518 | |||
1519 | ret = regmap_write(wm8993->regmap, WM8993_GPIO_CTRL_1, val); | ||
1520 | if (ret != 0) | ||
1521 | dev_err(wm8993->dev, "Failed to ack interrupt: %d\n", ret); | ||
1522 | |||
1523 | return IRQ_HANDLED; | ||
1524 | } | ||
1525 | |||
1381 | static const struct snd_soc_dai_ops wm8993_ops = { | 1526 | static const struct snd_soc_dai_ops wm8993_ops = { |
1382 | .set_sysclk = wm8993_set_sysclk, | 1527 | .set_sysclk = wm8993_set_sysclk, |
1383 | .set_fmt = wm8993_set_dai_fmt, | 1528 | .set_fmt = wm8993_set_dai_fmt, |
@@ -1402,6 +1547,7 @@ static struct snd_soc_dai_driver wm8993_dai = { | |||
1402 | .channels_max = 2, | 1547 | .channels_max = 2, |
1403 | .rates = WM8993_RATES, | 1548 | .rates = WM8993_RATES, |
1404 | .formats = WM8993_FORMATS, | 1549 | .formats = WM8993_FORMATS, |
1550 | .sig_bits = 24, | ||
1405 | }, | 1551 | }, |
1406 | .capture = { | 1552 | .capture = { |
1407 | .stream_name = "Capture", | 1553 | .stream_name = "Capture", |
@@ -1409,6 +1555,7 @@ static struct snd_soc_dai_driver wm8993_dai = { | |||
1409 | .channels_max = 2, | 1555 | .channels_max = 2, |
1410 | .rates = WM8993_RATES, | 1556 | .rates = WM8993_RATES, |
1411 | .formats = WM8993_FORMATS, | 1557 | .formats = WM8993_FORMATS, |
1558 | .sig_bits = 24, | ||
1412 | }, | 1559 | }, |
1413 | .ops = &wm8993_ops, | 1560 | .ops = &wm8993_ops, |
1414 | .symmetric_rates = 1, | 1561 | .symmetric_rates = 1, |
@@ -1418,49 +1565,20 @@ static int wm8993_probe(struct snd_soc_codec *codec) | |||
1418 | { | 1565 | { |
1419 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); | 1566 | struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
1420 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 1567 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
1421 | int ret, i, val; | 1568 | int ret; |
1422 | 1569 | ||
1423 | wm8993->hubs_data.hp_startup_mode = 1; | 1570 | wm8993->hubs_data.hp_startup_mode = 1; |
1424 | wm8993->hubs_data.dcs_codes_l = -2; | 1571 | wm8993->hubs_data.dcs_codes_l = -2; |
1425 | wm8993->hubs_data.dcs_codes_r = -2; | 1572 | wm8993->hubs_data.dcs_codes_r = -2; |
1426 | wm8993->hubs_data.series_startup = 1; | 1573 | wm8993->hubs_data.series_startup = 1; |
1427 | 1574 | ||
1428 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); | 1575 | codec->control_data = wm8993->regmap; |
1576 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
1429 | if (ret != 0) { | 1577 | if (ret != 0) { |
1430 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 1578 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
1431 | return ret; | 1579 | return ret; |
1432 | } | 1580 | } |
1433 | 1581 | ||
1434 | for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++) | ||
1435 | wm8993->supplies[i].supply = wm8993_supply_names[i]; | ||
1436 | |||
1437 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies), | ||
1438 | wm8993->supplies); | ||
1439 | if (ret != 0) { | ||
1440 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | ||
1441 | return ret; | ||
1442 | } | ||
1443 | |||
1444 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), | ||
1445 | wm8993->supplies); | ||
1446 | if (ret != 0) { | ||
1447 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | ||
1448 | goto err_get; | ||
1449 | } | ||
1450 | |||
1451 | val = snd_soc_read(codec, WM8993_SOFTWARE_RESET); | ||
1452 | if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) { | ||
1453 | dev_err(codec->dev, "Invalid ID register value %x\n", val); | ||
1454 | ret = -EINVAL; | ||
1455 | goto err_enable; | ||
1456 | } | ||
1457 | |||
1458 | ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff); | ||
1459 | if (ret != 0) | ||
1460 | goto err_enable; | ||
1461 | |||
1462 | codec->cache_only = 1; | ||
1463 | |||
1464 | /* By default we're using the output mixers */ | 1582 | /* By default we're using the output mixers */ |
1465 | wm8993->class_w_users = 2; | 1583 | wm8993->class_w_users = 2; |
1466 | 1584 | ||
@@ -1489,15 +1607,15 @@ static int wm8993_probe(struct snd_soc_codec *codec) | |||
1489 | 1607 | ||
1490 | ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1608 | ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1491 | if (ret != 0) | 1609 | if (ret != 0) |
1492 | goto err_enable; | 1610 | return ret; |
1493 | 1611 | ||
1494 | snd_soc_add_controls(codec, wm8993_snd_controls, | 1612 | snd_soc_add_codec_controls(codec, wm8993_snd_controls, |
1495 | ARRAY_SIZE(wm8993_snd_controls)); | 1613 | ARRAY_SIZE(wm8993_snd_controls)); |
1496 | if (wm8993->pdata.num_retune_configs != 0) { | 1614 | if (wm8993->pdata.num_retune_configs != 0) { |
1497 | dev_dbg(codec->dev, "Using ReTune Mobile\n"); | 1615 | dev_dbg(codec->dev, "Using ReTune Mobile\n"); |
1498 | } else { | 1616 | } else { |
1499 | dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n"); | 1617 | dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n"); |
1500 | snd_soc_add_controls(codec, wm8993_eq_controls, | 1618 | snd_soc_add_codec_controls(codec, wm8993_eq_controls, |
1501 | ARRAY_SIZE(wm8993_eq_controls)); | 1619 | ARRAY_SIZE(wm8993_eq_controls)); |
1502 | } | 1620 | } |
1503 | 1621 | ||
@@ -1509,13 +1627,14 @@ static int wm8993_probe(struct snd_soc_codec *codec) | |||
1509 | wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, | 1627 | wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, |
1510 | wm8993->pdata.lineout2_diff); | 1628 | wm8993->pdata.lineout2_diff); |
1511 | 1629 | ||
1630 | /* If the line outputs are differential then we aren't presenting | ||
1631 | * VMID as an output and can disable it. | ||
1632 | */ | ||
1633 | if (wm8993->pdata.lineout1_diff && wm8993->pdata.lineout2_diff) | ||
1634 | codec->dapm.idle_bias_off = 1; | ||
1635 | |||
1512 | return 0; | 1636 | return 0; |
1513 | 1637 | ||
1514 | err_enable: | ||
1515 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1516 | err_get: | ||
1517 | regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1518 | return ret; | ||
1519 | } | 1638 | } |
1520 | 1639 | ||
1521 | static int wm8993_remove(struct snd_soc_codec *codec) | 1640 | static int wm8993_remove(struct snd_soc_codec *codec) |
@@ -1578,41 +1697,149 @@ static int wm8993_resume(struct snd_soc_codec *codec) | |||
1578 | #define wm8993_resume NULL | 1697 | #define wm8993_resume NULL |
1579 | #endif | 1698 | #endif |
1580 | 1699 | ||
1700 | /* Tune DC servo configuration */ | ||
1701 | static struct reg_default wm8993_regmap_patch[] = { | ||
1702 | { 0x44, 3 }, | ||
1703 | { 0x56, 3 }, | ||
1704 | { 0x44, 0 }, | ||
1705 | }; | ||
1706 | |||
1707 | static const struct regmap_config wm8993_regmap = { | ||
1708 | .reg_bits = 8, | ||
1709 | .val_bits = 16, | ||
1710 | |||
1711 | .max_register = WM8993_MAX_REGISTER, | ||
1712 | .volatile_reg = wm8993_volatile, | ||
1713 | .readable_reg = wm8993_readable, | ||
1714 | |||
1715 | .cache_type = REGCACHE_RBTREE, | ||
1716 | .reg_defaults = wm8993_reg_defaults, | ||
1717 | .num_reg_defaults = ARRAY_SIZE(wm8993_reg_defaults), | ||
1718 | }; | ||
1719 | |||
1581 | static struct snd_soc_codec_driver soc_codec_dev_wm8993 = { | 1720 | static struct snd_soc_codec_driver soc_codec_dev_wm8993 = { |
1582 | .probe = wm8993_probe, | 1721 | .probe = wm8993_probe, |
1583 | .remove = wm8993_remove, | 1722 | .remove = wm8993_remove, |
1584 | .suspend = wm8993_suspend, | 1723 | .suspend = wm8993_suspend, |
1585 | .resume = wm8993_resume, | 1724 | .resume = wm8993_resume, |
1586 | .set_bias_level = wm8993_set_bias_level, | 1725 | .set_bias_level = wm8993_set_bias_level, |
1587 | .reg_cache_size = ARRAY_SIZE(wm8993_reg_defaults), | ||
1588 | .reg_word_size = sizeof(u16), | ||
1589 | .reg_cache_default = wm8993_reg_defaults, | ||
1590 | .volatile_register = wm8993_volatile, | ||
1591 | }; | 1726 | }; |
1592 | 1727 | ||
1593 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1594 | static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, | 1728 | static __devinit int wm8993_i2c_probe(struct i2c_client *i2c, |
1595 | const struct i2c_device_id *id) | 1729 | const struct i2c_device_id *id) |
1596 | { | 1730 | { |
1597 | struct wm8993_priv *wm8993; | 1731 | struct wm8993_priv *wm8993; |
1598 | int ret; | 1732 | unsigned int reg; |
1733 | int ret, i; | ||
1599 | 1734 | ||
1600 | wm8993 = devm_kzalloc(&i2c->dev, sizeof(struct wm8993_priv), | 1735 | wm8993 = devm_kzalloc(&i2c->dev, sizeof(struct wm8993_priv), |
1601 | GFP_KERNEL); | 1736 | GFP_KERNEL); |
1602 | if (wm8993 == NULL) | 1737 | if (wm8993 == NULL) |
1603 | return -ENOMEM; | 1738 | return -ENOMEM; |
1604 | 1739 | ||
1740 | wm8993->dev = &i2c->dev; | ||
1741 | init_completion(&wm8993->fll_lock); | ||
1742 | |||
1743 | wm8993->regmap = regmap_init_i2c(i2c, &wm8993_regmap); | ||
1744 | if (IS_ERR(wm8993->regmap)) { | ||
1745 | ret = PTR_ERR(wm8993->regmap); | ||
1746 | dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); | ||
1747 | return ret; | ||
1748 | } | ||
1749 | |||
1605 | i2c_set_clientdata(i2c, wm8993); | 1750 | i2c_set_clientdata(i2c, wm8993); |
1606 | 1751 | ||
1752 | for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++) | ||
1753 | wm8993->supplies[i].supply = wm8993_supply_names[i]; | ||
1754 | |||
1755 | ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8993->supplies), | ||
1756 | wm8993->supplies); | ||
1757 | if (ret != 0) { | ||
1758 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); | ||
1759 | goto err; | ||
1760 | } | ||
1761 | |||
1762 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), | ||
1763 | wm8993->supplies); | ||
1764 | if (ret != 0) { | ||
1765 | dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); | ||
1766 | goto err_get; | ||
1767 | } | ||
1768 | |||
1769 | ret = regmap_read(wm8993->regmap, WM8993_SOFTWARE_RESET, ®); | ||
1770 | if (ret != 0) { | ||
1771 | dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); | ||
1772 | goto err_enable; | ||
1773 | } | ||
1774 | |||
1775 | if (reg != 0x8993) { | ||
1776 | dev_err(&i2c->dev, "Invalid ID register value %x\n", reg); | ||
1777 | ret = -EINVAL; | ||
1778 | goto err_enable; | ||
1779 | } | ||
1780 | |||
1781 | ret = regmap_write(wm8993->regmap, WM8993_SOFTWARE_RESET, 0xffff); | ||
1782 | if (ret != 0) | ||
1783 | goto err_enable; | ||
1784 | |||
1785 | ret = regmap_register_patch(wm8993->regmap, wm8993_regmap_patch, | ||
1786 | ARRAY_SIZE(wm8993_regmap_patch)); | ||
1787 | if (ret != 0) | ||
1788 | dev_warn(wm8993->dev, "Failed to apply regmap patch: %d\n", | ||
1789 | ret); | ||
1790 | |||
1791 | if (i2c->irq) { | ||
1792 | /* Put GPIO1 into interrupt mode (only GPIO1 can output IRQ) */ | ||
1793 | ret = regmap_update_bits(wm8993->regmap, WM8993_GPIO1, | ||
1794 | WM8993_GPIO1_PD | | ||
1795 | WM8993_GPIO1_SEL_MASK, 7); | ||
1796 | if (ret != 0) | ||
1797 | goto err_enable; | ||
1798 | |||
1799 | ret = request_threaded_irq(i2c->irq, NULL, wm8993_irq, | ||
1800 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | ||
1801 | "wm8993", wm8993); | ||
1802 | if (ret != 0) | ||
1803 | goto err_enable; | ||
1804 | |||
1805 | } | ||
1806 | |||
1807 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1808 | |||
1809 | regcache_cache_only(wm8993->regmap, true); | ||
1810 | |||
1607 | ret = snd_soc_register_codec(&i2c->dev, | 1811 | ret = snd_soc_register_codec(&i2c->dev, |
1608 | &soc_codec_dev_wm8993, &wm8993_dai, 1); | 1812 | &soc_codec_dev_wm8993, &wm8993_dai, 1); |
1813 | if (ret != 0) { | ||
1814 | dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); | ||
1815 | goto err_irq; | ||
1816 | } | ||
1817 | |||
1818 | return 0; | ||
1819 | |||
1820 | err_irq: | ||
1821 | if (i2c->irq) | ||
1822 | free_irq(i2c->irq, wm8993); | ||
1823 | err_enable: | ||
1824 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1825 | err_get: | ||
1826 | regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1827 | err: | ||
1828 | regmap_exit(wm8993->regmap); | ||
1609 | return ret; | 1829 | return ret; |
1610 | } | 1830 | } |
1611 | 1831 | ||
1612 | static __devexit int wm8993_i2c_remove(struct i2c_client *client) | 1832 | static __devexit int wm8993_i2c_remove(struct i2c_client *i2c) |
1613 | { | 1833 | { |
1614 | snd_soc_unregister_codec(&client->dev); | 1834 | struct wm8993_priv *wm8993 = i2c_get_clientdata(i2c); |
1615 | kfree(i2c_get_clientdata(client)); | 1835 | |
1836 | snd_soc_unregister_codec(&i2c->dev); | ||
1837 | if (i2c->irq) | ||
1838 | free_irq(i2c->irq, wm8993); | ||
1839 | regmap_exit(wm8993->regmap); | ||
1840 | regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1841 | regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); | ||
1842 | |||
1616 | return 0; | 1843 | return 0; |
1617 | } | 1844 | } |
1618 | 1845 | ||
@@ -1631,30 +1858,8 @@ static struct i2c_driver wm8993_i2c_driver = { | |||
1631 | .remove = __devexit_p(wm8993_i2c_remove), | 1858 | .remove = __devexit_p(wm8993_i2c_remove), |
1632 | .id_table = wm8993_i2c_id, | 1859 | .id_table = wm8993_i2c_id, |
1633 | }; | 1860 | }; |
1634 | #endif | ||
1635 | |||
1636 | static int __init wm8993_modinit(void) | ||
1637 | { | ||
1638 | int ret = 0; | ||
1639 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1640 | ret = i2c_add_driver(&wm8993_i2c_driver); | ||
1641 | if (ret != 0) { | ||
1642 | pr_err("WM8993: Unable to register I2C driver: %d\n", | ||
1643 | ret); | ||
1644 | } | ||
1645 | #endif | ||
1646 | return ret; | ||
1647 | } | ||
1648 | module_init(wm8993_modinit); | ||
1649 | |||
1650 | static void __exit wm8993_exit(void) | ||
1651 | { | ||
1652 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1653 | i2c_del_driver(&wm8993_i2c_driver); | ||
1654 | #endif | ||
1655 | } | ||
1656 | module_exit(wm8993_exit); | ||
1657 | 1861 | ||
1862 | module_i2c_driver(wm8993_i2c_driver); | ||
1658 | 1863 | ||
1659 | MODULE_DESCRIPTION("ASoC WM8993 driver"); | 1864 | MODULE_DESCRIPTION("ASoC WM8993 driver"); |
1660 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 1865 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
diff --git a/sound/soc/codecs/wm8993.h b/sound/soc/codecs/wm8993.h index 2184617b9611..4478b40c86e3 100644 --- a/sound/soc/codecs/wm8993.h +++ b/sound/soc/codecs/wm8993.h | |||
@@ -31,6 +31,7 @@ | |||
31 | #define WM8993_GPIO_CTRL_1 0x12 | 31 | #define WM8993_GPIO_CTRL_1 0x12 |
32 | #define WM8993_GPIO1 0x13 | 32 | #define WM8993_GPIO1 0x13 |
33 | #define WM8993_IRQ_DEBOUNCE 0x14 | 33 | #define WM8993_IRQ_DEBOUNCE 0x14 |
34 | #define WM8993_INPUTS_CLAMP_REG 0x15 | ||
34 | #define WM8993_GPIOCTRL_2 0x16 | 35 | #define WM8993_GPIOCTRL_2 0x16 |
35 | #define WM8993_GPIO_POL 0x17 | 36 | #define WM8993_GPIO_POL 0x17 |
36 | #define WM8993_LEFT_LINE_INPUT_1_2_VOLUME 0x18 | 37 | #define WM8993_LEFT_LINE_INPUT_1_2_VOLUME 0x18 |
@@ -656,6 +657,14 @@ | |||
656 | #define WM8993_GPIO1_DB_WIDTH 1 /* GPIO1_DB */ | 657 | #define WM8993_GPIO1_DB_WIDTH 1 /* GPIO1_DB */ |
657 | 658 | ||
658 | /* | 659 | /* |
660 | * R21 (0x15) - Inputs Clamp | ||
661 | */ | ||
662 | #define WM8993_INPUTS_CLAMP 0x0040 /* INPUTS_CLAMP */ | ||
663 | #define WM8993_INPUTS_CLAMP_MASK 0x0040 /* INPUTS_CLAMP */ | ||
664 | #define WM8993_INPUTS_CLAMP_SHIFT 7 /* INPUTS_CLAMP */ | ||
665 | #define WM8993_INPUTS_CLAMP_WIDTH 1 /* INPUTS_CLAMP */ | ||
666 | |||
667 | /* | ||
659 | * R22 (0x16) - GPIOCTRL 2 | 668 | * R22 (0x16) - GPIOCTRL 2 |
660 | */ | 669 | */ |
661 | #define WM8993_IM_JD2_EINT 0x2000 /* IM_JD2_EINT */ | 670 | #define WM8993_IM_JD2_EINT 0x2000 /* IM_JD2_EINT */ |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 93d27b660257..fe7fbaeb7146 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -686,14 +686,23 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode) | |||
686 | { | 686 | { |
687 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 687 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
688 | 688 | ||
689 | if (!wm8994->jackdet || !wm8994->jack_cb) | ||
690 | return; | ||
691 | |||
689 | if (wm8994->active_refcount) | 692 | if (wm8994->active_refcount) |
690 | mode = WM1811_JACKDET_MODE_AUDIO; | 693 | mode = WM1811_JACKDET_MODE_AUDIO; |
691 | 694 | ||
695 | if (mode == wm8994->jackdet_mode) | ||
696 | return; | ||
697 | |||
698 | wm8994->jackdet_mode = mode; | ||
699 | |||
700 | /* Always use audio mode to detect while the system is active */ | ||
701 | if (mode != WM1811_JACKDET_MODE_NONE) | ||
702 | mode = WM1811_JACKDET_MODE_AUDIO; | ||
703 | |||
692 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | 704 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, |
693 | WM1811_JACKDET_MODE_MASK, mode); | 705 | WM1811_JACKDET_MODE_MASK, mode); |
694 | |||
695 | if (mode == WM1811_JACKDET_MODE_MIC) | ||
696 | msleep(2); | ||
697 | } | 706 | } |
698 | 707 | ||
699 | static void active_reference(struct snd_soc_codec *codec) | 708 | static void active_reference(struct snd_soc_codec *codec) |
@@ -707,15 +716,8 @@ static void active_reference(struct snd_soc_codec *codec) | |||
707 | dev_dbg(codec->dev, "Active refcount incremented, now %d\n", | 716 | dev_dbg(codec->dev, "Active refcount incremented, now %d\n", |
708 | wm8994->active_refcount); | 717 | wm8994->active_refcount); |
709 | 718 | ||
710 | if (wm8994->active_refcount == 1) { | 719 | /* If we're using jack detection go into audio mode */ |
711 | /* If we're using jack detection go into audio mode */ | 720 | wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_AUDIO); |
712 | if (wm8994->jackdet && wm8994->jack_cb) { | ||
713 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
714 | WM1811_JACKDET_MODE_MASK, | ||
715 | WM1811_JACKDET_MODE_AUDIO); | ||
716 | msleep(2); | ||
717 | } | ||
718 | } | ||
719 | 721 | ||
720 | mutex_unlock(&wm8994->accdet_lock); | 722 | mutex_unlock(&wm8994->accdet_lock); |
721 | } | 723 | } |
@@ -734,16 +736,12 @@ static void active_dereference(struct snd_soc_codec *codec) | |||
734 | 736 | ||
735 | if (wm8994->active_refcount == 0) { | 737 | if (wm8994->active_refcount == 0) { |
736 | /* Go into appropriate detection only mode */ | 738 | /* Go into appropriate detection only mode */ |
737 | if (wm8994->jackdet && wm8994->jack_cb) { | 739 | if (wm8994->jack_mic || wm8994->mic_detecting) |
738 | if (wm8994->jack_mic || wm8994->mic_detecting) | 740 | mode = WM1811_JACKDET_MODE_MIC; |
739 | mode = WM1811_JACKDET_MODE_MIC; | 741 | else |
740 | else | 742 | mode = WM1811_JACKDET_MODE_JACK; |
741 | mode = WM1811_JACKDET_MODE_JACK; | ||
742 | 743 | ||
743 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | 744 | wm1811_jackdet_set_mode(codec, mode); |
744 | WM1811_JACKDET_MODE_MASK, | ||
745 | mode); | ||
746 | } | ||
747 | } | 745 | } |
748 | 746 | ||
749 | mutex_unlock(&wm8994->accdet_lock); | 747 | mutex_unlock(&wm8994->accdet_lock); |
@@ -770,28 +768,77 @@ static void vmid_reference(struct snd_soc_codec *codec) | |||
770 | { | 768 | { |
771 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 769 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
772 | 770 | ||
771 | pm_runtime_get_sync(codec->dev); | ||
772 | |||
773 | wm8994->vmid_refcount++; | 773 | wm8994->vmid_refcount++; |
774 | 774 | ||
775 | dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n", | 775 | dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n", |
776 | wm8994->vmid_refcount); | 776 | wm8994->vmid_refcount); |
777 | 777 | ||
778 | if (wm8994->vmid_refcount == 1) { | 778 | if (wm8994->vmid_refcount == 1) { |
779 | /* Startup bias, VMID ramp & buffer */ | 779 | snd_soc_update_bits(codec, WM8994_ANTIPOP_1, |
780 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | 780 | WM8994_LINEOUT1_DISCH | |
781 | WM8994_STARTUP_BIAS_ENA | | 781 | WM8994_LINEOUT2_DISCH, 0); |
782 | WM8994_VMID_BUF_ENA | | ||
783 | WM8994_VMID_RAMP_MASK, | ||
784 | WM8994_STARTUP_BIAS_ENA | | ||
785 | WM8994_VMID_BUF_ENA | | ||
786 | (0x11 << WM8994_VMID_RAMP_SHIFT)); | ||
787 | 782 | ||
788 | /* Main bias enable, VMID=2x40k */ | 783 | wm_hubs_vmid_ena(codec); |
789 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | 784 | |
790 | WM8994_BIAS_ENA | | 785 | switch (wm8994->vmid_mode) { |
791 | WM8994_VMID_SEL_MASK, | 786 | default: |
792 | WM8994_BIAS_ENA | 0x2); | 787 | WARN_ON(0 == "Invalid VMID mode"); |
788 | case WM8994_VMID_NORMAL: | ||
789 | /* Startup bias, VMID ramp & buffer */ | ||
790 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
791 | WM8994_BIAS_SRC | | ||
792 | WM8994_VMID_DISCH | | ||
793 | WM8994_STARTUP_BIAS_ENA | | ||
794 | WM8994_VMID_BUF_ENA | | ||
795 | WM8994_VMID_RAMP_MASK, | ||
796 | WM8994_BIAS_SRC | | ||
797 | WM8994_STARTUP_BIAS_ENA | | ||
798 | WM8994_VMID_BUF_ENA | | ||
799 | (0x3 << WM8994_VMID_RAMP_SHIFT)); | ||
800 | |||
801 | /* Main bias enable, VMID=2x40k */ | ||
802 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | ||
803 | WM8994_BIAS_ENA | | ||
804 | WM8994_VMID_SEL_MASK, | ||
805 | WM8994_BIAS_ENA | 0x2); | ||
806 | |||
807 | msleep(50); | ||
793 | 808 | ||
794 | msleep(20); | 809 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, |
810 | WM8994_VMID_RAMP_MASK | | ||
811 | WM8994_BIAS_SRC, | ||
812 | 0); | ||
813 | break; | ||
814 | |||
815 | case WM8994_VMID_FORCE: | ||
816 | /* Startup bias, slow VMID ramp & buffer */ | ||
817 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
818 | WM8994_BIAS_SRC | | ||
819 | WM8994_VMID_DISCH | | ||
820 | WM8994_STARTUP_BIAS_ENA | | ||
821 | WM8994_VMID_BUF_ENA | | ||
822 | WM8994_VMID_RAMP_MASK, | ||
823 | WM8994_BIAS_SRC | | ||
824 | WM8994_STARTUP_BIAS_ENA | | ||
825 | WM8994_VMID_BUF_ENA | | ||
826 | (0x2 << WM8994_VMID_RAMP_SHIFT)); | ||
827 | |||
828 | /* Main bias enable, VMID=2x40k */ | ||
829 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | ||
830 | WM8994_BIAS_ENA | | ||
831 | WM8994_VMID_SEL_MASK, | ||
832 | WM8994_BIAS_ENA | 0x2); | ||
833 | |||
834 | msleep(400); | ||
835 | |||
836 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
837 | WM8994_VMID_RAMP_MASK | | ||
838 | WM8994_BIAS_SRC, | ||
839 | 0); | ||
840 | break; | ||
841 | } | ||
795 | } | 842 | } |
796 | } | 843 | } |
797 | 844 | ||
@@ -805,30 +852,55 @@ static void vmid_dereference(struct snd_soc_codec *codec) | |||
805 | wm8994->vmid_refcount); | 852 | wm8994->vmid_refcount); |
806 | 853 | ||
807 | if (wm8994->vmid_refcount == 0) { | 854 | if (wm8994->vmid_refcount == 0) { |
808 | /* Switch over to startup biases */ | 855 | if (wm8994->hubs.lineout1_se) |
856 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3, | ||
857 | WM8994_LINEOUT1N_ENA | | ||
858 | WM8994_LINEOUT1P_ENA, | ||
859 | WM8994_LINEOUT1N_ENA | | ||
860 | WM8994_LINEOUT1P_ENA); | ||
861 | |||
862 | if (wm8994->hubs.lineout2_se) | ||
863 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3, | ||
864 | WM8994_LINEOUT2N_ENA | | ||
865 | WM8994_LINEOUT2P_ENA, | ||
866 | WM8994_LINEOUT2N_ENA | | ||
867 | WM8994_LINEOUT2P_ENA); | ||
868 | |||
869 | /* Start discharging VMID */ | ||
809 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | 870 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, |
810 | WM8994_BIAS_SRC | | 871 | WM8994_BIAS_SRC | |
811 | WM8994_STARTUP_BIAS_ENA | | 872 | WM8994_VMID_DISCH, |
812 | WM8994_VMID_BUF_ENA | | ||
813 | WM8994_VMID_RAMP_MASK, | ||
814 | WM8994_BIAS_SRC | | 873 | WM8994_BIAS_SRC | |
815 | WM8994_STARTUP_BIAS_ENA | | 874 | WM8994_VMID_DISCH); |
816 | WM8994_VMID_BUF_ENA | | ||
817 | (1 << WM8994_VMID_RAMP_SHIFT)); | ||
818 | 875 | ||
819 | /* Disable main biases */ | 876 | switch (wm8994->vmid_mode) { |
820 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | 877 | case WM8994_VMID_FORCE: |
821 | WM8994_BIAS_ENA | | 878 | msleep(350); |
822 | WM8994_VMID_SEL_MASK, 0); | 879 | break; |
880 | default: | ||
881 | break; | ||
882 | } | ||
883 | |||
884 | snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL, | ||
885 | WM8994_VROI, WM8994_VROI); | ||
823 | 886 | ||
824 | /* Discharge line */ | 887 | /* Active discharge */ |
825 | snd_soc_update_bits(codec, WM8994_ANTIPOP_1, | 888 | snd_soc_update_bits(codec, WM8994_ANTIPOP_1, |
826 | WM8994_LINEOUT1_DISCH | | 889 | WM8994_LINEOUT1_DISCH | |
827 | WM8994_LINEOUT2_DISCH, | 890 | WM8994_LINEOUT2_DISCH, |
828 | WM8994_LINEOUT1_DISCH | | 891 | WM8994_LINEOUT1_DISCH | |
829 | WM8994_LINEOUT2_DISCH); | 892 | WM8994_LINEOUT2_DISCH); |
830 | 893 | ||
831 | msleep(5); | 894 | msleep(150); |
895 | |||
896 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_3, | ||
897 | WM8994_LINEOUT1N_ENA | | ||
898 | WM8994_LINEOUT1P_ENA | | ||
899 | WM8994_LINEOUT2N_ENA | | ||
900 | WM8994_LINEOUT2P_ENA, 0); | ||
901 | |||
902 | snd_soc_update_bits(codec, WM8994_ADDITIONAL_CONTROL, | ||
903 | WM8994_VROI, 0); | ||
832 | 904 | ||
833 | /* Switch off startup biases */ | 905 | /* Switch off startup biases */ |
834 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | 906 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, |
@@ -836,7 +908,15 @@ static void vmid_dereference(struct snd_soc_codec *codec) | |||
836 | WM8994_STARTUP_BIAS_ENA | | 908 | WM8994_STARTUP_BIAS_ENA | |
837 | WM8994_VMID_BUF_ENA | | 909 | WM8994_VMID_BUF_ENA | |
838 | WM8994_VMID_RAMP_MASK, 0); | 910 | WM8994_VMID_RAMP_MASK, 0); |
911 | |||
912 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | ||
913 | WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0); | ||
914 | |||
915 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
916 | WM8994_VMID_RAMP_MASK, 0); | ||
839 | } | 917 | } |
918 | |||
919 | pm_runtime_put(codec->dev); | ||
840 | } | 920 | } |
841 | 921 | ||
842 | static int vmid_event(struct snd_soc_dapm_widget *w, | 922 | static int vmid_event(struct snd_soc_dapm_widget *w, |
@@ -1450,17 +1530,17 @@ SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0, | |||
1450 | WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev, | 1530 | WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev, |
1451 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 1531 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
1452 | 1532 | ||
1453 | SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), | 1533 | SND_SOC_DAPM_AIF_IN("AIF1DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0), |
1454 | SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), | 1534 | SND_SOC_DAPM_AIF_IN("AIF2DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0), |
1455 | SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), | 1535 | SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0), |
1456 | SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), | 1536 | SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0), |
1457 | 1537 | ||
1458 | SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), | 1538 | SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), |
1459 | SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux), | 1539 | SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux), |
1460 | SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux), | 1540 | SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux), |
1461 | 1541 | ||
1462 | SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), | 1542 | SND_SOC_DAPM_AIF_IN("AIF3DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0), |
1463 | SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), | 1543 | SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", NULL, 0, SND_SOC_NOPM, 0, 0), |
1464 | 1544 | ||
1465 | SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0), | 1545 | SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0), |
1466 | 1546 | ||
@@ -1575,6 +1655,14 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
1575 | 1655 | ||
1576 | { "TOCLK", NULL, "CLK_SYS" }, | 1656 | { "TOCLK", NULL, "CLK_SYS" }, |
1577 | 1657 | ||
1658 | { "AIF1DACDAT", NULL, "AIF1 Playback" }, | ||
1659 | { "AIF2DACDAT", NULL, "AIF2 Playback" }, | ||
1660 | { "AIF3DACDAT", NULL, "AIF3 Playback" }, | ||
1661 | |||
1662 | { "AIF1 Capture", NULL, "AIF1ADCDAT" }, | ||
1663 | { "AIF2 Capture", NULL, "AIF2ADCDAT" }, | ||
1664 | { "AIF3 Capture", NULL, "AIF3ADCDAT" }, | ||
1665 | |||
1578 | /* AIF1 outputs */ | 1666 | /* AIF1 outputs */ |
1579 | { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" }, | 1667 | { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" }, |
1580 | { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" }, | 1668 | { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" }, |
@@ -1887,7 +1975,8 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
1887 | WM8994_FLL1_OUTDIV_MASK | | 1975 | WM8994_FLL1_OUTDIV_MASK | |
1888 | WM8994_FLL1_FRATIO_MASK, reg); | 1976 | WM8994_FLL1_FRATIO_MASK, reg); |
1889 | 1977 | ||
1890 | snd_soc_write(codec, WM8994_FLL1_CONTROL_3 + reg_offset, fll.k); | 1978 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_3 + reg_offset, |
1979 | WM8994_FLL1_K_MASK, fll.k); | ||
1891 | 1980 | ||
1892 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset, | 1981 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset, |
1893 | WM8994_FLL1_N_MASK, | 1982 | WM8994_FLL1_N_MASK, |
@@ -2065,6 +2154,8 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, | |||
2065 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2154 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2066 | struct wm8994 *control = wm8994->wm8994; | 2155 | struct wm8994 *control = wm8994->wm8994; |
2067 | 2156 | ||
2157 | wm_hubs_set_bias_level(codec, level); | ||
2158 | |||
2068 | switch (level) { | 2159 | switch (level) { |
2069 | case SND_SOC_BIAS_ON: | 2160 | case SND_SOC_BIAS_ON: |
2070 | break; | 2161 | break; |
@@ -2090,26 +2181,9 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, | |||
2090 | case SND_SOC_BIAS_STANDBY: | 2181 | case SND_SOC_BIAS_STANDBY: |
2091 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 2182 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
2092 | switch (control->type) { | 2183 | switch (control->type) { |
2093 | case WM8994: | ||
2094 | if (wm8994->revision < 4) { | ||
2095 | /* Tweak DC servo and DSP | ||
2096 | * configuration for improved | ||
2097 | * performance. */ | ||
2098 | snd_soc_write(codec, 0x102, 0x3); | ||
2099 | snd_soc_write(codec, 0x56, 0x3); | ||
2100 | snd_soc_write(codec, 0x817, 0); | ||
2101 | snd_soc_write(codec, 0x102, 0); | ||
2102 | } | ||
2103 | break; | ||
2104 | |||
2105 | case WM8958: | 2184 | case WM8958: |
2106 | if (wm8994->revision == 0) { | 2185 | if (wm8994->revision == 0) { |
2107 | /* Optimise performance for rev A */ | 2186 | /* Optimise performance for rev A */ |
2108 | snd_soc_write(codec, 0x102, 0x3); | ||
2109 | snd_soc_write(codec, 0xcb, 0x81); | ||
2110 | snd_soc_write(codec, 0x817, 0); | ||
2111 | snd_soc_write(codec, 0x102, 0); | ||
2112 | |||
2113 | snd_soc_update_bits(codec, | 2187 | snd_soc_update_bits(codec, |
2114 | WM8958_CHARGE_PUMP_2, | 2188 | WM8958_CHARGE_PUMP_2, |
2115 | WM8958_CP_DISCH, | 2189 | WM8958_CP_DISCH, |
@@ -2117,13 +2191,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, | |||
2117 | } | 2191 | } |
2118 | break; | 2192 | break; |
2119 | 2193 | ||
2120 | case WM1811: | 2194 | default: |
2121 | if (wm8994->revision < 2) { | ||
2122 | snd_soc_write(codec, 0x102, 0x3); | ||
2123 | snd_soc_write(codec, 0x5d, 0x7e); | ||
2124 | snd_soc_write(codec, 0x5e, 0x0); | ||
2125 | snd_soc_write(codec, 0x102, 0x0); | ||
2126 | } | ||
2127 | break; | 2195 | break; |
2128 | } | 2196 | } |
2129 | 2197 | ||
@@ -2159,11 +2227,61 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, | |||
2159 | wm8994->cur_fw = NULL; | 2227 | wm8994->cur_fw = NULL; |
2160 | break; | 2228 | break; |
2161 | } | 2229 | } |
2230 | |||
2162 | codec->dapm.bias_level = level; | 2231 | codec->dapm.bias_level = level; |
2163 | 2232 | ||
2164 | return 0; | 2233 | return 0; |
2165 | } | 2234 | } |
2166 | 2235 | ||
2236 | int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode) | ||
2237 | { | ||
2238 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
2239 | |||
2240 | switch (mode) { | ||
2241 | case WM8994_VMID_NORMAL: | ||
2242 | if (wm8994->hubs.lineout1_se) { | ||
2243 | snd_soc_dapm_disable_pin(&codec->dapm, | ||
2244 | "LINEOUT1N Driver"); | ||
2245 | snd_soc_dapm_disable_pin(&codec->dapm, | ||
2246 | "LINEOUT1P Driver"); | ||
2247 | } | ||
2248 | if (wm8994->hubs.lineout2_se) { | ||
2249 | snd_soc_dapm_disable_pin(&codec->dapm, | ||
2250 | "LINEOUT2N Driver"); | ||
2251 | snd_soc_dapm_disable_pin(&codec->dapm, | ||
2252 | "LINEOUT2P Driver"); | ||
2253 | } | ||
2254 | |||
2255 | /* Do the sync with the old mode to allow it to clean up */ | ||
2256 | snd_soc_dapm_sync(&codec->dapm); | ||
2257 | wm8994->vmid_mode = mode; | ||
2258 | break; | ||
2259 | |||
2260 | case WM8994_VMID_FORCE: | ||
2261 | if (wm8994->hubs.lineout1_se) { | ||
2262 | snd_soc_dapm_force_enable_pin(&codec->dapm, | ||
2263 | "LINEOUT1N Driver"); | ||
2264 | snd_soc_dapm_force_enable_pin(&codec->dapm, | ||
2265 | "LINEOUT1P Driver"); | ||
2266 | } | ||
2267 | if (wm8994->hubs.lineout2_se) { | ||
2268 | snd_soc_dapm_force_enable_pin(&codec->dapm, | ||
2269 | "LINEOUT2N Driver"); | ||
2270 | snd_soc_dapm_force_enable_pin(&codec->dapm, | ||
2271 | "LINEOUT2P Driver"); | ||
2272 | } | ||
2273 | |||
2274 | wm8994->vmid_mode = mode; | ||
2275 | snd_soc_dapm_sync(&codec->dapm); | ||
2276 | break; | ||
2277 | |||
2278 | default: | ||
2279 | return -EINVAL; | ||
2280 | } | ||
2281 | |||
2282 | return 0; | ||
2283 | } | ||
2284 | |||
2167 | static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | 2285 | static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
2168 | { | 2286 | { |
2169 | struct snd_soc_codec *codec = dai->codec; | 2287 | struct snd_soc_codec *codec = dai->codec; |
@@ -2645,6 +2763,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = { | |||
2645 | .channels_max = 2, | 2763 | .channels_max = 2, |
2646 | .rates = WM8994_RATES, | 2764 | .rates = WM8994_RATES, |
2647 | .formats = WM8994_FORMATS, | 2765 | .formats = WM8994_FORMATS, |
2766 | .sig_bits = 24, | ||
2648 | }, | 2767 | }, |
2649 | .capture = { | 2768 | .capture = { |
2650 | .stream_name = "AIF1 Capture", | 2769 | .stream_name = "AIF1 Capture", |
@@ -2652,6 +2771,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = { | |||
2652 | .channels_max = 2, | 2771 | .channels_max = 2, |
2653 | .rates = WM8994_RATES, | 2772 | .rates = WM8994_RATES, |
2654 | .formats = WM8994_FORMATS, | 2773 | .formats = WM8994_FORMATS, |
2774 | .sig_bits = 24, | ||
2655 | }, | 2775 | }, |
2656 | .ops = &wm8994_aif1_dai_ops, | 2776 | .ops = &wm8994_aif1_dai_ops, |
2657 | }, | 2777 | }, |
@@ -2664,6 +2784,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = { | |||
2664 | .channels_max = 2, | 2784 | .channels_max = 2, |
2665 | .rates = WM8994_RATES, | 2785 | .rates = WM8994_RATES, |
2666 | .formats = WM8994_FORMATS, | 2786 | .formats = WM8994_FORMATS, |
2787 | .sig_bits = 24, | ||
2667 | }, | 2788 | }, |
2668 | .capture = { | 2789 | .capture = { |
2669 | .stream_name = "AIF2 Capture", | 2790 | .stream_name = "AIF2 Capture", |
@@ -2671,6 +2792,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = { | |||
2671 | .channels_max = 2, | 2792 | .channels_max = 2, |
2672 | .rates = WM8994_RATES, | 2793 | .rates = WM8994_RATES, |
2673 | .formats = WM8994_FORMATS, | 2794 | .formats = WM8994_FORMATS, |
2795 | .sig_bits = 24, | ||
2674 | }, | 2796 | }, |
2675 | .probe = wm8994_aif2_probe, | 2797 | .probe = wm8994_aif2_probe, |
2676 | .ops = &wm8994_aif2_dai_ops, | 2798 | .ops = &wm8994_aif2_dai_ops, |
@@ -2684,6 +2806,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = { | |||
2684 | .channels_max = 2, | 2806 | .channels_max = 2, |
2685 | .rates = WM8994_RATES, | 2807 | .rates = WM8994_RATES, |
2686 | .formats = WM8994_FORMATS, | 2808 | .formats = WM8994_FORMATS, |
2809 | .sig_bits = 24, | ||
2687 | }, | 2810 | }, |
2688 | .capture = { | 2811 | .capture = { |
2689 | .stream_name = "AIF3 Capture", | 2812 | .stream_name = "AIF3 Capture", |
@@ -2691,13 +2814,14 @@ static struct snd_soc_dai_driver wm8994_dai[] = { | |||
2691 | .channels_max = 2, | 2814 | .channels_max = 2, |
2692 | .rates = WM8994_RATES, | 2815 | .rates = WM8994_RATES, |
2693 | .formats = WM8994_FORMATS, | 2816 | .formats = WM8994_FORMATS, |
2694 | }, | 2817 | .sig_bits = 24, |
2818 | }, | ||
2695 | .ops = &wm8994_aif3_dai_ops, | 2819 | .ops = &wm8994_aif3_dai_ops, |
2696 | } | 2820 | } |
2697 | }; | 2821 | }; |
2698 | 2822 | ||
2699 | #ifdef CONFIG_PM | 2823 | #ifdef CONFIG_PM |
2700 | static int wm8994_suspend(struct snd_soc_codec *codec) | 2824 | static int wm8994_codec_suspend(struct snd_soc_codec *codec) |
2701 | { | 2825 | { |
2702 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2826 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2703 | struct wm8994 *control = wm8994->wm8994; | 2827 | struct wm8994 *control = wm8994->wm8994; |
@@ -2731,7 +2855,7 @@ static int wm8994_suspend(struct snd_soc_codec *codec) | |||
2731 | return 0; | 2855 | return 0; |
2732 | } | 2856 | } |
2733 | 2857 | ||
2734 | static int wm8994_resume(struct snd_soc_codec *codec) | 2858 | static int wm8994_codec_resume(struct snd_soc_codec *codec) |
2735 | { | 2859 | { |
2736 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2860 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2737 | struct wm8994 *control = wm8994->wm8994; | 2861 | struct wm8994 *control = wm8994->wm8994; |
@@ -2753,13 +2877,6 @@ static int wm8994_resume(struct snd_soc_codec *codec) | |||
2753 | codec->cache_only = 0; | 2877 | codec->cache_only = 0; |
2754 | } | 2878 | } |
2755 | 2879 | ||
2756 | /* Restore the registers */ | ||
2757 | ret = snd_soc_cache_sync(codec); | ||
2758 | if (ret != 0) | ||
2759 | dev_err(codec->dev, "Failed to sync cache: %d\n", ret); | ||
2760 | |||
2761 | wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
2762 | |||
2763 | for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { | 2880 | for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { |
2764 | if (!wm8994->fll_suspend[i].out) | 2881 | if (!wm8994->fll_suspend[i].out) |
2765 | continue; | 2882 | continue; |
@@ -2787,6 +2904,7 @@ static int wm8994_resume(struct snd_soc_codec *codec) | |||
2787 | WM1811_JACKDET_MODE_JACK); | 2904 | WM1811_JACKDET_MODE_JACK); |
2788 | break; | 2905 | break; |
2789 | } | 2906 | } |
2907 | break; | ||
2790 | case WM8958: | 2908 | case WM8958: |
2791 | if (wm8994->jack_cb) | 2909 | if (wm8994->jack_cb) |
2792 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | 2910 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, |
@@ -2797,8 +2915,8 @@ static int wm8994_resume(struct snd_soc_codec *codec) | |||
2797 | return 0; | 2915 | return 0; |
2798 | } | 2916 | } |
2799 | #else | 2917 | #else |
2800 | #define wm8994_suspend NULL | 2918 | #define wm8994_codec_suspend NULL |
2801 | #define wm8994_resume NULL | 2919 | #define wm8994_codec_resume NULL |
2802 | #endif | 2920 | #endif |
2803 | 2921 | ||
2804 | static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) | 2922 | static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) |
@@ -2861,7 +2979,7 @@ static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994) | |||
2861 | wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; | 2979 | wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts; |
2862 | wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; | 2980 | wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts; |
2863 | 2981 | ||
2864 | ret = snd_soc_add_controls(wm8994->codec, controls, | 2982 | ret = snd_soc_add_codec_controls(wm8994->codec, controls, |
2865 | ARRAY_SIZE(controls)); | 2983 | ARRAY_SIZE(controls)); |
2866 | if (ret != 0) | 2984 | if (ret != 0) |
2867 | dev_err(wm8994->codec->dev, | 2985 | dev_err(wm8994->codec->dev, |
@@ -2914,7 +3032,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | |||
2914 | wm8994->drc_enum.max = pdata->num_drc_cfgs; | 3032 | wm8994->drc_enum.max = pdata->num_drc_cfgs; |
2915 | wm8994->drc_enum.texts = wm8994->drc_texts; | 3033 | wm8994->drc_enum.texts = wm8994->drc_texts; |
2916 | 3034 | ||
2917 | ret = snd_soc_add_controls(wm8994->codec, controls, | 3035 | ret = snd_soc_add_codec_controls(wm8994->codec, controls, |
2918 | ARRAY_SIZE(controls)); | 3036 | ARRAY_SIZE(controls)); |
2919 | if (ret != 0) | 3037 | if (ret != 0) |
2920 | dev_err(wm8994->codec->dev, | 3038 | dev_err(wm8994->codec->dev, |
@@ -2930,7 +3048,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | |||
2930 | if (pdata->num_retune_mobile_cfgs) | 3048 | if (pdata->num_retune_mobile_cfgs) |
2931 | wm8994_handle_retune_mobile_pdata(wm8994); | 3049 | wm8994_handle_retune_mobile_pdata(wm8994); |
2932 | else | 3050 | else |
2933 | snd_soc_add_controls(wm8994->codec, wm8994_eq_controls, | 3051 | snd_soc_add_codec_controls(wm8994->codec, wm8994_eq_controls, |
2934 | ARRAY_SIZE(wm8994_eq_controls)); | 3052 | ARRAY_SIZE(wm8994_eq_controls)); |
2935 | 3053 | ||
2936 | for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) { | 3054 | for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) { |
@@ -2947,8 +3065,6 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | |||
2947 | * @codec: WM8994 codec | 3065 | * @codec: WM8994 codec |
2948 | * @jack: jack to report detection events on | 3066 | * @jack: jack to report detection events on |
2949 | * @micbias: microphone bias to detect on | 3067 | * @micbias: microphone bias to detect on |
2950 | * @det: value to report for presence detection | ||
2951 | * @shrt: value to report for short detection | ||
2952 | * | 3068 | * |
2953 | * Enable microphone detection via IRQ on the WM8994. If GPIOs are | 3069 | * Enable microphone detection via IRQ on the WM8994. If GPIOs are |
2954 | * being used to bring out signals to the processor then only platform | 3070 | * being used to bring out signals to the processor then only platform |
@@ -2959,43 +3075,63 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) | |||
2959 | * and micbias2_lvl platform data members. | 3075 | * and micbias2_lvl platform data members. |
2960 | */ | 3076 | */ |
2961 | int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | 3077 | int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, |
2962 | int micbias, int det, int shrt) | 3078 | int micbias) |
2963 | { | 3079 | { |
2964 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 3080 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
2965 | struct wm8994_micdet *micdet; | 3081 | struct wm8994_micdet *micdet; |
2966 | struct wm8994 *control = wm8994->wm8994; | 3082 | struct wm8994 *control = wm8994->wm8994; |
2967 | int reg; | 3083 | int reg, ret; |
2968 | 3084 | ||
2969 | if (control->type != WM8994) | 3085 | if (control->type != WM8994) { |
3086 | dev_warn(codec->dev, "Not a WM8994\n"); | ||
2970 | return -EINVAL; | 3087 | return -EINVAL; |
3088 | } | ||
2971 | 3089 | ||
2972 | switch (micbias) { | 3090 | switch (micbias) { |
2973 | case 1: | 3091 | case 1: |
2974 | micdet = &wm8994->micdet[0]; | 3092 | micdet = &wm8994->micdet[0]; |
3093 | if (jack) | ||
3094 | ret = snd_soc_dapm_force_enable_pin(&codec->dapm, | ||
3095 | "MICBIAS1"); | ||
3096 | else | ||
3097 | ret = snd_soc_dapm_disable_pin(&codec->dapm, | ||
3098 | "MICBIAS1"); | ||
2975 | break; | 3099 | break; |
2976 | case 2: | 3100 | case 2: |
2977 | micdet = &wm8994->micdet[1]; | 3101 | micdet = &wm8994->micdet[1]; |
3102 | if (jack) | ||
3103 | ret = snd_soc_dapm_force_enable_pin(&codec->dapm, | ||
3104 | "MICBIAS1"); | ||
3105 | else | ||
3106 | ret = snd_soc_dapm_disable_pin(&codec->dapm, | ||
3107 | "MICBIAS1"); | ||
2978 | break; | 3108 | break; |
2979 | default: | 3109 | default: |
3110 | dev_warn(codec->dev, "Invalid MICBIAS %d\n", micbias); | ||
2980 | return -EINVAL; | 3111 | return -EINVAL; |
2981 | } | 3112 | } |
3113 | |||
3114 | if (ret != 0) | ||
3115 | dev_warn(codec->dev, "Failed to configure MICBIAS%d: %d\n", | ||
3116 | micbias, ret); | ||
2982 | 3117 | ||
2983 | dev_dbg(codec->dev, "Configuring microphone detection on %d: %x %x\n", | 3118 | dev_dbg(codec->dev, "Configuring microphone detection on %d %p\n", |
2984 | micbias, det, shrt); | 3119 | micbias, jack); |
2985 | 3120 | ||
2986 | /* Store the configuration */ | 3121 | /* Store the configuration */ |
2987 | micdet->jack = jack; | 3122 | micdet->jack = jack; |
2988 | micdet->det = det; | 3123 | micdet->detecting = true; |
2989 | micdet->shrt = shrt; | ||
2990 | 3124 | ||
2991 | /* If either of the jacks is set up then enable detection */ | 3125 | /* If either of the jacks is set up then enable detection */ |
2992 | if (wm8994->micdet[0].jack || wm8994->micdet[1].jack) | 3126 | if (wm8994->micdet[0].jack || wm8994->micdet[1].jack) |
2993 | reg = WM8994_MICD_ENA; | 3127 | reg = WM8994_MICD_ENA; |
2994 | else | 3128 | else |
2995 | reg = 0; | 3129 | reg = 0; |
2996 | 3130 | ||
2997 | snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg); | 3131 | snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, reg); |
2998 | 3132 | ||
3133 | snd_soc_dapm_sync(&codec->dapm); | ||
3134 | |||
2999 | return 0; | 3135 | return 0; |
3000 | } | 3136 | } |
3001 | EXPORT_SYMBOL_GPL(wm8994_mic_detect); | 3137 | EXPORT_SYMBOL_GPL(wm8994_mic_detect); |
@@ -3021,20 +3157,42 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data) | |||
3021 | dev_dbg(codec->dev, "Microphone status: %x\n", reg); | 3157 | dev_dbg(codec->dev, "Microphone status: %x\n", reg); |
3022 | 3158 | ||
3023 | report = 0; | 3159 | report = 0; |
3024 | if (reg & WM8994_MIC1_DET_STS) | 3160 | if (reg & WM8994_MIC1_DET_STS) { |
3025 | report |= priv->micdet[0].det; | 3161 | if (priv->micdet[0].detecting) |
3026 | if (reg & WM8994_MIC1_SHRT_STS) | 3162 | report = SND_JACK_HEADSET; |
3027 | report |= priv->micdet[0].shrt; | 3163 | } |
3164 | if (reg & WM8994_MIC1_SHRT_STS) { | ||
3165 | if (priv->micdet[0].detecting) | ||
3166 | report = SND_JACK_HEADPHONE; | ||
3167 | else | ||
3168 | report |= SND_JACK_BTN_0; | ||
3169 | } | ||
3170 | if (report) | ||
3171 | priv->micdet[0].detecting = false; | ||
3172 | else | ||
3173 | priv->micdet[0].detecting = true; | ||
3174 | |||
3028 | snd_soc_jack_report(priv->micdet[0].jack, report, | 3175 | snd_soc_jack_report(priv->micdet[0].jack, report, |
3029 | priv->micdet[0].det | priv->micdet[0].shrt); | 3176 | SND_JACK_HEADSET | SND_JACK_BTN_0); |
3030 | 3177 | ||
3031 | report = 0; | 3178 | report = 0; |
3032 | if (reg & WM8994_MIC2_DET_STS) | 3179 | if (reg & WM8994_MIC2_DET_STS) { |
3033 | report |= priv->micdet[1].det; | 3180 | if (priv->micdet[1].detecting) |
3034 | if (reg & WM8994_MIC2_SHRT_STS) | 3181 | report = SND_JACK_HEADSET; |
3035 | report |= priv->micdet[1].shrt; | 3182 | } |
3183 | if (reg & WM8994_MIC2_SHRT_STS) { | ||
3184 | if (priv->micdet[1].detecting) | ||
3185 | report = SND_JACK_HEADPHONE; | ||
3186 | else | ||
3187 | report |= SND_JACK_BTN_0; | ||
3188 | } | ||
3189 | if (report) | ||
3190 | priv->micdet[1].detecting = false; | ||
3191 | else | ||
3192 | priv->micdet[1].detecting = true; | ||
3193 | |||
3036 | snd_soc_jack_report(priv->micdet[1].jack, report, | 3194 | snd_soc_jack_report(priv->micdet[1].jack, report, |
3037 | priv->micdet[1].det | priv->micdet[1].shrt); | 3195 | SND_JACK_HEADSET | SND_JACK_BTN_0); |
3038 | 3196 | ||
3039 | return IRQ_HANDLED; | 3197 | return IRQ_HANDLED; |
3040 | } | 3198 | } |
@@ -3083,7 +3241,7 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
3083 | } | 3241 | } |
3084 | 3242 | ||
3085 | 3243 | ||
3086 | if (wm8994->mic_detecting && status & 0x4) { | 3244 | if (wm8994->mic_detecting && status & 0xfc) { |
3087 | dev_dbg(codec->dev, "Detected headphone\n"); | 3245 | dev_dbg(codec->dev, "Detected headphone\n"); |
3088 | wm8994->mic_detecting = false; | 3246 | wm8994->mic_detecting = false; |
3089 | 3247 | ||
@@ -3094,11 +3252,23 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
3094 | 3252 | ||
3095 | /* If we have jackdet that will detect removal */ | 3253 | /* If we have jackdet that will detect removal */ |
3096 | if (wm8994->jackdet) { | 3254 | if (wm8994->jackdet) { |
3255 | mutex_lock(&wm8994->accdet_lock); | ||
3256 | |||
3097 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | 3257 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, |
3098 | WM8958_MICD_ENA, 0); | 3258 | WM8958_MICD_ENA, 0); |
3099 | 3259 | ||
3100 | wm1811_jackdet_set_mode(codec, | 3260 | wm1811_jackdet_set_mode(codec, |
3101 | WM1811_JACKDET_MODE_JACK); | 3261 | WM1811_JACKDET_MODE_JACK); |
3262 | |||
3263 | mutex_unlock(&wm8994->accdet_lock); | ||
3264 | |||
3265 | if (wm8994->pdata->jd_ext_cap) { | ||
3266 | mutex_lock(&codec->mutex); | ||
3267 | snd_soc_dapm_disable_pin(&codec->dapm, | ||
3268 | "MICBIAS2"); | ||
3269 | snd_soc_dapm_sync(&codec->dapm); | ||
3270 | mutex_unlock(&codec->mutex); | ||
3271 | } | ||
3102 | } | 3272 | } |
3103 | } | 3273 | } |
3104 | 3274 | ||
@@ -3133,6 +3303,7 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3133 | struct wm8994_priv *wm8994 = data; | 3303 | struct wm8994_priv *wm8994 = data; |
3134 | struct snd_soc_codec *codec = wm8994->codec; | 3304 | struct snd_soc_codec *codec = wm8994->codec; |
3135 | int reg; | 3305 | int reg; |
3306 | bool present; | ||
3136 | 3307 | ||
3137 | mutex_lock(&wm8994->accdet_lock); | 3308 | mutex_lock(&wm8994->accdet_lock); |
3138 | 3309 | ||
@@ -3145,11 +3316,17 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3145 | 3316 | ||
3146 | dev_dbg(codec->dev, "JACKDET %x\n", reg); | 3317 | dev_dbg(codec->dev, "JACKDET %x\n", reg); |
3147 | 3318 | ||
3148 | if (reg & WM1811_JACKDET_LVL) { | 3319 | present = reg & WM1811_JACKDET_LVL; |
3320 | |||
3321 | if (present) { | ||
3149 | dev_dbg(codec->dev, "Jack detected\n"); | 3322 | dev_dbg(codec->dev, "Jack detected\n"); |
3150 | 3323 | ||
3151 | snd_soc_jack_report(wm8994->micdet[0].jack, | 3324 | snd_soc_update_bits(codec, WM8958_MICBIAS2, |
3152 | SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); | 3325 | WM8958_MICB2_DISCH, 0); |
3326 | |||
3327 | /* Disable debounce while inserted */ | ||
3328 | snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, | ||
3329 | WM1811_JACKDET_DB, 0); | ||
3153 | 3330 | ||
3154 | /* | 3331 | /* |
3155 | * Start off measument of microphone impedence to find | 3332 | * Start off measument of microphone impedence to find |
@@ -3157,14 +3334,18 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3157 | */ | 3334 | */ |
3158 | wm8994->mic_detecting = true; | 3335 | wm8994->mic_detecting = true; |
3159 | wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); | 3336 | wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_MIC); |
3337 | |||
3160 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | 3338 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, |
3161 | WM8958_MICD_ENA, WM8958_MICD_ENA); | 3339 | WM8958_MICD_ENA, WM8958_MICD_ENA); |
3162 | } else { | 3340 | } else { |
3163 | dev_dbg(codec->dev, "Jack not detected\n"); | 3341 | dev_dbg(codec->dev, "Jack not detected\n"); |
3164 | 3342 | ||
3165 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, | 3343 | snd_soc_update_bits(codec, WM8958_MICBIAS2, |
3166 | SND_JACK_MECHANICAL | SND_JACK_HEADSET | | 3344 | WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); |
3167 | wm8994->btn_mask); | 3345 | |
3346 | /* Enable debounce while removed */ | ||
3347 | snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, | ||
3348 | WM1811_JACKDET_DB, WM1811_JACKDET_DB); | ||
3168 | 3349 | ||
3169 | wm8994->mic_detecting = false; | 3350 | wm8994->mic_detecting = false; |
3170 | wm8994->jack_mic = false; | 3351 | wm8994->jack_mic = false; |
@@ -3175,6 +3356,28 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3175 | 3356 | ||
3176 | mutex_unlock(&wm8994->accdet_lock); | 3357 | mutex_unlock(&wm8994->accdet_lock); |
3177 | 3358 | ||
3359 | /* If required for an external cap force MICBIAS on */ | ||
3360 | if (wm8994->pdata->jd_ext_cap) { | ||
3361 | mutex_lock(&codec->mutex); | ||
3362 | |||
3363 | if (present) | ||
3364 | snd_soc_dapm_force_enable_pin(&codec->dapm, | ||
3365 | "MICBIAS2"); | ||
3366 | else | ||
3367 | snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); | ||
3368 | |||
3369 | snd_soc_dapm_sync(&codec->dapm); | ||
3370 | mutex_unlock(&codec->mutex); | ||
3371 | } | ||
3372 | |||
3373 | if (present) | ||
3374 | snd_soc_jack_report(wm8994->micdet[0].jack, | ||
3375 | SND_JACK_MECHANICAL, SND_JACK_MECHANICAL); | ||
3376 | else | ||
3377 | snd_soc_jack_report(wm8994->micdet[0].jack, 0, | ||
3378 | SND_JACK_MECHANICAL | SND_JACK_HEADSET | | ||
3379 | wm8994->btn_mask); | ||
3380 | |||
3178 | return IRQ_HANDLED; | 3381 | return IRQ_HANDLED; |
3179 | } | 3382 | } |
3180 | 3383 | ||
@@ -3217,6 +3420,7 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
3217 | } | 3420 | } |
3218 | 3421 | ||
3219 | snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS"); | 3422 | snd_soc_dapm_force_enable_pin(&codec->dapm, "CLK_SYS"); |
3423 | snd_soc_dapm_sync(&codec->dapm); | ||
3220 | 3424 | ||
3221 | wm8994->micdet[0].jack = jack; | 3425 | wm8994->micdet[0].jack = jack; |
3222 | wm8994->jack_cb = cb; | 3426 | wm8994->jack_cb = cb; |
@@ -3247,6 +3451,9 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
3247 | * otherwise jump straight to microphone detection. | 3451 | * otherwise jump straight to microphone detection. |
3248 | */ | 3452 | */ |
3249 | if (wm8994->jackdet) { | 3453 | if (wm8994->jackdet) { |
3454 | snd_soc_update_bits(codec, WM8958_MICBIAS2, | ||
3455 | WM8958_MICB2_DISCH, | ||
3456 | WM8958_MICB2_DISCH); | ||
3250 | snd_soc_update_bits(codec, WM8994_LDO_1, | 3457 | snd_soc_update_bits(codec, WM8994_LDO_1, |
3251 | WM8994_LDO1_DISCH, 0); | 3458 | WM8994_LDO1_DISCH, 0); |
3252 | wm1811_jackdet_set_mode(codec, | 3459 | wm1811_jackdet_set_mode(codec, |
@@ -3259,7 +3466,9 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
3259 | } else { | 3466 | } else { |
3260 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | 3467 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, |
3261 | WM8958_MICD_ENA, 0); | 3468 | WM8958_MICD_ENA, 0); |
3469 | wm1811_jackdet_set_mode(codec, WM1811_JACKDET_MODE_NONE); | ||
3262 | snd_soc_dapm_disable_pin(&codec->dapm, "CLK_SYS"); | 3470 | snd_soc_dapm_disable_pin(&codec->dapm, "CLK_SYS"); |
3471 | snd_soc_dapm_sync(&codec->dapm); | ||
3263 | } | 3472 | } |
3264 | 3473 | ||
3265 | return 0; | 3474 | return 0; |
@@ -3272,17 +3481,13 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3272 | struct snd_soc_codec *codec = wm8994->codec; | 3481 | struct snd_soc_codec *codec = wm8994->codec; |
3273 | int reg, count; | 3482 | int reg, count; |
3274 | 3483 | ||
3275 | mutex_lock(&wm8994->accdet_lock); | ||
3276 | |||
3277 | /* | 3484 | /* |
3278 | * Jack detection may have detected a removal simulataneously | 3485 | * Jack detection may have detected a removal simulataneously |
3279 | * with an update of the MICDET status; if so it will have | 3486 | * with an update of the MICDET status; if so it will have |
3280 | * stopped detection and we can ignore this interrupt. | 3487 | * stopped detection and we can ignore this interrupt. |
3281 | */ | 3488 | */ |
3282 | if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) { | 3489 | if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) |
3283 | mutex_unlock(&wm8994->accdet_lock); | ||
3284 | return IRQ_HANDLED; | 3490 | return IRQ_HANDLED; |
3285 | } | ||
3286 | 3491 | ||
3287 | /* We may occasionally read a detection without an impedence | 3492 | /* We may occasionally read a detection without an impedence |
3288 | * range being provided - if that happens loop again. | 3493 | * range being provided - if that happens loop again. |
@@ -3291,7 +3496,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3291 | do { | 3496 | do { |
3292 | reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); | 3497 | reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); |
3293 | if (reg < 0) { | 3498 | if (reg < 0) { |
3294 | mutex_unlock(&wm8994->accdet_lock); | ||
3295 | dev_err(codec->dev, | 3499 | dev_err(codec->dev, |
3296 | "Failed to read mic detect status: %d\n", | 3500 | "Failed to read mic detect status: %d\n", |
3297 | reg); | 3501 | reg); |
@@ -3322,8 +3526,6 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3322 | dev_warn(codec->dev, "Accessory detection with no callback\n"); | 3526 | dev_warn(codec->dev, "Accessory detection with no callback\n"); |
3323 | 3527 | ||
3324 | out: | 3528 | out: |
3325 | mutex_unlock(&wm8994->accdet_lock); | ||
3326 | |||
3327 | return IRQ_HANDLED; | 3529 | return IRQ_HANDLED; |
3328 | } | 3530 | } |
3329 | 3531 | ||
@@ -3357,23 +3559,16 @@ static irqreturn_t wm8994_temp_shut(int irq, void *data) | |||
3357 | static int wm8994_codec_probe(struct snd_soc_codec *codec) | 3559 | static int wm8994_codec_probe(struct snd_soc_codec *codec) |
3358 | { | 3560 | { |
3359 | struct wm8994 *control = dev_get_drvdata(codec->dev->parent); | 3561 | struct wm8994 *control = dev_get_drvdata(codec->dev->parent); |
3360 | struct wm8994_priv *wm8994; | 3562 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
3361 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 3563 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
3362 | unsigned int reg; | 3564 | unsigned int reg; |
3363 | int ret, i; | 3565 | int ret, i; |
3364 | 3566 | ||
3567 | wm8994->codec = codec; | ||
3365 | codec->control_data = control->regmap; | 3568 | codec->control_data = control->regmap; |
3366 | 3569 | ||
3367 | wm8994 = devm_kzalloc(codec->dev, sizeof(struct wm8994_priv), | ||
3368 | GFP_KERNEL); | ||
3369 | if (wm8994 == NULL) | ||
3370 | return -ENOMEM; | ||
3371 | snd_soc_codec_set_drvdata(codec, wm8994); | ||
3372 | |||
3373 | snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | 3570 | snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); |
3374 | 3571 | ||
3375 | wm8994->wm8994 = dev_get_drvdata(codec->dev->parent); | ||
3376 | wm8994->pdata = dev_get_platdata(codec->dev->parent); | ||
3377 | wm8994->codec = codec; | 3572 | wm8994->codec = codec; |
3378 | 3573 | ||
3379 | mutex_init(&wm8994->accdet_lock); | 3574 | mutex_init(&wm8994->accdet_lock); |
@@ -3388,12 +3583,20 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3388 | WM8994_IRQ_MIC1_DET; | 3583 | WM8994_IRQ_MIC1_DET; |
3389 | 3584 | ||
3390 | pm_runtime_enable(codec->dev); | 3585 | pm_runtime_enable(codec->dev); |
3391 | pm_runtime_resume(codec->dev); | 3586 | pm_runtime_idle(codec->dev); |
3587 | |||
3588 | /* By default use idle_bias_off, will override for WM8994 */ | ||
3589 | codec->dapm.idle_bias_off = 1; | ||
3392 | 3590 | ||
3393 | /* Set revision-specific configuration */ | 3591 | /* Set revision-specific configuration */ |
3394 | wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); | 3592 | wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); |
3395 | switch (control->type) { | 3593 | switch (control->type) { |
3396 | case WM8994: | 3594 | case WM8994: |
3595 | /* Single ended line outputs should have VMID on. */ | ||
3596 | if (!wm8994->pdata->lineout1_diff || | ||
3597 | !wm8994->pdata->lineout2_diff) | ||
3598 | codec->dapm.idle_bias_off = 0; | ||
3599 | |||
3397 | switch (wm8994->revision) { | 3600 | switch (wm8994->revision) { |
3398 | case 2: | 3601 | case 2: |
3399 | case 3: | 3602 | case 3: |
@@ -3411,11 +3614,14 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3411 | 3614 | ||
3412 | case WM8958: | 3615 | case WM8958: |
3413 | wm8994->hubs.dcs_readback_mode = 1; | 3616 | wm8994->hubs.dcs_readback_mode = 1; |
3617 | wm8994->hubs.hp_startup_mode = 1; | ||
3414 | break; | 3618 | break; |
3415 | 3619 | ||
3416 | case WM1811: | 3620 | case WM1811: |
3417 | wm8994->hubs.dcs_readback_mode = 2; | 3621 | wm8994->hubs.dcs_readback_mode = 2; |
3418 | wm8994->hubs.no_series_update = 1; | 3622 | wm8994->hubs.no_series_update = 1; |
3623 | wm8994->hubs.hp_startup_mode = 1; | ||
3624 | wm8994->hubs.no_cache_class_w = true; | ||
3419 | 3625 | ||
3420 | switch (wm8994->revision) { | 3626 | switch (wm8994->revision) { |
3421 | case 0: | 3627 | case 0: |
@@ -3532,6 +3738,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3532 | wm8994->fll_locked_irq = false; | 3738 | wm8994->fll_locked_irq = false; |
3533 | } | 3739 | } |
3534 | 3740 | ||
3741 | /* Make sure we can read from the GPIOs if they're inputs */ | ||
3742 | pm_runtime_get_sync(codec->dev); | ||
3743 | |||
3535 | /* Remember if AIFnLRCLK is configured as a GPIO. This should be | 3744 | /* Remember if AIFnLRCLK is configured as a GPIO. This should be |
3536 | * configured on init - if a system wants to do this dynamically | 3745 | * configured on init - if a system wants to do this dynamically |
3537 | * at runtime we can deal with that then. | 3746 | * at runtime we can deal with that then. |
@@ -3560,7 +3769,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3560 | wm8994->lrclk_shared[1] = 0; | 3769 | wm8994->lrclk_shared[1] = 0; |
3561 | } | 3770 | } |
3562 | 3771 | ||
3563 | wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 3772 | pm_runtime_put(codec->dev); |
3564 | 3773 | ||
3565 | /* Latch volume updates (right only; we always do left then right). */ | 3774 | /* Latch volume updates (right only; we always do left then right). */ |
3566 | snd_soc_update_bits(codec, WM8994_AIF1_DAC1_LEFT_VOLUME, | 3775 | snd_soc_update_bits(codec, WM8994_AIF1_DAC1_LEFT_VOLUME, |
@@ -3638,7 +3847,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3638 | wm8994_handle_pdata(wm8994); | 3847 | wm8994_handle_pdata(wm8994); |
3639 | 3848 | ||
3640 | wm_hubs_add_analogue_controls(codec); | 3849 | wm_hubs_add_analogue_controls(codec); |
3641 | snd_soc_add_controls(codec, wm8994_snd_controls, | 3850 | snd_soc_add_codec_controls(codec, wm8994_snd_controls, |
3642 | ARRAY_SIZE(wm8994_snd_controls)); | 3851 | ARRAY_SIZE(wm8994_snd_controls)); |
3643 | snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets, | 3852 | snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets, |
3644 | ARRAY_SIZE(wm8994_dapm_widgets)); | 3853 | ARRAY_SIZE(wm8994_dapm_widgets)); |
@@ -3664,7 +3873,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3664 | } | 3873 | } |
3665 | break; | 3874 | break; |
3666 | case WM8958: | 3875 | case WM8958: |
3667 | snd_soc_add_controls(codec, wm8958_snd_controls, | 3876 | snd_soc_add_codec_controls(codec, wm8958_snd_controls, |
3668 | ARRAY_SIZE(wm8958_snd_controls)); | 3877 | ARRAY_SIZE(wm8958_snd_controls)); |
3669 | snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, | 3878 | snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, |
3670 | ARRAY_SIZE(wm8958_dapm_widgets)); | 3879 | ARRAY_SIZE(wm8958_dapm_widgets)); |
@@ -3686,7 +3895,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3686 | break; | 3895 | break; |
3687 | 3896 | ||
3688 | case WM1811: | 3897 | case WM1811: |
3689 | snd_soc_add_controls(codec, wm8958_snd_controls, | 3898 | snd_soc_add_codec_controls(codec, wm8958_snd_controls, |
3690 | ARRAY_SIZE(wm8958_snd_controls)); | 3899 | ARRAY_SIZE(wm8958_snd_controls)); |
3691 | snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, | 3900 | snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, |
3692 | ARRAY_SIZE(wm8958_dapm_widgets)); | 3901 | ARRAY_SIZE(wm8958_dapm_widgets)); |
@@ -3815,24 +4024,27 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) | |||
3815 | return 0; | 4024 | return 0; |
3816 | } | 4025 | } |
3817 | 4026 | ||
3818 | static int wm8994_soc_volatile(struct snd_soc_codec *codec, | ||
3819 | unsigned int reg) | ||
3820 | { | ||
3821 | return true; | ||
3822 | } | ||
3823 | |||
3824 | static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { | 4027 | static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { |
3825 | .probe = wm8994_codec_probe, | 4028 | .probe = wm8994_codec_probe, |
3826 | .remove = wm8994_codec_remove, | 4029 | .remove = wm8994_codec_remove, |
3827 | .suspend = wm8994_suspend, | 4030 | .suspend = wm8994_codec_suspend, |
3828 | .resume = wm8994_resume, | 4031 | .resume = wm8994_codec_resume, |
3829 | .set_bias_level = wm8994_set_bias_level, | 4032 | .set_bias_level = wm8994_set_bias_level, |
3830 | .reg_cache_size = WM8994_MAX_REGISTER, | ||
3831 | .volatile_register = wm8994_soc_volatile, | ||
3832 | }; | 4033 | }; |
3833 | 4034 | ||
3834 | static int __devinit wm8994_probe(struct platform_device *pdev) | 4035 | static int __devinit wm8994_probe(struct platform_device *pdev) |
3835 | { | 4036 | { |
4037 | struct wm8994_priv *wm8994; | ||
4038 | |||
4039 | wm8994 = devm_kzalloc(&pdev->dev, sizeof(struct wm8994_priv), | ||
4040 | GFP_KERNEL); | ||
4041 | if (wm8994 == NULL) | ||
4042 | return -ENOMEM; | ||
4043 | platform_set_drvdata(pdev, wm8994); | ||
4044 | |||
4045 | wm8994->wm8994 = dev_get_drvdata(pdev->dev.parent); | ||
4046 | wm8994->pdata = dev_get_platdata(pdev->dev.parent); | ||
4047 | |||
3836 | return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994, | 4048 | return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994, |
3837 | wm8994_dai, ARRAY_SIZE(wm8994_dai)); | 4049 | wm8994_dai, ARRAY_SIZE(wm8994_dai)); |
3838 | } | 4050 | } |
@@ -3843,11 +4055,43 @@ static int __devexit wm8994_remove(struct platform_device *pdev) | |||
3843 | return 0; | 4055 | return 0; |
3844 | } | 4056 | } |
3845 | 4057 | ||
4058 | #ifdef CONFIG_PM_SLEEP | ||
4059 | static int wm8994_suspend(struct device *dev) | ||
4060 | { | ||
4061 | struct wm8994_priv *wm8994 = dev_get_drvdata(dev); | ||
4062 | |||
4063 | /* Drop down to power saving mode when system is suspended */ | ||
4064 | if (wm8994->jackdet && !wm8994->active_refcount) | ||
4065 | regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2, | ||
4066 | WM1811_JACKDET_MODE_MASK, | ||
4067 | wm8994->jackdet_mode); | ||
4068 | |||
4069 | return 0; | ||
4070 | } | ||
4071 | |||
4072 | static int wm8994_resume(struct device *dev) | ||
4073 | { | ||
4074 | struct wm8994_priv *wm8994 = dev_get_drvdata(dev); | ||
4075 | |||
4076 | if (wm8994->jackdet && wm8994->jack_cb) | ||
4077 | regmap_update_bits(wm8994->wm8994->regmap, WM8994_ANTIPOP_2, | ||
4078 | WM1811_JACKDET_MODE_MASK, | ||
4079 | WM1811_JACKDET_MODE_AUDIO); | ||
4080 | |||
4081 | return 0; | ||
4082 | } | ||
4083 | #endif | ||
4084 | |||
4085 | static const struct dev_pm_ops wm8994_pm_ops = { | ||
4086 | SET_SYSTEM_SLEEP_PM_OPS(wm8994_suspend, wm8994_resume) | ||
4087 | }; | ||
4088 | |||
3846 | static struct platform_driver wm8994_codec_driver = { | 4089 | static struct platform_driver wm8994_codec_driver = { |
3847 | .driver = { | 4090 | .driver = { |
3848 | .name = "wm8994-codec", | 4091 | .name = "wm8994-codec", |
3849 | .owner = THIS_MODULE, | 4092 | .owner = THIS_MODULE, |
3850 | }, | 4093 | .pm = &wm8994_pm_ops, |
4094 | }, | ||
3851 | .probe = wm8994_probe, | 4095 | .probe = wm8994_probe, |
3852 | .remove = __devexit_p(wm8994_remove), | 4096 | .remove = __devexit_p(wm8994_remove), |
3853 | }; | 4097 | }; |
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index c3a42474ab19..c724112998d8 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h | |||
@@ -32,13 +32,20 @@ | |||
32 | #define WM8994_FLL_SRC_LRCLK 3 | 32 | #define WM8994_FLL_SRC_LRCLK 3 |
33 | #define WM8994_FLL_SRC_BCLK 4 | 33 | #define WM8994_FLL_SRC_BCLK 4 |
34 | 34 | ||
35 | enum wm8994_vmid_mode { | ||
36 | WM8994_VMID_NORMAL, | ||
37 | WM8994_VMID_FORCE, | ||
38 | }; | ||
39 | |||
35 | typedef void (*wm8958_micdet_cb)(u16 status, void *data); | 40 | typedef void (*wm8958_micdet_cb)(u16 status, void *data); |
36 | 41 | ||
37 | int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | 42 | int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, |
38 | int micbias, int det, int shrt); | 43 | int micbias); |
39 | int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | 44 | int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, |
40 | wm8958_micdet_cb cb, void *cb_data); | 45 | wm8958_micdet_cb cb, void *cb_data); |
41 | 46 | ||
47 | int wm8994_vmid_mode(struct snd_soc_codec *codec, enum wm8994_vmid_mode mode); | ||
48 | |||
42 | int wm8958_aif_ev(struct snd_soc_dapm_widget *w, | 49 | int wm8958_aif_ev(struct snd_soc_dapm_widget *w, |
43 | struct snd_kcontrol *kcontrol, int event); | 50 | struct snd_kcontrol *kcontrol, int event); |
44 | 51 | ||
@@ -46,8 +53,7 @@ void wm8958_dsp2_init(struct snd_soc_codec *codec); | |||
46 | 53 | ||
47 | struct wm8994_micdet { | 54 | struct wm8994_micdet { |
48 | struct snd_soc_jack *jack; | 55 | struct snd_soc_jack *jack; |
49 | int det; | 56 | bool detecting; |
50 | int shrt; | ||
51 | }; | 57 | }; |
52 | 58 | ||
53 | /* codec private data */ | 59 | /* codec private data */ |
@@ -76,6 +82,7 @@ struct wm8994_priv { | |||
76 | 82 | ||
77 | int vmid_refcount; | 83 | int vmid_refcount; |
78 | int active_refcount; | 84 | int active_refcount; |
85 | enum wm8994_vmid_mode vmid_mode; | ||
79 | 86 | ||
80 | int dac_rates[2]; | 87 | int dac_rates[2]; |
81 | int lrclk_shared[2]; | 88 | int lrclk_shared[2]; |
@@ -123,6 +130,7 @@ struct wm8994_priv { | |||
123 | bool jack_mic; | 130 | bool jack_mic; |
124 | int btn_mask; | 131 | int btn_mask; |
125 | bool jackdet; | 132 | bool jackdet; |
133 | int jackdet_mode; | ||
126 | 134 | ||
127 | wm8958_micdet_cb jack_cb; | 135 | wm8958_micdet_cb jack_cb; |
128 | void *jack_cb_data; | 136 | void *jack_cb_data; |
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index c8aada597d70..28c89b094c6e 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c | |||
@@ -2047,7 +2047,6 @@ static int wm8995_probe(struct snd_soc_codec *codec) | |||
2047 | int i; | 2047 | int i; |
2048 | int ret; | 2048 | int ret; |
2049 | 2049 | ||
2050 | codec->dapm.idle_bias_off = 1; | ||
2051 | wm8995 = snd_soc_codec_get_drvdata(codec); | 2050 | wm8995 = snd_soc_codec_get_drvdata(codec); |
2052 | wm8995->codec = codec; | 2051 | wm8995->codec = codec; |
2053 | 2052 | ||
@@ -2137,7 +2136,7 @@ static int wm8995_probe(struct snd_soc_codec *codec) | |||
2137 | 2136 | ||
2138 | wm8995_update_class_w(codec); | 2137 | wm8995_update_class_w(codec); |
2139 | 2138 | ||
2140 | snd_soc_add_controls(codec, wm8995_snd_controls, | 2139 | snd_soc_add_codec_controls(codec, wm8995_snd_controls, |
2141 | ARRAY_SIZE(wm8995_snd_controls)); | 2140 | ARRAY_SIZE(wm8995_snd_controls)); |
2142 | snd_soc_dapm_new_controls(&codec->dapm, wm8995_dapm_widgets, | 2141 | snd_soc_dapm_new_controls(&codec->dapm, wm8995_dapm_widgets, |
2143 | ARRAY_SIZE(wm8995_dapm_widgets)); | 2142 | ARRAY_SIZE(wm8995_dapm_widgets)); |
@@ -2241,6 +2240,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8995 = { | |||
2241 | .suspend = wm8995_suspend, | 2240 | .suspend = wm8995_suspend, |
2242 | .resume = wm8995_resume, | 2241 | .resume = wm8995_resume, |
2243 | .set_bias_level = wm8995_set_bias_level, | 2242 | .set_bias_level = wm8995_set_bias_level, |
2243 | .idle_bias_off = true, | ||
2244 | }; | 2244 | }; |
2245 | 2245 | ||
2246 | static struct regmap_config wm8995_regmap = { | 2246 | static struct regmap_config wm8995_regmap = { |
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index d8da10fe5b52..1fd635494045 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c | |||
@@ -73,7 +73,6 @@ struct wm8996_priv { | |||
73 | 73 | ||
74 | struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES]; | 74 | struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES]; |
75 | struct notifier_block disable_nb[WM8996_NUM_SUPPLIES]; | 75 | struct notifier_block disable_nb[WM8996_NUM_SUPPLIES]; |
76 | struct regulator *cpvdd; | ||
77 | int bg_ena; | 76 | int bg_ena; |
78 | 77 | ||
79 | struct wm8996_pdata pdata; | 78 | struct wm8996_pdata pdata; |
@@ -90,6 +89,7 @@ struct wm8996_priv { | |||
90 | struct snd_soc_jack *jack; | 89 | struct snd_soc_jack *jack; |
91 | bool detecting; | 90 | bool detecting; |
92 | bool jack_mic; | 91 | bool jack_mic; |
92 | int jack_flips; | ||
93 | wm8996_polarity_fn polarity_cb; | 93 | wm8996_polarity_fn polarity_cb; |
94 | 94 | ||
95 | #ifdef CONFIG_GPIOLIB | 95 | #ifdef CONFIG_GPIOLIB |
@@ -108,7 +108,7 @@ static int wm8996_regulator_event_##n(struct notifier_block *nb, \ | |||
108 | struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \ | 108 | struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \ |
109 | disable_nb[n]); \ | 109 | disable_nb[n]); \ |
110 | if (event & REGULATOR_EVENT_DISABLE) { \ | 110 | if (event & REGULATOR_EVENT_DISABLE) { \ |
111 | regcache_cache_only(wm8996->regmap, true); \ | 111 | regcache_mark_dirty(wm8996->regmap); \ |
112 | } \ | 112 | } \ |
113 | return 0; \ | 113 | return 0; \ |
114 | } | 114 | } |
@@ -118,7 +118,6 @@ WM8996_REGULATOR_EVENT(1) | |||
118 | WM8996_REGULATOR_EVENT(2) | 118 | WM8996_REGULATOR_EVENT(2) |
119 | 119 | ||
120 | static struct reg_default wm8996_reg[] = { | 120 | static struct reg_default wm8996_reg[] = { |
121 | { WM8996_SOFTWARE_RESET, 0x8996 }, | ||
122 | { WM8996_POWER_MANAGEMENT_1, 0x0 }, | 121 | { WM8996_POWER_MANAGEMENT_1, 0x0 }, |
123 | { WM8996_POWER_MANAGEMENT_2, 0x0 }, | 122 | { WM8996_POWER_MANAGEMENT_2, 0x0 }, |
124 | { WM8996_POWER_MANAGEMENT_3, 0x0 }, | 123 | { WM8996_POWER_MANAGEMENT_3, 0x0 }, |
@@ -153,7 +152,6 @@ static struct reg_default wm8996_reg[] = { | |||
153 | { WM8996_CHARGE_PUMP_1, 0x1f25 }, | 152 | { WM8996_CHARGE_PUMP_1, 0x1f25 }, |
154 | { WM8996_CHARGE_PUMP_2, 0xab19 }, | 153 | { WM8996_CHARGE_PUMP_2, 0xab19 }, |
155 | { WM8996_DC_SERVO_1, 0x0 }, | 154 | { WM8996_DC_SERVO_1, 0x0 }, |
156 | { WM8996_DC_SERVO_2, 0x0 }, | ||
157 | { WM8996_DC_SERVO_3, 0x0 }, | 155 | { WM8996_DC_SERVO_3, 0x0 }, |
158 | { WM8996_DC_SERVO_5, 0x2a2a }, | 156 | { WM8996_DC_SERVO_5, 0x2a2a }, |
159 | { WM8996_DC_SERVO_6, 0x0 }, | 157 | { WM8996_DC_SERVO_6, 0x0 }, |
@@ -716,10 +714,16 @@ SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0), | |||
716 | SOC_SINGLE("DSP1 DRC TXL Switch", WM8996_DSP1_DRC_1, 0, 1, 0), | 714 | SOC_SINGLE("DSP1 DRC TXL Switch", WM8996_DSP1_DRC_1, 0, 1, 0), |
717 | SOC_SINGLE("DSP1 DRC TXR Switch", WM8996_DSP1_DRC_1, 1, 1, 0), | 715 | SOC_SINGLE("DSP1 DRC TXR Switch", WM8996_DSP1_DRC_1, 1, 1, 0), |
718 | SOC_SINGLE("DSP1 DRC RX Switch", WM8996_DSP1_DRC_1, 2, 1, 0), | 716 | SOC_SINGLE("DSP1 DRC RX Switch", WM8996_DSP1_DRC_1, 2, 1, 0), |
717 | SND_SOC_BYTES_MASK("DSP1 DRC", WM8996_DSP1_DRC_1, 5, | ||
718 | WM8996_DSP1RX_DRC_ENA | WM8996_DSP1TXL_DRC_ENA | | ||
719 | WM8996_DSP1TXR_DRC_ENA), | ||
719 | 720 | ||
720 | SOC_SINGLE("DSP2 DRC TXL Switch", WM8996_DSP2_DRC_1, 0, 1, 0), | 721 | SOC_SINGLE("DSP2 DRC TXL Switch", WM8996_DSP2_DRC_1, 0, 1, 0), |
721 | SOC_SINGLE("DSP2 DRC TXR Switch", WM8996_DSP2_DRC_1, 1, 1, 0), | 722 | SOC_SINGLE("DSP2 DRC TXR Switch", WM8996_DSP2_DRC_1, 1, 1, 0), |
722 | SOC_SINGLE("DSP2 DRC RX Switch", WM8996_DSP2_DRC_1, 2, 1, 0), | 723 | SOC_SINGLE("DSP2 DRC RX Switch", WM8996_DSP2_DRC_1, 2, 1, 0), |
724 | SND_SOC_BYTES_MASK("DSP2 DRC", WM8996_DSP2_DRC_1, 5, | ||
725 | WM8996_DSP2RX_DRC_ENA | WM8996_DSP2TXL_DRC_ENA | | ||
726 | WM8996_DSP2TXR_DRC_ENA), | ||
723 | }; | 727 | }; |
724 | 728 | ||
725 | static const struct snd_kcontrol_new wm8996_eq_controls[] = { | 729 | static const struct snd_kcontrol_new wm8996_eq_controls[] = { |
@@ -792,29 +796,18 @@ static int bg_event(struct snd_soc_dapm_widget *w, | |||
792 | static int cp_event(struct snd_soc_dapm_widget *w, | 796 | static int cp_event(struct snd_soc_dapm_widget *w, |
793 | struct snd_kcontrol *kcontrol, int event) | 797 | struct snd_kcontrol *kcontrol, int event) |
794 | { | 798 | { |
795 | struct snd_soc_codec *codec = w->codec; | ||
796 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | ||
797 | int ret = 0; | 799 | int ret = 0; |
798 | 800 | ||
799 | switch (event) { | 801 | switch (event) { |
800 | case SND_SOC_DAPM_PRE_PMU: | ||
801 | ret = regulator_enable(wm8996->cpvdd); | ||
802 | if (ret != 0) | ||
803 | dev_err(codec->dev, "Failed to enable CPVDD: %d\n", | ||
804 | ret); | ||
805 | break; | ||
806 | case SND_SOC_DAPM_POST_PMU: | 802 | case SND_SOC_DAPM_POST_PMU: |
807 | msleep(5); | 803 | msleep(5); |
808 | break; | 804 | break; |
809 | case SND_SOC_DAPM_POST_PMD: | ||
810 | regulator_disable_deferred(wm8996->cpvdd, 20); | ||
811 | break; | ||
812 | default: | 805 | default: |
813 | BUG(); | 806 | BUG(); |
814 | ret = -EINVAL; | 807 | ret = -EINVAL; |
815 | } | 808 | } |
816 | 809 | ||
817 | return ret; | 810 | return 0; |
818 | } | 811 | } |
819 | 812 | ||
820 | static int rmv_short_event(struct snd_soc_dapm_widget *w, | 813 | static int rmv_short_event(struct snd_soc_dapm_widget *w, |
@@ -897,8 +890,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm, | |||
897 | val = 0; | 890 | val = 0; |
898 | mask = 0; | 891 | mask = 0; |
899 | if (wm8996->hpout_pending & HPOUT1L) { | 892 | if (wm8996->hpout_pending & HPOUT1L) { |
900 | val |= WM8996_HPOUT1L_RMV_SHORT; | 893 | val |= WM8996_HPOUT1L_RMV_SHORT | WM8996_HPOUT1L_OUTP; |
901 | mask |= WM8996_HPOUT1L_RMV_SHORT; | 894 | mask |= WM8996_HPOUT1L_RMV_SHORT | WM8996_HPOUT1L_OUTP; |
902 | } else { | 895 | } else { |
903 | mask |= WM8996_HPOUT1L_RMV_SHORT | | 896 | mask |= WM8996_HPOUT1L_RMV_SHORT | |
904 | WM8996_HPOUT1L_OUTP | | 897 | WM8996_HPOUT1L_OUTP | |
@@ -906,8 +899,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm, | |||
906 | } | 899 | } |
907 | 900 | ||
908 | if (wm8996->hpout_pending & HPOUT1R) { | 901 | if (wm8996->hpout_pending & HPOUT1R) { |
909 | val |= WM8996_HPOUT1R_RMV_SHORT; | 902 | val |= WM8996_HPOUT1R_RMV_SHORT | WM8996_HPOUT1R_OUTP; |
910 | mask |= WM8996_HPOUT1R_RMV_SHORT; | 903 | mask |= WM8996_HPOUT1R_RMV_SHORT | WM8996_HPOUT1R_OUTP; |
911 | } else { | 904 | } else { |
912 | mask |= WM8996_HPOUT1R_RMV_SHORT | | 905 | mask |= WM8996_HPOUT1R_RMV_SHORT | |
913 | WM8996_HPOUT1R_OUTP | | 906 | WM8996_HPOUT1R_OUTP | |
@@ -919,8 +912,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm, | |||
919 | val = 0; | 912 | val = 0; |
920 | mask = 0; | 913 | mask = 0; |
921 | if (wm8996->hpout_pending & HPOUT2L) { | 914 | if (wm8996->hpout_pending & HPOUT2L) { |
922 | val |= WM8996_HPOUT2L_RMV_SHORT; | 915 | val |= WM8996_HPOUT2L_RMV_SHORT | WM8996_HPOUT2L_OUTP; |
923 | mask |= WM8996_HPOUT2L_RMV_SHORT; | 916 | mask |= WM8996_HPOUT2L_RMV_SHORT | WM8996_HPOUT2L_OUTP; |
924 | } else { | 917 | } else { |
925 | mask |= WM8996_HPOUT2L_RMV_SHORT | | 918 | mask |= WM8996_HPOUT2L_RMV_SHORT | |
926 | WM8996_HPOUT2L_OUTP | | 919 | WM8996_HPOUT2L_OUTP | |
@@ -928,8 +921,8 @@ static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm, | |||
928 | } | 921 | } |
929 | 922 | ||
930 | if (wm8996->hpout_pending & HPOUT2R) { | 923 | if (wm8996->hpout_pending & HPOUT2R) { |
931 | val |= WM8996_HPOUT2R_RMV_SHORT; | 924 | val |= WM8996_HPOUT2R_RMV_SHORT | WM8996_HPOUT2R_OUTP; |
932 | mask |= WM8996_HPOUT2R_RMV_SHORT; | 925 | mask |= WM8996_HPOUT2R_RMV_SHORT | WM8996_HPOUT2R_OUTP; |
933 | } else { | 926 | } else { |
934 | mask |= WM8996_HPOUT2R_RMV_SHORT | | 927 | mask |= WM8996_HPOUT2R_RMV_SHORT | |
935 | WM8996_HPOUT2R_OUTP | | 928 | WM8996_HPOUT2R_OUTP | |
@@ -1116,11 +1109,12 @@ SND_SOC_DAPM_INPUT("IN2RP"), | |||
1116 | SND_SOC_DAPM_INPUT("DMIC1DAT"), | 1109 | SND_SOC_DAPM_INPUT("DMIC1DAT"), |
1117 | SND_SOC_DAPM_INPUT("DMIC2DAT"), | 1110 | SND_SOC_DAPM_INPUT("DMIC2DAT"), |
1118 | 1111 | ||
1112 | SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20), | ||
1119 | SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0), | 1113 | SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0), |
1120 | SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), | 1114 | SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), |
1121 | SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), | 1115 | SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), |
1122 | SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event, | 1116 | SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event, |
1123 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | 1117 | SND_SOC_DAPM_POST_PMU), |
1124 | SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event, | 1118 | SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event, |
1125 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | 1119 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
1126 | SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0), | 1120 | SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0), |
@@ -1179,41 +1173,25 @@ SND_SOC_DAPM_DAC("DAC2R", NULL, WM8996_POWER_MANAGEMENT_5, 2, 0), | |||
1179 | SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0), | 1173 | SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0), |
1180 | SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0), | 1174 | SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0), |
1181 | 1175 | ||
1182 | SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 0, | 1176 | SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0, WM8996_POWER_MANAGEMENT_4, 9, 0), |
1183 | WM8996_POWER_MANAGEMENT_4, 9, 0), | 1177 | SND_SOC_DAPM_AIF_IN("AIF2RX0", NULL, 1, WM8996_POWER_MANAGEMENT_4, 8, 0), |
1184 | SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 1, | 1178 | |
1185 | WM8996_POWER_MANAGEMENT_4, 8, 0), | 1179 | SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0, WM8996_POWER_MANAGEMENT_6, 9, 0), |
1186 | 1180 | SND_SOC_DAPM_AIF_OUT("AIF2TX0", NULL, 1, WM8996_POWER_MANAGEMENT_6, 8, 0), | |
1187 | SND_SOC_DAPM_AIF_OUT("AIF2TX1", "AIF2 Capture", 0, | 1181 | |
1188 | WM8996_POWER_MANAGEMENT_6, 9, 0), | 1182 | SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 5, WM8996_POWER_MANAGEMENT_4, 5, 0), |
1189 | SND_SOC_DAPM_AIF_OUT("AIF2TX0", "AIF2 Capture", 1, | 1183 | SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 4, WM8996_POWER_MANAGEMENT_4, 4, 0), |
1190 | WM8996_POWER_MANAGEMENT_6, 8, 0), | 1184 | SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 3, WM8996_POWER_MANAGEMENT_4, 3, 0), |
1191 | 1185 | SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 2, WM8996_POWER_MANAGEMENT_4, 2, 0), | |
1192 | SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5, | 1186 | SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 1, WM8996_POWER_MANAGEMENT_4, 1, 0), |
1193 | WM8996_POWER_MANAGEMENT_4, 5, 0), | 1187 | SND_SOC_DAPM_AIF_IN("AIF1RX0", NULL, 0, WM8996_POWER_MANAGEMENT_4, 0, 0), |
1194 | SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 4, | 1188 | |
1195 | WM8996_POWER_MANAGEMENT_4, 4, 0), | 1189 | SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 5, WM8996_POWER_MANAGEMENT_6, 5, 0), |
1196 | SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 3, | 1190 | SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 4, WM8996_POWER_MANAGEMENT_6, 4, 0), |
1197 | WM8996_POWER_MANAGEMENT_4, 3, 0), | 1191 | SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 3, WM8996_POWER_MANAGEMENT_6, 3, 0), |
1198 | SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 2, | 1192 | SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 2, WM8996_POWER_MANAGEMENT_6, 2, 0), |
1199 | WM8996_POWER_MANAGEMENT_4, 2, 0), | 1193 | SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 1, WM8996_POWER_MANAGEMENT_6, 1, 0), |
1200 | SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 1, | 1194 | SND_SOC_DAPM_AIF_OUT("AIF1TX0", NULL, 0, WM8996_POWER_MANAGEMENT_6, 0, 0), |
1201 | WM8996_POWER_MANAGEMENT_4, 1, 0), | ||
1202 | SND_SOC_DAPM_AIF_IN("AIF1RX0", "AIF1 Playback", 0, | ||
1203 | WM8996_POWER_MANAGEMENT_4, 0, 0), | ||
1204 | |||
1205 | SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 5, | ||
1206 | WM8996_POWER_MANAGEMENT_6, 5, 0), | ||
1207 | SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 4, | ||
1208 | WM8996_POWER_MANAGEMENT_6, 4, 0), | ||
1209 | SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 3, | ||
1210 | WM8996_POWER_MANAGEMENT_6, 3, 0), | ||
1211 | SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 2, | ||
1212 | WM8996_POWER_MANAGEMENT_6, 2, 0), | ||
1213 | SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 1, | ||
1214 | WM8996_POWER_MANAGEMENT_6, 1, 0), | ||
1215 | SND_SOC_DAPM_AIF_OUT("AIF1TX0", "AIF1 Capture", 0, | ||
1216 | WM8996_POWER_MANAGEMENT_6, 0, 0), | ||
1217 | 1195 | ||
1218 | /* We route as stereo pairs so define some dummy widgets to squash | 1196 | /* We route as stereo pairs so define some dummy widgets to squash |
1219 | * things down for now. RXA = 0,1, RXB = 2,3 and so on */ | 1197 | * things down for now. RXA = 0,1, RXB = 2,3 and so on */ |
@@ -1236,7 +1214,6 @@ SND_SOC_DAPM_PGA_S("HPOUT2L PGA", 0, WM8996_POWER_MANAGEMENT_1, 7, 0, NULL, 0), | |||
1236 | SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8996_ANALOGUE_HP_2, 5, 0, NULL, 0), | 1214 | SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8996_ANALOGUE_HP_2, 5, 0, NULL, 0), |
1237 | SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8996_DC_SERVO_1, 2, 0, dcs_start, | 1215 | SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8996_DC_SERVO_1, 2, 0, dcs_start, |
1238 | SND_SOC_DAPM_POST_PMU), | 1216 | SND_SOC_DAPM_POST_PMU), |
1239 | SND_SOC_DAPM_PGA_S("HPOUT2L_OUTP", 3, WM8996_ANALOGUE_HP_2, 6, 0, NULL, 0), | ||
1240 | SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0, | 1217 | SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0, |
1241 | rmv_short_event, | 1218 | rmv_short_event, |
1242 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), | 1219 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), |
@@ -1245,7 +1222,6 @@ SND_SOC_DAPM_PGA_S("HPOUT2R PGA", 0, WM8996_POWER_MANAGEMENT_1, 6, 0,NULL, 0), | |||
1245 | SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8996_ANALOGUE_HP_2, 1, 0, NULL, 0), | 1222 | SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8996_ANALOGUE_HP_2, 1, 0, NULL, 0), |
1246 | SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8996_DC_SERVO_1, 3, 0, dcs_start, | 1223 | SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8996_DC_SERVO_1, 3, 0, dcs_start, |
1247 | SND_SOC_DAPM_POST_PMU), | 1224 | SND_SOC_DAPM_POST_PMU), |
1248 | SND_SOC_DAPM_PGA_S("HPOUT2R_OUTP", 3, WM8996_ANALOGUE_HP_2, 2, 0, NULL, 0), | ||
1249 | SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0, | 1225 | SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0, |
1250 | rmv_short_event, | 1226 | rmv_short_event, |
1251 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), | 1227 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), |
@@ -1254,7 +1230,6 @@ SND_SOC_DAPM_PGA_S("HPOUT1L PGA", 0, WM8996_POWER_MANAGEMENT_1, 5, 0, NULL, 0), | |||
1254 | SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8996_ANALOGUE_HP_1, 5, 0, NULL, 0), | 1230 | SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8996_ANALOGUE_HP_1, 5, 0, NULL, 0), |
1255 | SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8996_DC_SERVO_1, 0, 0, dcs_start, | 1231 | SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8996_DC_SERVO_1, 0, 0, dcs_start, |
1256 | SND_SOC_DAPM_POST_PMU), | 1232 | SND_SOC_DAPM_POST_PMU), |
1257 | SND_SOC_DAPM_PGA_S("HPOUT1L_OUTP", 3, WM8996_ANALOGUE_HP_1, 6, 0, NULL, 0), | ||
1258 | SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0, | 1233 | SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0, |
1259 | rmv_short_event, | 1234 | rmv_short_event, |
1260 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), | 1235 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), |
@@ -1263,7 +1238,6 @@ SND_SOC_DAPM_PGA_S("HPOUT1R PGA", 0, WM8996_POWER_MANAGEMENT_1, 4, 0, NULL, 0), | |||
1263 | SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8996_ANALOGUE_HP_1, 1, 0, NULL, 0), | 1238 | SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8996_ANALOGUE_HP_1, 1, 0, NULL, 0), |
1264 | SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8996_DC_SERVO_1, 1, 0, dcs_start, | 1239 | SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8996_DC_SERVO_1, 1, 0, dcs_start, |
1265 | SND_SOC_DAPM_POST_PMU), | 1240 | SND_SOC_DAPM_POST_PMU), |
1266 | SND_SOC_DAPM_PGA_S("HPOUT1R_OUTP", 3, WM8996_ANALOGUE_HP_1, 2, 0, NULL, 0), | ||
1267 | SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0, | 1241 | SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0, |
1268 | rmv_short_event, | 1242 | rmv_short_event, |
1269 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), | 1243 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), |
@@ -1279,6 +1253,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = { | |||
1279 | { "AIFCLK", NULL, "SYSCLK" }, | 1253 | { "AIFCLK", NULL, "SYSCLK" }, |
1280 | { "SYSDSPCLK", NULL, "SYSCLK" }, | 1254 | { "SYSDSPCLK", NULL, "SYSCLK" }, |
1281 | { "Charge Pump", NULL, "SYSCLK" }, | 1255 | { "Charge Pump", NULL, "SYSCLK" }, |
1256 | { "Charge Pump", NULL, "CPVDD" }, | ||
1282 | 1257 | ||
1283 | { "MICB1", NULL, "LDO2" }, | 1258 | { "MICB1", NULL, "LDO2" }, |
1284 | { "MICB1", NULL, "MICB1 Audio" }, | 1259 | { "MICB1", NULL, "MICB1 Audio" }, |
@@ -1287,6 +1262,26 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = { | |||
1287 | { "MICB2", NULL, "MICB2 Audio" }, | 1262 | { "MICB2", NULL, "MICB2 Audio" }, |
1288 | { "MICB2", NULL, "Bandgap" }, | 1263 | { "MICB2", NULL, "Bandgap" }, |
1289 | 1264 | ||
1265 | { "AIF1RX0", NULL, "AIF1 Playback" }, | ||
1266 | { "AIF1RX1", NULL, "AIF1 Playback" }, | ||
1267 | { "AIF1RX2", NULL, "AIF1 Playback" }, | ||
1268 | { "AIF1RX3", NULL, "AIF1 Playback" }, | ||
1269 | { "AIF1RX4", NULL, "AIF1 Playback" }, | ||
1270 | { "AIF1RX5", NULL, "AIF1 Playback" }, | ||
1271 | |||
1272 | { "AIF2RX0", NULL, "AIF2 Playback" }, | ||
1273 | { "AIF2RX1", NULL, "AIF2 Playback" }, | ||
1274 | |||
1275 | { "AIF1 Capture", NULL, "AIF1TX0" }, | ||
1276 | { "AIF1 Capture", NULL, "AIF1TX1" }, | ||
1277 | { "AIF1 Capture", NULL, "AIF1TX2" }, | ||
1278 | { "AIF1 Capture", NULL, "AIF1TX3" }, | ||
1279 | { "AIF1 Capture", NULL, "AIF1TX4" }, | ||
1280 | { "AIF1 Capture", NULL, "AIF1TX5" }, | ||
1281 | |||
1282 | { "AIF2 Capture", NULL, "AIF2TX0" }, | ||
1283 | { "AIF2 Capture", NULL, "AIF2TX1" }, | ||
1284 | |||
1290 | { "IN1L PGA", NULL, "IN2LN" }, | 1285 | { "IN1L PGA", NULL, "IN2LN" }, |
1291 | { "IN1L PGA", NULL, "IN2LP" }, | 1286 | { "IN1L PGA", NULL, "IN2LP" }, |
1292 | { "IN1L PGA", NULL, "IN1LN" }, | 1287 | { "IN1L PGA", NULL, "IN1LN" }, |
@@ -1435,32 +1430,28 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = { | |||
1435 | { "HPOUT2L PGA", NULL, "DAC2L" }, | 1430 | { "HPOUT2L PGA", NULL, "DAC2L" }, |
1436 | { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" }, | 1431 | { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" }, |
1437 | { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" }, | 1432 | { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" }, |
1438 | { "HPOUT2L_OUTP", NULL, "HPOUT2L_DCS" }, | 1433 | { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_DCS" }, |
1439 | { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" }, | ||
1440 | 1434 | ||
1441 | { "HPOUT2R PGA", NULL, "Charge Pump" }, | 1435 | { "HPOUT2R PGA", NULL, "Charge Pump" }, |
1442 | { "HPOUT2R PGA", NULL, "Bandgap" }, | 1436 | { "HPOUT2R PGA", NULL, "Bandgap" }, |
1443 | { "HPOUT2R PGA", NULL, "DAC2R" }, | 1437 | { "HPOUT2R PGA", NULL, "DAC2R" }, |
1444 | { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" }, | 1438 | { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" }, |
1445 | { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" }, | 1439 | { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" }, |
1446 | { "HPOUT2R_OUTP", NULL, "HPOUT2R_DCS" }, | 1440 | { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_DCS" }, |
1447 | { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" }, | ||
1448 | 1441 | ||
1449 | { "HPOUT1L PGA", NULL, "Charge Pump" }, | 1442 | { "HPOUT1L PGA", NULL, "Charge Pump" }, |
1450 | { "HPOUT1L PGA", NULL, "Bandgap" }, | 1443 | { "HPOUT1L PGA", NULL, "Bandgap" }, |
1451 | { "HPOUT1L PGA", NULL, "DAC1L" }, | 1444 | { "HPOUT1L PGA", NULL, "DAC1L" }, |
1452 | { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" }, | 1445 | { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" }, |
1453 | { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" }, | 1446 | { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" }, |
1454 | { "HPOUT1L_OUTP", NULL, "HPOUT1L_DCS" }, | 1447 | { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_DCS" }, |
1455 | { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" }, | ||
1456 | 1448 | ||
1457 | { "HPOUT1R PGA", NULL, "Charge Pump" }, | 1449 | { "HPOUT1R PGA", NULL, "Charge Pump" }, |
1458 | { "HPOUT1R PGA", NULL, "Bandgap" }, | 1450 | { "HPOUT1R PGA", NULL, "Bandgap" }, |
1459 | { "HPOUT1R PGA", NULL, "DAC1R" }, | 1451 | { "HPOUT1R PGA", NULL, "DAC1R" }, |
1460 | { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" }, | 1452 | { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" }, |
1461 | { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" }, | 1453 | { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" }, |
1462 | { "HPOUT1R_OUTP", NULL, "HPOUT1R_DCS" }, | 1454 | { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_DCS" }, |
1463 | { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_OUTP" }, | ||
1464 | 1455 | ||
1465 | { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" }, | 1456 | { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" }, |
1466 | { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" }, | 1457 | { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" }, |
@@ -1719,6 +1710,7 @@ static int wm8996_reset(struct wm8996_priv *wm8996) | |||
1719 | { | 1710 | { |
1720 | if (wm8996->pdata.ldo_ena > 0) { | 1711 | if (wm8996->pdata.ldo_ena > 0) { |
1721 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); | 1712 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); |
1713 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1); | ||
1722 | return 0; | 1714 | return 0; |
1723 | } else { | 1715 | } else { |
1724 | return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET, | 1716 | return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET, |
@@ -1922,7 +1914,7 @@ static int wm8996_hw_params(struct snd_pcm_substream *substream, | |||
1922 | { | 1914 | { |
1923 | struct snd_soc_codec *codec = dai->codec; | 1915 | struct snd_soc_codec *codec = dai->codec; |
1924 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | 1916 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); |
1925 | int bits, i, bclk_rate; | 1917 | int bits, i, bclk_rate, best; |
1926 | int aifdata = 0; | 1918 | int aifdata = 0; |
1927 | int lrclk = 0; | 1919 | int lrclk = 0; |
1928 | int dsp = 0; | 1920 | int dsp = 0; |
@@ -1971,14 +1963,11 @@ static int wm8996_hw_params(struct snd_pcm_substream *substream, | |||
1971 | return bits; | 1963 | return bits; |
1972 | aifdata |= (bits << WM8996_AIF1TX_WL_SHIFT) | bits; | 1964 | aifdata |= (bits << WM8996_AIF1TX_WL_SHIFT) | bits; |
1973 | 1965 | ||
1966 | best = 0; | ||
1974 | for (i = 0; i < ARRAY_SIZE(dsp_divs); i++) { | 1967 | for (i = 0; i < ARRAY_SIZE(dsp_divs); i++) { |
1975 | if (dsp_divs[i] == params_rate(params)) | 1968 | if (abs(dsp_divs[i] - params_rate(params)) < |
1976 | break; | 1969 | abs(dsp_divs[best] - params_rate(params))) |
1977 | } | 1970 | best = i; |
1978 | if (i == ARRAY_SIZE(dsp_divs)) { | ||
1979 | dev_err(codec->dev, "Unsupported sample rate %dHz\n", | ||
1980 | params_rate(params)); | ||
1981 | return -EINVAL; | ||
1982 | } | 1971 | } |
1983 | dsp |= i << dsp_shift; | 1972 | dsp |= i << dsp_shift; |
1984 | 1973 | ||
@@ -2007,6 +1996,7 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai, | |||
2007 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | 1996 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); |
2008 | int lfclk = 0; | 1997 | int lfclk = 0; |
2009 | int ratediv = 0; | 1998 | int ratediv = 0; |
1999 | int sync = WM8996_REG_SYNC; | ||
2010 | int src; | 2000 | int src; |
2011 | int old; | 2001 | int old; |
2012 | 2002 | ||
@@ -2037,13 +2027,16 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai, | |||
2037 | } | 2027 | } |
2038 | 2028 | ||
2039 | switch (wm8996->sysclk) { | 2029 | switch (wm8996->sysclk) { |
2030 | case 5644800: | ||
2040 | case 6144000: | 2031 | case 6144000: |
2041 | snd_soc_update_bits(codec, WM8996_AIF_RATE, | 2032 | snd_soc_update_bits(codec, WM8996_AIF_RATE, |
2042 | WM8996_SYSCLK_RATE, 0); | 2033 | WM8996_SYSCLK_RATE, 0); |
2043 | break; | 2034 | break; |
2035 | case 22579200: | ||
2044 | case 24576000: | 2036 | case 24576000: |
2045 | ratediv = WM8996_SYSCLK_DIV; | 2037 | ratediv = WM8996_SYSCLK_DIV; |
2046 | wm8996->sysclk /= 2; | 2038 | wm8996->sysclk /= 2; |
2039 | case 11289600: | ||
2047 | case 12288000: | 2040 | case 12288000: |
2048 | snd_soc_update_bits(codec, WM8996_AIF_RATE, | 2041 | snd_soc_update_bits(codec, WM8996_AIF_RATE, |
2049 | WM8996_SYSCLK_RATE, WM8996_SYSCLK_RATE); | 2042 | WM8996_SYSCLK_RATE, WM8996_SYSCLK_RATE); |
@@ -2051,6 +2044,7 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai, | |||
2051 | case 32000: | 2044 | case 32000: |
2052 | case 32768: | 2045 | case 32768: |
2053 | lfclk = WM8996_LFCLK_ENA; | 2046 | lfclk = WM8996_LFCLK_ENA; |
2047 | sync = 0; | ||
2054 | break; | 2048 | break; |
2055 | default: | 2049 | default: |
2056 | dev_warn(codec->dev, "Unsupported clock rate %dHz\n", | 2050 | dev_warn(codec->dev, "Unsupported clock rate %dHz\n", |
@@ -2064,6 +2058,8 @@ static int wm8996_set_sysclk(struct snd_soc_dai *dai, | |||
2064 | WM8996_SYSCLK_SRC_MASK | WM8996_SYSCLK_DIV_MASK, | 2058 | WM8996_SYSCLK_SRC_MASK | WM8996_SYSCLK_DIV_MASK, |
2065 | src << WM8996_SYSCLK_SRC_SHIFT | ratediv); | 2059 | src << WM8996_SYSCLK_SRC_SHIFT | ratediv); |
2066 | snd_soc_update_bits(codec, WM8996_CLOCKING_1, WM8996_LFCLK_ENA, lfclk); | 2060 | snd_soc_update_bits(codec, WM8996_CLOCKING_1, WM8996_LFCLK_ENA, lfclk); |
2061 | snd_soc_update_bits(codec, WM8996_CONTROL_INTERFACE_1, | ||
2062 | WM8996_REG_SYNC, sync); | ||
2067 | snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1, | 2063 | snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1, |
2068 | WM8996_SYSCLK_ENA, old); | 2064 | WM8996_SYSCLK_ENA, old); |
2069 | 2065 | ||
@@ -2433,6 +2429,7 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
2433 | wm8996->jack = jack; | 2429 | wm8996->jack = jack; |
2434 | wm8996->detecting = true; | 2430 | wm8996->detecting = true; |
2435 | wm8996->polarity_cb = polarity_cb; | 2431 | wm8996->polarity_cb = polarity_cb; |
2432 | wm8996->jack_flips = 0; | ||
2436 | 2433 | ||
2437 | if (wm8996->polarity_cb) | 2434 | if (wm8996->polarity_cb) |
2438 | wm8996->polarity_cb(codec, 0); | 2435 | wm8996->polarity_cb(codec, 0); |
@@ -2548,6 +2545,19 @@ static void wm8996_hpdet_start(struct snd_soc_codec *codec) | |||
2548 | WM8996_HP_POLL, WM8996_HP_POLL); | 2545 | WM8996_HP_POLL, WM8996_HP_POLL); |
2549 | } | 2546 | } |
2550 | 2547 | ||
2548 | static void wm8996_report_headphone(struct snd_soc_codec *codec) | ||
2549 | { | ||
2550 | dev_dbg(codec->dev, "Headphone detected\n"); | ||
2551 | wm8996_hpdet_start(codec); | ||
2552 | |||
2553 | /* Increase the detection rate a bit for responsiveness. */ | ||
2554 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, | ||
2555 | WM8996_MICD_RATE_MASK | | ||
2556 | WM8996_MICD_BIAS_STARTTIME_MASK, | ||
2557 | 7 << WM8996_MICD_RATE_SHIFT | | ||
2558 | 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT); | ||
2559 | } | ||
2560 | |||
2551 | static void wm8996_micd(struct snd_soc_codec *codec) | 2561 | static void wm8996_micd(struct snd_soc_codec *codec) |
2552 | { | 2562 | { |
2553 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | 2563 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); |
@@ -2567,6 +2577,7 @@ static void wm8996_micd(struct snd_soc_codec *codec) | |||
2567 | dev_dbg(codec->dev, "Jack removal detected\n"); | 2577 | dev_dbg(codec->dev, "Jack removal detected\n"); |
2568 | wm8996->jack_mic = false; | 2578 | wm8996->jack_mic = false; |
2569 | wm8996->detecting = true; | 2579 | wm8996->detecting = true; |
2580 | wm8996->jack_flips = 0; | ||
2570 | snd_soc_jack_report(wm8996->jack, 0, | 2581 | snd_soc_jack_report(wm8996->jack, 0, |
2571 | SND_JACK_LINEOUT | SND_JACK_HEADSET | | 2582 | SND_JACK_LINEOUT | SND_JACK_HEADSET | |
2572 | SND_JACK_BTN_0); | 2583 | SND_JACK_BTN_0); |
@@ -2607,9 +2618,17 @@ static void wm8996_micd(struct snd_soc_codec *codec) | |||
2607 | /* If we detected a lower impedence during initial startup | 2618 | /* If we detected a lower impedence during initial startup |
2608 | * then we probably have the wrong polarity, flip it. Don't | 2619 | * then we probably have the wrong polarity, flip it. Don't |
2609 | * do this for the lowest impedences to speed up detection of | 2620 | * do this for the lowest impedences to speed up detection of |
2610 | * plain headphones. | 2621 | * plain headphones. If both polarities report a low |
2622 | * impedence then give up and report headphones. | ||
2611 | */ | 2623 | */ |
2612 | if (wm8996->detecting && (val & 0x3f0)) { | 2624 | if (wm8996->detecting && (val & 0x3f0)) { |
2625 | wm8996->jack_flips++; | ||
2626 | |||
2627 | if (wm8996->jack_flips > 1) { | ||
2628 | wm8996_report_headphone(codec); | ||
2629 | return; | ||
2630 | } | ||
2631 | |||
2613 | reg = snd_soc_read(codec, WM8996_ACCESSORY_DETECT_MODE_2); | 2632 | reg = snd_soc_read(codec, WM8996_ACCESSORY_DETECT_MODE_2); |
2614 | reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC | | 2633 | reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC | |
2615 | WM8996_MICD_BIAS_SRC; | 2634 | WM8996_MICD_BIAS_SRC; |
@@ -2636,17 +2655,7 @@ static void wm8996_micd(struct snd_soc_codec *codec) | |||
2636 | snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0, | 2655 | snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0, |
2637 | SND_JACK_BTN_0); | 2656 | SND_JACK_BTN_0); |
2638 | } else if (wm8996->detecting) { | 2657 | } else if (wm8996->detecting) { |
2639 | dev_dbg(codec->dev, "Headphone detected\n"); | 2658 | wm8996_report_headphone(codec); |
2640 | wm8996_hpdet_start(codec); | ||
2641 | |||
2642 | /* Increase the detection rate a bit for | ||
2643 | * responsiveness. | ||
2644 | */ | ||
2645 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, | ||
2646 | WM8996_MICD_RATE_MASK | | ||
2647 | WM8996_MICD_BIAS_STARTTIME_MASK, | ||
2648 | 7 << WM8996_MICD_RATE_SHIFT | | ||
2649 | 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT); | ||
2650 | } | 2659 | } |
2651 | } | 2660 | } |
2652 | } | 2661 | } |
@@ -2763,7 +2772,7 @@ static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec) | |||
2763 | wm8996->retune_mobile_enum.max = wm8996->num_retune_mobile_texts; | 2772 | wm8996->retune_mobile_enum.max = wm8996->num_retune_mobile_texts; |
2764 | wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts; | 2773 | wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts; |
2765 | 2774 | ||
2766 | ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); | 2775 | ret = snd_soc_add_codec_controls(codec, controls, ARRAY_SIZE(controls)); |
2767 | if (ret != 0) | 2776 | if (ret != 0) |
2768 | dev_err(codec->dev, | 2777 | dev_err(codec->dev, |
2769 | "Failed to add ReTune Mobile controls: %d\n", ret); | 2778 | "Failed to add ReTune Mobile controls: %d\n", ret); |
@@ -2786,7 +2795,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) | |||
2786 | int ret; | 2795 | int ret; |
2787 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | 2796 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); |
2788 | struct i2c_client *i2c = to_i2c_client(codec->dev); | 2797 | struct i2c_client *i2c = to_i2c_client(codec->dev); |
2789 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
2790 | int i, irq_flags; | 2798 | int i, irq_flags; |
2791 | 2799 | ||
2792 | wm8996->codec = codec; | 2800 | wm8996->codec = codec; |
@@ -2794,8 +2802,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) | |||
2794 | init_completion(&wm8996->dcs_done); | 2802 | init_completion(&wm8996->dcs_done); |
2795 | init_completion(&wm8996->fll_lock); | 2803 | init_completion(&wm8996->fll_lock); |
2796 | 2804 | ||
2797 | dapm->idle_bias_off = true; | ||
2798 | |||
2799 | codec->control_data = wm8996->regmap; | 2805 | codec->control_data = wm8996->regmap; |
2800 | 2806 | ||
2801 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); | 2807 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP); |
@@ -2961,7 +2967,7 @@ static int wm8996_probe(struct snd_soc_codec *codec) | |||
2961 | if (wm8996->pdata.num_retune_mobile_cfgs) | 2967 | if (wm8996->pdata.num_retune_mobile_cfgs) |
2962 | wm8996_retune_mobile_pdata(codec); | 2968 | wm8996_retune_mobile_pdata(codec); |
2963 | else | 2969 | else |
2964 | snd_soc_add_controls(codec, wm8996_eq_controls, | 2970 | snd_soc_add_codec_controls(codec, wm8996_eq_controls, |
2965 | ARRAY_SIZE(wm8996_eq_controls)); | 2971 | ARRAY_SIZE(wm8996_eq_controls)); |
2966 | 2972 | ||
2967 | /* If the TX LRCLK pins are not in LRCLK mode configure the | 2973 | /* If the TX LRCLK pins are not in LRCLK mode configure the |
@@ -3033,22 +3039,16 @@ static int wm8996_remove(struct snd_soc_codec *codec) | |||
3033 | for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) | 3039 | for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) |
3034 | regulator_unregister_notifier(wm8996->supplies[i].consumer, | 3040 | regulator_unregister_notifier(wm8996->supplies[i].consumer, |
3035 | &wm8996->disable_nb[i]); | 3041 | &wm8996->disable_nb[i]); |
3036 | regulator_put(wm8996->cpvdd); | ||
3037 | regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | 3042 | regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); |
3038 | 3043 | ||
3039 | return 0; | 3044 | return 0; |
3040 | } | 3045 | } |
3041 | 3046 | ||
3042 | static int wm8996_soc_volatile_register(struct snd_soc_codec *codec, | ||
3043 | unsigned int reg) | ||
3044 | { | ||
3045 | return true; | ||
3046 | } | ||
3047 | |||
3048 | static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { | 3047 | static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { |
3049 | .probe = wm8996_probe, | 3048 | .probe = wm8996_probe, |
3050 | .remove = wm8996_remove, | 3049 | .remove = wm8996_remove, |
3051 | .set_bias_level = wm8996_set_bias_level, | 3050 | .set_bias_level = wm8996_set_bias_level, |
3051 | .idle_bias_off = true, | ||
3052 | .seq_notifier = wm8996_seq_notifier, | 3052 | .seq_notifier = wm8996_seq_notifier, |
3053 | .controls = wm8996_snd_controls, | 3053 | .controls = wm8996_snd_controls, |
3054 | .num_controls = ARRAY_SIZE(wm8996_snd_controls), | 3054 | .num_controls = ARRAY_SIZE(wm8996_snd_controls), |
@@ -3057,12 +3057,11 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { | |||
3057 | .dapm_routes = wm8996_dapm_routes, | 3057 | .dapm_routes = wm8996_dapm_routes, |
3058 | .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes), | 3058 | .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes), |
3059 | .set_pll = wm8996_set_fll, | 3059 | .set_pll = wm8996_set_fll, |
3060 | .reg_cache_size = WM8996_MAX_REGISTER, | ||
3061 | .volatile_register = wm8996_soc_volatile_register, | ||
3062 | }; | 3060 | }; |
3063 | 3061 | ||
3064 | #define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ | 3062 | #define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ |
3065 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000) | 3063 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ |
3064 | SNDRV_PCM_RATE_48000) | ||
3066 | #define WM8996_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ | 3065 | #define WM8996_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ |
3067 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\ | 3066 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\ |
3068 | SNDRV_PCM_FMTBIT_S32_LE) | 3067 | SNDRV_PCM_FMTBIT_S32_LE) |
@@ -3082,6 +3081,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = { | |||
3082 | .channels_max = 6, | 3081 | .channels_max = 6, |
3083 | .rates = WM8996_RATES, | 3082 | .rates = WM8996_RATES, |
3084 | .formats = WM8996_FORMATS, | 3083 | .formats = WM8996_FORMATS, |
3084 | .sig_bits = 24, | ||
3085 | }, | 3085 | }, |
3086 | .capture = { | 3086 | .capture = { |
3087 | .stream_name = "AIF1 Capture", | 3087 | .stream_name = "AIF1 Capture", |
@@ -3089,6 +3089,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = { | |||
3089 | .channels_max = 6, | 3089 | .channels_max = 6, |
3090 | .rates = WM8996_RATES, | 3090 | .rates = WM8996_RATES, |
3091 | .formats = WM8996_FORMATS, | 3091 | .formats = WM8996_FORMATS, |
3092 | .sig_bits = 24, | ||
3092 | }, | 3093 | }, |
3093 | .ops = &wm8996_dai_ops, | 3094 | .ops = &wm8996_dai_ops, |
3094 | }, | 3095 | }, |
@@ -3100,6 +3101,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = { | |||
3100 | .channels_max = 2, | 3101 | .channels_max = 2, |
3101 | .rates = WM8996_RATES, | 3102 | .rates = WM8996_RATES, |
3102 | .formats = WM8996_FORMATS, | 3103 | .formats = WM8996_FORMATS, |
3104 | .sig_bits = 24, | ||
3103 | }, | 3105 | }, |
3104 | .capture = { | 3106 | .capture = { |
3105 | .stream_name = "AIF2 Capture", | 3107 | .stream_name = "AIF2 Capture", |
@@ -3107,6 +3109,7 @@ static struct snd_soc_dai_driver wm8996_dai[] = { | |||
3107 | .channels_max = 2, | 3109 | .channels_max = 2, |
3108 | .rates = WM8996_RATES, | 3110 | .rates = WM8996_RATES, |
3109 | .formats = WM8996_FORMATS, | 3111 | .formats = WM8996_FORMATS, |
3112 | .sig_bits = 24, | ||
3110 | }, | 3113 | }, |
3111 | .ops = &wm8996_dai_ops, | 3114 | .ops = &wm8996_dai_ops, |
3112 | }, | 3115 | }, |
@@ -3144,25 +3147,18 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, | |||
3144 | for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) | 3147 | for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) |
3145 | wm8996->supplies[i].supply = wm8996_supply_names[i]; | 3148 | wm8996->supplies[i].supply = wm8996_supply_names[i]; |
3146 | 3149 | ||
3147 | ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies), | 3150 | ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies), |
3148 | wm8996->supplies); | 3151 | wm8996->supplies); |
3149 | if (ret != 0) { | 3152 | if (ret != 0) { |
3150 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); | 3153 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); |
3151 | goto err_gpio; | 3154 | goto err_gpio; |
3152 | } | 3155 | } |
3153 | 3156 | ||
3154 | wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD"); | ||
3155 | if (IS_ERR(wm8996->cpvdd)) { | ||
3156 | ret = PTR_ERR(wm8996->cpvdd); | ||
3157 | dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret); | ||
3158 | goto err_get; | ||
3159 | } | ||
3160 | |||
3161 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), | 3157 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), |
3162 | wm8996->supplies); | 3158 | wm8996->supplies); |
3163 | if (ret != 0) { | 3159 | if (ret != 0) { |
3164 | dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); | 3160 | dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); |
3165 | goto err_cpvdd; | 3161 | goto err_gpio; |
3166 | } | 3162 | } |
3167 | 3163 | ||
3168 | if (wm8996->pdata.ldo_ena > 0) { | 3164 | if (wm8996->pdata.ldo_ena > 0) { |
@@ -3183,7 +3179,7 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, | |||
3183 | goto err_regmap; | 3179 | goto err_regmap; |
3184 | } | 3180 | } |
3185 | if (reg != 0x8915) { | 3181 | if (reg != 0x8915) { |
3186 | dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", ret); | 3182 | dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", reg); |
3187 | ret = -EINVAL; | 3183 | ret = -EINVAL; |
3188 | goto err_regmap; | 3184 | goto err_regmap; |
3189 | } | 3185 | } |
@@ -3224,10 +3220,6 @@ err_enable: | |||
3224 | if (wm8996->pdata.ldo_ena > 0) | 3220 | if (wm8996->pdata.ldo_ena > 0) |
3225 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); | 3221 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); |
3226 | regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | 3222 | regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); |
3227 | err_cpvdd: | ||
3228 | regulator_put(wm8996->cpvdd); | ||
3229 | err_get: | ||
3230 | regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | ||
3231 | err_gpio: | 3223 | err_gpio: |
3232 | if (wm8996->pdata.ldo_ena > 0) | 3224 | if (wm8996->pdata.ldo_ena > 0) |
3233 | gpio_free(wm8996->pdata.ldo_ena); | 3225 | gpio_free(wm8996->pdata.ldo_ena); |
@@ -3242,8 +3234,6 @@ static __devexit int wm8996_i2c_remove(struct i2c_client *client) | |||
3242 | 3234 | ||
3243 | snd_soc_unregister_codec(&client->dev); | 3235 | snd_soc_unregister_codec(&client->dev); |
3244 | wm8996_free_gpio(wm8996); | 3236 | wm8996_free_gpio(wm8996); |
3245 | regulator_put(wm8996->cpvdd); | ||
3246 | regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | ||
3247 | regmap_exit(wm8996->regmap); | 3237 | regmap_exit(wm8996->regmap); |
3248 | if (wm8996->pdata.ldo_ena > 0) { | 3238 | if (wm8996->pdata.ldo_ena > 0) { |
3249 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); | 3239 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); |
@@ -3268,25 +3258,7 @@ static struct i2c_driver wm8996_i2c_driver = { | |||
3268 | .id_table = wm8996_i2c_id, | 3258 | .id_table = wm8996_i2c_id, |
3269 | }; | 3259 | }; |
3270 | 3260 | ||
3271 | static int __init wm8996_modinit(void) | 3261 | module_i2c_driver(wm8996_i2c_driver); |
3272 | { | ||
3273 | int ret; | ||
3274 | |||
3275 | ret = i2c_add_driver(&wm8996_i2c_driver); | ||
3276 | if (ret != 0) { | ||
3277 | printk(KERN_ERR "Failed to register WM8996 I2C driver: %d\n", | ||
3278 | ret); | ||
3279 | } | ||
3280 | |||
3281 | return ret; | ||
3282 | } | ||
3283 | module_init(wm8996_modinit); | ||
3284 | |||
3285 | static void __exit wm8996_exit(void) | ||
3286 | { | ||
3287 | i2c_del_driver(&wm8996_i2c_driver); | ||
3288 | } | ||
3289 | module_exit(wm8996_exit); | ||
3290 | 3262 | ||
3291 | MODULE_DESCRIPTION("ASoC WM8996 driver"); | 3263 | MODULE_DESCRIPTION("ASoC WM8996 driver"); |
3292 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 3264 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
diff --git a/sound/soc/codecs/wm8996.h b/sound/soc/codecs/wm8996.h index 0fde643194ce..de9ac3e44aec 100644 --- a/sound/soc/codecs/wm8996.h +++ b/sound/soc/codecs/wm8996.h | |||
@@ -1567,6 +1567,10 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
1567 | /* | 1567 | /* |
1568 | * R257 (0x101) - Control Interface (1) | 1568 | * R257 (0x101) - Control Interface (1) |
1569 | */ | 1569 | */ |
1570 | #define WM8996_REG_SYNC 0x8000 /* REG_SYNC */ | ||
1571 | #define WM8996_REG_SYNC_MASK 0x8000 /* REG_SYNC */ | ||
1572 | #define WM8996_REG_SYNC_SHIFT 15 /* REG_SYNC */ | ||
1573 | #define WM8996_REG_SYNC_WIDTH 1 /* REG_SYNC */ | ||
1570 | #define WM8996_AUTO_INC 0x0004 /* AUTO_INC */ | 1574 | #define WM8996_AUTO_INC 0x0004 /* AUTO_INC */ |
1571 | #define WM8996_AUTO_INC_MASK 0x0004 /* AUTO_INC */ | 1575 | #define WM8996_AUTO_INC_MASK 0x0004 /* AUTO_INC */ |
1572 | #define WM8996_AUTO_INC_SHIFT 2 /* AUTO_INC */ | 1576 | #define WM8996_AUTO_INC_SHIFT 2 /* AUTO_INC */ |
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index a6bab392700e..076c126ed9b1 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c | |||
@@ -824,6 +824,8 @@ static const struct snd_soc_dapm_route wm9081_audio_paths[] = { | |||
824 | static int wm9081_set_bias_level(struct snd_soc_codec *codec, | 824 | static int wm9081_set_bias_level(struct snd_soc_codec *codec, |
825 | enum snd_soc_bias_level level) | 825 | enum snd_soc_bias_level level) |
826 | { | 826 | { |
827 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); | ||
828 | |||
827 | switch (level) { | 829 | switch (level) { |
828 | case SND_SOC_BIAS_ON: | 830 | case SND_SOC_BIAS_ON: |
829 | break; | 831 | break; |
@@ -841,6 +843,9 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, | |||
841 | case SND_SOC_BIAS_STANDBY: | 843 | case SND_SOC_BIAS_STANDBY: |
842 | /* Initial cold start */ | 844 | /* Initial cold start */ |
843 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 845 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
846 | regcache_cache_only(wm9081->regmap, false); | ||
847 | regcache_sync(wm9081->regmap); | ||
848 | |||
844 | /* Disable LINEOUT discharge */ | 849 | /* Disable LINEOUT discharge */ |
845 | snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, | 850 | snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, |
846 | WM9081_LINEOUT_DISCH, 0); | 851 | WM9081_LINEOUT_DISCH, 0); |
@@ -892,6 +897,8 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, | |||
892 | snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, | 897 | snd_soc_update_bits(codec, WM9081_ANTI_POP_CONTROL, |
893 | WM9081_LINEOUT_DISCH, | 898 | WM9081_LINEOUT_DISCH, |
894 | WM9081_LINEOUT_DISCH); | 899 | WM9081_LINEOUT_DISCH); |
900 | |||
901 | regcache_cache_only(wm9081->regmap, true); | ||
895 | break; | 902 | break; |
896 | } | 903 | } |
897 | 904 | ||
@@ -1258,7 +1265,6 @@ static int wm9081_probe(struct snd_soc_codec *codec) | |||
1258 | { | 1265 | { |
1259 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); | 1266 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); |
1260 | int ret; | 1267 | int ret; |
1261 | u16 reg; | ||
1262 | 1268 | ||
1263 | codec->control_data = wm9081->regmap; | 1269 | codec->control_data = wm9081->regmap; |
1264 | 1270 | ||
@@ -1268,16 +1274,6 @@ static int wm9081_probe(struct snd_soc_codec *codec) | |||
1268 | return ret; | 1274 | return ret; |
1269 | } | 1275 | } |
1270 | 1276 | ||
1271 | reg = 0; | ||
1272 | if (wm9081->pdata.irq_high) | ||
1273 | reg |= WM9081_IRQ_POL; | ||
1274 | if (!wm9081->pdata.irq_cmos) | ||
1275 | reg |= WM9081_IRQ_OP_CTRL; | ||
1276 | snd_soc_update_bits(codec, WM9081_INTERRUPT_CONTROL, | ||
1277 | WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg); | ||
1278 | |||
1279 | wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1280 | |||
1281 | /* Enable zero cross by default */ | 1277 | /* Enable zero cross by default */ |
1282 | snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT, | 1278 | snd_soc_update_bits(codec, WM9081_ANALOGUE_LINEOUT, |
1283 | WM9081_LINEOUTZC, WM9081_LINEOUTZC); | 1279 | WM9081_LINEOUTZC, WM9081_LINEOUTZC); |
@@ -1287,7 +1283,7 @@ static int wm9081_probe(struct snd_soc_codec *codec) | |||
1287 | if (!wm9081->pdata.num_retune_configs) { | 1283 | if (!wm9081->pdata.num_retune_configs) { |
1288 | dev_dbg(codec->dev, | 1284 | dev_dbg(codec->dev, |
1289 | "No ReTune Mobile data, using normal EQ\n"); | 1285 | "No ReTune Mobile data, using normal EQ\n"); |
1290 | snd_soc_add_controls(codec, wm9081_eq_controls, | 1286 | snd_soc_add_codec_controls(codec, wm9081_eq_controls, |
1291 | ARRAY_SIZE(wm9081_eq_controls)); | 1287 | ARRAY_SIZE(wm9081_eq_controls)); |
1292 | } | 1288 | } |
1293 | 1289 | ||
@@ -1300,38 +1296,15 @@ static int wm9081_remove(struct snd_soc_codec *codec) | |||
1300 | return 0; | 1296 | return 0; |
1301 | } | 1297 | } |
1302 | 1298 | ||
1303 | #ifdef CONFIG_PM | ||
1304 | static int wm9081_suspend(struct snd_soc_codec *codec) | ||
1305 | { | ||
1306 | wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1307 | |||
1308 | return 0; | ||
1309 | } | ||
1310 | |||
1311 | static int wm9081_resume(struct snd_soc_codec *codec) | ||
1312 | { | ||
1313 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); | ||
1314 | |||
1315 | regcache_sync(wm9081->regmap); | ||
1316 | |||
1317 | wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1318 | |||
1319 | return 0; | ||
1320 | } | ||
1321 | #else | ||
1322 | #define wm9081_suspend NULL | ||
1323 | #define wm9081_resume NULL | ||
1324 | #endif | ||
1325 | |||
1326 | static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { | 1299 | static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { |
1327 | .probe = wm9081_probe, | 1300 | .probe = wm9081_probe, |
1328 | .remove = wm9081_remove, | 1301 | .remove = wm9081_remove, |
1329 | .suspend = wm9081_suspend, | ||
1330 | .resume = wm9081_resume, | ||
1331 | 1302 | ||
1332 | .set_sysclk = wm9081_set_sysclk, | 1303 | .set_sysclk = wm9081_set_sysclk, |
1333 | .set_bias_level = wm9081_set_bias_level, | 1304 | .set_bias_level = wm9081_set_bias_level, |
1334 | 1305 | ||
1306 | .idle_bias_off = true, | ||
1307 | |||
1335 | .controls = wm9081_snd_controls, | 1308 | .controls = wm9081_snd_controls, |
1336 | .num_controls = ARRAY_SIZE(wm9081_snd_controls), | 1309 | .num_controls = ARRAY_SIZE(wm9081_snd_controls), |
1337 | .dapm_widgets = wm9081_dapm_widgets, | 1310 | .dapm_widgets = wm9081_dapm_widgets, |
@@ -1395,6 +1368,16 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, | |||
1395 | memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), | 1368 | memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), |
1396 | sizeof(wm9081->pdata)); | 1369 | sizeof(wm9081->pdata)); |
1397 | 1370 | ||
1371 | reg = 0; | ||
1372 | if (wm9081->pdata.irq_high) | ||
1373 | reg |= WM9081_IRQ_POL; | ||
1374 | if (!wm9081->pdata.irq_cmos) | ||
1375 | reg |= WM9081_IRQ_OP_CTRL; | ||
1376 | regmap_update_bits(wm9081->regmap, WM9081_INTERRUPT_CONTROL, | ||
1377 | WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg); | ||
1378 | |||
1379 | regcache_cache_only(wm9081->regmap, true); | ||
1380 | |||
1398 | ret = snd_soc_register_codec(&i2c->dev, | 1381 | ret = snd_soc_register_codec(&i2c->dev, |
1399 | &soc_codec_dev_wm9081, &wm9081_dai, 1); | 1382 | &soc_codec_dev_wm9081, &wm9081_dai, 1); |
1400 | if (ret < 0) | 1383 | if (ret < 0) |
@@ -1435,28 +1418,7 @@ static struct i2c_driver wm9081_i2c_driver = { | |||
1435 | }; | 1418 | }; |
1436 | #endif | 1419 | #endif |
1437 | 1420 | ||
1438 | static int __init wm9081_modinit(void) | 1421 | module_i2c_driver(wm9081_i2c_driver); |
1439 | { | ||
1440 | int ret = 0; | ||
1441 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1442 | ret = i2c_add_driver(&wm9081_i2c_driver); | ||
1443 | if (ret != 0) { | ||
1444 | printk(KERN_ERR "Failed to register WM9081 I2C driver: %d\n", | ||
1445 | ret); | ||
1446 | } | ||
1447 | #endif | ||
1448 | return ret; | ||
1449 | } | ||
1450 | module_init(wm9081_modinit); | ||
1451 | |||
1452 | static void __exit wm9081_exit(void) | ||
1453 | { | ||
1454 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1455 | i2c_del_driver(&wm9081_i2c_driver); | ||
1456 | #endif | ||
1457 | } | ||
1458 | module_exit(wm9081_exit); | ||
1459 | |||
1460 | 1422 | ||
1461 | MODULE_DESCRIPTION("ASoC WM9081 driver"); | 1423 | MODULE_DESCRIPTION("ASoC WM9081 driver"); |
1462 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 1424 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 41ebe0dce772..4b263b6edf13 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
26 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/regmap.h> | ||
28 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
29 | #include <sound/initval.h> | 30 | #include <sound/initval.h> |
30 | #include <sound/soc.h> | 31 | #include <sound/soc.h> |
@@ -33,116 +34,51 @@ | |||
33 | 34 | ||
34 | #include "wm9090.h" | 35 | #include "wm9090.h" |
35 | 36 | ||
36 | static const u16 wm9090_reg_defaults[] = { | 37 | static const struct reg_default wm9090_reg_defaults[] = { |
37 | 0x9093, /* R0 - Software Reset */ | 38 | { 1, 0x0006 }, /* R1 - Power Management (1) */ |
38 | 0x0006, /* R1 - Power Management (1) */ | 39 | { 2, 0x6000 }, /* R2 - Power Management (2) */ |
39 | 0x6000, /* R2 - Power Management (2) */ | 40 | { 3, 0x0000 }, /* R3 - Power Management (3) */ |
40 | 0x0000, /* R3 - Power Management (3) */ | 41 | { 6, 0x01C0 }, /* R6 - Clocking 1 */ |
41 | 0x0000, /* R4 */ | 42 | { 22, 0x0003 }, /* R22 - IN1 Line Control */ |
42 | 0x0000, /* R5 */ | 43 | { 23, 0x0003 }, /* R23 - IN2 Line Control */ |
43 | 0x01C0, /* R6 - Clocking 1 */ | 44 | { 24, 0x0083 }, /* R24 - IN1 Line Input A Volume */ |
44 | 0x0000, /* R7 */ | 45 | { 25, 0x0083 }, /* R25 - IN1 Line Input B Volume */ |
45 | 0x0000, /* R8 */ | 46 | { 26, 0x0083 }, /* R26 - IN2 Line Input A Volume */ |
46 | 0x0000, /* R9 */ | 47 | { 27, 0x0083 }, /* R27 - IN2 Line Input B Volume */ |
47 | 0x0000, /* R10 */ | 48 | { 28, 0x002D }, /* R28 - Left Output Volume */ |
48 | 0x0000, /* R11 */ | 49 | { 29, 0x002D }, /* R29 - Right Output Volume */ |
49 | 0x0000, /* R12 */ | 50 | { 34, 0x0100 }, /* R34 - SPKMIXL Attenuation */ |
50 | 0x0000, /* R13 */ | 51 | { 35, 0x0010 }, /* R36 - SPKOUT Mixers */ |
51 | 0x0000, /* R14 */ | 52 | { 37, 0x0140 }, /* R37 - ClassD3 */ |
52 | 0x0000, /* R15 */ | 53 | { 38, 0x0039 }, /* R38 - Speaker Volume Left */ |
53 | 0x0000, /* R16 */ | 54 | { 45, 0x0000 }, /* R45 - Output Mixer1 */ |
54 | 0x0000, /* R17 */ | 55 | { 46, 0x0000 }, /* R46 - Output Mixer2 */ |
55 | 0x0000, /* R18 */ | 56 | { 47, 0x0100 }, /* R47 - Output Mixer3 */ |
56 | 0x0000, /* R19 */ | 57 | { 48, 0x0100 }, /* R48 - Output Mixer4 */ |
57 | 0x0000, /* R20 */ | 58 | { 54, 0x0000 }, /* R54 - Speaker Mixer */ |
58 | 0x0000, /* R21 */ | 59 | { 57, 0x000D }, /* R57 - AntiPOP2 */ |
59 | 0x0003, /* R22 - IN1 Line Control */ | 60 | { 70, 0x0000 }, /* R70 - Write Sequencer 0 */ |
60 | 0x0003, /* R23 - IN2 Line Control */ | 61 | { 71, 0x0000 }, /* R71 - Write Sequencer 1 */ |
61 | 0x0083, /* R24 - IN1 Line Input A Volume */ | 62 | { 72, 0x0000 }, /* R72 - Write Sequencer 2 */ |
62 | 0x0083, /* R25 - IN1 Line Input B Volume */ | 63 | { 73, 0x0000 }, /* R73 - Write Sequencer 3 */ |
63 | 0x0083, /* R26 - IN2 Line Input A Volume */ | 64 | { 74, 0x0000 }, /* R74 - Write Sequencer 4 */ |
64 | 0x0083, /* R27 - IN2 Line Input B Volume */ | 65 | { 75, 0x0000 }, /* R75 - Write Sequencer 5 */ |
65 | 0x002D, /* R28 - Left Output Volume */ | 66 | { 76, 0x1F25 }, /* R76 - Charge Pump 1 */ |
66 | 0x002D, /* R29 - Right Output Volume */ | 67 | { 85, 0x054A }, /* R85 - DC Servo 1 */ |
67 | 0x0000, /* R30 */ | 68 | { 87, 0x0000 }, /* R87 - DC Servo 3 */ |
68 | 0x0000, /* R31 */ | 69 | { 96, 0x0100 }, /* R96 - Analogue HP 0 */ |
69 | 0x0000, /* R32 */ | 70 | { 98, 0x8640 }, /* R98 - AGC Control 0 */ |
70 | 0x0000, /* R33 */ | 71 | { 99, 0xC000 }, /* R99 - AGC Control 1 */ |
71 | 0x0100, /* R34 - SPKMIXL Attenuation */ | 72 | { 100, 0x0200 }, /* R100 - AGC Control 2 */ |
72 | 0x0000, /* R35 */ | ||
73 | 0x0010, /* R36 - SPKOUT Mixers */ | ||
74 | 0x0140, /* R37 - ClassD3 */ | ||
75 | 0x0039, /* R38 - Speaker Volume Left */ | ||
76 | 0x0000, /* R39 */ | ||
77 | 0x0000, /* R40 */ | ||
78 | 0x0000, /* R41 */ | ||
79 | 0x0000, /* R42 */ | ||
80 | 0x0000, /* R43 */ | ||
81 | 0x0000, /* R44 */ | ||
82 | 0x0000, /* R45 - Output Mixer1 */ | ||
83 | 0x0000, /* R46 - Output Mixer2 */ | ||
84 | 0x0100, /* R47 - Output Mixer3 */ | ||
85 | 0x0100, /* R48 - Output Mixer4 */ | ||
86 | 0x0000, /* R49 */ | ||
87 | 0x0000, /* R50 */ | ||
88 | 0x0000, /* R51 */ | ||
89 | 0x0000, /* R52 */ | ||
90 | 0x0000, /* R53 */ | ||
91 | 0x0000, /* R54 - Speaker Mixer */ | ||
92 | 0x0000, /* R55 */ | ||
93 | 0x0000, /* R56 */ | ||
94 | 0x000D, /* R57 - AntiPOP2 */ | ||
95 | 0x0000, /* R58 */ | ||
96 | 0x0000, /* R59 */ | ||
97 | 0x0000, /* R60 */ | ||
98 | 0x0000, /* R61 */ | ||
99 | 0x0000, /* R62 */ | ||
100 | 0x0000, /* R63 */ | ||
101 | 0x0000, /* R64 */ | ||
102 | 0x0000, /* R65 */ | ||
103 | 0x0000, /* R66 */ | ||
104 | 0x0000, /* R67 */ | ||
105 | 0x0000, /* R68 */ | ||
106 | 0x0000, /* R69 */ | ||
107 | 0x0000, /* R70 - Write Sequencer 0 */ | ||
108 | 0x0000, /* R71 - Write Sequencer 1 */ | ||
109 | 0x0000, /* R72 - Write Sequencer 2 */ | ||
110 | 0x0000, /* R73 - Write Sequencer 3 */ | ||
111 | 0x0000, /* R74 - Write Sequencer 4 */ | ||
112 | 0x0000, /* R75 - Write Sequencer 5 */ | ||
113 | 0x1F25, /* R76 - Charge Pump 1 */ | ||
114 | 0x0000, /* R77 */ | ||
115 | 0x0000, /* R78 */ | ||
116 | 0x0000, /* R79 */ | ||
117 | 0x0000, /* R80 */ | ||
118 | 0x0000, /* R81 */ | ||
119 | 0x0000, /* R82 */ | ||
120 | 0x0000, /* R83 */ | ||
121 | 0x0000, /* R84 - DC Servo 0 */ | ||
122 | 0x054A, /* R85 - DC Servo 1 */ | ||
123 | 0x0000, /* R86 */ | ||
124 | 0x0000, /* R87 - DC Servo 3 */ | ||
125 | 0x0000, /* R88 - DC Servo Readback 0 */ | ||
126 | 0x0000, /* R89 - DC Servo Readback 1 */ | ||
127 | 0x0000, /* R90 - DC Servo Readback 2 */ | ||
128 | 0x0000, /* R91 */ | ||
129 | 0x0000, /* R92 */ | ||
130 | 0x0000, /* R93 */ | ||
131 | 0x0000, /* R94 */ | ||
132 | 0x0000, /* R95 */ | ||
133 | 0x0100, /* R96 - Analogue HP 0 */ | ||
134 | 0x0000, /* R97 */ | ||
135 | 0x8640, /* R98 - AGC Control 0 */ | ||
136 | 0xC000, /* R99 - AGC Control 1 */ | ||
137 | 0x0200, /* R100 - AGC Control 2 */ | ||
138 | }; | 73 | }; |
139 | 74 | ||
140 | /* This struct is used to save the context */ | 75 | /* This struct is used to save the context */ |
141 | struct wm9090_priv { | 76 | struct wm9090_priv { |
142 | struct wm9090_platform_data pdata; | 77 | struct wm9090_platform_data pdata; |
78 | struct regmap *regmap; | ||
143 | }; | 79 | }; |
144 | 80 | ||
145 | static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg) | 81 | static bool wm9090_volatile(struct device *dev, unsigned int reg) |
146 | { | 82 | { |
147 | switch (reg) { | 83 | switch (reg) { |
148 | case WM9090_SOFTWARE_RESET: | 84 | case WM9090_SOFTWARE_RESET: |
@@ -150,10 +86,60 @@ static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg) | |||
150 | case WM9090_DC_SERVO_READBACK_0: | 86 | case WM9090_DC_SERVO_READBACK_0: |
151 | case WM9090_DC_SERVO_READBACK_1: | 87 | case WM9090_DC_SERVO_READBACK_1: |
152 | case WM9090_DC_SERVO_READBACK_2: | 88 | case WM9090_DC_SERVO_READBACK_2: |
153 | return 1; | 89 | return true; |
154 | 90 | ||
155 | default: | 91 | default: |
156 | return 0; | 92 | return false; |
93 | } | ||
94 | } | ||
95 | |||
96 | static bool wm9090_readable(struct device *dev, unsigned int reg) | ||
97 | { | ||
98 | switch (reg) { | ||
99 | case WM9090_SOFTWARE_RESET: | ||
100 | case WM9090_POWER_MANAGEMENT_1: | ||
101 | case WM9090_POWER_MANAGEMENT_2: | ||
102 | case WM9090_POWER_MANAGEMENT_3: | ||
103 | case WM9090_CLOCKING_1: | ||
104 | case WM9090_IN1_LINE_CONTROL: | ||
105 | case WM9090_IN2_LINE_CONTROL: | ||
106 | case WM9090_IN1_LINE_INPUT_A_VOLUME: | ||
107 | case WM9090_IN1_LINE_INPUT_B_VOLUME: | ||
108 | case WM9090_IN2_LINE_INPUT_A_VOLUME: | ||
109 | case WM9090_IN2_LINE_INPUT_B_VOLUME: | ||
110 | case WM9090_LEFT_OUTPUT_VOLUME: | ||
111 | case WM9090_RIGHT_OUTPUT_VOLUME: | ||
112 | case WM9090_SPKMIXL_ATTENUATION: | ||
113 | case WM9090_SPKOUT_MIXERS: | ||
114 | case WM9090_CLASSD3: | ||
115 | case WM9090_SPEAKER_VOLUME_LEFT: | ||
116 | case WM9090_OUTPUT_MIXER1: | ||
117 | case WM9090_OUTPUT_MIXER2: | ||
118 | case WM9090_OUTPUT_MIXER3: | ||
119 | case WM9090_OUTPUT_MIXER4: | ||
120 | case WM9090_SPEAKER_MIXER: | ||
121 | case WM9090_ANTIPOP2: | ||
122 | case WM9090_WRITE_SEQUENCER_0: | ||
123 | case WM9090_WRITE_SEQUENCER_1: | ||
124 | case WM9090_WRITE_SEQUENCER_2: | ||
125 | case WM9090_WRITE_SEQUENCER_3: | ||
126 | case WM9090_WRITE_SEQUENCER_4: | ||
127 | case WM9090_WRITE_SEQUENCER_5: | ||
128 | case WM9090_CHARGE_PUMP_1: | ||
129 | case WM9090_DC_SERVO_0: | ||
130 | case WM9090_DC_SERVO_1: | ||
131 | case WM9090_DC_SERVO_3: | ||
132 | case WM9090_DC_SERVO_READBACK_0: | ||
133 | case WM9090_DC_SERVO_READBACK_1: | ||
134 | case WM9090_DC_SERVO_READBACK_2: | ||
135 | case WM9090_ANALOGUE_HP_0: | ||
136 | case WM9090_AGC_CONTROL_0: | ||
137 | case WM9090_AGC_CONTROL_1: | ||
138 | case WM9090_AGC_CONTROL_2: | ||
139 | return true; | ||
140 | |||
141 | default: | ||
142 | return false; | ||
157 | } | 143 | } |
158 | } | 144 | } |
159 | 145 | ||
@@ -447,7 +433,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec) | |||
447 | 433 | ||
448 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | 434 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); |
449 | 435 | ||
450 | snd_soc_add_controls(codec, wm9090_controls, | 436 | snd_soc_add_codec_controls(codec, wm9090_controls, |
451 | ARRAY_SIZE(wm9090_controls)); | 437 | ARRAY_SIZE(wm9090_controls)); |
452 | 438 | ||
453 | if (wm9090->pdata.lin1_diff) { | 439 | if (wm9090->pdata.lin1_diff) { |
@@ -456,7 +442,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec) | |||
456 | } else { | 442 | } else { |
457 | snd_soc_dapm_add_routes(dapm, audio_map_in1_se, | 443 | snd_soc_dapm_add_routes(dapm, audio_map_in1_se, |
458 | ARRAY_SIZE(audio_map_in1_se)); | 444 | ARRAY_SIZE(audio_map_in1_se)); |
459 | snd_soc_add_controls(codec, wm9090_in1_se_controls, | 445 | snd_soc_add_codec_controls(codec, wm9090_in1_se_controls, |
460 | ARRAY_SIZE(wm9090_in1_se_controls)); | 446 | ARRAY_SIZE(wm9090_in1_se_controls)); |
461 | } | 447 | } |
462 | 448 | ||
@@ -466,7 +452,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec) | |||
466 | } else { | 452 | } else { |
467 | snd_soc_dapm_add_routes(dapm, audio_map_in2_se, | 453 | snd_soc_dapm_add_routes(dapm, audio_map_in2_se, |
468 | ARRAY_SIZE(audio_map_in2_se)); | 454 | ARRAY_SIZE(audio_map_in2_se)); |
469 | snd_soc_add_controls(codec, wm9090_in2_se_controls, | 455 | snd_soc_add_codec_controls(codec, wm9090_in2_se_controls, |
470 | ARRAY_SIZE(wm9090_in2_se_controls)); | 456 | ARRAY_SIZE(wm9090_in2_se_controls)); |
471 | } | 457 | } |
472 | 458 | ||
@@ -492,8 +478,7 @@ static int wm9090_add_controls(struct snd_soc_codec *codec) | |||
492 | static int wm9090_set_bias_level(struct snd_soc_codec *codec, | 478 | static int wm9090_set_bias_level(struct snd_soc_codec *codec, |
493 | enum snd_soc_bias_level level) | 479 | enum snd_soc_bias_level level) |
494 | { | 480 | { |
495 | u16 *reg_cache = codec->reg_cache; | 481 | struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec); |
496 | int i, ret; | ||
497 | 482 | ||
498 | switch (level) { | 483 | switch (level) { |
499 | case SND_SOC_BIAS_ON: | 484 | case SND_SOC_BIAS_ON: |
@@ -513,7 +498,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec, | |||
513 | case SND_SOC_BIAS_STANDBY: | 498 | case SND_SOC_BIAS_STANDBY: |
514 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 499 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
515 | /* Restore the register cache */ | 500 | /* Restore the register cache */ |
516 | snd_soc_cache_sync(codec); | 501 | regcache_sync(wm9090->regmap); |
517 | } | 502 | } |
518 | 503 | ||
519 | /* We keep VMID off during standby since the combination of | 504 | /* We keep VMID off during standby since the combination of |
@@ -537,26 +522,16 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec, | |||
537 | 522 | ||
538 | static int wm9090_probe(struct snd_soc_codec *codec) | 523 | static int wm9090_probe(struct snd_soc_codec *codec) |
539 | { | 524 | { |
525 | struct wm9090_priv *wm9090 = dev_get_drvdata(codec->dev); | ||
540 | int ret; | 526 | int ret; |
541 | 527 | ||
542 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); | 528 | codec->control_data = wm9090->regmap; |
529 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP); | ||
543 | if (ret != 0) { | 530 | if (ret != 0) { |
544 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 531 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
545 | return ret; | 532 | return ret; |
546 | } | 533 | } |
547 | 534 | ||
548 | ret = snd_soc_read(codec, WM9090_SOFTWARE_RESET); | ||
549 | if (ret < 0) | ||
550 | return ret; | ||
551 | if (ret != wm9090_reg_defaults[WM9090_SOFTWARE_RESET]) { | ||
552 | dev_err(codec->dev, "Device is not a WM9090, ID=%x\n", ret); | ||
553 | return -EINVAL; | ||
554 | } | ||
555 | |||
556 | ret = snd_soc_write(codec, WM9090_SOFTWARE_RESET, 0); | ||
557 | if (ret < 0) | ||
558 | return ret; | ||
559 | |||
560 | /* Configure some defaults; they will be written out when we | 535 | /* Configure some defaults; they will be written out when we |
561 | * bring the bias up. | 536 | * bring the bias up. |
562 | */ | 537 | */ |
@@ -624,16 +599,27 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9090 = { | |||
624 | .suspend = wm9090_suspend, | 599 | .suspend = wm9090_suspend, |
625 | .resume = wm9090_resume, | 600 | .resume = wm9090_resume, |
626 | .set_bias_level = wm9090_set_bias_level, | 601 | .set_bias_level = wm9090_set_bias_level, |
627 | .reg_cache_size = (WM9090_MAX_REGISTER + 1), | ||
628 | .reg_word_size = sizeof(u16), | ||
629 | .reg_cache_default = wm9090_reg_defaults, | ||
630 | .volatile_register = wm9090_volatile, | ||
631 | }; | 602 | }; |
632 | 603 | ||
604 | static const struct regmap_config wm9090_regmap = { | ||
605 | .reg_bits = 8, | ||
606 | .val_bits = 16, | ||
607 | |||
608 | .max_register = WM9090_MAX_REGISTER, | ||
609 | .volatile_reg = wm9090_volatile, | ||
610 | .readable_reg = wm9090_readable, | ||
611 | |||
612 | .cache_type = REGCACHE_RBTREE, | ||
613 | .reg_defaults = wm9090_reg_defaults, | ||
614 | .num_reg_defaults = ARRAY_SIZE(wm9090_reg_defaults), | ||
615 | }; | ||
616 | |||
617 | |||
633 | static int wm9090_i2c_probe(struct i2c_client *i2c, | 618 | static int wm9090_i2c_probe(struct i2c_client *i2c, |
634 | const struct i2c_device_id *id) | 619 | const struct i2c_device_id *id) |
635 | { | 620 | { |
636 | struct wm9090_priv *wm9090; | 621 | struct wm9090_priv *wm9090; |
622 | unsigned int reg; | ||
637 | int ret; | 623 | int ret; |
638 | 624 | ||
639 | wm9090 = devm_kzalloc(&i2c->dev, sizeof(*wm9090), GFP_KERNEL); | 625 | wm9090 = devm_kzalloc(&i2c->dev, sizeof(*wm9090), GFP_KERNEL); |
@@ -642,6 +628,26 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, | |||
642 | return -ENOMEM; | 628 | return -ENOMEM; |
643 | } | 629 | } |
644 | 630 | ||
631 | wm9090->regmap = regmap_init_i2c(i2c, &wm9090_regmap); | ||
632 | if (IS_ERR(wm9090->regmap)) { | ||
633 | ret = PTR_ERR(wm9090->regmap); | ||
634 | dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret); | ||
635 | return ret; | ||
636 | } | ||
637 | |||
638 | ret = regmap_read(wm9090->regmap, WM9090_SOFTWARE_RESET, ®); | ||
639 | if (ret < 0) | ||
640 | goto err; | ||
641 | if (reg != 0x9093) { | ||
642 | dev_err(&i2c->dev, "Device is not a WM9090, ID=%x\n", reg); | ||
643 | ret = -ENODEV; | ||
644 | goto err; | ||
645 | } | ||
646 | |||
647 | ret = regmap_write(wm9090->regmap, WM9090_SOFTWARE_RESET, 0); | ||
648 | if (ret < 0) | ||
649 | goto err; | ||
650 | |||
645 | if (i2c->dev.platform_data) | 651 | if (i2c->dev.platform_data) |
646 | memcpy(&wm9090->pdata, i2c->dev.platform_data, | 652 | memcpy(&wm9090->pdata, i2c->dev.platform_data, |
647 | sizeof(wm9090->pdata)); | 653 | sizeof(wm9090->pdata)); |
@@ -650,6 +656,15 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, | |||
650 | 656 | ||
651 | ret = snd_soc_register_codec(&i2c->dev, | 657 | ret = snd_soc_register_codec(&i2c->dev, |
652 | &soc_codec_dev_wm9090, NULL, 0); | 658 | &soc_codec_dev_wm9090, NULL, 0); |
659 | if (ret != 0) { | ||
660 | dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); | ||
661 | goto err; | ||
662 | } | ||
663 | |||
664 | return 0; | ||
665 | |||
666 | err: | ||
667 | regmap_exit(wm9090->regmap); | ||
653 | return ret; | 668 | return ret; |
654 | } | 669 | } |
655 | 670 | ||
@@ -658,6 +673,7 @@ static int __devexit wm9090_i2c_remove(struct i2c_client *i2c) | |||
658 | struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c); | 673 | struct wm9090_priv *wm9090 = i2c_get_clientdata(i2c); |
659 | 674 | ||
660 | snd_soc_unregister_codec(&i2c->dev); | 675 | snd_soc_unregister_codec(&i2c->dev); |
676 | regmap_exit(wm9090->regmap); | ||
661 | 677 | ||
662 | return 0; | 678 | return 0; |
663 | } | 679 | } |
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 40c92ead85a3..cacc6a86b46f 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c | |||
@@ -351,7 +351,7 @@ static int wm9705_soc_probe(struct snd_soc_codec *codec) | |||
351 | if (ret) | 351 | if (ret) |
352 | goto reset_err; | 352 | goto reset_err; |
353 | 353 | ||
354 | snd_soc_add_controls(codec, wm9705_snd_ac97_controls, | 354 | snd_soc_add_codec_controls(codec, wm9705_snd_ac97_controls, |
355 | ARRAY_SIZE(wm9705_snd_ac97_controls)); | 355 | ARRAY_SIZE(wm9705_snd_ac97_controls)); |
356 | 356 | ||
357 | return 0; | 357 | return 0; |
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index b7b31f84c10b..b342ae50bcd6 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c | |||
@@ -20,10 +20,9 @@ | |||
20 | #include <sound/ac97_codec.h> | 20 | #include <sound/ac97_codec.h> |
21 | #include <sound/initval.h> | 21 | #include <sound/initval.h> |
22 | #include <sound/soc.h> | 22 | #include <sound/soc.h> |
23 | #include <sound/tlv.h> | ||
23 | #include "wm9712.h" | 24 | #include "wm9712.h" |
24 | 25 | ||
25 | #define WM9712_VERSION "0.4" | ||
26 | |||
27 | static unsigned int ac97_read(struct snd_soc_codec *codec, | 26 | static unsigned int ac97_read(struct snd_soc_codec *codec, |
28 | unsigned int reg); | 27 | unsigned int reg); |
29 | static int ac97_write(struct snd_soc_codec *codec, | 28 | static int ac97_write(struct snd_soc_codec *codec, |
@@ -71,6 +70,9 @@ static const char *wm9712_rec_sel[] = {"Mic", "NC", "NC", "Speaker Mixer", | |||
71 | static const char *wm9712_ng_type[] = {"Constant Gain", "Mute"}; | 70 | static const char *wm9712_ng_type[] = {"Constant Gain", "Mute"}; |
72 | static const char *wm9712_diff_sel[] = {"Mic", "Line"}; | 71 | static const char *wm9712_diff_sel[] = {"Mic", "Line"}; |
73 | 72 | ||
73 | static const DECLARE_TLV_DB_SCALE(main_tlv, -3450, 150, 0); | ||
74 | static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 2000, 0); | ||
75 | |||
74 | static const struct soc_enum wm9712_enum[] = { | 76 | static const struct soc_enum wm9712_enum[] = { |
75 | SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9712_alc_select), | 77 | SOC_ENUM_SINGLE(AC97_PCI_SVID, 14, 4, wm9712_alc_select), |
76 | SOC_ENUM_SINGLE(AC97_VIDEO, 12, 4, wm9712_alc_mux), | 78 | SOC_ENUM_SINGLE(AC97_VIDEO, 12, 4, wm9712_alc_mux), |
@@ -149,9 +151,9 @@ SOC_ENUM("Capture Volume Steps", wm9712_enum[6]), | |||
149 | SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1), | 151 | SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1), |
150 | SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), | 152 | SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), |
151 | 153 | ||
152 | SOC_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), | 154 | SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv), |
153 | SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), | 155 | SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv), |
154 | SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), | 156 | SOC_SINGLE_TLV("Mic Boost Volume", AC97_MIC, 7, 1, 0, boost_tlv), |
155 | }; | 157 | }; |
156 | 158 | ||
157 | /* We have to create a fake left and right HP mixers because | 159 | /* We have to create a fake left and right HP mixers because |
@@ -619,8 +621,6 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) | |||
619 | { | 621 | { |
620 | int ret = 0; | 622 | int ret = 0; |
621 | 623 | ||
622 | printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION); | ||
623 | |||
624 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | 624 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); |
625 | if (ret < 0) { | 625 | if (ret < 0) { |
626 | printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); | 626 | printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); |
@@ -637,7 +637,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) | |||
637 | ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); | 637 | ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); |
638 | 638 | ||
639 | wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 639 | wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
640 | snd_soc_add_controls(codec, wm9712_snd_ac97_controls, | 640 | snd_soc_add_codec_controls(codec, wm9712_snd_ac97_controls, |
641 | ARRAY_SIZE(wm9712_snd_ac97_controls)); | 641 | ARRAY_SIZE(wm9712_snd_ac97_controls)); |
642 | 642 | ||
643 | return 0; | 643 | return 0; |
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 2b8479bfcd93..2d22cc70d536 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c | |||
@@ -1216,7 +1216,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) | |||
1216 | reg = ac97_read(codec, AC97_CD) & 0x7fff; | 1216 | reg = ac97_read(codec, AC97_CD) & 0x7fff; |
1217 | ac97_write(codec, AC97_CD, reg); | 1217 | ac97_write(codec, AC97_CD, reg); |
1218 | 1218 | ||
1219 | snd_soc_add_controls(codec, wm9713_snd_ac97_controls, | 1219 | snd_soc_add_codec_controls(codec, wm9713_snd_ac97_controls, |
1220 | ARRAY_SIZE(wm9713_snd_ac97_controls)); | 1220 | ARRAY_SIZE(wm9713_snd_ac97_controls)); |
1221 | 1221 | ||
1222 | return 0; | 1222 | return 0; |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 2a61094075f8..f13f2886339c 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -172,7 +172,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) | |||
172 | break; | 172 | break; |
173 | default: | 173 | default: |
174 | WARN(1, "Unknown DCS readback method\n"); | 174 | WARN(1, "Unknown DCS readback method\n"); |
175 | break; | 175 | return; |
176 | } | 176 | } |
177 | 177 | ||
178 | dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); | 178 | dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); |
@@ -207,7 +207,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) | |||
207 | 207 | ||
208 | /* Save the callibrated offset if we're in class W mode and | 208 | /* Save the callibrated offset if we're in class W mode and |
209 | * therefore don't have any analogue signal mixed in. */ | 209 | * therefore don't have any analogue signal mixed in. */ |
210 | if (hubs->class_w) | 210 | if (hubs->class_w && !hubs->no_cache_class_w) |
211 | hubs->class_w_dcs = dcs_cfg; | 211 | hubs->class_w_dcs = dcs_cfg; |
212 | } | 212 | } |
213 | 213 | ||
@@ -500,6 +500,36 @@ static int earpiece_event(struct snd_soc_dapm_widget *w, | |||
500 | return 0; | 500 | return 0; |
501 | } | 501 | } |
502 | 502 | ||
503 | static int lineout_event(struct snd_soc_dapm_widget *w, | ||
504 | struct snd_kcontrol *control, int event) | ||
505 | { | ||
506 | struct snd_soc_codec *codec = w->codec; | ||
507 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | ||
508 | bool *flag; | ||
509 | |||
510 | switch (w->shift) { | ||
511 | case WM8993_LINEOUT1N_ENA_SHIFT: | ||
512 | flag = &hubs->lineout1n_ena; | ||
513 | break; | ||
514 | case WM8993_LINEOUT1P_ENA_SHIFT: | ||
515 | flag = &hubs->lineout1p_ena; | ||
516 | break; | ||
517 | case WM8993_LINEOUT2N_ENA_SHIFT: | ||
518 | flag = &hubs->lineout2n_ena; | ||
519 | break; | ||
520 | case WM8993_LINEOUT2P_ENA_SHIFT: | ||
521 | flag = &hubs->lineout2p_ena; | ||
522 | break; | ||
523 | default: | ||
524 | WARN(1, "Unknown line output"); | ||
525 | return -EINVAL; | ||
526 | } | ||
527 | |||
528 | *flag = SND_SOC_DAPM_EVENT_ON(event); | ||
529 | |||
530 | return 0; | ||
531 | } | ||
532 | |||
503 | static const struct snd_kcontrol_new in1l_pga[] = { | 533 | static const struct snd_kcontrol_new in1l_pga[] = { |
504 | SOC_DAPM_SINGLE("IN1LP Switch", WM8993_INPUT_MIXER2, 5, 1, 0), | 534 | SOC_DAPM_SINGLE("IN1LP Switch", WM8993_INPUT_MIXER2, 5, 1, 0), |
505 | SOC_DAPM_SINGLE("IN1LN Switch", WM8993_INPUT_MIXER2, 4, 1, 0), | 535 | SOC_DAPM_SINGLE("IN1LN Switch", WM8993_INPUT_MIXER2, 4, 1, 0), |
@@ -586,14 +616,14 @@ SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER1, 0, 1, 0), | |||
586 | }; | 616 | }; |
587 | 617 | ||
588 | static const struct snd_kcontrol_new line2_mix[] = { | 618 | static const struct snd_kcontrol_new line2_mix[] = { |
589 | SOC_DAPM_SINGLE("IN2R Switch", WM8993_LINE_MIXER2, 2, 1, 0), | 619 | SOC_DAPM_SINGLE("IN1L Switch", WM8993_LINE_MIXER2, 2, 1, 0), |
590 | SOC_DAPM_SINGLE("IN2L Switch", WM8993_LINE_MIXER2, 1, 1, 0), | 620 | SOC_DAPM_SINGLE("IN1R Switch", WM8993_LINE_MIXER2, 1, 1, 0), |
591 | SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER2, 0, 1, 0), | 621 | SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER2, 0, 1, 0), |
592 | }; | 622 | }; |
593 | 623 | ||
594 | static const struct snd_kcontrol_new line2n_mix[] = { | 624 | static const struct snd_kcontrol_new line2n_mix[] = { |
595 | SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER2, 6, 1, 0), | 625 | SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER2, 5, 1, 0), |
596 | SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 5, 1, 0), | 626 | SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 6, 1, 0), |
597 | }; | 627 | }; |
598 | 628 | ||
599 | static const struct snd_kcontrol_new line2p_mix[] = { | 629 | static const struct snd_kcontrol_new line2p_mix[] = { |
@@ -638,9 +668,8 @@ SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0), | |||
638 | 668 | ||
639 | SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event, | 669 | SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event, |
640 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), | 670 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), |
641 | SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0, | 671 | SND_SOC_DAPM_OUT_DRV_E("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0, |
642 | NULL, 0, | 672 | hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
643 | hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
644 | 673 | ||
645 | SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, | 674 | SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, |
646 | earpiece_mixer, ARRAY_SIZE(earpiece_mixer)), | 675 | earpiece_mixer, ARRAY_SIZE(earpiece_mixer)), |
@@ -654,10 +683,10 @@ SND_SOC_DAPM_MIXER("SPKR Boost", SND_SOC_NOPM, 0, 0, | |||
654 | right_speaker_boost, ARRAY_SIZE(right_speaker_boost)), | 683 | right_speaker_boost, ARRAY_SIZE(right_speaker_boost)), |
655 | 684 | ||
656 | SND_SOC_DAPM_SUPPLY("TSHUT", WM8993_POWER_MANAGEMENT_2, 14, 0, NULL, 0), | 685 | SND_SOC_DAPM_SUPPLY("TSHUT", WM8993_POWER_MANAGEMENT_2, 14, 0, NULL, 0), |
657 | SND_SOC_DAPM_PGA("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0, | 686 | SND_SOC_DAPM_OUT_DRV("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0, |
658 | NULL, 0), | 687 | NULL, 0), |
659 | SND_SOC_DAPM_PGA("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0, | 688 | SND_SOC_DAPM_OUT_DRV("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0, |
660 | NULL, 0), | 689 | NULL, 0), |
661 | 690 | ||
662 | SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0, | 691 | SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0, |
663 | line1_mix, ARRAY_SIZE(line1_mix)), | 692 | line1_mix, ARRAY_SIZE(line1_mix)), |
@@ -673,14 +702,18 @@ SND_SOC_DAPM_MIXER("LINEOUT2N Mixer", SND_SOC_NOPM, 0, 0, | |||
673 | SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0, | 702 | SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0, |
674 | line2p_mix, ARRAY_SIZE(line2p_mix)), | 703 | line2p_mix, ARRAY_SIZE(line2p_mix)), |
675 | 704 | ||
676 | SND_SOC_DAPM_PGA("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0, | 705 | SND_SOC_DAPM_OUT_DRV_E("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0, |
677 | NULL, 0), | 706 | NULL, 0, lineout_event, |
678 | SND_SOC_DAPM_PGA("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0, | 707 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
679 | NULL, 0), | 708 | SND_SOC_DAPM_OUT_DRV_E("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0, |
680 | SND_SOC_DAPM_PGA("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0, | 709 | NULL, 0, lineout_event, |
681 | NULL, 0), | 710 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
682 | SND_SOC_DAPM_PGA("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0, | 711 | SND_SOC_DAPM_OUT_DRV_E("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0, |
683 | NULL, 0), | 712 | NULL, 0, lineout_event, |
713 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
714 | SND_SOC_DAPM_OUT_DRV_E("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0, | ||
715 | NULL, 0, lineout_event, | ||
716 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
684 | 717 | ||
685 | SND_SOC_DAPM_OUTPUT("SPKOUTLP"), | 718 | SND_SOC_DAPM_OUTPUT("SPKOUTLP"), |
686 | SND_SOC_DAPM_OUTPUT("SPKOUTLN"), | 719 | SND_SOC_DAPM_OUTPUT("SPKOUTLN"), |
@@ -844,8 +877,8 @@ static const struct snd_soc_dapm_route lineout1_se_routes[] = { | |||
844 | }; | 877 | }; |
845 | 878 | ||
846 | static const struct snd_soc_dapm_route lineout2_diff_routes[] = { | 879 | static const struct snd_soc_dapm_route lineout2_diff_routes[] = { |
847 | { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" }, | 880 | { "LINEOUT2 Mixer", "IN1L Switch", "IN1L PGA" }, |
848 | { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" }, | 881 | { "LINEOUT2 Mixer", "IN1R Switch", "IN1R PGA" }, |
849 | { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" }, | 882 | { "LINEOUT2 Mixer", "Output Switch", "Right Output PGA" }, |
850 | 883 | ||
851 | { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" }, | 884 | { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" }, |
@@ -895,7 +928,7 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec) | |||
895 | WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU, | 928 | WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU, |
896 | WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU); | 929 | WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU); |
897 | 930 | ||
898 | snd_soc_add_controls(codec, analogue_snd_controls, | 931 | snd_soc_add_codec_controls(codec, analogue_snd_controls, |
899 | ARRAY_SIZE(analogue_snd_controls)); | 932 | ARRAY_SIZE(analogue_snd_controls)); |
900 | 933 | ||
901 | snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets, | 934 | snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets, |
@@ -943,6 +976,11 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec, | |||
943 | int jd_scthr, int jd_thr, int micbias1_lvl, | 976 | int jd_scthr, int jd_thr, int micbias1_lvl, |
944 | int micbias2_lvl) | 977 | int micbias2_lvl) |
945 | { | 978 | { |
979 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | ||
980 | |||
981 | hubs->lineout1_se = !lineout1_diff; | ||
982 | hubs->lineout2_se = !lineout2_diff; | ||
983 | |||
946 | if (!lineout1_diff) | 984 | if (!lineout1_diff) |
947 | snd_soc_update_bits(codec, WM8993_LINE_MIXER1, | 985 | snd_soc_update_bits(codec, WM8993_LINE_MIXER1, |
948 | WM8993_LINEOUT1_MODE, | 986 | WM8993_LINEOUT1_MODE, |
@@ -952,11 +990,10 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec, | |||
952 | WM8993_LINEOUT2_MODE, | 990 | WM8993_LINEOUT2_MODE, |
953 | WM8993_LINEOUT2_MODE); | 991 | WM8993_LINEOUT2_MODE); |
954 | 992 | ||
955 | /* If the line outputs are differential then we aren't presenting | 993 | if (!lineout1_diff && !lineout2_diff) |
956 | * VMID as an output and can disable it. | 994 | snd_soc_update_bits(codec, WM8993_ANTIPOP1, |
957 | */ | 995 | WM8993_LINEOUT_VMID_BUF_ENA, |
958 | if (lineout1_diff && lineout2_diff) | 996 | WM8993_LINEOUT_VMID_BUF_ENA); |
959 | codec->dapm.idle_bias_off = 1; | ||
960 | 997 | ||
961 | if (lineout1fb) | 998 | if (lineout1fb) |
962 | snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL, | 999 | snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL, |
@@ -978,6 +1015,69 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec, | |||
978 | } | 1015 | } |
979 | EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata); | 1016 | EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata); |
980 | 1017 | ||
1018 | void wm_hubs_vmid_ena(struct snd_soc_codec *codec) | ||
1019 | { | ||
1020 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | ||
1021 | int val = 0; | ||
1022 | |||
1023 | if (hubs->lineout1_se) | ||
1024 | val |= WM8993_LINEOUT1N_ENA | WM8993_LINEOUT1P_ENA; | ||
1025 | |||
1026 | if (hubs->lineout2_se) | ||
1027 | val |= WM8993_LINEOUT2N_ENA | WM8993_LINEOUT2P_ENA; | ||
1028 | |||
1029 | /* Enable the line outputs while we power up */ | ||
1030 | snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3, val, val); | ||
1031 | } | ||
1032 | EXPORT_SYMBOL_GPL(wm_hubs_vmid_ena); | ||
1033 | |||
1034 | void wm_hubs_set_bias_level(struct snd_soc_codec *codec, | ||
1035 | enum snd_soc_bias_level level) | ||
1036 | { | ||
1037 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | ||
1038 | int val; | ||
1039 | |||
1040 | switch (level) { | ||
1041 | case SND_SOC_BIAS_STANDBY: | ||
1042 | /* Clamp the inputs to VMID while we ramp to charge caps */ | ||
1043 | snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG, | ||
1044 | WM8993_INPUTS_CLAMP, WM8993_INPUTS_CLAMP); | ||
1045 | break; | ||
1046 | |||
1047 | case SND_SOC_BIAS_ON: | ||
1048 | /* Turn off any unneded single ended outputs */ | ||
1049 | val = 0; | ||
1050 | |||
1051 | if (hubs->lineout1_se && hubs->lineout1n_ena) | ||
1052 | val |= WM8993_LINEOUT1N_ENA; | ||
1053 | |||
1054 | if (hubs->lineout1_se && hubs->lineout1p_ena) | ||
1055 | val |= WM8993_LINEOUT1P_ENA; | ||
1056 | |||
1057 | if (hubs->lineout2_se && hubs->lineout2n_ena) | ||
1058 | val |= WM8993_LINEOUT2N_ENA; | ||
1059 | |||
1060 | if (hubs->lineout2_se && hubs->lineout2p_ena) | ||
1061 | val |= WM8993_LINEOUT2P_ENA; | ||
1062 | |||
1063 | snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3, | ||
1064 | WM8993_LINEOUT1N_ENA | | ||
1065 | WM8993_LINEOUT1P_ENA | | ||
1066 | WM8993_LINEOUT2N_ENA | | ||
1067 | WM8993_LINEOUT2P_ENA, | ||
1068 | val); | ||
1069 | |||
1070 | /* Remove the input clamps */ | ||
1071 | snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG, | ||
1072 | WM8993_INPUTS_CLAMP, 0); | ||
1073 | break; | ||
1074 | |||
1075 | default: | ||
1076 | break; | ||
1077 | } | ||
1078 | } | ||
1079 | EXPORT_SYMBOL_GPL(wm_hubs_set_bias_level); | ||
1080 | |||
981 | MODULE_DESCRIPTION("Shared support for Wolfson hubs products"); | 1081 | MODULE_DESCRIPTION("Shared support for Wolfson hubs products"); |
982 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 1082 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
983 | MODULE_LICENSE("GPL"); | 1083 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h index c674c7a502a6..5705276f4943 100644 --- a/sound/soc/codecs/wm_hubs.h +++ b/sound/soc/codecs/wm_hubs.h | |||
@@ -30,9 +30,18 @@ struct wm_hubs_data { | |||
30 | int series_startup; | 30 | int series_startup; |
31 | int no_series_update; | 31 | int no_series_update; |
32 | 32 | ||
33 | bool no_cache_class_w; | ||
33 | bool class_w; | 34 | bool class_w; |
34 | u16 class_w_dcs; | 35 | u16 class_w_dcs; |
35 | 36 | ||
37 | bool lineout1_se; | ||
38 | bool lineout1n_ena; | ||
39 | bool lineout1p_ena; | ||
40 | |||
41 | bool lineout2_se; | ||
42 | bool lineout2n_ena; | ||
43 | bool lineout2p_ena; | ||
44 | |||
36 | bool dcs_done_irq; | 45 | bool dcs_done_irq; |
37 | struct completion dcs_done; | 46 | struct completion dcs_done; |
38 | }; | 47 | }; |
@@ -46,5 +55,8 @@ extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *, | |||
46 | int micbias1_lvl, int micbias2_lvl); | 55 | int micbias1_lvl, int micbias2_lvl); |
47 | 56 | ||
48 | extern irqreturn_t wm_hubs_dcs_done(int irq, void *data); | 57 | extern irqreturn_t wm_hubs_dcs_done(int irq, void *data); |
58 | extern void wm_hubs_vmid_ena(struct snd_soc_codec *codec); | ||
59 | extern void wm_hubs_set_bias_level(struct snd_soc_codec *codec, | ||
60 | enum snd_soc_bias_level level); | ||
49 | 61 | ||
50 | #endif | 62 | #endif |
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index b26401f87b85..97d77b298968 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c | |||
@@ -826,7 +826,7 @@ static void davinci_pcm_free(struct snd_pcm *pcm) | |||
826 | } | 826 | } |
827 | } | 827 | } |
828 | 828 | ||
829 | static u64 davinci_pcm_dmamask = 0xffffffff; | 829 | static u64 davinci_pcm_dmamask = DMA_BIT_MASK(32); |
830 | 830 | ||
831 | static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd) | 831 | static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd) |
832 | { | 832 | { |
@@ -837,7 +837,7 @@ static int davinci_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
837 | if (!card->dev->dma_mask) | 837 | if (!card->dev->dma_mask) |
838 | card->dev->dma_mask = &davinci_pcm_dmamask; | 838 | card->dev->dma_mask = &davinci_pcm_dmamask; |
839 | if (!card->dev->coherent_dma_mask) | 839 | if (!card->dev->coherent_dma_mask) |
840 | card->dev->coherent_dma_mask = 0xffffffff; | 840 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); |
841 | 841 | ||
842 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | 842 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { |
843 | ret = davinci_pcm_preallocate_dma_buffer(pcm, | 843 | ret = davinci_pcm_preallocate_dma_buffer(pcm, |
diff --git a/sound/soc/ep93xx/Kconfig b/sound/soc/ep93xx/Kconfig index 91a28de94109..88143db7e753 100644 --- a/sound/soc/ep93xx/Kconfig +++ b/sound/soc/ep93xx/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config SND_EP93XX_SOC | 1 | config SND_EP93XX_SOC |
2 | tristate "SoC Audio support for the Cirrus Logic EP93xx series" | 2 | tristate "SoC Audio support for the Cirrus Logic EP93xx series" |
3 | depends on ARCH_EP93XX && SND_SOC | 3 | depends on ARCH_EP93XX && SND_SOC |
4 | select SND_SOC_DMAENGINE_PCM | ||
4 | help | 5 | help |
5 | Say Y or M if you want to add support for codecs attached to | 6 | Say Y or M if you want to add support for codecs attached to |
6 | the EP93xx I2S or AC97 interfaces. | 7 | the EP93xx I2S or AC97 interfaces. |
diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/ep93xx/edb93xx.c index bae5cbbbd2b2..e01cb02abd3a 100644 --- a/sound/soc/ep93xx/edb93xx.c +++ b/sound/soc/ep93xx/edb93xx.c | |||
@@ -85,9 +85,7 @@ static int __devinit edb93xx_probe(struct platform_device *pdev) | |||
85 | struct snd_soc_card *card = &snd_soc_edb93xx; | 85 | struct snd_soc_card *card = &snd_soc_edb93xx; |
86 | int ret; | 86 | int ret; |
87 | 87 | ||
88 | ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, | 88 | ret = ep93xx_i2s_acquire(); |
89 | EP93XX_SYSCON_I2SCLKDIV_ORIDE | | ||
90 | EP93XX_SYSCON_I2SCLKDIV_SPOL); | ||
91 | if (ret) | 89 | if (ret) |
92 | return ret; | 90 | return ret; |
93 | 91 | ||
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c index de8390449873..162dbb74f4cc 100644 --- a/sound/soc/ep93xx/ep93xx-pcm.c +++ b/sound/soc/ep93xx/ep93xx-pcm.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <sound/pcm.h> | 23 | #include <sound/pcm.h> |
24 | #include <sound/pcm_params.h> | 24 | #include <sound/pcm_params.h> |
25 | #include <sound/soc.h> | 25 | #include <sound/soc.h> |
26 | #include <sound/dmaengine_pcm.h> | ||
26 | 27 | ||
27 | #include <mach/dma.h> | 28 | #include <mach/dma.h> |
28 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
@@ -52,26 +53,6 @@ static const struct snd_pcm_hardware ep93xx_pcm_hardware = { | |||
52 | .fifo_size = 32, | 53 | .fifo_size = 32, |
53 | }; | 54 | }; |
54 | 55 | ||
55 | struct ep93xx_runtime_data | ||
56 | { | ||
57 | int pointer_bytes; | ||
58 | int periods; | ||
59 | int period_bytes; | ||
60 | struct dma_chan *dma_chan; | ||
61 | struct ep93xx_dma_data dma_data; | ||
62 | }; | ||
63 | |||
64 | static void ep93xx_pcm_dma_callback(void *data) | ||
65 | { | ||
66 | struct snd_pcm_substream *substream = data; | ||
67 | struct ep93xx_runtime_data *rtd = substream->runtime->private_data; | ||
68 | |||
69 | rtd->pointer_bytes += rtd->period_bytes; | ||
70 | rtd->pointer_bytes %= rtd->period_bytes * rtd->periods; | ||
71 | |||
72 | snd_pcm_period_elapsed(substream); | ||
73 | } | ||
74 | |||
75 | static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param) | 56 | static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param) |
76 | { | 57 | { |
77 | struct ep93xx_dma_data *data = filter_param; | 58 | struct ep93xx_dma_data *data = filter_param; |
@@ -86,98 +67,48 @@ static bool ep93xx_pcm_dma_filter(struct dma_chan *chan, void *filter_param) | |||
86 | 67 | ||
87 | static int ep93xx_pcm_open(struct snd_pcm_substream *substream) | 68 | static int ep93xx_pcm_open(struct snd_pcm_substream *substream) |
88 | { | 69 | { |
89 | struct snd_soc_pcm_runtime *soc_rtd = substream->private_data; | 70 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
90 | struct snd_soc_dai *cpu_dai = soc_rtd->cpu_dai; | 71 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
91 | struct ep93xx_pcm_dma_params *dma_params; | 72 | struct ep93xx_pcm_dma_params *dma_params; |
92 | struct ep93xx_runtime_data *rtd; | 73 | struct ep93xx_dma_data *dma_data; |
93 | dma_cap_mask_t mask; | ||
94 | int ret; | 74 | int ret; |
95 | 75 | ||
96 | ret = snd_pcm_hw_constraint_integer(substream->runtime, | ||
97 | SNDRV_PCM_HW_PARAM_PERIODS); | ||
98 | if (ret < 0) | ||
99 | return ret; | ||
100 | |||
101 | snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware); | 76 | snd_soc_set_runtime_hwparams(substream, &ep93xx_pcm_hardware); |
102 | 77 | ||
103 | rtd = kmalloc(sizeof(*rtd), GFP_KERNEL); | 78 | dma_data = kmalloc(sizeof(*dma_data), GFP_KERNEL); |
104 | if (!rtd) | 79 | if (!dma_data) |
105 | return -ENOMEM; | 80 | return -ENOMEM; |
106 | 81 | ||
107 | dma_cap_zero(mask); | ||
108 | dma_cap_set(DMA_SLAVE, mask); | ||
109 | dma_cap_set(DMA_CYCLIC, mask); | ||
110 | |||
111 | dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream); | 82 | dma_params = snd_soc_dai_get_dma_data(cpu_dai, substream); |
112 | rtd->dma_data.port = dma_params->dma_port; | 83 | dma_data->port = dma_params->dma_port; |
113 | rtd->dma_data.name = dma_params->name; | 84 | dma_data->name = dma_params->name; |
114 | 85 | dma_data->direction = snd_pcm_substream_to_dma_direction(substream); | |
115 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
116 | rtd->dma_data.direction = DMA_MEM_TO_DEV; | ||
117 | else | ||
118 | rtd->dma_data.direction = DMA_DEV_TO_MEM; | ||
119 | |||
120 | rtd->dma_chan = dma_request_channel(mask, ep93xx_pcm_dma_filter, | ||
121 | &rtd->dma_data); | ||
122 | if (!rtd->dma_chan) { | ||
123 | kfree(rtd); | ||
124 | return -EINVAL; | ||
125 | } | ||
126 | |||
127 | substream->runtime->private_data = rtd; | ||
128 | return 0; | ||
129 | } | ||
130 | 86 | ||
131 | static int ep93xx_pcm_close(struct snd_pcm_substream *substream) | 87 | ret = snd_dmaengine_pcm_open(substream, ep93xx_pcm_dma_filter, dma_data); |
132 | { | 88 | if (ret) { |
133 | struct ep93xx_runtime_data *rtd = substream->runtime->private_data; | 89 | kfree(dma_data); |
90 | return ret; | ||
91 | } | ||
134 | 92 | ||
135 | dma_release_channel(rtd->dma_chan); | 93 | snd_dmaengine_pcm_set_data(substream, dma_data); |
136 | kfree(rtd); | ||
137 | return 0; | ||
138 | } | ||
139 | 94 | ||
140 | static int ep93xx_pcm_dma_submit(struct snd_pcm_substream *substream) | ||
141 | { | ||
142 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
143 | struct ep93xx_runtime_data *rtd = runtime->private_data; | ||
144 | struct dma_chan *chan = rtd->dma_chan; | ||
145 | struct dma_device *dma_dev = chan->device; | ||
146 | struct dma_async_tx_descriptor *desc; | ||
147 | |||
148 | rtd->pointer_bytes = 0; | ||
149 | desc = dma_dev->device_prep_dma_cyclic(chan, runtime->dma_addr, | ||
150 | rtd->period_bytes * rtd->periods, | ||
151 | rtd->period_bytes, | ||
152 | rtd->dma_data.direction); | ||
153 | if (!desc) | ||
154 | return -EINVAL; | ||
155 | |||
156 | desc->callback = ep93xx_pcm_dma_callback; | ||
157 | desc->callback_param = substream; | ||
158 | |||
159 | dmaengine_submit(desc); | ||
160 | return 0; | 95 | return 0; |
161 | } | 96 | } |
162 | 97 | ||
163 | static void ep93xx_pcm_dma_flush(struct snd_pcm_substream *substream) | 98 | static int ep93xx_pcm_close(struct snd_pcm_substream *substream) |
164 | { | 99 | { |
165 | struct snd_pcm_runtime *runtime = substream->runtime; | 100 | struct dma_data *dma_data = snd_dmaengine_pcm_get_data(substream); |
166 | struct ep93xx_runtime_data *rtd = runtime->private_data; | ||
167 | 101 | ||
168 | dmaengine_terminate_all(rtd->dma_chan); | 102 | snd_dmaengine_pcm_close(substream); |
103 | kfree(dma_data); | ||
104 | return 0; | ||
169 | } | 105 | } |
170 | 106 | ||
171 | static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream, | 107 | static int ep93xx_pcm_hw_params(struct snd_pcm_substream *substream, |
172 | struct snd_pcm_hw_params *params) | 108 | struct snd_pcm_hw_params *params) |
173 | { | 109 | { |
174 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
175 | struct ep93xx_runtime_data *rtd = runtime->private_data; | ||
176 | |||
177 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 110 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); |
178 | 111 | ||
179 | rtd->periods = params_periods(params); | ||
180 | rtd->period_bytes = params_period_bytes(params); | ||
181 | return 0; | 112 | return 0; |
182 | } | 113 | } |
183 | 114 | ||
@@ -187,41 +118,6 @@ static int ep93xx_pcm_hw_free(struct snd_pcm_substream *substream) | |||
187 | return 0; | 118 | return 0; |
188 | } | 119 | } |
189 | 120 | ||
190 | static int ep93xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
191 | { | ||
192 | int ret; | ||
193 | |||
194 | ret = 0; | ||
195 | switch (cmd) { | ||
196 | case SNDRV_PCM_TRIGGER_START: | ||
197 | case SNDRV_PCM_TRIGGER_RESUME: | ||
198 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
199 | ret = ep93xx_pcm_dma_submit(substream); | ||
200 | break; | ||
201 | |||
202 | case SNDRV_PCM_TRIGGER_STOP: | ||
203 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
204 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
205 | ep93xx_pcm_dma_flush(substream); | ||
206 | break; | ||
207 | |||
208 | default: | ||
209 | ret = -EINVAL; | ||
210 | break; | ||
211 | } | ||
212 | |||
213 | return ret; | ||
214 | } | ||
215 | |||
216 | static snd_pcm_uframes_t ep93xx_pcm_pointer(struct snd_pcm_substream *substream) | ||
217 | { | ||
218 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
219 | struct ep93xx_runtime_data *rtd = substream->runtime->private_data; | ||
220 | |||
221 | /* FIXME: implement this with sub-period granularity */ | ||
222 | return bytes_to_frames(runtime, rtd->pointer_bytes); | ||
223 | } | ||
224 | |||
225 | static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream, | 121 | static int ep93xx_pcm_mmap(struct snd_pcm_substream *substream, |
226 | struct vm_area_struct *vma) | 122 | struct vm_area_struct *vma) |
227 | { | 123 | { |
@@ -239,8 +135,8 @@ static struct snd_pcm_ops ep93xx_pcm_ops = { | |||
239 | .ioctl = snd_pcm_lib_ioctl, | 135 | .ioctl = snd_pcm_lib_ioctl, |
240 | .hw_params = ep93xx_pcm_hw_params, | 136 | .hw_params = ep93xx_pcm_hw_params, |
241 | .hw_free = ep93xx_pcm_hw_free, | 137 | .hw_free = ep93xx_pcm_hw_free, |
242 | .trigger = ep93xx_pcm_trigger, | 138 | .trigger = snd_dmaengine_pcm_trigger, |
243 | .pointer = ep93xx_pcm_pointer, | 139 | .pointer = snd_dmaengine_pcm_pointer, |
244 | .mmap = ep93xx_pcm_mmap, | 140 | .mmap = ep93xx_pcm_mmap, |
245 | }; | 141 | }; |
246 | 142 | ||
@@ -281,7 +177,7 @@ static void ep93xx_pcm_free_dma_buffers(struct snd_pcm *pcm) | |||
281 | } | 177 | } |
282 | } | 178 | } |
283 | 179 | ||
284 | static u64 ep93xx_pcm_dmamask = 0xffffffff; | 180 | static u64 ep93xx_pcm_dmamask = DMA_BIT_MASK(32); |
285 | 181 | ||
286 | static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd) | 182 | static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd) |
287 | { | 183 | { |
@@ -292,7 +188,7 @@ static int ep93xx_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
292 | if (!card->dev->dma_mask) | 188 | if (!card->dev->dma_mask) |
293 | card->dev->dma_mask = &ep93xx_pcm_dmamask; | 189 | card->dev->dma_mask = &ep93xx_pcm_dmamask; |
294 | if (!card->dev->coherent_dma_mask) | 190 | if (!card->dev->coherent_dma_mask) |
295 | card->dev->coherent_dma_mask = 0xffffffff; | 191 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); |
296 | 192 | ||
297 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | 193 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { |
298 | ret = ep93xx_pcm_preallocate_dma_buffer(pcm, | 194 | ret = ep93xx_pcm_preallocate_dma_buffer(pcm, |
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c index ccae34a3f280..a193cea3cf3c 100644 --- a/sound/soc/ep93xx/snappercl15.c +++ b/sound/soc/ep93xx/snappercl15.c | |||
@@ -103,9 +103,7 @@ static int __devinit snappercl15_probe(struct platform_device *pdev) | |||
103 | struct snd_soc_card *card = &snd_soc_snappercl15; | 103 | struct snd_soc_card *card = &snd_soc_snappercl15; |
104 | int ret; | 104 | int ret; |
105 | 105 | ||
106 | ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, | 106 | ret = ep93xx_i2s_acquire(); |
107 | EP93XX_SYSCON_I2SCLKDIV_ORIDE | | ||
108 | EP93XX_SYSCON_I2SCLKDIV_SPOL); | ||
109 | if (ret) | 107 | if (ret) |
110 | return ret; | 108 | return ret; |
111 | 109 | ||
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index 4f59bbaba48f..96bb92dd174c 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c | |||
@@ -311,23 +311,23 @@ static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd) | |||
311 | * should allocate a DMA buffer only for the streams that are valid. | 311 | * should allocate a DMA buffer only for the streams that are valid. |
312 | */ | 312 | */ |
313 | 313 | ||
314 | if (pcm->streams[0].substream) { | 314 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { |
315 | ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev, | 315 | ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev, |
316 | fsl_dma_hardware.buffer_bytes_max, | 316 | fsl_dma_hardware.buffer_bytes_max, |
317 | &pcm->streams[0].substream->dma_buffer); | 317 | &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer); |
318 | if (ret) { | 318 | if (ret) { |
319 | dev_err(card->dev, "can't alloc playback dma buffer\n"); | 319 | dev_err(card->dev, "can't alloc playback dma buffer\n"); |
320 | return ret; | 320 | return ret; |
321 | } | 321 | } |
322 | } | 322 | } |
323 | 323 | ||
324 | if (pcm->streams[1].substream) { | 324 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { |
325 | ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev, | 325 | ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev, |
326 | fsl_dma_hardware.buffer_bytes_max, | 326 | fsl_dma_hardware.buffer_bytes_max, |
327 | &pcm->streams[1].substream->dma_buffer); | 327 | &pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->dma_buffer); |
328 | if (ret) { | 328 | if (ret) { |
329 | dev_err(card->dev, "can't alloc capture dma buffer\n"); | 329 | dev_err(card->dev, "can't alloc capture dma buffer\n"); |
330 | snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer); | 330 | snd_dma_free_pages(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer); |
331 | return ret; | 331 | return ret; |
332 | } | 332 | } |
333 | } | 333 | } |
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 3e066966d878..2eb407fa3b48 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -716,12 +716,12 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) | |||
716 | } | 716 | } |
717 | 717 | ||
718 | /* Trigger the machine driver's probe function. The platform driver | 718 | /* Trigger the machine driver's probe function. The platform driver |
719 | * name of the machine driver is taken from the /model property of the | 719 | * name of the machine driver is taken from /compatible property of the |
720 | * device tree. We also pass the address of the CPU DAI driver | 720 | * device tree. We also pass the address of the CPU DAI driver |
721 | * structure. | 721 | * structure. |
722 | */ | 722 | */ |
723 | sprop = of_get_property(of_find_node_by_path("/"), "model", NULL); | 723 | sprop = of_get_property(of_find_node_by_path("/"), "compatible", NULL); |
724 | /* Sometimes the model name has a "fsl," prefix, so we strip that. */ | 724 | /* Sometimes the compatible name has a "fsl," prefix, so we strip it. */ |
725 | p = strrchr(sprop, ','); | 725 | p = strrchr(sprop, ','); |
726 | if (p) | 726 | if (p) |
727 | sprop = p + 1; | 727 | sprop = p + 1; |
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index e7803d34c425..9a3f7c5ab687 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/of_device.h> | 10 | #include <linux/of_device.h> |
11 | #include <linux/dma-mapping.h> | ||
11 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
12 | #include <linux/of_platform.h> | 13 | #include <linux/of_platform.h> |
13 | 14 | ||
@@ -298,7 +299,7 @@ static struct snd_pcm_ops psc_dma_ops = { | |||
298 | .hw_params = psc_dma_hw_params, | 299 | .hw_params = psc_dma_hw_params, |
299 | }; | 300 | }; |
300 | 301 | ||
301 | static u64 psc_dma_dmamask = 0xffffffff; | 302 | static u64 psc_dma_dmamask = DMA_BIT_MASK(32); |
302 | static int psc_dma_new(struct snd_soc_pcm_runtime *rtd) | 303 | static int psc_dma_new(struct snd_soc_pcm_runtime *rtd) |
303 | { | 304 | { |
304 | struct snd_card *card = rtd->card->snd_card; | 305 | struct snd_card *card = rtd->card->snd_card; |
@@ -314,18 +315,18 @@ static int psc_dma_new(struct snd_soc_pcm_runtime *rtd) | |||
314 | if (!card->dev->dma_mask) | 315 | if (!card->dev->dma_mask) |
315 | card->dev->dma_mask = &psc_dma_dmamask; | 316 | card->dev->dma_mask = &psc_dma_dmamask; |
316 | if (!card->dev->coherent_dma_mask) | 317 | if (!card->dev->coherent_dma_mask) |
317 | card->dev->coherent_dma_mask = 0xffffffff; | 318 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); |
318 | 319 | ||
319 | if (pcm->streams[0].substream) { | 320 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { |
320 | rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev, | 321 | rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev, |
321 | size, &pcm->streams[0].substream->dma_buffer); | 322 | size, &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer); |
322 | if (rc) | 323 | if (rc) |
323 | goto playback_alloc_err; | 324 | goto playback_alloc_err; |
324 | } | 325 | } |
325 | 326 | ||
326 | if (pcm->streams[1].substream) { | 327 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { |
327 | rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev, | 328 | rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev, |
328 | size, &pcm->streams[1].substream->dma_buffer); | 329 | size, &pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->dma_buffer); |
329 | if (rc) | 330 | if (rc) |
330 | goto capture_alloc_err; | 331 | goto capture_alloc_err; |
331 | } | 332 | } |
@@ -336,8 +337,8 @@ static int psc_dma_new(struct snd_soc_pcm_runtime *rtd) | |||
336 | return 0; | 337 | return 0; |
337 | 338 | ||
338 | capture_alloc_err: | 339 | capture_alloc_err: |
339 | if (pcm->streams[0].substream) | 340 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) |
340 | snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer); | 341 | snd_dma_free_pages(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer); |
341 | 342 | ||
342 | playback_alloc_err: | 343 | playback_alloc_err: |
343 | dev_err(card->dev, "Cannot allocate buffer(s)\n"); | 344 | dev_err(card->dev, "Cannot allocate buffer(s)\n"); |
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index 0ea4a5a96e06..afbabf427f27 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c | |||
@@ -245,7 +245,7 @@ static int get_parent_cell_index(struct device_node *np) | |||
245 | * 'struct device' It's ugly and hackish, but it works. | 245 | * 'struct device' It's ugly and hackish, but it works. |
246 | * | 246 | * |
247 | * The dev_name for such devices include the bus number and I2C address. For | 247 | * The dev_name for such devices include the bus number and I2C address. For |
248 | * example, "cs4270-codec.0-004f". | 248 | * example, "cs4270.0-004f". |
249 | */ | 249 | */ |
250 | static int codec_node_dev_name(struct device_node *np, char *buf, size_t len) | 250 | static int codec_node_dev_name(struct device_node *np, char *buf, size_t len) |
251 | { | 251 | { |
@@ -267,13 +267,13 @@ static int codec_node_dev_name(struct device_node *np, char *buf, size_t len) | |||
267 | if (!i2c) | 267 | if (!i2c) |
268 | return -ENODEV; | 268 | return -ENODEV; |
269 | 269 | ||
270 | snprintf(buf, len, "%s-codec.%u-%04x", temp, i2c->adapter->nr, addr); | 270 | snprintf(buf, len, "%s.%u-%04x", temp, i2c->adapter->nr, addr); |
271 | 271 | ||
272 | return 0; | 272 | return 0; |
273 | } | 273 | } |
274 | 274 | ||
275 | static int get_dma_channel(struct device_node *ssi_np, | 275 | static int get_dma_channel(struct device_node *ssi_np, |
276 | const char *compatible, | 276 | const char *name, |
277 | struct snd_soc_dai_link *dai, | 277 | struct snd_soc_dai_link *dai, |
278 | unsigned int *dma_channel_id, | 278 | unsigned int *dma_channel_id, |
279 | unsigned int *dma_id) | 279 | unsigned int *dma_id) |
@@ -283,7 +283,7 @@ static int get_dma_channel(struct device_node *ssi_np, | |||
283 | const u32 *iprop; | 283 | const u32 *iprop; |
284 | int ret; | 284 | int ret; |
285 | 285 | ||
286 | dma_channel_np = get_node_by_phandle_name(ssi_np, compatible, | 286 | dma_channel_np = get_node_by_phandle_name(ssi_np, name, |
287 | "fsl,ssi-dma-channel"); | 287 | "fsl,ssi-dma-channel"); |
288 | if (!dma_channel_np) | 288 | if (!dma_channel_np) |
289 | return -EINVAL; | 289 | return -EINVAL; |
@@ -336,12 +336,8 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev) | |||
336 | const char *sprop; | 336 | const char *sprop; |
337 | const u32 *iprop; | 337 | const u32 *iprop; |
338 | 338 | ||
339 | /* We are only interested in SSIs with a codec phandle in them, | 339 | /* Find the codec node for this SSI. */ |
340 | * so let's make sure this SSI has one. The MPC8610 HPCD only | 340 | codec_np = of_parse_phandle(np, "codec-handle", 0); |
341 | * knows about the CS4270 codec, so reject anything else. | ||
342 | */ | ||
343 | codec_np = get_node_by_phandle_name(np, "codec-handle", | ||
344 | "cirrus,cs4270"); | ||
345 | if (!codec_np) { | 341 | if (!codec_np) { |
346 | dev_err(dev, "invalid codec node\n"); | 342 | dev_err(dev, "invalid codec node\n"); |
347 | return -EINVAL; | 343 | return -EINVAL; |
@@ -550,7 +546,7 @@ static struct platform_driver mpc8610_hpcd_driver = { | |||
550 | .probe = mpc8610_hpcd_probe, | 546 | .probe = mpc8610_hpcd_probe, |
551 | .remove = __devexit_p(mpc8610_hpcd_remove), | 547 | .remove = __devexit_p(mpc8610_hpcd_remove), |
552 | .driver = { | 548 | .driver = { |
553 | /* The name must match the 'model' property in the device tree, | 549 | /* The name must match 'compatible' property in the device tree, |
554 | * in lowercase letters. | 550 | * in lowercase letters. |
555 | */ | 551 | */ |
556 | .name = "snd-soc-mpc8610hpcd", | 552 | .name = "snd-soc-mpc8610hpcd", |
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c index a5d4e80a9cf4..46623405a2ce 100644 --- a/sound/soc/fsl/p1022_ds.c +++ b/sound/soc/fsl/p1022_ds.c | |||
@@ -276,7 +276,7 @@ static int codec_node_dev_name(struct device_node *np, char *buf, size_t len) | |||
276 | } | 276 | } |
277 | 277 | ||
278 | static int get_dma_channel(struct device_node *ssi_np, | 278 | static int get_dma_channel(struct device_node *ssi_np, |
279 | const char *compatible, | 279 | const char *name, |
280 | struct snd_soc_dai_link *dai, | 280 | struct snd_soc_dai_link *dai, |
281 | unsigned int *dma_channel_id, | 281 | unsigned int *dma_channel_id, |
282 | unsigned int *dma_id) | 282 | unsigned int *dma_id) |
@@ -286,7 +286,7 @@ static int get_dma_channel(struct device_node *ssi_np, | |||
286 | const u32 *iprop; | 286 | const u32 *iprop; |
287 | int ret; | 287 | int ret; |
288 | 288 | ||
289 | dma_channel_np = get_node_by_phandle_name(ssi_np, compatible, | 289 | dma_channel_np = get_node_by_phandle_name(ssi_np, name, |
290 | "fsl,ssi-dma-channel"); | 290 | "fsl,ssi-dma-channel"); |
291 | if (!dma_channel_np) | 291 | if (!dma_channel_np) |
292 | return -EINVAL; | 292 | return -EINVAL; |
@@ -395,7 +395,8 @@ static int p1022_ds_probe(struct platform_device *pdev) | |||
395 | } | 395 | } |
396 | 396 | ||
397 | if (strcasecmp(sprop, "i2s-slave") == 0) { | 397 | if (strcasecmp(sprop, "i2s-slave") == 0) { |
398 | mdata->dai_format = SND_SOC_DAIFMT_I2S; | 398 | mdata->dai_format = SND_SOC_DAIFMT_NB_NF | |
399 | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM; | ||
399 | mdata->codec_clk_direction = SND_SOC_CLOCK_OUT; | 400 | mdata->codec_clk_direction = SND_SOC_CLOCK_OUT; |
400 | mdata->cpu_clk_direction = SND_SOC_CLOCK_IN; | 401 | mdata->cpu_clk_direction = SND_SOC_CLOCK_IN; |
401 | 402 | ||
@@ -412,31 +413,38 @@ static int p1022_ds_probe(struct platform_device *pdev) | |||
412 | } | 413 | } |
413 | mdata->clk_frequency = be32_to_cpup(iprop); | 414 | mdata->clk_frequency = be32_to_cpup(iprop); |
414 | } else if (strcasecmp(sprop, "i2s-master") == 0) { | 415 | } else if (strcasecmp(sprop, "i2s-master") == 0) { |
415 | mdata->dai_format = SND_SOC_DAIFMT_I2S; | 416 | mdata->dai_format = SND_SOC_DAIFMT_NB_NF | |
417 | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS; | ||
416 | mdata->codec_clk_direction = SND_SOC_CLOCK_IN; | 418 | mdata->codec_clk_direction = SND_SOC_CLOCK_IN; |
417 | mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT; | 419 | mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT; |
418 | } else if (strcasecmp(sprop, "lj-slave") == 0) { | 420 | } else if (strcasecmp(sprop, "lj-slave") == 0) { |
419 | mdata->dai_format = SND_SOC_DAIFMT_LEFT_J; | 421 | mdata->dai_format = SND_SOC_DAIFMT_NB_NF | |
422 | SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM; | ||
420 | mdata->codec_clk_direction = SND_SOC_CLOCK_OUT; | 423 | mdata->codec_clk_direction = SND_SOC_CLOCK_OUT; |
421 | mdata->cpu_clk_direction = SND_SOC_CLOCK_IN; | 424 | mdata->cpu_clk_direction = SND_SOC_CLOCK_IN; |
422 | } else if (strcasecmp(sprop, "lj-master") == 0) { | 425 | } else if (strcasecmp(sprop, "lj-master") == 0) { |
423 | mdata->dai_format = SND_SOC_DAIFMT_LEFT_J; | 426 | mdata->dai_format = SND_SOC_DAIFMT_NB_NF | |
427 | SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBS_CFS; | ||
424 | mdata->codec_clk_direction = SND_SOC_CLOCK_IN; | 428 | mdata->codec_clk_direction = SND_SOC_CLOCK_IN; |
425 | mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT; | 429 | mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT; |
426 | } else if (strcasecmp(sprop, "rj-slave") == 0) { | 430 | } else if (strcasecmp(sprop, "rj-slave") == 0) { |
427 | mdata->dai_format = SND_SOC_DAIFMT_RIGHT_J; | 431 | mdata->dai_format = SND_SOC_DAIFMT_NB_NF | |
432 | SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBM_CFM; | ||
428 | mdata->codec_clk_direction = SND_SOC_CLOCK_OUT; | 433 | mdata->codec_clk_direction = SND_SOC_CLOCK_OUT; |
429 | mdata->cpu_clk_direction = SND_SOC_CLOCK_IN; | 434 | mdata->cpu_clk_direction = SND_SOC_CLOCK_IN; |
430 | } else if (strcasecmp(sprop, "rj-master") == 0) { | 435 | } else if (strcasecmp(sprop, "rj-master") == 0) { |
431 | mdata->dai_format = SND_SOC_DAIFMT_RIGHT_J; | 436 | mdata->dai_format = SND_SOC_DAIFMT_NB_NF | |
437 | SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBS_CFS; | ||
432 | mdata->codec_clk_direction = SND_SOC_CLOCK_IN; | 438 | mdata->codec_clk_direction = SND_SOC_CLOCK_IN; |
433 | mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT; | 439 | mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT; |
434 | } else if (strcasecmp(sprop, "ac97-slave") == 0) { | 440 | } else if (strcasecmp(sprop, "ac97-slave") == 0) { |
435 | mdata->dai_format = SND_SOC_DAIFMT_AC97; | 441 | mdata->dai_format = SND_SOC_DAIFMT_NB_NF | |
442 | SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBM_CFM; | ||
436 | mdata->codec_clk_direction = SND_SOC_CLOCK_OUT; | 443 | mdata->codec_clk_direction = SND_SOC_CLOCK_OUT; |
437 | mdata->cpu_clk_direction = SND_SOC_CLOCK_IN; | 444 | mdata->cpu_clk_direction = SND_SOC_CLOCK_IN; |
438 | } else if (strcasecmp(sprop, "ac97-master") == 0) { | 445 | } else if (strcasecmp(sprop, "ac97-master") == 0) { |
439 | mdata->dai_format = SND_SOC_DAIFMT_AC97; | 446 | mdata->dai_format = SND_SOC_DAIFMT_NB_NF | |
447 | SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBS_CFS; | ||
440 | mdata->codec_clk_direction = SND_SOC_CLOCK_IN; | 448 | mdata->codec_clk_direction = SND_SOC_CLOCK_IN; |
441 | mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT; | 449 | mdata->cpu_clk_direction = SND_SOC_CLOCK_OUT; |
442 | } else { | 450 | } else { |
@@ -543,6 +551,11 @@ static struct platform_driver p1022_ds_driver = { | |||
543 | .probe = p1022_ds_probe, | 551 | .probe = p1022_ds_probe, |
544 | .remove = __devexit_p(p1022_ds_remove), | 552 | .remove = __devexit_p(p1022_ds_remove), |
545 | .driver = { | 553 | .driver = { |
554 | /* | ||
555 | * The name must match 'compatible' property in the device tree, | ||
556 | * in lowercase letters. | ||
557 | */ | ||
558 | .name = "snd-soc-p1022ds", | ||
546 | .owner = THIS_MODULE, | 559 | .owner = THIS_MODULE, |
547 | }, | 560 | }, |
548 | }; | 561 | }; |
@@ -556,33 +569,6 @@ static int __init p1022_ds_init(void) | |||
556 | { | 569 | { |
557 | struct device_node *guts_np; | 570 | struct device_node *guts_np; |
558 | struct resource res; | 571 | struct resource res; |
559 | const char *sprop; | ||
560 | |||
561 | /* | ||
562 | * Check if we're actually running on a P1022DS. Older device trees | ||
563 | * have a model of "fsl,P1022" and newer ones use "fsl,P1022DS", so we | ||
564 | * need to support both. The SSI driver uses that property to link to | ||
565 | * the machine driver, so have to match it. | ||
566 | */ | ||
567 | sprop = of_get_property(of_find_node_by_path("/"), "model", NULL); | ||
568 | if (!sprop) { | ||
569 | pr_err("snd-soc-p1022ds: missing /model node"); | ||
570 | return -ENODEV; | ||
571 | } | ||
572 | |||
573 | pr_debug("snd-soc-p1022ds: board model name is %s\n", sprop); | ||
574 | |||
575 | /* | ||
576 | * The name of this board, taken from the device tree. Normally, this is a* | ||
577 | * fixed string, but some P1022DS device trees have a /model property of | ||
578 | * "fsl,P1022", and others have "fsl,P1022DS". | ||
579 | */ | ||
580 | if (strcasecmp(sprop, "fsl,p1022ds") == 0) | ||
581 | p1022_ds_driver.driver.name = "snd-soc-p1022ds"; | ||
582 | else if (strcasecmp(sprop, "fsl,p1022") == 0) | ||
583 | p1022_ds_driver.driver.name = "snd-soc-p1022"; | ||
584 | else | ||
585 | return -ENODEV; | ||
586 | 572 | ||
587 | /* Get the physical address of the global utilities registers */ | 573 | /* Get the physical address of the global utilities registers */ |
588 | guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts"); | 574 | guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts"); |
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig index 738391757f2c..810acaa09009 100644 --- a/sound/soc/imx/Kconfig +++ b/sound/soc/imx/Kconfig | |||
@@ -1,9 +1,6 @@ | |||
1 | menuconfig SND_IMX_SOC | 1 | menuconfig SND_IMX_SOC |
2 | tristate "SoC Audio for Freescale i.MX CPUs" | 2 | tristate "SoC Audio for Freescale i.MX CPUs" |
3 | depends on ARCH_MXC | 3 | depends on ARCH_MXC |
4 | select SND_PCM | ||
5 | select FIQ | ||
6 | select SND_SOC_AC97_BUS | ||
7 | help | 4 | help |
8 | Say Y or M if you want to add support for codecs attached to | 5 | Say Y or M if you want to add support for codecs attached to |
9 | the i.MX SSI interface. | 6 | the i.MX SSI interface. |
@@ -11,10 +8,23 @@ menuconfig SND_IMX_SOC | |||
11 | 8 | ||
12 | if SND_IMX_SOC | 9 | if SND_IMX_SOC |
13 | 10 | ||
11 | config SND_SOC_IMX_SSI | ||
12 | tristate | ||
13 | |||
14 | config SND_SOC_IMX_PCM | ||
15 | tristate | ||
16 | |||
14 | config SND_MXC_SOC_FIQ | 17 | config SND_MXC_SOC_FIQ |
15 | tristate | 18 | tristate |
19 | select FIQ | ||
20 | select SND_SOC_IMX_PCM | ||
16 | 21 | ||
17 | config SND_MXC_SOC_MX2 | 22 | config SND_MXC_SOC_MX2 |
23 | select SND_SOC_DMAENGINE_PCM | ||
24 | tristate | ||
25 | select SND_SOC_IMX_PCM | ||
26 | |||
27 | config SND_SOC_IMX_AUDMUX | ||
18 | tristate | 28 | tristate |
19 | 29 | ||
20 | config SND_MXC_SOC_WM1133_EV1 | 30 | config SND_MXC_SOC_WM1133_EV1 |
@@ -22,6 +32,8 @@ config SND_MXC_SOC_WM1133_EV1 | |||
22 | depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL | 32 | depends on MACH_MX31ADS_WM1133_EV1 && EXPERIMENTAL |
23 | select SND_SOC_WM8350 | 33 | select SND_SOC_WM8350 |
24 | select SND_MXC_SOC_FIQ | 34 | select SND_MXC_SOC_FIQ |
35 | select SND_SOC_IMX_AUDMUX | ||
36 | select SND_SOC_IMX_SSI | ||
25 | help | 37 | help |
26 | Enable support for audio on the i.MX31ADS with the WM1133-EV1 | 38 | Enable support for audio on the i.MX31ADS with the WM1133-EV1 |
27 | PMIC board with WM8835x fitted. | 39 | PMIC board with WM8835x fitted. |
@@ -31,6 +43,8 @@ config SND_SOC_MX27VIS_AIC32X4 | |||
31 | depends on MACH_IMX27_VISSTRIM_M10 && I2C | 43 | depends on MACH_IMX27_VISSTRIM_M10 && I2C |
32 | select SND_SOC_TLV320AIC32X4 | 44 | select SND_SOC_TLV320AIC32X4 |
33 | select SND_MXC_SOC_MX2 | 45 | select SND_MXC_SOC_MX2 |
46 | select SND_SOC_IMX_AUDMUX | ||
47 | select SND_SOC_IMX_SSI | ||
34 | help | 48 | help |
35 | Say Y if you want to add support for SoC audio on Visstrim SM10 | 49 | Say Y if you want to add support for SoC audio on Visstrim SM10 |
36 | board with TLV320AIC32X4 codec. | 50 | board with TLV320AIC32X4 codec. |
@@ -38,8 +52,11 @@ config SND_SOC_MX27VIS_AIC32X4 | |||
38 | config SND_SOC_PHYCORE_AC97 | 52 | config SND_SOC_PHYCORE_AC97 |
39 | tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards" | 53 | tristate "SoC Audio support for Phytec phyCORE (and phyCARD) boards" |
40 | depends on MACH_PCM043 || MACH_PCA100 | 54 | depends on MACH_PCM043 || MACH_PCA100 |
55 | select SND_SOC_AC97_BUS | ||
41 | select SND_SOC_WM9712 | 56 | select SND_SOC_WM9712 |
42 | select SND_MXC_SOC_FIQ | 57 | select SND_MXC_SOC_FIQ |
58 | select SND_SOC_IMX_AUDMUX | ||
59 | select SND_SOC_IMX_SSI | ||
43 | help | 60 | help |
44 | Say Y if you want to add support for SoC audio on Phytec phyCORE | 61 | Say Y if you want to add support for SoC audio on Phytec phyCORE |
45 | and phyCARD boards in AC97 mode | 62 | and phyCARD boards in AC97 mode |
@@ -53,6 +70,8 @@ config SND_SOC_EUKREA_TLV320 | |||
53 | depends on I2C | 70 | depends on I2C |
54 | select SND_SOC_TLV320AIC23 | 71 | select SND_SOC_TLV320AIC23 |
55 | select SND_MXC_SOC_FIQ | 72 | select SND_MXC_SOC_FIQ |
73 | select SND_SOC_IMX_AUDMUX | ||
74 | select SND_SOC_IMX_SSI | ||
56 | help | 75 | help |
57 | Enable I2S based access to the TLV320AIC23B codec attached | 76 | Enable I2S based access to the TLV320AIC23B codec attached |
58 | to the SSI interface | 77 | to the SSI interface |
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile index d6d609ba7e24..f5db3e92d0d1 100644 --- a/sound/soc/imx/Makefile +++ b/sound/soc/imx/Makefile | |||
@@ -1,11 +1,14 @@ | |||
1 | # i.MX Platform Support | 1 | # i.MX Platform Support |
2 | snd-soc-imx-objs := imx-ssi.o | 2 | snd-soc-imx-ssi-objs := imx-ssi.o |
3 | snd-soc-imx-fiq-objs := imx-pcm-fiq.o | 3 | snd-soc-imx-audmux-objs := imx-audmux.o |
4 | snd-soc-imx-mx2-objs := imx-pcm-dma-mx2.o | ||
5 | 4 | ||
6 | obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o | 5 | obj-$(CONFIG_SND_SOC_IMX_SSI) += snd-soc-imx-ssi.o |
7 | obj-$(CONFIG_SND_MXC_SOC_FIQ) += snd-soc-imx-fiq.o | 6 | obj-$(CONFIG_SND_SOC_IMX_AUDMUX) += snd-soc-imx-audmux.o |
8 | obj-$(CONFIG_SND_MXC_SOC_MX2) += snd-soc-imx-mx2.o | 7 | |
8 | obj-$(CONFIG_SND_SOC_IMX_PCM) += snd-soc-imx-pcm.o | ||
9 | snd-soc-imx-pcm-y := imx-pcm.o | ||
10 | snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_FIQ) += imx-pcm-fiq.o | ||
11 | snd-soc-imx-pcm-$(CONFIG_SND_MXC_SOC_MX2) += imx-pcm-dma-mx2.o | ||
9 | 12 | ||
10 | # i.MX Machine Support | 13 | # i.MX Machine Support |
11 | snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o | 14 | snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o |
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c index 1c1fdd10f73f..7d4475cfdb24 100644 --- a/sound/soc/imx/eukrea-tlv320.c +++ b/sound/soc/imx/eukrea-tlv320.c | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #include "../codecs/tlv320aic23.h" | 27 | #include "../codecs/tlv320aic23.h" |
28 | #include "imx-ssi.h" | 28 | #include "imx-ssi.h" |
29 | #include "imx-audmux.h" | ||
29 | 30 | ||
30 | #define CODEC_CLOCK 12000000 | 31 | #define CODEC_CLOCK 12000000 |
31 | 32 | ||
@@ -97,12 +98,43 @@ static struct platform_device *eukrea_tlv320_snd_device; | |||
97 | static int __init eukrea_tlv320_init(void) | 98 | static int __init eukrea_tlv320_init(void) |
98 | { | 99 | { |
99 | int ret; | 100 | int ret; |
100 | 101 | int int_port = 0, ext_port; | |
101 | if (!machine_is_eukrea_cpuimx27() && !machine_is_eukrea_cpuimx25sd() | 102 | |
102 | && !machine_is_eukrea_cpuimx35sd() | 103 | if (machine_is_eukrea_cpuimx27()) { |
103 | && !machine_is_eukrea_cpuimx51sd()) | 104 | imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, |
105 | IMX_AUDMUX_V1_PCR_SYN | | ||
106 | IMX_AUDMUX_V1_PCR_TFSDIR | | ||
107 | IMX_AUDMUX_V1_PCR_TCLKDIR | | ||
108 | IMX_AUDMUX_V1_PCR_RFSDIR | | ||
109 | IMX_AUDMUX_V1_PCR_RCLKDIR | | ||
110 | IMX_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) | | ||
111 | IMX_AUDMUX_V1_PCR_RFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) | | ||
112 | IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) | ||
113 | ); | ||
114 | imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR3_SSI_PINS_4, | ||
115 | IMX_AUDMUX_V1_PCR_SYN | | ||
116 | IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0) | ||
117 | ); | ||
118 | } else if (machine_is_eukrea_cpuimx25sd() || | ||
119 | machine_is_eukrea_cpuimx35sd() || | ||
120 | machine_is_eukrea_cpuimx51sd()) { | ||
121 | ext_port = machine_is_eukrea_cpuimx25sd() ? 4 : 3; | ||
122 | imx_audmux_v2_configure_port(int_port, | ||
123 | IMX_AUDMUX_V2_PTCR_SYN | | ||
124 | IMX_AUDMUX_V2_PTCR_TFSDIR | | ||
125 | IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) | | ||
126 | IMX_AUDMUX_V2_PTCR_TCLKDIR | | ||
127 | IMX_AUDMUX_V2_PTCR_TCSEL(ext_port), | ||
128 | IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port) | ||
129 | ); | ||
130 | imx_audmux_v2_configure_port(ext_port, | ||
131 | IMX_AUDMUX_V2_PTCR_SYN, | ||
132 | IMX_AUDMUX_V2_PDCR_RXDSEL(int_port) | ||
133 | ); | ||
134 | } else { | ||
104 | /* return happy. We might run on a totally different machine */ | 135 | /* return happy. We might run on a totally different machine */ |
105 | return 0; | 136 | return 0; |
137 | } | ||
106 | 138 | ||
107 | eukrea_tlv320_snd_device = platform_device_alloc("soc-audio", -1); | 139 | eukrea_tlv320_snd_device = platform_device_alloc("soc-audio", -1); |
108 | if (!eukrea_tlv320_snd_device) | 140 | if (!eukrea_tlv320_snd_device) |
diff --git a/sound/soc/imx/imx-audmux.c b/sound/soc/imx/imx-audmux.c new file mode 100644 index 000000000000..601df809a26a --- /dev/null +++ b/sound/soc/imx/imx-audmux.c | |||
@@ -0,0 +1,314 @@ | |||
1 | /* | ||
2 | * Copyright 2012 Freescale Semiconductor, Inc. | ||
3 | * Copyright 2012 Linaro Ltd. | ||
4 | * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> | ||
5 | * | ||
6 | * Initial development of this code was funded by | ||
7 | * Phytec Messtechnik GmbH, http://www.phytec.de | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | */ | ||
19 | |||
20 | #include <linux/clk.h> | ||
21 | #include <linux/debugfs.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/of.h> | ||
26 | #include <linux/of_device.h> | ||
27 | #include <linux/platform_device.h> | ||
28 | #include <linux/slab.h> | ||
29 | |||
30 | #include "imx-audmux.h" | ||
31 | |||
32 | #define DRIVER_NAME "imx-audmux" | ||
33 | |||
34 | static struct clk *audmux_clk; | ||
35 | static void __iomem *audmux_base; | ||
36 | |||
37 | #define IMX_AUDMUX_V2_PTCR(x) ((x) * 8) | ||
38 | #define IMX_AUDMUX_V2_PDCR(x) ((x) * 8 + 4) | ||
39 | |||
40 | #ifdef CONFIG_DEBUG_FS | ||
41 | static struct dentry *audmux_debugfs_root; | ||
42 | |||
43 | static int audmux_open_file(struct inode *inode, struct file *file) | ||
44 | { | ||
45 | file->private_data = inode->i_private; | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | /* There is an annoying discontinuity in the SSI numbering with regard | ||
50 | * to the Linux number of the devices */ | ||
51 | static const char *audmux_port_string(int port) | ||
52 | { | ||
53 | switch (port) { | ||
54 | case MX31_AUDMUX_PORT1_SSI0: | ||
55 | return "imx-ssi.0"; | ||
56 | case MX31_AUDMUX_PORT2_SSI1: | ||
57 | return "imx-ssi.1"; | ||
58 | case MX31_AUDMUX_PORT3_SSI_PINS_3: | ||
59 | return "SSI3"; | ||
60 | case MX31_AUDMUX_PORT4_SSI_PINS_4: | ||
61 | return "SSI4"; | ||
62 | case MX31_AUDMUX_PORT5_SSI_PINS_5: | ||
63 | return "SSI5"; | ||
64 | case MX31_AUDMUX_PORT6_SSI_PINS_6: | ||
65 | return "SSI6"; | ||
66 | default: | ||
67 | return "UNKNOWN"; | ||
68 | } | ||
69 | } | ||
70 | |||
71 | static ssize_t audmux_read_file(struct file *file, char __user *user_buf, | ||
72 | size_t count, loff_t *ppos) | ||
73 | { | ||
74 | ssize_t ret; | ||
75 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
76 | int port = (int)file->private_data; | ||
77 | u32 pdcr, ptcr; | ||
78 | |||
79 | if (!buf) | ||
80 | return -ENOMEM; | ||
81 | |||
82 | if (audmux_clk) | ||
83 | clk_prepare_enable(audmux_clk); | ||
84 | |||
85 | ptcr = readl(audmux_base + IMX_AUDMUX_V2_PTCR(port)); | ||
86 | pdcr = readl(audmux_base + IMX_AUDMUX_V2_PDCR(port)); | ||
87 | |||
88 | if (audmux_clk) | ||
89 | clk_disable_unprepare(audmux_clk); | ||
90 | |||
91 | ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n", | ||
92 | pdcr, ptcr); | ||
93 | |||
94 | if (ptcr & IMX_AUDMUX_V2_PTCR_TFSDIR) | ||
95 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
96 | "TxFS output from %s, ", | ||
97 | audmux_port_string((ptcr >> 27) & 0x7)); | ||
98 | else | ||
99 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
100 | "TxFS input, "); | ||
101 | |||
102 | if (ptcr & IMX_AUDMUX_V2_PTCR_TCLKDIR) | ||
103 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
104 | "TxClk output from %s", | ||
105 | audmux_port_string((ptcr >> 22) & 0x7)); | ||
106 | else | ||
107 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
108 | "TxClk input"); | ||
109 | |||
110 | ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n"); | ||
111 | |||
112 | if (ptcr & IMX_AUDMUX_V2_PTCR_SYN) { | ||
113 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
114 | "Port is symmetric"); | ||
115 | } else { | ||
116 | if (ptcr & IMX_AUDMUX_V2_PTCR_RFSDIR) | ||
117 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
118 | "RxFS output from %s, ", | ||
119 | audmux_port_string((ptcr >> 17) & 0x7)); | ||
120 | else | ||
121 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
122 | "RxFS input, "); | ||
123 | |||
124 | if (ptcr & IMX_AUDMUX_V2_PTCR_RCLKDIR) | ||
125 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
126 | "RxClk output from %s", | ||
127 | audmux_port_string((ptcr >> 12) & 0x7)); | ||
128 | else | ||
129 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
130 | "RxClk input"); | ||
131 | } | ||
132 | |||
133 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | ||
134 | "\nData received from %s\n", | ||
135 | audmux_port_string((pdcr >> 13) & 0x7)); | ||
136 | |||
137 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); | ||
138 | |||
139 | kfree(buf); | ||
140 | |||
141 | return ret; | ||
142 | } | ||
143 | |||
144 | static const struct file_operations audmux_debugfs_fops = { | ||
145 | .open = audmux_open_file, | ||
146 | .read = audmux_read_file, | ||
147 | .llseek = default_llseek, | ||
148 | }; | ||
149 | |||
150 | static void __init audmux_debugfs_init(void) | ||
151 | { | ||
152 | int i; | ||
153 | char buf[20]; | ||
154 | |||
155 | audmux_debugfs_root = debugfs_create_dir("audmux", NULL); | ||
156 | if (!audmux_debugfs_root) { | ||
157 | pr_warning("Failed to create AUDMUX debugfs root\n"); | ||
158 | return; | ||
159 | } | ||
160 | |||
161 | for (i = 1; i < 8; i++) { | ||
162 | snprintf(buf, sizeof(buf), "ssi%d", i); | ||
163 | if (!debugfs_create_file(buf, 0444, audmux_debugfs_root, | ||
164 | (void *)i, &audmux_debugfs_fops)) | ||
165 | pr_warning("Failed to create AUDMUX port %d debugfs file\n", | ||
166 | i); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | static void __devexit audmux_debugfs_remove(void) | ||
171 | { | ||
172 | debugfs_remove_recursive(audmux_debugfs_root); | ||
173 | } | ||
174 | #else | ||
175 | static inline void audmux_debugfs_init(void) | ||
176 | { | ||
177 | } | ||
178 | |||
179 | static inline void audmux_debugfs_remove(void) | ||
180 | { | ||
181 | } | ||
182 | #endif | ||
183 | |||
184 | enum imx_audmux_type { | ||
185 | IMX21_AUDMUX, | ||
186 | IMX31_AUDMUX, | ||
187 | } audmux_type; | ||
188 | |||
189 | static struct platform_device_id imx_audmux_ids[] = { | ||
190 | { | ||
191 | .name = "imx21-audmux", | ||
192 | .driver_data = IMX21_AUDMUX, | ||
193 | }, { | ||
194 | .name = "imx31-audmux", | ||
195 | .driver_data = IMX31_AUDMUX, | ||
196 | }, { | ||
197 | /* sentinel */ | ||
198 | } | ||
199 | }; | ||
200 | MODULE_DEVICE_TABLE(platform, imx_audmux_ids); | ||
201 | |||
202 | static const struct of_device_id imx_audmux_dt_ids[] = { | ||
203 | { .compatible = "fsl,imx21-audmux", .data = &imx_audmux_ids[0], }, | ||
204 | { .compatible = "fsl,imx31-audmux", .data = &imx_audmux_ids[1], }, | ||
205 | { /* sentinel */ } | ||
206 | }; | ||
207 | MODULE_DEVICE_TABLE(of, imx_audmux_dt_ids); | ||
208 | |||
209 | static const uint8_t port_mapping[] = { | ||
210 | 0x0, 0x4, 0x8, 0x10, 0x14, 0x1c, | ||
211 | }; | ||
212 | |||
213 | int imx_audmux_v1_configure_port(unsigned int port, unsigned int pcr) | ||
214 | { | ||
215 | if (audmux_type != IMX21_AUDMUX) | ||
216 | return -EINVAL; | ||
217 | |||
218 | if (!audmux_base) | ||
219 | return -ENOSYS; | ||
220 | |||
221 | if (port >= ARRAY_SIZE(port_mapping)) | ||
222 | return -EINVAL; | ||
223 | |||
224 | writel(pcr, audmux_base + port_mapping[port]); | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | EXPORT_SYMBOL_GPL(imx_audmux_v1_configure_port); | ||
229 | |||
230 | int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr, | ||
231 | unsigned int pdcr) | ||
232 | { | ||
233 | if (audmux_type != IMX31_AUDMUX) | ||
234 | return -EINVAL; | ||
235 | |||
236 | if (!audmux_base) | ||
237 | return -ENOSYS; | ||
238 | |||
239 | if (audmux_clk) | ||
240 | clk_prepare_enable(audmux_clk); | ||
241 | |||
242 | writel(ptcr, audmux_base + IMX_AUDMUX_V2_PTCR(port)); | ||
243 | writel(pdcr, audmux_base + IMX_AUDMUX_V2_PDCR(port)); | ||
244 | |||
245 | if (audmux_clk) | ||
246 | clk_disable_unprepare(audmux_clk); | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | EXPORT_SYMBOL_GPL(imx_audmux_v2_configure_port); | ||
251 | |||
252 | static int __devinit imx_audmux_probe(struct platform_device *pdev) | ||
253 | { | ||
254 | struct resource *res; | ||
255 | const struct of_device_id *of_id = | ||
256 | of_match_device(imx_audmux_dt_ids, &pdev->dev); | ||
257 | |||
258 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
259 | audmux_base = devm_request_and_ioremap(&pdev->dev, res); | ||
260 | if (!audmux_base) | ||
261 | return -EADDRNOTAVAIL; | ||
262 | |||
263 | audmux_clk = clk_get(&pdev->dev, "audmux"); | ||
264 | if (IS_ERR(audmux_clk)) { | ||
265 | dev_dbg(&pdev->dev, "cannot get clock: %ld\n", | ||
266 | PTR_ERR(audmux_clk)); | ||
267 | audmux_clk = NULL; | ||
268 | } | ||
269 | |||
270 | if (of_id) | ||
271 | pdev->id_entry = of_id->data; | ||
272 | audmux_type = pdev->id_entry->driver_data; | ||
273 | if (audmux_type == IMX31_AUDMUX) | ||
274 | audmux_debugfs_init(); | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static int __devexit imx_audmux_remove(struct platform_device *pdev) | ||
280 | { | ||
281 | if (audmux_type == IMX31_AUDMUX) | ||
282 | audmux_debugfs_remove(); | ||
283 | clk_put(audmux_clk); | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static struct platform_driver imx_audmux_driver = { | ||
289 | .probe = imx_audmux_probe, | ||
290 | .remove = __devexit_p(imx_audmux_remove), | ||
291 | .id_table = imx_audmux_ids, | ||
292 | .driver = { | ||
293 | .name = DRIVER_NAME, | ||
294 | .owner = THIS_MODULE, | ||
295 | .of_match_table = imx_audmux_dt_ids, | ||
296 | } | ||
297 | }; | ||
298 | |||
299 | static int __init imx_audmux_init(void) | ||
300 | { | ||
301 | return platform_driver_register(&imx_audmux_driver); | ||
302 | } | ||
303 | subsys_initcall(imx_audmux_init); | ||
304 | |||
305 | static void __exit imx_audmux_exit(void) | ||
306 | { | ||
307 | platform_driver_unregister(&imx_audmux_driver); | ||
308 | } | ||
309 | module_exit(imx_audmux_exit); | ||
310 | |||
311 | MODULE_DESCRIPTION("Freescale i.MX AUDMUX driver"); | ||
312 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>"); | ||
313 | MODULE_LICENSE("GPL v2"); | ||
314 | MODULE_ALIAS("platform:" DRIVER_NAME); | ||
diff --git a/sound/soc/imx/imx-audmux.h b/sound/soc/imx/imx-audmux.h new file mode 100644 index 000000000000..04ebbab8d7b9 --- /dev/null +++ b/sound/soc/imx/imx-audmux.h | |||
@@ -0,0 +1,60 @@ | |||
1 | #ifndef __IMX_AUDMUX_H | ||
2 | #define __IMX_AUDMUX_H | ||
3 | |||
4 | #define MX27_AUDMUX_HPCR1_SSI0 0 | ||
5 | #define MX27_AUDMUX_HPCR2_SSI1 1 | ||
6 | #define MX27_AUDMUX_HPCR3_SSI_PINS_4 2 | ||
7 | #define MX27_AUDMUX_PPCR1_SSI_PINS_1 3 | ||
8 | #define MX27_AUDMUX_PPCR2_SSI_PINS_2 4 | ||
9 | #define MX27_AUDMUX_PPCR3_SSI_PINS_3 5 | ||
10 | |||
11 | #define MX31_AUDMUX_PORT1_SSI0 0 | ||
12 | #define MX31_AUDMUX_PORT2_SSI1 1 | ||
13 | #define MX31_AUDMUX_PORT3_SSI_PINS_3 2 | ||
14 | #define MX31_AUDMUX_PORT4_SSI_PINS_4 3 | ||
15 | #define MX31_AUDMUX_PORT5_SSI_PINS_5 4 | ||
16 | #define MX31_AUDMUX_PORT6_SSI_PINS_6 5 | ||
17 | |||
18 | #define MX51_AUDMUX_PORT1_SSI0 0 | ||
19 | #define MX51_AUDMUX_PORT2_SSI1 1 | ||
20 | #define MX51_AUDMUX_PORT3 2 | ||
21 | #define MX51_AUDMUX_PORT4 3 | ||
22 | #define MX51_AUDMUX_PORT5 4 | ||
23 | #define MX51_AUDMUX_PORT6 5 | ||
24 | #define MX51_AUDMUX_PORT7 6 | ||
25 | |||
26 | /* Register definitions for the i.MX21/27 Digital Audio Multiplexer */ | ||
27 | #define IMX_AUDMUX_V1_PCR_INMMASK(x) ((x) & 0xff) | ||
28 | #define IMX_AUDMUX_V1_PCR_INMEN (1 << 8) | ||
29 | #define IMX_AUDMUX_V1_PCR_TXRXEN (1 << 10) | ||
30 | #define IMX_AUDMUX_V1_PCR_SYN (1 << 12) | ||
31 | #define IMX_AUDMUX_V1_PCR_RXDSEL(x) (((x) & 0x7) << 13) | ||
32 | #define IMX_AUDMUX_V1_PCR_RFCSEL(x) (((x) & 0xf) << 20) | ||
33 | #define IMX_AUDMUX_V1_PCR_RCLKDIR (1 << 24) | ||
34 | #define IMX_AUDMUX_V1_PCR_RFSDIR (1 << 25) | ||
35 | #define IMX_AUDMUX_V1_PCR_TFCSEL(x) (((x) & 0xf) << 26) | ||
36 | #define IMX_AUDMUX_V1_PCR_TCLKDIR (1 << 30) | ||
37 | #define IMX_AUDMUX_V1_PCR_TFSDIR (1 << 31) | ||
38 | |||
39 | /* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */ | ||
40 | #define IMX_AUDMUX_V2_PTCR_TFSDIR (1 << 31) | ||
41 | #define IMX_AUDMUX_V2_PTCR_TFSEL(x) (((x) & 0xf) << 27) | ||
42 | #define IMX_AUDMUX_V2_PTCR_TCLKDIR (1 << 26) | ||
43 | #define IMX_AUDMUX_V2_PTCR_TCSEL(x) (((x) & 0xf) << 22) | ||
44 | #define IMX_AUDMUX_V2_PTCR_RFSDIR (1 << 21) | ||
45 | #define IMX_AUDMUX_V2_PTCR_RFSEL(x) (((x) & 0xf) << 17) | ||
46 | #define IMX_AUDMUX_V2_PTCR_RCLKDIR (1 << 16) | ||
47 | #define IMX_AUDMUX_V2_PTCR_RCSEL(x) (((x) & 0xf) << 12) | ||
48 | #define IMX_AUDMUX_V2_PTCR_SYN (1 << 11) | ||
49 | |||
50 | #define IMX_AUDMUX_V2_PDCR_RXDSEL(x) (((x) & 0x7) << 13) | ||
51 | #define IMX_AUDMUX_V2_PDCR_TXRXEN (1 << 12) | ||
52 | #define IMX_AUDMUX_V2_PDCR_MODE(x) (((x) & 0x3) << 8) | ||
53 | #define IMX_AUDMUX_V2_PDCR_INMMASK(x) ((x) & 0xff) | ||
54 | |||
55 | int imx_audmux_v1_configure_port(unsigned int port, unsigned int pcr); | ||
56 | |||
57 | int imx_audmux_v2_configure_port(unsigned int port, unsigned int ptcr, | ||
58 | unsigned int pdcr); | ||
59 | |||
60 | #endif /* __IMX_AUDMUX_H */ | ||
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index 5780c9b9d569..e43c8fa2788b 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c | |||
@@ -27,212 +27,54 @@ | |||
27 | #include <sound/pcm.h> | 27 | #include <sound/pcm.h> |
28 | #include <sound/pcm_params.h> | 28 | #include <sound/pcm_params.h> |
29 | #include <sound/soc.h> | 29 | #include <sound/soc.h> |
30 | #include <sound/dmaengine_pcm.h> | ||
30 | 31 | ||
31 | #include <mach/dma.h> | 32 | #include <mach/dma.h> |
32 | 33 | ||
33 | #include "imx-ssi.h" | 34 | #include "imx-pcm.h" |
34 | |||
35 | struct imx_pcm_runtime_data { | ||
36 | int period_bytes; | ||
37 | int periods; | ||
38 | int dma; | ||
39 | unsigned long offset; | ||
40 | unsigned long size; | ||
41 | void *buf; | ||
42 | int period_time; | ||
43 | struct dma_async_tx_descriptor *desc; | ||
44 | struct dma_chan *dma_chan; | ||
45 | struct imx_dma_data dma_data; | ||
46 | }; | ||
47 | |||
48 | static void audio_dma_irq(void *data) | ||
49 | { | ||
50 | struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data; | ||
51 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
52 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | ||
53 | |||
54 | iprtd->offset += iprtd->period_bytes; | ||
55 | iprtd->offset %= iprtd->period_bytes * iprtd->periods; | ||
56 | |||
57 | snd_pcm_period_elapsed(substream); | ||
58 | } | ||
59 | 35 | ||
60 | static bool filter(struct dma_chan *chan, void *param) | 36 | static bool filter(struct dma_chan *chan, void *param) |
61 | { | 37 | { |
62 | struct imx_pcm_runtime_data *iprtd = param; | ||
63 | |||
64 | if (!imx_dma_is_general_purpose(chan)) | 38 | if (!imx_dma_is_general_purpose(chan)) |
65 | return false; | 39 | return false; |
66 | 40 | ||
67 | chan->private = &iprtd->dma_data; | 41 | chan->private = param; |
68 | 42 | ||
69 | return true; | 43 | return true; |
70 | } | 44 | } |
71 | 45 | ||
72 | static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream, | 46 | static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, |
73 | struct snd_pcm_hw_params *params) | 47 | struct snd_pcm_hw_params *params) |
74 | { | 48 | { |
75 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 49 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
50 | struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); | ||
76 | struct imx_pcm_dma_params *dma_params; | 51 | struct imx_pcm_dma_params *dma_params; |
77 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
78 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | ||
79 | struct dma_slave_config slave_config; | 52 | struct dma_slave_config slave_config; |
80 | dma_cap_mask_t mask; | ||
81 | enum dma_slave_buswidth buswidth; | ||
82 | int ret; | 53 | int ret; |
83 | 54 | ||
84 | dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | 55 | dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
85 | 56 | ||
86 | iprtd->dma_data.peripheral_type = IMX_DMATYPE_SSI; | 57 | ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config); |
87 | iprtd->dma_data.priority = DMA_PRIO_HIGH; | 58 | if (ret) |
88 | iprtd->dma_data.dma_request = dma_params->dma; | 59 | return ret; |
89 | |||
90 | /* Try to grab a DMA channel */ | ||
91 | if (!iprtd->dma_chan) { | ||
92 | dma_cap_zero(mask); | ||
93 | dma_cap_set(DMA_SLAVE, mask); | ||
94 | iprtd->dma_chan = dma_request_channel(mask, filter, iprtd); | ||
95 | if (!iprtd->dma_chan) | ||
96 | return -EINVAL; | ||
97 | } | ||
98 | |||
99 | switch (params_format(params)) { | ||
100 | case SNDRV_PCM_FORMAT_S16_LE: | ||
101 | buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
102 | break; | ||
103 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
104 | case SNDRV_PCM_FORMAT_S24_LE: | ||
105 | buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
106 | break; | ||
107 | default: | ||
108 | return 0; | ||
109 | } | ||
110 | 60 | ||
111 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 61 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
112 | slave_config.direction = DMA_MEM_TO_DEV; | ||
113 | slave_config.dst_addr = dma_params->dma_addr; | 62 | slave_config.dst_addr = dma_params->dma_addr; |
114 | slave_config.dst_addr_width = buswidth; | ||
115 | slave_config.dst_maxburst = dma_params->burstsize; | 63 | slave_config.dst_maxburst = dma_params->burstsize; |
116 | } else { | 64 | } else { |
117 | slave_config.direction = DMA_DEV_TO_MEM; | ||
118 | slave_config.src_addr = dma_params->dma_addr; | 65 | slave_config.src_addr = dma_params->dma_addr; |
119 | slave_config.src_addr_width = buswidth; | ||
120 | slave_config.src_maxburst = dma_params->burstsize; | 66 | slave_config.src_maxburst = dma_params->burstsize; |
121 | } | 67 | } |
122 | 68 | ||
123 | ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config); | 69 | ret = dmaengine_slave_config(chan, &slave_config); |
124 | if (ret) | 70 | if (ret) |
125 | return ret; | 71 | return ret; |
126 | 72 | ||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, | ||
131 | struct snd_pcm_hw_params *params) | ||
132 | { | ||
133 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
134 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
135 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | ||
136 | unsigned long dma_addr; | ||
137 | struct dma_chan *chan; | ||
138 | struct imx_pcm_dma_params *dma_params; | ||
139 | int ret; | ||
140 | |||
141 | dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
142 | ret = imx_ssi_dma_alloc(substream, params); | ||
143 | if (ret) | ||
144 | return ret; | ||
145 | chan = iprtd->dma_chan; | ||
146 | |||
147 | iprtd->size = params_buffer_bytes(params); | ||
148 | iprtd->periods = params_periods(params); | ||
149 | iprtd->period_bytes = params_period_bytes(params); | ||
150 | iprtd->offset = 0; | ||
151 | iprtd->period_time = HZ / (params_rate(params) / | ||
152 | params_period_size(params)); | ||
153 | |||
154 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 73 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); |
155 | 74 | ||
156 | dma_addr = runtime->dma_addr; | ||
157 | |||
158 | iprtd->buf = (unsigned int *)substream->dma_buffer.area; | ||
159 | |||
160 | iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr, | ||
161 | iprtd->period_bytes * iprtd->periods, | ||
162 | iprtd->period_bytes, | ||
163 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? | ||
164 | DMA_MEM_TO_DEV : DMA_DEV_TO_MEM); | ||
165 | if (!iprtd->desc) { | ||
166 | dev_err(&chan->dev->device, "cannot prepare slave dma\n"); | ||
167 | return -EINVAL; | ||
168 | } | ||
169 | |||
170 | iprtd->desc->callback = audio_dma_irq; | ||
171 | iprtd->desc->callback_param = substream; | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream) | ||
177 | { | ||
178 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
179 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | ||
180 | |||
181 | if (iprtd->dma_chan) { | ||
182 | dma_release_channel(iprtd->dma_chan); | ||
183 | iprtd->dma_chan = NULL; | ||
184 | } | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream) | ||
190 | { | ||
191 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
192 | struct imx_pcm_dma_params *dma_params; | ||
193 | |||
194 | dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
195 | |||
196 | return 0; | 75 | return 0; |
197 | } | 76 | } |
198 | 77 | ||
199 | static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
200 | { | ||
201 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
202 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | ||
203 | |||
204 | switch (cmd) { | ||
205 | case SNDRV_PCM_TRIGGER_START: | ||
206 | case SNDRV_PCM_TRIGGER_RESUME: | ||
207 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
208 | dmaengine_submit(iprtd->desc); | ||
209 | |||
210 | break; | ||
211 | |||
212 | case SNDRV_PCM_TRIGGER_STOP: | ||
213 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
214 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
215 | dmaengine_terminate_all(iprtd->dma_chan); | ||
216 | |||
217 | break; | ||
218 | default: | ||
219 | return -EINVAL; | ||
220 | } | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream) | ||
226 | { | ||
227 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
228 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | ||
229 | |||
230 | pr_debug("%s: %ld %ld\n", __func__, iprtd->offset, | ||
231 | bytes_to_frames(substream->runtime, iprtd->offset)); | ||
232 | |||
233 | return bytes_to_frames(substream->runtime, iprtd->offset); | ||
234 | } | ||
235 | |||
236 | static struct snd_pcm_hardware snd_imx_hardware = { | 78 | static struct snd_pcm_hardware snd_imx_hardware = { |
237 | .info = SNDRV_PCM_INFO_INTERLEAVED | | 79 | .info = SNDRV_PCM_INFO_INTERLEAVED | |
238 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 80 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
@@ -254,33 +96,37 @@ static struct snd_pcm_hardware snd_imx_hardware = { | |||
254 | 96 | ||
255 | static int snd_imx_open(struct snd_pcm_substream *substream) | 97 | static int snd_imx_open(struct snd_pcm_substream *substream) |
256 | { | 98 | { |
257 | struct snd_pcm_runtime *runtime = substream->runtime; | 99 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
258 | struct imx_pcm_runtime_data *iprtd; | 100 | struct imx_pcm_dma_params *dma_params; |
101 | struct imx_dma_data *dma_data; | ||
259 | int ret; | 102 | int ret; |
260 | 103 | ||
261 | iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); | 104 | snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); |
262 | if (iprtd == NULL) | ||
263 | return -ENOMEM; | ||
264 | runtime->private_data = iprtd; | ||
265 | 105 | ||
266 | ret = snd_pcm_hw_constraint_integer(substream->runtime, | 106 | dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
267 | SNDRV_PCM_HW_PARAM_PERIODS); | 107 | |
268 | if (ret < 0) { | 108 | dma_data = kzalloc(sizeof(*dma_data), GFP_KERNEL); |
269 | kfree(iprtd); | 109 | dma_data->peripheral_type = IMX_DMATYPE_SSI; |
270 | return ret; | 110 | dma_data->priority = DMA_PRIO_HIGH; |
111 | dma_data->dma_request = dma_params->dma; | ||
112 | |||
113 | ret = snd_dmaengine_pcm_open(substream, filter, dma_data); | ||
114 | if (ret) { | ||
115 | kfree(dma_data); | ||
116 | return 0; | ||
271 | } | 117 | } |
272 | 118 | ||
273 | snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); | 119 | snd_dmaengine_pcm_set_data(substream, dma_data); |
274 | 120 | ||
275 | return 0; | 121 | return 0; |
276 | } | 122 | } |
277 | 123 | ||
278 | static int snd_imx_close(struct snd_pcm_substream *substream) | 124 | static int snd_imx_close(struct snd_pcm_substream *substream) |
279 | { | 125 | { |
280 | struct snd_pcm_runtime *runtime = substream->runtime; | 126 | struct imx_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream); |
281 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | ||
282 | 127 | ||
283 | kfree(iprtd); | 128 | snd_dmaengine_pcm_close(substream); |
129 | kfree(dma_data); | ||
284 | 130 | ||
285 | return 0; | 131 | return 0; |
286 | } | 132 | } |
@@ -290,10 +136,8 @@ static struct snd_pcm_ops imx_pcm_ops = { | |||
290 | .close = snd_imx_close, | 136 | .close = snd_imx_close, |
291 | .ioctl = snd_pcm_lib_ioctl, | 137 | .ioctl = snd_pcm_lib_ioctl, |
292 | .hw_params = snd_imx_pcm_hw_params, | 138 | .hw_params = snd_imx_pcm_hw_params, |
293 | .hw_free = snd_imx_pcm_hw_free, | 139 | .trigger = snd_dmaengine_pcm_trigger, |
294 | .prepare = snd_imx_pcm_prepare, | 140 | .pointer = snd_dmaengine_pcm_pointer, |
295 | .trigger = snd_imx_pcm_trigger, | ||
296 | .pointer = snd_imx_pcm_pointer, | ||
297 | .mmap = snd_imx_pcm_mmap, | 141 | .mmap = snd_imx_pcm_mmap, |
298 | }; | 142 | }; |
299 | 143 | ||
@@ -305,11 +149,6 @@ static struct snd_soc_platform_driver imx_soc_platform_mx2 = { | |||
305 | 149 | ||
306 | static int __devinit imx_soc_platform_probe(struct platform_device *pdev) | 150 | static int __devinit imx_soc_platform_probe(struct platform_device *pdev) |
307 | { | 151 | { |
308 | struct imx_ssi *ssi = platform_get_drvdata(pdev); | ||
309 | |||
310 | ssi->dma_params_tx.burstsize = 6; | ||
311 | ssi->dma_params_rx.burstsize = 4; | ||
312 | |||
313 | return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2); | 152 | return snd_soc_register_platform(&pdev->dev, &imx_soc_platform_mx2); |
314 | } | 153 | } |
315 | 154 | ||
diff --git a/sound/soc/imx/imx-pcm.c b/sound/soc/imx/imx-pcm.c new file mode 100644 index 000000000000..93dc360b1777 --- /dev/null +++ b/sound/soc/imx/imx-pcm.c | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de> | ||
3 | * | ||
4 | * This code is based on code copyrighted by Freescale, | ||
5 | * Liam Girdwood, Javier Martin and probably others. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/dma-mapping.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <sound/pcm.h> | ||
16 | #include <sound/soc.h> | ||
17 | #include "imx-pcm.h" | ||
18 | |||
19 | int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, | ||
20 | struct vm_area_struct *vma) | ||
21 | { | ||
22 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
23 | int ret; | ||
24 | |||
25 | ret = dma_mmap_writecombine(substream->pcm->card->dev, vma, | ||
26 | runtime->dma_area, runtime->dma_addr, runtime->dma_bytes); | ||
27 | |||
28 | pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret, | ||
29 | runtime->dma_area, | ||
30 | runtime->dma_addr, | ||
31 | runtime->dma_bytes); | ||
32 | return ret; | ||
33 | } | ||
34 | EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap); | ||
35 | |||
36 | static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) | ||
37 | { | ||
38 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | ||
39 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
40 | size_t size = IMX_SSI_DMABUF_SIZE; | ||
41 | |||
42 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
43 | buf->dev.dev = pcm->card->dev; | ||
44 | buf->private_data = NULL; | ||
45 | buf->area = dma_alloc_writecombine(pcm->card->dev, size, | ||
46 | &buf->addr, GFP_KERNEL); | ||
47 | if (!buf->area) | ||
48 | return -ENOMEM; | ||
49 | buf->bytes = size; | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | static u64 imx_pcm_dmamask = DMA_BIT_MASK(32); | ||
55 | |||
56 | int imx_pcm_new(struct snd_soc_pcm_runtime *rtd) | ||
57 | { | ||
58 | struct snd_card *card = rtd->card->snd_card; | ||
59 | struct snd_pcm *pcm = rtd->pcm; | ||
60 | int ret = 0; | ||
61 | |||
62 | if (!card->dev->dma_mask) | ||
63 | card->dev->dma_mask = &imx_pcm_dmamask; | ||
64 | if (!card->dev->coherent_dma_mask) | ||
65 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); | ||
66 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | ||
67 | ret = imx_pcm_preallocate_dma_buffer(pcm, | ||
68 | SNDRV_PCM_STREAM_PLAYBACK); | ||
69 | if (ret) | ||
70 | goto out; | ||
71 | } | ||
72 | |||
73 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | ||
74 | ret = imx_pcm_preallocate_dma_buffer(pcm, | ||
75 | SNDRV_PCM_STREAM_CAPTURE); | ||
76 | if (ret) | ||
77 | goto out; | ||
78 | } | ||
79 | |||
80 | out: | ||
81 | return ret; | ||
82 | } | ||
83 | EXPORT_SYMBOL_GPL(imx_pcm_new); | ||
84 | |||
85 | void imx_pcm_free(struct snd_pcm *pcm) | ||
86 | { | ||
87 | struct snd_pcm_substream *substream; | ||
88 | struct snd_dma_buffer *buf; | ||
89 | int stream; | ||
90 | |||
91 | for (stream = 0; stream < 2; stream++) { | ||
92 | substream = pcm->streams[stream].substream; | ||
93 | if (!substream) | ||
94 | continue; | ||
95 | |||
96 | buf = &substream->dma_buffer; | ||
97 | if (!buf->area) | ||
98 | continue; | ||
99 | |||
100 | dma_free_writecombine(pcm->card->dev, buf->bytes, | ||
101 | buf->area, buf->addr); | ||
102 | buf->area = NULL; | ||
103 | } | ||
104 | } | ||
105 | EXPORT_SYMBOL_GPL(imx_pcm_free); | ||
diff --git a/sound/soc/imx/imx-pcm.h b/sound/soc/imx/imx-pcm.h new file mode 100644 index 000000000000..b5f5c3acf34d --- /dev/null +++ b/sound/soc/imx/imx-pcm.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de> | ||
3 | * | ||
4 | * This code is based on code copyrighted by Freescale, | ||
5 | * Liam Girdwood, Javier Martin and probably others. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | |||
13 | #ifndef _IMX_PCM_H | ||
14 | #define _IMX_PCM_H | ||
15 | |||
16 | /* | ||
17 | * Do not change this as the FIQ handler depends on this size | ||
18 | */ | ||
19 | #define IMX_SSI_DMABUF_SIZE (64 * 1024) | ||
20 | |||
21 | struct imx_pcm_dma_params { | ||
22 | int dma; | ||
23 | unsigned long dma_addr; | ||
24 | int burstsize; | ||
25 | }; | ||
26 | |||
27 | int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, | ||
28 | struct vm_area_struct *vma); | ||
29 | int imx_pcm_new(struct snd_soc_pcm_runtime *rtd); | ||
30 | void imx_pcm_free(struct snd_pcm *pcm); | ||
31 | |||
32 | #endif /* _IMX_PCM_H */ | ||
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 01d1f749cf02..4f81ed456325 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c | |||
@@ -112,7 +112,7 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) | |||
112 | break; | 112 | break; |
113 | case SND_SOC_DAIFMT_DSP_A: | 113 | case SND_SOC_DAIFMT_DSP_A: |
114 | /* data on rising edge of bclk, frame high 1clk before data */ | 114 | /* data on rising edge of bclk, frame high 1clk before data */ |
115 | strcr |= SSI_STCR_TFSL | SSI_STCR_TEFS; | 115 | strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0 | SSI_STCR_TEFS; |
116 | break; | 116 | break; |
117 | } | 117 | } |
118 | 118 | ||
@@ -233,6 +233,23 @@ static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai, | |||
233 | return 0; | 233 | return 0; |
234 | } | 234 | } |
235 | 235 | ||
236 | static int imx_ssi_startup(struct snd_pcm_substream *substream, | ||
237 | struct snd_soc_dai *cpu_dai) | ||
238 | { | ||
239 | struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai); | ||
240 | struct imx_pcm_dma_params *dma_data; | ||
241 | |||
242 | /* Tx/Rx config */ | ||
243 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
244 | dma_data = &ssi->dma_params_tx; | ||
245 | else | ||
246 | dma_data = &ssi->dma_params_rx; | ||
247 | |||
248 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | |||
236 | /* | 253 | /* |
237 | * Should only be called when port is inactive (i.e. SSIEN = 0), | 254 | * Should only be called when port is inactive (i.e. SSIEN = 0), |
238 | * although can be called multiple times by upper layers. | 255 | * although can be called multiple times by upper layers. |
@@ -242,23 +259,17 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream, | |||
242 | struct snd_soc_dai *cpu_dai) | 259 | struct snd_soc_dai *cpu_dai) |
243 | { | 260 | { |
244 | struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai); | 261 | struct imx_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai); |
245 | struct imx_pcm_dma_params *dma_data; | ||
246 | u32 reg, sccr; | 262 | u32 reg, sccr; |
247 | 263 | ||
248 | /* Tx/Rx config */ | 264 | /* Tx/Rx config */ |
249 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 265 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
250 | reg = SSI_STCCR; | 266 | reg = SSI_STCCR; |
251 | dma_data = &ssi->dma_params_tx; | 267 | else |
252 | } else { | ||
253 | reg = SSI_SRCCR; | 268 | reg = SSI_SRCCR; |
254 | dma_data = &ssi->dma_params_rx; | ||
255 | } | ||
256 | 269 | ||
257 | if (ssi->flags & IMX_SSI_SYN) | 270 | if (ssi->flags & IMX_SSI_SYN) |
258 | reg = SSI_STCCR; | 271 | reg = SSI_STCCR; |
259 | 272 | ||
260 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); | ||
261 | |||
262 | sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK; | 273 | sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK; |
263 | 274 | ||
264 | /* DAI data (word) size */ | 275 | /* DAI data (word) size */ |
@@ -343,6 +354,7 @@ static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd, | |||
343 | } | 354 | } |
344 | 355 | ||
345 | static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = { | 356 | static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = { |
357 | .startup = imx_ssi_startup, | ||
346 | .hw_params = imx_ssi_hw_params, | 358 | .hw_params = imx_ssi_hw_params, |
347 | .set_fmt = imx_ssi_set_dai_fmt, | 359 | .set_fmt = imx_ssi_set_dai_fmt, |
348 | .set_clkdiv = imx_ssi_set_dai_clkdiv, | 360 | .set_clkdiv = imx_ssi_set_dai_clkdiv, |
@@ -351,94 +363,6 @@ static const struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = { | |||
351 | .trigger = imx_ssi_trigger, | 363 | .trigger = imx_ssi_trigger, |
352 | }; | 364 | }; |
353 | 365 | ||
354 | int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, | ||
355 | struct vm_area_struct *vma) | ||
356 | { | ||
357 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
358 | int ret; | ||
359 | |||
360 | ret = dma_mmap_writecombine(substream->pcm->card->dev, vma, | ||
361 | runtime->dma_area, runtime->dma_addr, runtime->dma_bytes); | ||
362 | |||
363 | pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret, | ||
364 | runtime->dma_area, | ||
365 | runtime->dma_addr, | ||
366 | runtime->dma_bytes); | ||
367 | return ret; | ||
368 | } | ||
369 | EXPORT_SYMBOL_GPL(snd_imx_pcm_mmap); | ||
370 | |||
371 | static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) | ||
372 | { | ||
373 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | ||
374 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
375 | size_t size = IMX_SSI_DMABUF_SIZE; | ||
376 | |||
377 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
378 | buf->dev.dev = pcm->card->dev; | ||
379 | buf->private_data = NULL; | ||
380 | buf->area = dma_alloc_writecombine(pcm->card->dev, size, | ||
381 | &buf->addr, GFP_KERNEL); | ||
382 | if (!buf->area) | ||
383 | return -ENOMEM; | ||
384 | buf->bytes = size; | ||
385 | |||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static u64 imx_pcm_dmamask = DMA_BIT_MASK(32); | ||
390 | |||
391 | int imx_pcm_new(struct snd_soc_pcm_runtime *rtd) | ||
392 | { | ||
393 | struct snd_card *card = rtd->card->snd_card; | ||
394 | struct snd_pcm *pcm = rtd->pcm; | ||
395 | int ret = 0; | ||
396 | |||
397 | if (!card->dev->dma_mask) | ||
398 | card->dev->dma_mask = &imx_pcm_dmamask; | ||
399 | if (!card->dev->coherent_dma_mask) | ||
400 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); | ||
401 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | ||
402 | ret = imx_pcm_preallocate_dma_buffer(pcm, | ||
403 | SNDRV_PCM_STREAM_PLAYBACK); | ||
404 | if (ret) | ||
405 | goto out; | ||
406 | } | ||
407 | |||
408 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | ||
409 | ret = imx_pcm_preallocate_dma_buffer(pcm, | ||
410 | SNDRV_PCM_STREAM_CAPTURE); | ||
411 | if (ret) | ||
412 | goto out; | ||
413 | } | ||
414 | |||
415 | out: | ||
416 | return ret; | ||
417 | } | ||
418 | EXPORT_SYMBOL_GPL(imx_pcm_new); | ||
419 | |||
420 | void imx_pcm_free(struct snd_pcm *pcm) | ||
421 | { | ||
422 | struct snd_pcm_substream *substream; | ||
423 | struct snd_dma_buffer *buf; | ||
424 | int stream; | ||
425 | |||
426 | for (stream = 0; stream < 2; stream++) { | ||
427 | substream = pcm->streams[stream].substream; | ||
428 | if (!substream) | ||
429 | continue; | ||
430 | |||
431 | buf = &substream->dma_buffer; | ||
432 | if (!buf->area) | ||
433 | continue; | ||
434 | |||
435 | dma_free_writecombine(pcm->card->dev, buf->bytes, | ||
436 | buf->area, buf->addr); | ||
437 | buf->area = NULL; | ||
438 | } | ||
439 | } | ||
440 | EXPORT_SYMBOL_GPL(imx_pcm_free); | ||
441 | |||
442 | static int imx_ssi_dai_probe(struct snd_soc_dai *dai) | 366 | static int imx_ssi_dai_probe(struct snd_soc_dai *dai) |
443 | { | 367 | { |
444 | struct imx_ssi *ssi = dev_get_drvdata(dai->dev); | 368 | struct imx_ssi *ssi = dev_get_drvdata(dai->dev); |
@@ -656,7 +580,7 @@ static int imx_ssi_probe(struct platform_device *pdev) | |||
656 | ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0; | 580 | ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0; |
657 | ssi->dma_params_tx.dma_addr = res->start + SSI_STX0; | 581 | ssi->dma_params_tx.dma_addr = res->start + SSI_STX0; |
658 | 582 | ||
659 | ssi->dma_params_tx.burstsize = 4; | 583 | ssi->dma_params_tx.burstsize = 6; |
660 | ssi->dma_params_rx.burstsize = 4; | 584 | ssi->dma_params_rx.burstsize = 4; |
661 | 585 | ||
662 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); | 586 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0"); |
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h index 1072dfb53e47..5744e86ca878 100644 --- a/sound/soc/imx/imx-ssi.h +++ b/sound/soc/imx/imx-ssi.h | |||
@@ -187,12 +187,7 @@ | |||
187 | 187 | ||
188 | #include <linux/dmaengine.h> | 188 | #include <linux/dmaengine.h> |
189 | #include <mach/dma.h> | 189 | #include <mach/dma.h> |
190 | 190 | #include "imx-pcm.h" | |
191 | struct imx_pcm_dma_params { | ||
192 | int dma; | ||
193 | unsigned long dma_addr; | ||
194 | int burstsize; | ||
195 | }; | ||
196 | 191 | ||
197 | struct imx_ssi { | 192 | struct imx_ssi { |
198 | struct platform_device *ac97_dev; | 193 | struct platform_device *ac97_dev; |
@@ -218,13 +213,4 @@ struct imx_ssi { | |||
218 | struct platform_device *soc_platform_pdev_fiq; | 213 | struct platform_device *soc_platform_pdev_fiq; |
219 | }; | 214 | }; |
220 | 215 | ||
221 | int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma); | ||
222 | int imx_pcm_new(struct snd_soc_pcm_runtime *rtd); | ||
223 | void imx_pcm_free(struct snd_pcm *pcm); | ||
224 | |||
225 | /* | ||
226 | * Do not change this as the FIQ handler depends on this size | ||
227 | */ | ||
228 | #define IMX_SSI_DMABUF_SIZE (64 * 1024) | ||
229 | |||
230 | #endif /* _IMX_SSI_H */ | 216 | #endif /* _IMX_SSI_H */ |
diff --git a/sound/soc/imx/mx27vis-aic32x4.c b/sound/soc/imx/mx27vis-aic32x4.c index 3c2eed9094d5..f6d04ad4bb39 100644 --- a/sound/soc/imx/mx27vis-aic32x4.c +++ b/sound/soc/imx/mx27vis-aic32x4.c | |||
@@ -25,15 +25,36 @@ | |||
25 | #include <linux/moduleparam.h> | 25 | #include <linux/moduleparam.h> |
26 | #include <linux/device.h> | 26 | #include <linux/device.h> |
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/gpio.h> | ||
28 | #include <sound/core.h> | 29 | #include <sound/core.h> |
29 | #include <sound/pcm.h> | 30 | #include <sound/pcm.h> |
30 | #include <sound/soc.h> | 31 | #include <sound/soc.h> |
31 | #include <sound/soc-dapm.h> | 32 | #include <sound/soc-dapm.h> |
33 | #include <sound/tlv.h> | ||
32 | #include <asm/mach-types.h> | 34 | #include <asm/mach-types.h> |
33 | #include <mach/audmux.h> | 35 | #include <mach/iomux-mx27.h> |
34 | 36 | ||
35 | #include "../codecs/tlv320aic32x4.h" | 37 | #include "../codecs/tlv320aic32x4.h" |
36 | #include "imx-ssi.h" | 38 | #include "imx-ssi.h" |
39 | #include "imx-audmux.h" | ||
40 | |||
41 | #define MX27VIS_AMP_GAIN 0 | ||
42 | #define MX27VIS_AMP_MUTE 1 | ||
43 | |||
44 | #define MX27VIS_PIN_G0 (GPIO_PORTF + 9) | ||
45 | #define MX27VIS_PIN_G1 (GPIO_PORTF + 8) | ||
46 | #define MX27VIS_PIN_SDL (GPIO_PORTE + 5) | ||
47 | #define MX27VIS_PIN_SDR (GPIO_PORTF + 7) | ||
48 | |||
49 | static int mx27vis_amp_gain; | ||
50 | static int mx27vis_amp_mute; | ||
51 | |||
52 | static const int mx27vis_amp_pins[] = { | ||
53 | MX27VIS_PIN_G0 | GPIO_GPIO | GPIO_OUT, | ||
54 | MX27VIS_PIN_G1 | GPIO_GPIO | GPIO_OUT, | ||
55 | MX27VIS_PIN_SDL | GPIO_GPIO | GPIO_OUT, | ||
56 | MX27VIS_PIN_SDR | GPIO_GPIO | GPIO_OUT, | ||
57 | }; | ||
37 | 58 | ||
38 | static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream, | 59 | static int mx27vis_aic32x4_hw_params(struct snd_pcm_substream *substream, |
39 | struct snd_pcm_hw_params *params) | 60 | struct snd_pcm_hw_params *params) |
@@ -74,6 +95,76 @@ static struct snd_soc_ops mx27vis_aic32x4_snd_ops = { | |||
74 | .hw_params = mx27vis_aic32x4_hw_params, | 95 | .hw_params = mx27vis_aic32x4_hw_params, |
75 | }; | 96 | }; |
76 | 97 | ||
98 | static int mx27vis_amp_set(struct snd_kcontrol *kcontrol, | ||
99 | struct snd_ctl_elem_value *ucontrol) | ||
100 | { | ||
101 | struct soc_mixer_control *mc = | ||
102 | (struct soc_mixer_control *)kcontrol->private_value; | ||
103 | int value = ucontrol->value.integer.value[0]; | ||
104 | unsigned int reg = mc->reg; | ||
105 | int max = mc->max; | ||
106 | |||
107 | if (value > max) | ||
108 | return -EINVAL; | ||
109 | |||
110 | switch (reg) { | ||
111 | case MX27VIS_AMP_GAIN: | ||
112 | gpio_set_value(MX27VIS_PIN_G0, value & 1); | ||
113 | gpio_set_value(MX27VIS_PIN_G1, value >> 1); | ||
114 | mx27vis_amp_gain = value; | ||
115 | break; | ||
116 | case MX27VIS_AMP_MUTE: | ||
117 | gpio_set_value(MX27VIS_PIN_SDL, value & 1); | ||
118 | gpio_set_value(MX27VIS_PIN_SDR, value >> 1); | ||
119 | mx27vis_amp_mute = value; | ||
120 | break; | ||
121 | } | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static int mx27vis_amp_get(struct snd_kcontrol *kcontrol, | ||
126 | struct snd_ctl_elem_value *ucontrol) | ||
127 | { | ||
128 | struct soc_mixer_control *mc = | ||
129 | (struct soc_mixer_control *)kcontrol->private_value; | ||
130 | unsigned int reg = mc->reg; | ||
131 | |||
132 | switch (reg) { | ||
133 | case MX27VIS_AMP_GAIN: | ||
134 | ucontrol->value.integer.value[0] = mx27vis_amp_gain; | ||
135 | break; | ||
136 | case MX27VIS_AMP_MUTE: | ||
137 | ucontrol->value.integer.value[0] = mx27vis_amp_mute; | ||
138 | break; | ||
139 | } | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | /* From 6dB to 24dB in steps of 6dB */ | ||
144 | static const DECLARE_TLV_DB_SCALE(mx27vis_amp_tlv, 600, 600, 0); | ||
145 | |||
146 | static const struct snd_kcontrol_new mx27vis_aic32x4_controls[] = { | ||
147 | SOC_DAPM_PIN_SWITCH("External Mic"), | ||
148 | SOC_SINGLE_EXT_TLV("LO Ext Boost", MX27VIS_AMP_GAIN, 0, 3, 0, | ||
149 | mx27vis_amp_get, mx27vis_amp_set, mx27vis_amp_tlv), | ||
150 | SOC_DOUBLE_EXT("LO Ext Mute Switch", MX27VIS_AMP_MUTE, 0, 1, 1, 0, | ||
151 | mx27vis_amp_get, mx27vis_amp_set), | ||
152 | }; | ||
153 | |||
154 | static const struct snd_soc_dapm_widget aic32x4_dapm_widgets[] = { | ||
155 | SND_SOC_DAPM_MIC("External Mic", NULL), | ||
156 | }; | ||
157 | |||
158 | static const struct snd_soc_dapm_route aic32x4_dapm_routes[] = { | ||
159 | {"Mic Bias", NULL, "External Mic"}, | ||
160 | {"IN1_R", NULL, "Mic Bias"}, | ||
161 | {"IN2_R", NULL, "Mic Bias"}, | ||
162 | {"IN3_R", NULL, "Mic Bias"}, | ||
163 | {"IN1_L", NULL, "Mic Bias"}, | ||
164 | {"IN2_L", NULL, "Mic Bias"}, | ||
165 | {"IN3_L", NULL, "Mic Bias"}, | ||
166 | }; | ||
167 | |||
77 | static struct snd_soc_dai_link mx27vis_aic32x4_dai = { | 168 | static struct snd_soc_dai_link mx27vis_aic32x4_dai = { |
78 | .name = "tlv320aic32x4", | 169 | .name = "tlv320aic32x4", |
79 | .stream_name = "TLV320AIC32X4", | 170 | .stream_name = "TLV320AIC32X4", |
@@ -89,50 +180,66 @@ static struct snd_soc_card mx27vis_aic32x4 = { | |||
89 | .owner = THIS_MODULE, | 180 | .owner = THIS_MODULE, |
90 | .dai_link = &mx27vis_aic32x4_dai, | 181 | .dai_link = &mx27vis_aic32x4_dai, |
91 | .num_links = 1, | 182 | .num_links = 1, |
183 | .controls = mx27vis_aic32x4_controls, | ||
184 | .num_controls = ARRAY_SIZE(mx27vis_aic32x4_controls), | ||
185 | .dapm_widgets = aic32x4_dapm_widgets, | ||
186 | .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets), | ||
187 | .dapm_routes = aic32x4_dapm_routes, | ||
188 | .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), | ||
92 | }; | 189 | }; |
93 | 190 | ||
94 | static struct platform_device *mx27vis_aic32x4_snd_device; | 191 | static int __devinit mx27vis_aic32x4_probe(struct platform_device *pdev) |
95 | |||
96 | static int __init mx27vis_aic32x4_init(void) | ||
97 | { | 192 | { |
98 | int ret; | 193 | int ret; |
99 | 194 | ||
100 | mx27vis_aic32x4_snd_device = platform_device_alloc("soc-audio", -1); | 195 | mx27vis_aic32x4.dev = &pdev->dev; |
101 | if (!mx27vis_aic32x4_snd_device) | 196 | ret = snd_soc_register_card(&mx27vis_aic32x4); |
102 | return -ENOMEM; | ||
103 | |||
104 | platform_set_drvdata(mx27vis_aic32x4_snd_device, &mx27vis_aic32x4); | ||
105 | ret = platform_device_add(mx27vis_aic32x4_snd_device); | ||
106 | |||
107 | if (ret) { | 197 | if (ret) { |
108 | printk(KERN_ERR "ASoC: Platform device allocation failed\n"); | 198 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", |
109 | platform_device_put(mx27vis_aic32x4_snd_device); | 199 | ret); |
200 | return ret; | ||
110 | } | 201 | } |
111 | 202 | ||
112 | /* Connect SSI0 as clock slave to SSI1 external pins */ | 203 | /* Connect SSI0 as clock slave to SSI1 external pins */ |
113 | mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, | 204 | imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, |
114 | MXC_AUDMUX_V1_PCR_SYN | | 205 | IMX_AUDMUX_V1_PCR_SYN | |
115 | MXC_AUDMUX_V1_PCR_TFSDIR | | 206 | IMX_AUDMUX_V1_PCR_TFSDIR | |
116 | MXC_AUDMUX_V1_PCR_TCLKDIR | | 207 | IMX_AUDMUX_V1_PCR_TCLKDIR | |
117 | MXC_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) | | 208 | IMX_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) | |
118 | MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) | 209 | IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_PPCR1_SSI_PINS_1) |
119 | ); | 210 | ); |
120 | mxc_audmux_v1_configure_port(MX27_AUDMUX_PPCR1_SSI_PINS_1, | 211 | imx_audmux_v1_configure_port(MX27_AUDMUX_PPCR1_SSI_PINS_1, |
121 | MXC_AUDMUX_V1_PCR_SYN | | 212 | IMX_AUDMUX_V1_PCR_SYN | |
122 | MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0) | 213 | IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0) |
123 | ); | 214 | ); |
124 | 215 | ||
216 | ret = mxc_gpio_setup_multiple_pins(mx27vis_amp_pins, | ||
217 | ARRAY_SIZE(mx27vis_amp_pins), "MX27VIS_AMP"); | ||
218 | if (ret) | ||
219 | printk(KERN_ERR "ASoC: unable to setup gpios\n"); | ||
220 | |||
125 | return ret; | 221 | return ret; |
126 | } | 222 | } |
127 | 223 | ||
128 | static void __exit mx27vis_aic32x4_exit(void) | 224 | static int __devexit mx27vis_aic32x4_remove(struct platform_device *pdev) |
129 | { | 225 | { |
130 | platform_device_unregister(mx27vis_aic32x4_snd_device); | 226 | snd_soc_unregister_card(&mx27vis_aic32x4); |
227 | |||
228 | return 0; | ||
131 | } | 229 | } |
132 | 230 | ||
133 | module_init(mx27vis_aic32x4_init); | 231 | static struct platform_driver mx27vis_aic32x4_audio_driver = { |
134 | module_exit(mx27vis_aic32x4_exit); | 232 | .driver = { |
233 | .name = "mx27vis", | ||
234 | .owner = THIS_MODULE, | ||
235 | }, | ||
236 | .probe = mx27vis_aic32x4_probe, | ||
237 | .remove = __devexit_p(mx27vis_aic32x4_remove), | ||
238 | }; | ||
239 | |||
240 | module_platform_driver(mx27vis_aic32x4_audio_driver); | ||
135 | 241 | ||
136 | MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>"); | 242 | MODULE_AUTHOR("Javier Martin <javier.martin@vista-silicon.com>"); |
137 | MODULE_DESCRIPTION("ALSA SoC AIC32X4 mx27 visstrim"); | 243 | MODULE_DESCRIPTION("ALSA SoC AIC32X4 mx27 visstrim"); |
138 | MODULE_LICENSE("GPL"); | 244 | MODULE_LICENSE("GPL"); |
245 | MODULE_ALIAS("platform:mx27vis"); | ||
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c index 6ac12111de6a..f8da6dd115ed 100644 --- a/sound/soc/imx/phycore-ac97.c +++ b/sound/soc/imx/phycore-ac97.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <sound/soc.h> | 19 | #include <sound/soc.h> |
20 | #include <asm/mach-types.h> | 20 | #include <asm/mach-types.h> |
21 | 21 | ||
22 | #include "imx-audmux.h" | ||
23 | |||
22 | static struct snd_soc_card imx_phycore; | 24 | static struct snd_soc_card imx_phycore; |
23 | 25 | ||
24 | static struct snd_soc_ops imx_phycore_hifi_ops = { | 26 | static struct snd_soc_ops imx_phycore_hifi_ops = { |
@@ -50,9 +52,32 @@ static int __init imx_phycore_init(void) | |||
50 | { | 52 | { |
51 | int ret; | 53 | int ret; |
52 | 54 | ||
53 | if (!machine_is_pcm043() && !machine_is_pca100()) | 55 | if (machine_is_pca100()) { |
56 | imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0, | ||
57 | IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */ | ||
58 | IMX_AUDMUX_V1_PCR_TFCSEL(3) | | ||
59 | IMX_AUDMUX_V1_PCR_TCLKDIR | /* clock is output */ | ||
60 | IMX_AUDMUX_V1_PCR_RXDSEL(3)); | ||
61 | imx_audmux_v1_configure_port(3, | ||
62 | IMX_AUDMUX_V1_PCR_SYN | /* 4wire mode */ | ||
63 | IMX_AUDMUX_V1_PCR_TFCSEL(0) | | ||
64 | IMX_AUDMUX_V1_PCR_TFSDIR | | ||
65 | IMX_AUDMUX_V1_PCR_RXDSEL(0)); | ||
66 | } else if (machine_is_pcm043()) { | ||
67 | imx_audmux_v2_configure_port(3, | ||
68 | IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */ | ||
69 | IMX_AUDMUX_V2_PTCR_TFSEL(0) | | ||
70 | IMX_AUDMUX_V2_PTCR_TFSDIR, | ||
71 | IMX_AUDMUX_V2_PDCR_RXDSEL(0)); | ||
72 | imx_audmux_v2_configure_port(0, | ||
73 | IMX_AUDMUX_V2_PTCR_SYN | /* 4wire mode */ | ||
74 | IMX_AUDMUX_V2_PTCR_TCSEL(3) | | ||
75 | IMX_AUDMUX_V2_PTCR_TCLKDIR, /* clock is output */ | ||
76 | IMX_AUDMUX_V2_PDCR_RXDSEL(3)); | ||
77 | } else { | ||
54 | /* return happy. We might run on a totally different machine */ | 78 | /* return happy. We might run on a totally different machine */ |
55 | return 0; | 79 | return 0; |
80 | } | ||
56 | 81 | ||
57 | imx_phycore_snd_ac97_device = platform_device_alloc("soc-audio", -1); | 82 | imx_phycore_snd_ac97_device = platform_device_alloc("soc-audio", -1); |
58 | if (!imx_phycore_snd_ac97_device) | 83 | if (!imx_phycore_snd_ac97_device) |
diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c index 37480c90e997..fe54a69073e5 100644 --- a/sound/soc/imx/wm1133-ev1.c +++ b/sound/soc/imx/wm1133-ev1.c | |||
@@ -21,10 +21,9 @@ | |||
21 | #include <sound/pcm_params.h> | 21 | #include <sound/pcm_params.h> |
22 | #include <sound/soc.h> | 22 | #include <sound/soc.h> |
23 | 23 | ||
24 | #include <mach/audmux.h> | ||
25 | |||
26 | #include "imx-ssi.h" | 24 | #include "imx-ssi.h" |
27 | #include "../codecs/wm8350.h" | 25 | #include "../codecs/wm8350.h" |
26 | #include "imx-audmux.h" | ||
28 | 27 | ||
29 | /* There is a silicon mic on the board optionally connected via a solder pad | 28 | /* There is a silicon mic on the board optionally connected via a solder pad |
30 | * SP1. Define this to enable it. | 29 | * SP1. Define this to enable it. |
@@ -268,17 +267,17 @@ static int __init wm1133_ev1_audio_init(void) | |||
268 | unsigned int ptcr, pdcr; | 267 | unsigned int ptcr, pdcr; |
269 | 268 | ||
270 | /* SSI0 mastered by port 5 */ | 269 | /* SSI0 mastered by port 5 */ |
271 | ptcr = MXC_AUDMUX_V2_PTCR_SYN | | 270 | ptcr = IMX_AUDMUX_V2_PTCR_SYN | |
272 | MXC_AUDMUX_V2_PTCR_TFSDIR | | 271 | IMX_AUDMUX_V2_PTCR_TFSDIR | |
273 | MXC_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT5_SSI_PINS_5) | | 272 | IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT5_SSI_PINS_5) | |
274 | MXC_AUDMUX_V2_PTCR_TCLKDIR | | 273 | IMX_AUDMUX_V2_PTCR_TCLKDIR | |
275 | MXC_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT5_SSI_PINS_5); | 274 | IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT5_SSI_PINS_5); |
276 | pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT5_SSI_PINS_5); | 275 | pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT5_SSI_PINS_5); |
277 | mxc_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0, ptcr, pdcr); | 276 | imx_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0, ptcr, pdcr); |
278 | 277 | ||
279 | ptcr = MXC_AUDMUX_V2_PTCR_SYN; | 278 | ptcr = IMX_AUDMUX_V2_PTCR_SYN; |
280 | pdcr = MXC_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0); | 279 | pdcr = IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0); |
281 | mxc_audmux_v2_configure_port(MX31_AUDMUX_PORT5_SSI_PINS_5, ptcr, pdcr); | 280 | imx_audmux_v2_configure_port(MX31_AUDMUX_PORT5_SSI_PINS_5, ptcr, pdcr); |
282 | 281 | ||
283 | wm1133_ev1_snd_device = platform_device_alloc("soc-audio", -1); | 282 | wm1133_ev1_snd_device = platform_device_alloc("soc-audio", -1); |
284 | if (!wm1133_ev1_snd_device) | 283 | if (!wm1133_ev1_snd_device) |
diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c index 0097c3b13a1a..e8aaff18d7cc 100644 --- a/sound/soc/jz4740/qi_lb60.c +++ b/sound/soc/jz4740/qi_lb60.c | |||
@@ -91,56 +91,52 @@ static struct snd_soc_card qi_lb60 = { | |||
91 | .num_dapm_routes = ARRAY_SIZE(qi_lb60_routes), | 91 | .num_dapm_routes = ARRAY_SIZE(qi_lb60_routes), |
92 | }; | 92 | }; |
93 | 93 | ||
94 | static struct platform_device *qi_lb60_snd_device; | ||
95 | |||
96 | static const struct gpio qi_lb60_gpios[] = { | 94 | static const struct gpio qi_lb60_gpios[] = { |
97 | { QI_LB60_SND_GPIO, GPIOF_OUT_INIT_LOW, "SND" }, | 95 | { QI_LB60_SND_GPIO, GPIOF_OUT_INIT_LOW, "SND" }, |
98 | { QI_LB60_AMP_GPIO, GPIOF_OUT_INIT_LOW, "AMP" }, | 96 | { QI_LB60_AMP_GPIO, GPIOF_OUT_INIT_LOW, "AMP" }, |
99 | }; | 97 | }; |
100 | 98 | ||
101 | static int __init qi_lb60_init(void) | 99 | static int __devinit qi_lb60_probe(struct platform_device *pdev) |
102 | { | 100 | { |
101 | struct snd_soc_card *card = &qi_lb60; | ||
103 | int ret; | 102 | int ret; |
104 | 103 | ||
105 | qi_lb60_snd_device = platform_device_alloc("soc-audio", -1); | ||
106 | |||
107 | if (!qi_lb60_snd_device) | ||
108 | return -ENOMEM; | ||
109 | |||
110 | ret = gpio_request_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); | 104 | ret = gpio_request_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); |
111 | if (ret) { | 105 | if (ret) |
112 | pr_err("qi_lb60 snd: Failed to request gpios: %d\n", ret); | 106 | return ret; |
113 | goto err_device_put; | ||
114 | } | ||
115 | 107 | ||
116 | platform_set_drvdata(qi_lb60_snd_device, &qi_lb60); | 108 | card->dev = &pdev->dev; |
117 | 109 | ||
118 | ret = platform_device_add(qi_lb60_snd_device); | 110 | ret = snd_soc_register_card(card); |
119 | if (ret) { | 111 | if (ret) { |
120 | pr_err("qi_lb60 snd: Failed to add snd soc device: %d\n", ret); | 112 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", |
121 | goto err_unset_pdata; | 113 | ret); |
114 | gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); | ||
122 | } | 115 | } |
123 | |||
124 | return 0; | ||
125 | |||
126 | err_unset_pdata: | ||
127 | platform_set_drvdata(qi_lb60_snd_device, NULL); | ||
128 | /*err_gpio_free_array:*/ | ||
129 | gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); | ||
130 | err_device_put: | ||
131 | platform_device_put(qi_lb60_snd_device); | ||
132 | |||
133 | return ret; | 116 | return ret; |
134 | } | 117 | } |
135 | module_init(qi_lb60_init); | ||
136 | 118 | ||
137 | static void __exit qi_lb60_exit(void) | 119 | static int __devexit qi_lb60_remove(struct platform_device *pdev) |
138 | { | 120 | { |
139 | platform_device_unregister(qi_lb60_snd_device); | 121 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
122 | |||
123 | snd_soc_unregister_card(card); | ||
140 | gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); | 124 | gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); |
125 | return 0; | ||
141 | } | 126 | } |
142 | module_exit(qi_lb60_exit); | 127 | |
128 | static struct platform_driver qi_lb60_driver = { | ||
129 | .driver = { | ||
130 | .name = "qi-lb60-audio", | ||
131 | .owner = THIS_MODULE, | ||
132 | }, | ||
133 | .probe = qi_lb60_probe, | ||
134 | .remove = __devexit_p(qi_lb60_remove), | ||
135 | }; | ||
136 | |||
137 | module_platform_driver(qi_lb60_driver); | ||
143 | 138 | ||
144 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | 139 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); |
145 | MODULE_DESCRIPTION("ALSA SoC QI LB60 Audio support"); | 140 | MODULE_DESCRIPTION("ALSA SoC QI LB60 Audio support"); |
146 | MODULE_LICENSE("GPL v2"); | 141 | MODULE_LICENSE("GPL v2"); |
142 | MODULE_ALIAS("platform:qi-lb60-audio"); | ||
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c index d03854027128..b9f16598324c 100644 --- a/sound/soc/kirkwood/kirkwood-dma.c +++ b/sound/soc/kirkwood/kirkwood-dma.c | |||
@@ -55,7 +55,7 @@ static struct snd_pcm_hardware kirkwood_dma_snd_hw = { | |||
55 | .fifo_size = 0, | 55 | .fifo_size = 0, |
56 | }; | 56 | }; |
57 | 57 | ||
58 | static u64 kirkwood_dma_dmamask = 0xFFFFFFFFUL; | 58 | static u64 kirkwood_dma_dmamask = DMA_BIT_MASK(32); |
59 | 59 | ||
60 | static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id) | 60 | static irqreturn_t kirkwood_dma_irq(int irq, void *dev_id) |
61 | { | 61 | { |
@@ -324,7 +324,7 @@ static int kirkwood_dma_new(struct snd_soc_pcm_runtime *rtd) | |||
324 | if (!card->dev->dma_mask) | 324 | if (!card->dev->dma_mask) |
325 | card->dev->dma_mask = &kirkwood_dma_dmamask; | 325 | card->dev->dma_mask = &kirkwood_dma_dmamask; |
326 | if (!card->dev->coherent_dma_mask) | 326 | if (!card->dev->coherent_dma_mask) |
327 | card->dev->coherent_dma_mask = 0xffffffff; | 327 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); |
328 | 328 | ||
329 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | 329 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { |
330 | ret = kirkwood_dma_preallocate_dma_buffer(pcm, | 330 | ret = kirkwood_dma_preallocate_dma_buffer(pcm, |
diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c index 55d2ed3df30d..80bd59c33be4 100644 --- a/sound/soc/kirkwood/kirkwood-openrd.c +++ b/sound/soc/kirkwood/kirkwood-openrd.c | |||
@@ -71,41 +71,41 @@ static struct snd_soc_card openrd_client = { | |||
71 | .num_links = ARRAY_SIZE(openrd_client_dai), | 71 | .num_links = ARRAY_SIZE(openrd_client_dai), |
72 | }; | 72 | }; |
73 | 73 | ||
74 | static struct platform_device *openrd_client_snd_device; | 74 | static int __devinit openrd_probe(struct platform_device *pdev) |
75 | |||
76 | static int __init openrd_client_init(void) | ||
77 | { | 75 | { |
76 | struct snd_soc_card *card = &openrd_client; | ||
78 | int ret; | 77 | int ret; |
79 | 78 | ||
80 | if (!machine_is_openrd_client() && !machine_is_openrd_ultimate()) | 79 | card->dev = &pdev->dev; |
81 | return 0; | ||
82 | |||
83 | openrd_client_snd_device = platform_device_alloc("soc-audio", -1); | ||
84 | if (!openrd_client_snd_device) | ||
85 | return -ENOMEM; | ||
86 | |||
87 | platform_set_drvdata(openrd_client_snd_device, | ||
88 | &openrd_client); | ||
89 | |||
90 | ret = platform_device_add(openrd_client_snd_device); | ||
91 | if (ret) { | ||
92 | printk(KERN_ERR "%s: platform_device_add failed\n", __func__); | ||
93 | platform_device_put(openrd_client_snd_device); | ||
94 | } | ||
95 | 80 | ||
81 | ret = snd_soc_register_card(card); | ||
82 | if (ret) | ||
83 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", | ||
84 | ret); | ||
96 | return ret; | 85 | return ret; |
97 | } | 86 | } |
98 | 87 | ||
99 | static void __exit openrd_client_exit(void) | 88 | static int __devexit openrd_remove(struct platform_device *pdev) |
100 | { | 89 | { |
101 | platform_device_unregister(openrd_client_snd_device); | 90 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
91 | |||
92 | snd_soc_unregister_card(card); | ||
93 | return 0; | ||
102 | } | 94 | } |
103 | 95 | ||
104 | module_init(openrd_client_init); | 96 | static struct platform_driver openrd_driver = { |
105 | module_exit(openrd_client_exit); | 97 | .driver = { |
98 | .name = "openrd-client-audio", | ||
99 | .owner = THIS_MODULE, | ||
100 | }, | ||
101 | .probe = openrd_probe, | ||
102 | .remove = __devexit_p(openrd_remove), | ||
103 | }; | ||
104 | |||
105 | module_platform_driver(openrd_driver); | ||
106 | 106 | ||
107 | /* Module information */ | 107 | /* Module information */ |
108 | MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); | 108 | MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); |
109 | MODULE_DESCRIPTION("ALSA SoC OpenRD Client"); | 109 | MODULE_DESCRIPTION("ALSA SoC OpenRD Client"); |
110 | MODULE_LICENSE("GPL"); | 110 | MODULE_LICENSE("GPL"); |
111 | MODULE_ALIAS("platform:soc-audio"); | 111 | MODULE_ALIAS("platform:openrd-client-audio"); |
diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c index b47cc4e9b746..f8983635f7ef 100644 --- a/sound/soc/kirkwood/kirkwood-t5325.c +++ b/sound/soc/kirkwood/kirkwood-t5325.c | |||
@@ -80,7 +80,6 @@ static struct snd_soc_dai_link t5325_dai[] = { | |||
80 | }, | 80 | }, |
81 | }; | 81 | }; |
82 | 82 | ||
83 | |||
84 | static struct snd_soc_card t5325 = { | 83 | static struct snd_soc_card t5325 = { |
85 | .name = "t5325", | 84 | .name = "t5325", |
86 | .owner = THIS_MODULE, | 85 | .owner = THIS_MODULE, |
@@ -93,38 +92,40 @@ static struct snd_soc_card t5325 = { | |||
93 | .num_dapm_routes = ARRAY_SIZE(t5325_route), | 92 | .num_dapm_routes = ARRAY_SIZE(t5325_route), |
94 | }; | 93 | }; |
95 | 94 | ||
96 | static struct platform_device *t5325_snd_device; | 95 | static int __devinit t5325_probe(struct platform_device *pdev) |
97 | |||
98 | static int __init t5325_init(void) | ||
99 | { | 96 | { |
97 | struct snd_soc_card *card = &t5325; | ||
100 | int ret; | 98 | int ret; |
101 | 99 | ||
102 | if (!machine_is_t5325()) | 100 | card->dev = &pdev->dev; |
103 | return 0; | ||
104 | |||
105 | t5325_snd_device = platform_device_alloc("soc-audio", -1); | ||
106 | if (!t5325_snd_device) | ||
107 | return -ENOMEM; | ||
108 | |||
109 | platform_set_drvdata(t5325_snd_device, | ||
110 | &t5325); | ||
111 | |||
112 | ret = platform_device_add(t5325_snd_device); | ||
113 | if (ret) { | ||
114 | printk(KERN_ERR "%s: platform_device_add failed\n", __func__); | ||
115 | platform_device_put(t5325_snd_device); | ||
116 | } | ||
117 | 101 | ||
102 | ret = snd_soc_register_card(card); | ||
103 | if (ret) | ||
104 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", | ||
105 | ret); | ||
118 | return ret; | 106 | return ret; |
119 | } | 107 | } |
120 | module_init(t5325_init); | ||
121 | 108 | ||
122 | static void __exit t5325_exit(void) | 109 | static int __devexit t5325_remove(struct platform_device *pdev) |
123 | { | 110 | { |
124 | platform_device_unregister(t5325_snd_device); | 111 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
112 | |||
113 | snd_soc_unregister_card(card); | ||
114 | return 0; | ||
125 | } | 115 | } |
126 | module_exit(t5325_exit); | 116 | |
117 | static struct platform_driver t5325_driver = { | ||
118 | .driver = { | ||
119 | .name = "t5325-audio", | ||
120 | .owner = THIS_MODULE, | ||
121 | }, | ||
122 | .probe = t5325_probe, | ||
123 | .remove = __devexit_p(t5325_remove), | ||
124 | }; | ||
125 | |||
126 | module_platform_driver(t5325_driver); | ||
127 | 127 | ||
128 | MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); | 128 | MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); |
129 | MODULE_DESCRIPTION("ALSA SoC t5325 audio client"); | 129 | MODULE_DESCRIPTION("ALSA SoC t5325 audio client"); |
130 | MODULE_LICENSE("GPL"); | 130 | MODULE_LICENSE("GPL"); |
131 | MODULE_ALIAS("platform:t5325-audio"); | ||
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c index 6f77eef0f131..2937e54da49e 100644 --- a/sound/soc/mid-x86/mfld_machine.c +++ b/sound/soc/mid-x86/mfld_machine.c | |||
@@ -235,7 +235,7 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime) | |||
235 | snd_soc_dapm_enable_pin(dapm, "Headphones"); | 235 | snd_soc_dapm_enable_pin(dapm, "Headphones"); |
236 | snd_soc_dapm_enable_pin(dapm, "Mic"); | 236 | snd_soc_dapm_enable_pin(dapm, "Mic"); |
237 | 237 | ||
238 | ret_val = snd_soc_add_controls(codec, mfld_snd_controls, | 238 | ret_val = snd_soc_add_codec_controls(codec, mfld_snd_controls, |
239 | ARRAY_SIZE(mfld_snd_controls)); | 239 | ARRAY_SIZE(mfld_snd_controls)); |
240 | if (ret_val) { | 240 | if (ret_val) { |
241 | pr_err("soc_add_controls failed %d", ret_val); | 241 | pr_err("soc_add_controls failed %d", ret_val); |
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig index e4ba8d5f25fa..99a997f19bb9 100644 --- a/sound/soc/mxs/Kconfig +++ b/sound/soc/mxs/Kconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | menuconfig SND_MXS_SOC | 1 | menuconfig SND_MXS_SOC |
2 | tristate "SoC Audio for Freescale MXS CPUs" | 2 | tristate "SoC Audio for Freescale MXS CPUs" |
3 | depends on ARCH_MXS | 3 | depends on ARCH_MXS |
4 | select SND_PCM | 4 | select SND_SOC_DMAENGINE_PCM |
5 | help | 5 | help |
6 | Say Y or M if you want to add support for codecs attached to | 6 | Say Y or M if you want to add support for codecs attached to |
7 | the MXS SAIF interface. | 7 | the MXS SAIF interface. |
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c index 105f42a394df..6ca1f46d84a4 100644 --- a/sound/soc/mxs/mxs-pcm.c +++ b/sound/soc/mxs/mxs-pcm.c | |||
@@ -34,10 +34,16 @@ | |||
34 | #include <sound/pcm.h> | 34 | #include <sound/pcm.h> |
35 | #include <sound/pcm_params.h> | 35 | #include <sound/pcm_params.h> |
36 | #include <sound/soc.h> | 36 | #include <sound/soc.h> |
37 | #include <sound/dmaengine_pcm.h> | ||
37 | 38 | ||
38 | #include <mach/dma.h> | 39 | #include <mach/dma.h> |
39 | #include "mxs-pcm.h" | 40 | #include "mxs-pcm.h" |
40 | 41 | ||
42 | struct mxs_pcm_dma_data { | ||
43 | struct mxs_dma_data dma_data; | ||
44 | struct mxs_pcm_dma_params *dma_params; | ||
45 | }; | ||
46 | |||
41 | static struct snd_pcm_hardware snd_mxs_hardware = { | 47 | static struct snd_pcm_hardware snd_mxs_hardware = { |
42 | .info = SNDRV_PCM_INFO_MMAP | | 48 | .info = SNDRV_PCM_INFO_MMAP | |
43 | SNDRV_PCM_INFO_MMAP_VALID | | 49 | SNDRV_PCM_INFO_MMAP_VALID | |
@@ -58,21 +64,10 @@ static struct snd_pcm_hardware snd_mxs_hardware = { | |||
58 | 64 | ||
59 | }; | 65 | }; |
60 | 66 | ||
61 | static void audio_dma_irq(void *data) | ||
62 | { | ||
63 | struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data; | ||
64 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
65 | struct mxs_pcm_runtime_data *iprtd = runtime->private_data; | ||
66 | |||
67 | iprtd->offset += iprtd->period_bytes; | ||
68 | iprtd->offset %= iprtd->period_bytes * iprtd->periods; | ||
69 | snd_pcm_period_elapsed(substream); | ||
70 | } | ||
71 | |||
72 | static bool filter(struct dma_chan *chan, void *param) | 67 | static bool filter(struct dma_chan *chan, void *param) |
73 | { | 68 | { |
74 | struct mxs_pcm_runtime_data *iprtd = param; | 69 | struct mxs_pcm_dma_data *pcm_dma_data = param; |
75 | struct mxs_pcm_dma_params *dma_params = iprtd->dma_params; | 70 | struct mxs_pcm_dma_params *dma_params = pcm_dma_data->dma_params; |
76 | 71 | ||
77 | if (!mxs_dma_is_apbx(chan)) | 72 | if (!mxs_dma_is_apbx(chan)) |
78 | return false; | 73 | return false; |
@@ -80,150 +75,51 @@ static bool filter(struct dma_chan *chan, void *param) | |||
80 | if (chan->chan_id != dma_params->chan_num) | 75 | if (chan->chan_id != dma_params->chan_num) |
81 | return false; | 76 | return false; |
82 | 77 | ||
83 | chan->private = &iprtd->dma_data; | 78 | chan->private = &pcm_dma_data->dma_data; |
84 | 79 | ||
85 | return true; | 80 | return true; |
86 | } | 81 | } |
87 | 82 | ||
88 | static int mxs_dma_alloc(struct snd_pcm_substream *substream, | ||
89 | struct snd_pcm_hw_params *params) | ||
90 | { | ||
91 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
92 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
93 | struct mxs_pcm_runtime_data *iprtd = runtime->private_data; | ||
94 | dma_cap_mask_t mask; | ||
95 | |||
96 | iprtd->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
97 | |||
98 | dma_cap_zero(mask); | ||
99 | dma_cap_set(DMA_SLAVE, mask); | ||
100 | iprtd->dma_data.chan_irq = iprtd->dma_params->chan_irq; | ||
101 | iprtd->dma_chan = dma_request_channel(mask, filter, iprtd); | ||
102 | if (!iprtd->dma_chan) | ||
103 | return -EINVAL; | ||
104 | |||
105 | return 0; | ||
106 | } | ||
107 | |||
108 | static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream, | 83 | static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream, |
109 | struct snd_pcm_hw_params *params) | 84 | struct snd_pcm_hw_params *params) |
110 | { | 85 | { |
111 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
112 | struct mxs_pcm_runtime_data *iprtd = runtime->private_data; | ||
113 | unsigned long dma_addr; | ||
114 | struct dma_chan *chan; | ||
115 | int ret; | ||
116 | |||
117 | ret = mxs_dma_alloc(substream, params); | ||
118 | if (ret) | ||
119 | return ret; | ||
120 | chan = iprtd->dma_chan; | ||
121 | |||
122 | iprtd->size = params_buffer_bytes(params); | ||
123 | iprtd->periods = params_periods(params); | ||
124 | iprtd->period_bytes = params_period_bytes(params); | ||
125 | iprtd->offset = 0; | ||
126 | iprtd->period_time = HZ / (params_rate(params) / | ||
127 | params_period_size(params)); | ||
128 | |||
129 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 86 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); |
130 | 87 | ||
131 | dma_addr = runtime->dma_addr; | ||
132 | |||
133 | iprtd->buf = substream->dma_buffer.area; | ||
134 | |||
135 | iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr, | ||
136 | iprtd->period_bytes * iprtd->periods, | ||
137 | iprtd->period_bytes, | ||
138 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? | ||
139 | DMA_MEM_TO_DEV : DMA_DEV_TO_MEM); | ||
140 | if (!iprtd->desc) { | ||
141 | dev_err(&chan->dev->device, "cannot prepare slave dma\n"); | ||
142 | return -EINVAL; | ||
143 | } | ||
144 | |||
145 | iprtd->desc->callback = audio_dma_irq; | ||
146 | iprtd->desc->callback_param = substream; | ||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static int snd_mxs_pcm_hw_free(struct snd_pcm_substream *substream) | ||
152 | { | ||
153 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
154 | struct mxs_pcm_runtime_data *iprtd = runtime->private_data; | ||
155 | |||
156 | if (iprtd->dma_chan) { | ||
157 | dma_release_channel(iprtd->dma_chan); | ||
158 | iprtd->dma_chan = NULL; | ||
159 | } | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static int snd_mxs_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
165 | { | ||
166 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
167 | struct mxs_pcm_runtime_data *iprtd = runtime->private_data; | ||
168 | |||
169 | switch (cmd) { | ||
170 | case SNDRV_PCM_TRIGGER_START: | ||
171 | case SNDRV_PCM_TRIGGER_RESUME: | ||
172 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
173 | dmaengine_submit(iprtd->desc); | ||
174 | |||
175 | break; | ||
176 | case SNDRV_PCM_TRIGGER_STOP: | ||
177 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
178 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
179 | dmaengine_terminate_all(iprtd->dma_chan); | ||
180 | |||
181 | break; | ||
182 | default: | ||
183 | return -EINVAL; | ||
184 | } | ||
185 | |||
186 | return 0; | 88 | return 0; |
187 | } | 89 | } |
188 | 90 | ||
189 | static snd_pcm_uframes_t snd_mxs_pcm_pointer( | ||
190 | struct snd_pcm_substream *substream) | ||
191 | { | ||
192 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
193 | struct mxs_pcm_runtime_data *iprtd = runtime->private_data; | ||
194 | |||
195 | return bytes_to_frames(substream->runtime, iprtd->offset); | ||
196 | } | ||
197 | |||
198 | static int snd_mxs_open(struct snd_pcm_substream *substream) | 91 | static int snd_mxs_open(struct snd_pcm_substream *substream) |
199 | { | 92 | { |
200 | struct snd_pcm_runtime *runtime = substream->runtime; | 93 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
201 | struct mxs_pcm_runtime_data *iprtd; | 94 | struct mxs_pcm_dma_data *pcm_dma_data; |
202 | int ret; | 95 | int ret; |
203 | 96 | ||
204 | iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); | 97 | pcm_dma_data = kzalloc(sizeof(*pcm_dma_data), GFP_KERNEL); |
205 | if (iprtd == NULL) | 98 | if (pcm_dma_data == NULL) |
206 | return -ENOMEM; | 99 | return -ENOMEM; |
207 | runtime->private_data = iprtd; | ||
208 | 100 | ||
209 | ret = snd_pcm_hw_constraint_integer(substream->runtime, | 101 | pcm_dma_data->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
210 | SNDRV_PCM_HW_PARAM_PERIODS); | 102 | pcm_dma_data->dma_data.chan_irq = pcm_dma_data->dma_params->chan_irq; |
211 | if (ret < 0) { | 103 | |
212 | kfree(iprtd); | 104 | ret = snd_dmaengine_pcm_open(substream, filter, pcm_dma_data); |
105 | if (ret) { | ||
106 | kfree(pcm_dma_data); | ||
213 | return ret; | 107 | return ret; |
214 | } | 108 | } |
215 | 109 | ||
216 | snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware); | 110 | snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware); |
217 | 111 | ||
112 | snd_dmaengine_pcm_set_data(substream, pcm_dma_data); | ||
113 | |||
218 | return 0; | 114 | return 0; |
219 | } | 115 | } |
220 | 116 | ||
221 | static int snd_mxs_close(struct snd_pcm_substream *substream) | 117 | static int snd_mxs_close(struct snd_pcm_substream *substream) |
222 | { | 118 | { |
223 | struct snd_pcm_runtime *runtime = substream->runtime; | 119 | struct mxs_pcm_dma_data *pcm_dma_data = snd_dmaengine_pcm_get_data(substream); |
224 | struct mxs_pcm_runtime_data *iprtd = runtime->private_data; | ||
225 | 120 | ||
226 | kfree(iprtd); | 121 | snd_dmaengine_pcm_close(substream); |
122 | kfree(pcm_dma_data); | ||
227 | 123 | ||
228 | return 0; | 124 | return 0; |
229 | } | 125 | } |
@@ -244,9 +140,8 @@ static struct snd_pcm_ops mxs_pcm_ops = { | |||
244 | .close = snd_mxs_close, | 140 | .close = snd_mxs_close, |
245 | .ioctl = snd_pcm_lib_ioctl, | 141 | .ioctl = snd_pcm_lib_ioctl, |
246 | .hw_params = snd_mxs_pcm_hw_params, | 142 | .hw_params = snd_mxs_pcm_hw_params, |
247 | .hw_free = snd_mxs_pcm_hw_free, | 143 | .trigger = snd_dmaengine_pcm_trigger, |
248 | .trigger = snd_mxs_pcm_trigger, | 144 | .pointer = snd_dmaengine_pcm_pointer, |
249 | .pointer = snd_mxs_pcm_pointer, | ||
250 | .mmap = snd_mxs_pcm_mmap, | 145 | .mmap = snd_mxs_pcm_mmap, |
251 | }; | 146 | }; |
252 | 147 | ||
diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h index f55ac4f7a76a..5f01a9124b3d 100644 --- a/sound/soc/mxs/mxs-pcm.h +++ b/sound/soc/mxs/mxs-pcm.h | |||
@@ -19,25 +19,9 @@ | |||
19 | #ifndef _MXS_PCM_H | 19 | #ifndef _MXS_PCM_H |
20 | #define _MXS_PCM_H | 20 | #define _MXS_PCM_H |
21 | 21 | ||
22 | #include <mach/dma.h> | ||
23 | |||
24 | struct mxs_pcm_dma_params { | 22 | struct mxs_pcm_dma_params { |
25 | int chan_irq; | 23 | int chan_irq; |
26 | int chan_num; | 24 | int chan_num; |
27 | }; | 25 | }; |
28 | 26 | ||
29 | struct mxs_pcm_runtime_data { | ||
30 | int period_bytes; | ||
31 | int periods; | ||
32 | int dma; | ||
33 | unsigned long offset; | ||
34 | unsigned long size; | ||
35 | void *buf; | ||
36 | int period_time; | ||
37 | struct dma_async_tx_descriptor *desc; | ||
38 | struct dma_chan *dma_chan; | ||
39 | struct mxs_dma_data dma_data; | ||
40 | struct mxs_pcm_dma_params *dma_params; | ||
41 | }; | ||
42 | |||
43 | #endif | 27 | #endif |
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index dccfb37a9626..12be05b16880 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c | |||
@@ -124,6 +124,8 @@ static int mxs_saif_set_clk(struct mxs_saif *saif, | |||
124 | * | 124 | * |
125 | * If MCLK is not used, we just set saif clk to 512*fs. | 125 | * If MCLK is not used, we just set saif clk to 512*fs. |
126 | */ | 126 | */ |
127 | clk_prepare_enable(master_saif->clk); | ||
128 | |||
127 | if (master_saif->mclk_in_use) { | 129 | if (master_saif->mclk_in_use) { |
128 | if (mclk % 32 == 0) { | 130 | if (mclk % 32 == 0) { |
129 | scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; | 131 | scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; |
@@ -133,6 +135,7 @@ static int mxs_saif_set_clk(struct mxs_saif *saif, | |||
133 | ret = clk_set_rate(master_saif->clk, 384 * rate); | 135 | ret = clk_set_rate(master_saif->clk, 384 * rate); |
134 | } else { | 136 | } else { |
135 | /* SAIF MCLK should be either 32x or 48x */ | 137 | /* SAIF MCLK should be either 32x or 48x */ |
138 | clk_disable_unprepare(master_saif->clk); | ||
136 | return -EINVAL; | 139 | return -EINVAL; |
137 | } | 140 | } |
138 | } else { | 141 | } else { |
@@ -140,6 +143,8 @@ static int mxs_saif_set_clk(struct mxs_saif *saif, | |||
140 | scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; | 143 | scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; |
141 | } | 144 | } |
142 | 145 | ||
146 | clk_disable_unprepare(master_saif->clk); | ||
147 | |||
143 | if (ret) | 148 | if (ret) |
144 | return ret; | 149 | return ret; |
145 | 150 | ||
@@ -625,7 +630,7 @@ static int mxs_saif_probe(struct platform_device *pdev) | |||
625 | if (pdev->id >= ARRAY_SIZE(mxs_saif)) | 630 | if (pdev->id >= ARRAY_SIZE(mxs_saif)) |
626 | return -EINVAL; | 631 | return -EINVAL; |
627 | 632 | ||
628 | saif = kzalloc(sizeof(*saif), GFP_KERNEL); | 633 | saif = devm_kzalloc(&pdev->dev, sizeof(*saif), GFP_KERNEL); |
629 | if (!saif) | 634 | if (!saif) |
630 | return -ENOMEM; | 635 | return -ENOMEM; |
631 | 636 | ||
@@ -650,29 +655,16 @@ static int mxs_saif_probe(struct platform_device *pdev) | |||
650 | ret = PTR_ERR(saif->clk); | 655 | ret = PTR_ERR(saif->clk); |
651 | dev_err(&pdev->dev, "Cannot get the clock: %d\n", | 656 | dev_err(&pdev->dev, "Cannot get the clock: %d\n", |
652 | ret); | 657 | ret); |
653 | goto failed_clk; | 658 | return ret; |
654 | } | 659 | } |
655 | 660 | ||
656 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 661 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
657 | if (!iores) { | ||
658 | ret = -ENODEV; | ||
659 | dev_err(&pdev->dev, "failed to get io resource: %d\n", | ||
660 | ret); | ||
661 | goto failed_get_resource; | ||
662 | } | ||
663 | |||
664 | if (!request_mem_region(iores->start, resource_size(iores), | ||
665 | "mxs-saif")) { | ||
666 | dev_err(&pdev->dev, "request_mem_region failed\n"); | ||
667 | ret = -EBUSY; | ||
668 | goto failed_get_resource; | ||
669 | } | ||
670 | 662 | ||
671 | saif->base = ioremap(iores->start, resource_size(iores)); | 663 | saif->base = devm_request_and_ioremap(&pdev->dev, iores); |
672 | if (!saif->base) { | 664 | if (!saif->base) { |
673 | dev_err(&pdev->dev, "ioremap failed\n"); | 665 | dev_err(&pdev->dev, "ioremap failed\n"); |
674 | ret = -ENODEV; | 666 | ret = -ENODEV; |
675 | goto failed_ioremap; | 667 | goto failed_get_resource; |
676 | } | 668 | } |
677 | 669 | ||
678 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 670 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); |
@@ -680,7 +672,7 @@ static int mxs_saif_probe(struct platform_device *pdev) | |||
680 | ret = -ENODEV; | 672 | ret = -ENODEV; |
681 | dev_err(&pdev->dev, "failed to get dma resource: %d\n", | 673 | dev_err(&pdev->dev, "failed to get dma resource: %d\n", |
682 | ret); | 674 | ret); |
683 | goto failed_ioremap; | 675 | goto failed_get_resource; |
684 | } | 676 | } |
685 | saif->dma_param.chan_num = dmares->start; | 677 | saif->dma_param.chan_num = dmares->start; |
686 | 678 | ||
@@ -689,14 +681,15 @@ static int mxs_saif_probe(struct platform_device *pdev) | |||
689 | ret = saif->irq; | 681 | ret = saif->irq; |
690 | dev_err(&pdev->dev, "failed to get irq resource: %d\n", | 682 | dev_err(&pdev->dev, "failed to get irq resource: %d\n", |
691 | ret); | 683 | ret); |
692 | goto failed_get_irq1; | 684 | goto failed_get_resource; |
693 | } | 685 | } |
694 | 686 | ||
695 | saif->dev = &pdev->dev; | 687 | saif->dev = &pdev->dev; |
696 | ret = request_irq(saif->irq, mxs_saif_irq, 0, "mxs-saif", saif); | 688 | ret = devm_request_irq(&pdev->dev, saif->irq, mxs_saif_irq, 0, |
689 | "mxs-saif", saif); | ||
697 | if (ret) { | 690 | if (ret) { |
698 | dev_err(&pdev->dev, "failed to request irq\n"); | 691 | dev_err(&pdev->dev, "failed to request irq\n"); |
699 | goto failed_get_irq1; | 692 | goto failed_get_resource; |
700 | } | 693 | } |
701 | 694 | ||
702 | saif->dma_param.chan_irq = platform_get_irq(pdev, 1); | 695 | saif->dma_param.chan_irq = platform_get_irq(pdev, 1); |
@@ -704,7 +697,7 @@ static int mxs_saif_probe(struct platform_device *pdev) | |||
704 | ret = saif->dma_param.chan_irq; | 697 | ret = saif->dma_param.chan_irq; |
705 | dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", | 698 | dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", |
706 | ret); | 699 | ret); |
707 | goto failed_get_irq2; | 700 | goto failed_get_resource; |
708 | } | 701 | } |
709 | 702 | ||
710 | platform_set_drvdata(pdev, saif); | 703 | platform_set_drvdata(pdev, saif); |
@@ -712,7 +705,7 @@ static int mxs_saif_probe(struct platform_device *pdev) | |||
712 | ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai); | 705 | ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai); |
713 | if (ret) { | 706 | if (ret) { |
714 | dev_err(&pdev->dev, "register DAI failed\n"); | 707 | dev_err(&pdev->dev, "register DAI failed\n"); |
715 | goto failed_register; | 708 | goto failed_get_resource; |
716 | } | 709 | } |
717 | 710 | ||
718 | saif->soc_platform_pdev = platform_device_alloc( | 711 | saif->soc_platform_pdev = platform_device_alloc( |
@@ -735,36 +728,19 @@ failed_pdev_add: | |||
735 | platform_device_put(saif->soc_platform_pdev); | 728 | platform_device_put(saif->soc_platform_pdev); |
736 | failed_pdev_alloc: | 729 | failed_pdev_alloc: |
737 | snd_soc_unregister_dai(&pdev->dev); | 730 | snd_soc_unregister_dai(&pdev->dev); |
738 | failed_register: | ||
739 | failed_get_irq2: | ||
740 | free_irq(saif->irq, saif); | ||
741 | failed_get_irq1: | ||
742 | iounmap(saif->base); | ||
743 | failed_ioremap: | ||
744 | release_mem_region(iores->start, resource_size(iores)); | ||
745 | failed_get_resource: | 731 | failed_get_resource: |
746 | clk_put(saif->clk); | 732 | clk_put(saif->clk); |
747 | failed_clk: | ||
748 | kfree(saif); | ||
749 | 733 | ||
750 | return ret; | 734 | return ret; |
751 | } | 735 | } |
752 | 736 | ||
753 | static int __devexit mxs_saif_remove(struct platform_device *pdev) | 737 | static int __devexit mxs_saif_remove(struct platform_device *pdev) |
754 | { | 738 | { |
755 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
756 | struct mxs_saif *saif = platform_get_drvdata(pdev); | 739 | struct mxs_saif *saif = platform_get_drvdata(pdev); |
757 | 740 | ||
758 | platform_device_unregister(saif->soc_platform_pdev); | 741 | platform_device_unregister(saif->soc_platform_pdev); |
759 | |||
760 | snd_soc_unregister_dai(&pdev->dev); | 742 | snd_soc_unregister_dai(&pdev->dev); |
761 | |||
762 | iounmap(saif->base); | ||
763 | release_mem_region(res->start, resource_size(res)); | ||
764 | free_irq(saif->irq, saif); | ||
765 | |||
766 | clk_put(saif->clk); | 743 | clk_put(saif->clk); |
767 | kfree(saif); | ||
768 | 744 | ||
769 | return 0; | 745 | return 0; |
770 | } | 746 | } |
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index fb1bf2581efb..e00dd0b1139c 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig | |||
@@ -7,7 +7,6 @@ config SND_OMAP_SOC_DMIC | |||
7 | 7 | ||
8 | config SND_OMAP_SOC_MCBSP | 8 | config SND_OMAP_SOC_MCBSP |
9 | tristate | 9 | tristate |
10 | select OMAP_MCBSP | ||
11 | 10 | ||
12 | config SND_OMAP_SOC_MCPDM | 11 | config SND_OMAP_SOC_MCPDM |
13 | tristate | 12 | tristate |
@@ -27,7 +26,6 @@ config SND_OMAP_SOC_N810 | |||
27 | config SND_OMAP_SOC_RX51 | 26 | config SND_OMAP_SOC_RX51 |
28 | tristate "SoC Audio support for Nokia RX-51" | 27 | tristate "SoC Audio support for Nokia RX-51" |
29 | depends on SND_OMAP_SOC && MACH_NOKIA_RX51 | 28 | depends on SND_OMAP_SOC && MACH_NOKIA_RX51 |
30 | select OMAP_MCBSP | ||
31 | select SND_OMAP_SOC_MCBSP | 29 | select SND_OMAP_SOC_MCBSP |
32 | select SND_SOC_TLV320AIC3X | 30 | select SND_SOC_TLV320AIC3X |
33 | select SND_SOC_TPA6130A2 | 31 | select SND_SOC_TPA6130A2 |
@@ -97,16 +95,19 @@ config SND_OMAP_SOC_SDP3430 | |||
97 | Say Y if you want to add support for SoC audio on Texas Instruments | 95 | Say Y if you want to add support for SoC audio on Texas Instruments |
98 | SDP3430. | 96 | SDP3430. |
99 | 97 | ||
100 | config SND_OMAP_SOC_SDP4430 | 98 | config SND_OMAP_SOC_OMAP_ABE_TWL6040 |
101 | tristate "SoC Audio support for Texas Instruments SDP4430" | 99 | tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" |
102 | depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_4430SDP | 100 | depends on TWL4030_CORE && SND_OMAP_SOC && ARCH_OMAP4 |
103 | select SND_OMAP_SOC_DMIC | 101 | select SND_OMAP_SOC_DMIC |
104 | select SND_OMAP_SOC_MCPDM | 102 | select SND_OMAP_SOC_MCPDM |
105 | select SND_SOC_TWL6040 | 103 | select SND_SOC_TWL6040 |
106 | select SND_SOC_DMIC | 104 | select SND_SOC_DMIC |
107 | help | 105 | help |
108 | Say Y if you want to add support for SoC audio on Texas Instruments | 106 | Say Y if you want to add support for SoC audio on OMAP boards using |
109 | SDP4430. | 107 | ABE and twl6040 codec. This driver currently supports: |
108 | - SDP4430/Blaze boards | ||
109 | - PandaBoard (4430) | ||
110 | - PandaBoardES (4460) | ||
110 | 111 | ||
111 | config SND_OMAP_SOC_OMAP4_HDMI | 112 | config SND_OMAP_SOC_OMAP4_HDMI |
112 | tristate "SoC Audio support for Texas Instruments OMAP4 HDMI" | 113 | tristate "SoC Audio support for Texas Instruments OMAP4 HDMI" |
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile index 1fd723fb559d..1d656bce01d4 100644 --- a/sound/soc/omap/Makefile +++ b/sound/soc/omap/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | # OMAP Platform Support | 1 | # OMAP Platform Support |
2 | snd-soc-omap-objs := omap-pcm.o | 2 | snd-soc-omap-objs := omap-pcm.o |
3 | snd-soc-omap-dmic-objs := omap-dmic.o | 3 | snd-soc-omap-dmic-objs := omap-dmic.o |
4 | snd-soc-omap-mcbsp-objs := omap-mcbsp.o | 4 | snd-soc-omap-mcbsp-objs := omap-mcbsp.o mcbsp.o |
5 | snd-soc-omap-mcpdm-objs := omap-mcpdm.o | 5 | snd-soc-omap-mcpdm-objs := omap-mcpdm.o |
6 | snd-soc-omap-hdmi-objs := omap-hdmi.o | 6 | snd-soc-omap-hdmi-objs := omap-hdmi.o |
7 | 7 | ||
@@ -20,7 +20,7 @@ snd-soc-overo-objs := overo.o | |||
20 | snd-soc-omap3evm-objs := omap3evm.o | 20 | snd-soc-omap3evm-objs := omap3evm.o |
21 | snd-soc-am3517evm-objs := am3517evm.o | 21 | snd-soc-am3517evm-objs := am3517evm.o |
22 | snd-soc-sdp3430-objs := sdp3430.o | 22 | snd-soc-sdp3430-objs := sdp3430.o |
23 | snd-soc-sdp4430-objs := sdp4430.o | 23 | snd-soc-omap-abe-twl6040-objs := omap-abe-twl6040.o |
24 | snd-soc-omap3pandora-objs := omap3pandora.o | 24 | snd-soc-omap3pandora-objs := omap3pandora.o |
25 | snd-soc-omap3beagle-objs := omap3beagle.o | 25 | snd-soc-omap3beagle-objs := omap3beagle.o |
26 | snd-soc-zoom2-objs := zoom2.o | 26 | snd-soc-zoom2-objs := zoom2.o |
@@ -36,7 +36,7 @@ obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o | |||
36 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o | 36 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o |
37 | obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o | 37 | obj-$(CONFIG_SND_OMAP_SOC_AM3517EVM) += snd-soc-am3517evm.o |
38 | obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o | 38 | obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o |
39 | obj-$(CONFIG_SND_OMAP_SOC_SDP4430) += snd-soc-sdp4430.o | 39 | obj-$(CONFIG_SND_OMAP_SOC_OMAP_ABE_TWL6040) += snd-soc-omap-abe-twl6040.o |
40 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o | 40 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o |
41 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o | 41 | obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o |
42 | obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o | 42 | obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o |
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c index add4866d7e67..009533ab8d18 100644 --- a/sound/soc/omap/am3517evm.c +++ b/sound/soc/omap/am3517evm.c | |||
@@ -95,7 +95,7 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
95 | static struct snd_soc_dai_link am3517evm_dai = { | 95 | static struct snd_soc_dai_link am3517evm_dai = { |
96 | .name = "TLV320AIC23", | 96 | .name = "TLV320AIC23", |
97 | .stream_name = "AIC23", | 97 | .stream_name = "AIC23", |
98 | .cpu_dai_name ="omap-mcbsp-dai.0", | 98 | .cpu_dai_name = "omap-mcbsp.1", |
99 | .codec_dai_name = "tlv320aic23-hifi", | 99 | .codec_dai_name = "tlv320aic23-hifi", |
100 | .platform_name = "omap-pcm-audio", | 100 | .platform_name = "omap-pcm-audio", |
101 | .codec_name = "tlv320aic23-codec.2-001a", | 101 | .codec_name = "tlv320aic23-codec.2-001a", |
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index a67f4370bc9f..7d4fa8ed6699 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c | |||
@@ -426,29 +426,6 @@ static struct snd_soc_ops ams_delta_ops = { | |||
426 | }; | 426 | }; |
427 | 427 | ||
428 | 428 | ||
429 | /* Board specific codec bias level control */ | ||
430 | static int ams_delta_set_bias_level(struct snd_soc_card *card, | ||
431 | struct snd_soc_dapm_context *dapm, | ||
432 | enum snd_soc_bias_level level) | ||
433 | { | ||
434 | switch (level) { | ||
435 | case SND_SOC_BIAS_ON: | ||
436 | case SND_SOC_BIAS_PREPARE: | ||
437 | case SND_SOC_BIAS_STANDBY: | ||
438 | if (card->dapm.bias_level == SND_SOC_BIAS_OFF) | ||
439 | ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET, | ||
440 | AMS_DELTA_LATCH2_MODEM_NRESET); | ||
441 | break; | ||
442 | case SND_SOC_BIAS_OFF: | ||
443 | if (card->dapm.bias_level != SND_SOC_BIAS_OFF) | ||
444 | ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET, | ||
445 | 0); | ||
446 | } | ||
447 | card->dapm.bias_level = level; | ||
448 | |||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | /* Digital mute implemented using modem/CPU multiplexer. | 429 | /* Digital mute implemented using modem/CPU multiplexer. |
453 | * Shares hardware with codec config pulse generation */ | 430 | * Shares hardware with codec config pulse generation */ |
454 | static bool ams_delta_muted = 1; | 431 | static bool ams_delta_muted = 1; |
@@ -512,9 +489,6 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) | |||
512 | ams_delta_ops.shutdown = ams_delta_shutdown; | 489 | ams_delta_ops.shutdown = ams_delta_shutdown; |
513 | } | 490 | } |
514 | 491 | ||
515 | /* Set codec bias level */ | ||
516 | ams_delta_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY); | ||
517 | |||
518 | /* Add hook switch - can be used to control the codec from userspace | 492 | /* Add hook switch - can be used to control the codec from userspace |
519 | * even if line discipline fails */ | 493 | * even if line discipline fails */ |
520 | ret = snd_soc_jack_new(rtd->codec, "hook_switch", | 494 | ret = snd_soc_jack_new(rtd->codec, "hook_switch", |
@@ -570,7 +544,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) | |||
570 | snd_soc_dapm_disable_pin(dapm, "AGCOUT"); | 544 | snd_soc_dapm_disable_pin(dapm, "AGCOUT"); |
571 | 545 | ||
572 | /* Add virtual switch */ | 546 | /* Add virtual switch */ |
573 | ret = snd_soc_add_controls(codec, ams_delta_audio_controls, | 547 | ret = snd_soc_add_codec_controls(codec, ams_delta_audio_controls, |
574 | ARRAY_SIZE(ams_delta_audio_controls)); | 548 | ARRAY_SIZE(ams_delta_audio_controls)); |
575 | if (ret) | 549 | if (ret) |
576 | dev_warn(card->dev, | 550 | dev_warn(card->dev, |
@@ -584,7 +558,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) | |||
584 | static struct snd_soc_dai_link ams_delta_dai_link = { | 558 | static struct snd_soc_dai_link ams_delta_dai_link = { |
585 | .name = "CX20442", | 559 | .name = "CX20442", |
586 | .stream_name = "CX20442", | 560 | .stream_name = "CX20442", |
587 | .cpu_dai_name ="omap-mcbsp-dai.0", | 561 | .cpu_dai_name = "omap-mcbsp.1", |
588 | .codec_dai_name = "cx20442-voice", | 562 | .codec_dai_name = "cx20442-voice", |
589 | .init = ams_delta_cx20442_init, | 563 | .init = ams_delta_cx20442_init, |
590 | .platform_name = "omap-pcm-audio", | 564 | .platform_name = "omap-pcm-audio", |
@@ -598,7 +572,6 @@ static struct snd_soc_card ams_delta_audio_card = { | |||
598 | .owner = THIS_MODULE, | 572 | .owner = THIS_MODULE, |
599 | .dai_link = &ams_delta_dai_link, | 573 | .dai_link = &ams_delta_dai_link, |
600 | .num_links = 1, | 574 | .num_links = 1, |
601 | .set_bias_level = ams_delta_set_bias_level, | ||
602 | }; | 575 | }; |
603 | 576 | ||
604 | /* Module init/exit */ | 577 | /* Module init/exit */ |
@@ -635,7 +608,7 @@ err: | |||
635 | platform_device_put(ams_delta_audio_platform_device); | 608 | platform_device_put(ams_delta_audio_platform_device); |
636 | return ret; | 609 | return ret; |
637 | } | 610 | } |
638 | module_init(ams_delta_module_init); | 611 | late_initcall(ams_delta_module_init); |
639 | 612 | ||
640 | static void __exit ams_delta_module_exit(void) | 613 | static void __exit ams_delta_module_exit(void) |
641 | { | 614 | { |
@@ -647,11 +620,6 @@ static void __exit ams_delta_module_exit(void) | |||
647 | ARRAY_SIZE(ams_delta_hook_switch_gpios), | 620 | ARRAY_SIZE(ams_delta_hook_switch_gpios), |
648 | ams_delta_hook_switch_gpios); | 621 | ams_delta_hook_switch_gpios); |
649 | 622 | ||
650 | /* Keep modem power on */ | ||
651 | ams_delta_set_bias_level(&ams_delta_audio_card, | ||
652 | &ams_delta_audio_card.rtd[0].codec->dapm, | ||
653 | SND_SOC_BIAS_STANDBY); | ||
654 | |||
655 | platform_device_unregister(cx20442_platform_device); | 623 | platform_device_unregister(cx20442_platform_device); |
656 | platform_device_unregister(ams_delta_audio_platform_device); | 624 | platform_device_unregister(ams_delta_audio_platform_device); |
657 | } | 625 | } |
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c index ccae58a1339c..e8357819175b 100644 --- a/sound/soc/omap/igep0020.c +++ b/sound/soc/omap/igep0020.c | |||
@@ -60,7 +60,7 @@ static struct snd_soc_ops igep2_ops = { | |||
60 | static struct snd_soc_dai_link igep2_dai = { | 60 | static struct snd_soc_dai_link igep2_dai = { |
61 | .name = "TWL4030", | 61 | .name = "TWL4030", |
62 | .stream_name = "TWL4030", | 62 | .stream_name = "TWL4030", |
63 | .cpu_dai_name = "omap-mcbsp-dai.1", | 63 | .cpu_dai_name = "omap-mcbsp.2", |
64 | .codec_dai_name = "twl4030-hifi", | 64 | .codec_dai_name = "twl4030-hifi", |
65 | .platform_name = "omap-pcm-audio", | 65 | .platform_name = "omap-pcm-audio", |
66 | .codec_name = "twl4030-codec", | 66 | .codec_name = "twl4030-codec", |
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c new file mode 100644 index 000000000000..e5f44440d1b9 --- /dev/null +++ b/sound/soc/omap/mcbsp.c | |||
@@ -0,0 +1,1040 @@ | |||
1 | /* | ||
2 | * sound/soc/omap/mcbsp.c | ||
3 | * | ||
4 | * Copyright (C) 2004 Nokia Corporation | ||
5 | * Author: Samuel Ortiz <samuel.ortiz@nokia.com> | ||
6 | * | ||
7 | * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com> | ||
8 | * Peter Ujfalusi <peter.ujfalusi@ti.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * Multichannel mode not supported. | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/device.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/err.h> | ||
23 | #include <linux/clk.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/slab.h> | ||
27 | |||
28 | #include <plat/mcbsp.h> | ||
29 | |||
30 | #include "mcbsp.h" | ||
31 | |||
32 | static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val) | ||
33 | { | ||
34 | void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step; | ||
35 | |||
36 | if (mcbsp->pdata->reg_size == 2) { | ||
37 | ((u16 *)mcbsp->reg_cache)[reg] = (u16)val; | ||
38 | __raw_writew((u16)val, addr); | ||
39 | } else { | ||
40 | ((u32 *)mcbsp->reg_cache)[reg] = val; | ||
41 | __raw_writel(val, addr); | ||
42 | } | ||
43 | } | ||
44 | |||
45 | static int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache) | ||
46 | { | ||
47 | void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step; | ||
48 | |||
49 | if (mcbsp->pdata->reg_size == 2) { | ||
50 | return !from_cache ? __raw_readw(addr) : | ||
51 | ((u16 *)mcbsp->reg_cache)[reg]; | ||
52 | } else { | ||
53 | return !from_cache ? __raw_readl(addr) : | ||
54 | ((u32 *)mcbsp->reg_cache)[reg]; | ||
55 | } | ||
56 | } | ||
57 | |||
58 | static void omap_mcbsp_st_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val) | ||
59 | { | ||
60 | __raw_writel(val, mcbsp->st_data->io_base_st + reg); | ||
61 | } | ||
62 | |||
63 | static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg) | ||
64 | { | ||
65 | return __raw_readl(mcbsp->st_data->io_base_st + reg); | ||
66 | } | ||
67 | |||
68 | #define MCBSP_READ(mcbsp, reg) \ | ||
69 | omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 0) | ||
70 | #define MCBSP_WRITE(mcbsp, reg, val) \ | ||
71 | omap_mcbsp_write(mcbsp, OMAP_MCBSP_REG_##reg, val) | ||
72 | #define MCBSP_READ_CACHE(mcbsp, reg) \ | ||
73 | omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 1) | ||
74 | |||
75 | #define MCBSP_ST_READ(mcbsp, reg) \ | ||
76 | omap_mcbsp_st_read(mcbsp, OMAP_ST_REG_##reg) | ||
77 | #define MCBSP_ST_WRITE(mcbsp, reg, val) \ | ||
78 | omap_mcbsp_st_write(mcbsp, OMAP_ST_REG_##reg, val) | ||
79 | |||
80 | static void omap_mcbsp_dump_reg(struct omap_mcbsp *mcbsp) | ||
81 | { | ||
82 | dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id); | ||
83 | dev_dbg(mcbsp->dev, "DRR2: 0x%04x\n", | ||
84 | MCBSP_READ(mcbsp, DRR2)); | ||
85 | dev_dbg(mcbsp->dev, "DRR1: 0x%04x\n", | ||
86 | MCBSP_READ(mcbsp, DRR1)); | ||
87 | dev_dbg(mcbsp->dev, "DXR2: 0x%04x\n", | ||
88 | MCBSP_READ(mcbsp, DXR2)); | ||
89 | dev_dbg(mcbsp->dev, "DXR1: 0x%04x\n", | ||
90 | MCBSP_READ(mcbsp, DXR1)); | ||
91 | dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n", | ||
92 | MCBSP_READ(mcbsp, SPCR2)); | ||
93 | dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n", | ||
94 | MCBSP_READ(mcbsp, SPCR1)); | ||
95 | dev_dbg(mcbsp->dev, "RCR2: 0x%04x\n", | ||
96 | MCBSP_READ(mcbsp, RCR2)); | ||
97 | dev_dbg(mcbsp->dev, "RCR1: 0x%04x\n", | ||
98 | MCBSP_READ(mcbsp, RCR1)); | ||
99 | dev_dbg(mcbsp->dev, "XCR2: 0x%04x\n", | ||
100 | MCBSP_READ(mcbsp, XCR2)); | ||
101 | dev_dbg(mcbsp->dev, "XCR1: 0x%04x\n", | ||
102 | MCBSP_READ(mcbsp, XCR1)); | ||
103 | dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n", | ||
104 | MCBSP_READ(mcbsp, SRGR2)); | ||
105 | dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n", | ||
106 | MCBSP_READ(mcbsp, SRGR1)); | ||
107 | dev_dbg(mcbsp->dev, "PCR0: 0x%04x\n", | ||
108 | MCBSP_READ(mcbsp, PCR0)); | ||
109 | dev_dbg(mcbsp->dev, "***********************\n"); | ||
110 | } | ||
111 | |||
112 | static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id) | ||
113 | { | ||
114 | struct omap_mcbsp *mcbsp_tx = dev_id; | ||
115 | u16 irqst_spcr2; | ||
116 | |||
117 | irqst_spcr2 = MCBSP_READ(mcbsp_tx, SPCR2); | ||
118 | dev_dbg(mcbsp_tx->dev, "TX IRQ callback : 0x%x\n", irqst_spcr2); | ||
119 | |||
120 | if (irqst_spcr2 & XSYNC_ERR) { | ||
121 | dev_err(mcbsp_tx->dev, "TX Frame Sync Error! : 0x%x\n", | ||
122 | irqst_spcr2); | ||
123 | /* Writing zero to XSYNC_ERR clears the IRQ */ | ||
124 | MCBSP_WRITE(mcbsp_tx, SPCR2, MCBSP_READ_CACHE(mcbsp_tx, SPCR2)); | ||
125 | } | ||
126 | |||
127 | return IRQ_HANDLED; | ||
128 | } | ||
129 | |||
130 | static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id) | ||
131 | { | ||
132 | struct omap_mcbsp *mcbsp_rx = dev_id; | ||
133 | u16 irqst_spcr1; | ||
134 | |||
135 | irqst_spcr1 = MCBSP_READ(mcbsp_rx, SPCR1); | ||
136 | dev_dbg(mcbsp_rx->dev, "RX IRQ callback : 0x%x\n", irqst_spcr1); | ||
137 | |||
138 | if (irqst_spcr1 & RSYNC_ERR) { | ||
139 | dev_err(mcbsp_rx->dev, "RX Frame Sync Error! : 0x%x\n", | ||
140 | irqst_spcr1); | ||
141 | /* Writing zero to RSYNC_ERR clears the IRQ */ | ||
142 | MCBSP_WRITE(mcbsp_rx, SPCR1, MCBSP_READ_CACHE(mcbsp_rx, SPCR1)); | ||
143 | } | ||
144 | |||
145 | return IRQ_HANDLED; | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * omap_mcbsp_config simply write a config to the | ||
150 | * appropriate McBSP. | ||
151 | * You either call this function or set the McBSP registers | ||
152 | * by yourself before calling omap_mcbsp_start(). | ||
153 | */ | ||
154 | void omap_mcbsp_config(struct omap_mcbsp *mcbsp, | ||
155 | const struct omap_mcbsp_reg_cfg *config) | ||
156 | { | ||
157 | dev_dbg(mcbsp->dev, "Configuring McBSP%d phys_base: 0x%08lx\n", | ||
158 | mcbsp->id, mcbsp->phys_base); | ||
159 | |||
160 | /* We write the given config */ | ||
161 | MCBSP_WRITE(mcbsp, SPCR2, config->spcr2); | ||
162 | MCBSP_WRITE(mcbsp, SPCR1, config->spcr1); | ||
163 | MCBSP_WRITE(mcbsp, RCR2, config->rcr2); | ||
164 | MCBSP_WRITE(mcbsp, RCR1, config->rcr1); | ||
165 | MCBSP_WRITE(mcbsp, XCR2, config->xcr2); | ||
166 | MCBSP_WRITE(mcbsp, XCR1, config->xcr1); | ||
167 | MCBSP_WRITE(mcbsp, SRGR2, config->srgr2); | ||
168 | MCBSP_WRITE(mcbsp, SRGR1, config->srgr1); | ||
169 | MCBSP_WRITE(mcbsp, MCR2, config->mcr2); | ||
170 | MCBSP_WRITE(mcbsp, MCR1, config->mcr1); | ||
171 | MCBSP_WRITE(mcbsp, PCR0, config->pcr0); | ||
172 | if (mcbsp->pdata->has_ccr) { | ||
173 | MCBSP_WRITE(mcbsp, XCCR, config->xccr); | ||
174 | MCBSP_WRITE(mcbsp, RCCR, config->rccr); | ||
175 | } | ||
176 | /* Enable wakeup behavior */ | ||
177 | if (mcbsp->pdata->has_wakeup) | ||
178 | MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN); | ||
179 | } | ||
180 | |||
181 | /** | ||
182 | * omap_mcbsp_dma_reg_params - returns the address of mcbsp data register | ||
183 | * @id - mcbsp id | ||
184 | * @stream - indicates the direction of data flow (rx or tx) | ||
185 | * | ||
186 | * Returns the address of mcbsp data transmit register or data receive register | ||
187 | * to be used by DMA for transferring/receiving data based on the value of | ||
188 | * @stream for the requested mcbsp given by @id | ||
189 | */ | ||
190 | static int omap_mcbsp_dma_reg_params(struct omap_mcbsp *mcbsp, | ||
191 | unsigned int stream) | ||
192 | { | ||
193 | int data_reg; | ||
194 | |||
195 | if (mcbsp->pdata->reg_size == 2) { | ||
196 | if (stream) | ||
197 | data_reg = OMAP_MCBSP_REG_DRR1; | ||
198 | else | ||
199 | data_reg = OMAP_MCBSP_REG_DXR1; | ||
200 | } else { | ||
201 | if (stream) | ||
202 | data_reg = OMAP_MCBSP_REG_DRR; | ||
203 | else | ||
204 | data_reg = OMAP_MCBSP_REG_DXR; | ||
205 | } | ||
206 | |||
207 | return mcbsp->phys_dma_base + data_reg * mcbsp->pdata->reg_step; | ||
208 | } | ||
209 | |||
210 | static void omap_st_on(struct omap_mcbsp *mcbsp) | ||
211 | { | ||
212 | unsigned int w; | ||
213 | |||
214 | if (mcbsp->pdata->enable_st_clock) | ||
215 | mcbsp->pdata->enable_st_clock(mcbsp->id, 1); | ||
216 | |||
217 | /* Enable McBSP Sidetone */ | ||
218 | w = MCBSP_READ(mcbsp, SSELCR); | ||
219 | MCBSP_WRITE(mcbsp, SSELCR, w | SIDETONEEN); | ||
220 | |||
221 | /* Enable Sidetone from Sidetone Core */ | ||
222 | w = MCBSP_ST_READ(mcbsp, SSELCR); | ||
223 | MCBSP_ST_WRITE(mcbsp, SSELCR, w | ST_SIDETONEEN); | ||
224 | } | ||
225 | |||
226 | static void omap_st_off(struct omap_mcbsp *mcbsp) | ||
227 | { | ||
228 | unsigned int w; | ||
229 | |||
230 | w = MCBSP_ST_READ(mcbsp, SSELCR); | ||
231 | MCBSP_ST_WRITE(mcbsp, SSELCR, w & ~(ST_SIDETONEEN)); | ||
232 | |||
233 | w = MCBSP_READ(mcbsp, SSELCR); | ||
234 | MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN)); | ||
235 | |||
236 | if (mcbsp->pdata->enable_st_clock) | ||
237 | mcbsp->pdata->enable_st_clock(mcbsp->id, 0); | ||
238 | } | ||
239 | |||
240 | static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir) | ||
241 | { | ||
242 | u16 val, i; | ||
243 | |||
244 | val = MCBSP_ST_READ(mcbsp, SSELCR); | ||
245 | |||
246 | if (val & ST_COEFFWREN) | ||
247 | MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN)); | ||
248 | |||
249 | MCBSP_ST_WRITE(mcbsp, SSELCR, val | ST_COEFFWREN); | ||
250 | |||
251 | for (i = 0; i < 128; i++) | ||
252 | MCBSP_ST_WRITE(mcbsp, SFIRCR, fir[i]); | ||
253 | |||
254 | i = 0; | ||
255 | |||
256 | val = MCBSP_ST_READ(mcbsp, SSELCR); | ||
257 | while (!(val & ST_COEFFWRDONE) && (++i < 1000)) | ||
258 | val = MCBSP_ST_READ(mcbsp, SSELCR); | ||
259 | |||
260 | MCBSP_ST_WRITE(mcbsp, SSELCR, val & ~(ST_COEFFWREN)); | ||
261 | |||
262 | if (i == 1000) | ||
263 | dev_err(mcbsp->dev, "McBSP FIR load error!\n"); | ||
264 | } | ||
265 | |||
266 | static void omap_st_chgain(struct omap_mcbsp *mcbsp) | ||
267 | { | ||
268 | u16 w; | ||
269 | struct omap_mcbsp_st_data *st_data = mcbsp->st_data; | ||
270 | |||
271 | w = MCBSP_ST_READ(mcbsp, SSELCR); | ||
272 | |||
273 | MCBSP_ST_WRITE(mcbsp, SGAINCR, ST_CH0GAIN(st_data->ch0gain) | \ | ||
274 | ST_CH1GAIN(st_data->ch1gain)); | ||
275 | } | ||
276 | |||
277 | int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain) | ||
278 | { | ||
279 | struct omap_mcbsp_st_data *st_data = mcbsp->st_data; | ||
280 | int ret = 0; | ||
281 | |||
282 | if (!st_data) | ||
283 | return -ENOENT; | ||
284 | |||
285 | spin_lock_irq(&mcbsp->lock); | ||
286 | if (channel == 0) | ||
287 | st_data->ch0gain = chgain; | ||
288 | else if (channel == 1) | ||
289 | st_data->ch1gain = chgain; | ||
290 | else | ||
291 | ret = -EINVAL; | ||
292 | |||
293 | if (st_data->enabled) | ||
294 | omap_st_chgain(mcbsp); | ||
295 | spin_unlock_irq(&mcbsp->lock); | ||
296 | |||
297 | return ret; | ||
298 | } | ||
299 | |||
300 | int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain) | ||
301 | { | ||
302 | struct omap_mcbsp_st_data *st_data = mcbsp->st_data; | ||
303 | int ret = 0; | ||
304 | |||
305 | if (!st_data) | ||
306 | return -ENOENT; | ||
307 | |||
308 | spin_lock_irq(&mcbsp->lock); | ||
309 | if (channel == 0) | ||
310 | *chgain = st_data->ch0gain; | ||
311 | else if (channel == 1) | ||
312 | *chgain = st_data->ch1gain; | ||
313 | else | ||
314 | ret = -EINVAL; | ||
315 | spin_unlock_irq(&mcbsp->lock); | ||
316 | |||
317 | return ret; | ||
318 | } | ||
319 | |||
320 | static int omap_st_start(struct omap_mcbsp *mcbsp) | ||
321 | { | ||
322 | struct omap_mcbsp_st_data *st_data = mcbsp->st_data; | ||
323 | |||
324 | if (st_data->enabled && !st_data->running) { | ||
325 | omap_st_fir_write(mcbsp, st_data->taps); | ||
326 | omap_st_chgain(mcbsp); | ||
327 | |||
328 | if (!mcbsp->free) { | ||
329 | omap_st_on(mcbsp); | ||
330 | st_data->running = 1; | ||
331 | } | ||
332 | } | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | int omap_st_enable(struct omap_mcbsp *mcbsp) | ||
338 | { | ||
339 | struct omap_mcbsp_st_data *st_data = mcbsp->st_data; | ||
340 | |||
341 | if (!st_data) | ||
342 | return -ENODEV; | ||
343 | |||
344 | spin_lock_irq(&mcbsp->lock); | ||
345 | st_data->enabled = 1; | ||
346 | omap_st_start(mcbsp); | ||
347 | spin_unlock_irq(&mcbsp->lock); | ||
348 | |||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | static int omap_st_stop(struct omap_mcbsp *mcbsp) | ||
353 | { | ||
354 | struct omap_mcbsp_st_data *st_data = mcbsp->st_data; | ||
355 | |||
356 | if (st_data->running) { | ||
357 | if (!mcbsp->free) { | ||
358 | omap_st_off(mcbsp); | ||
359 | st_data->running = 0; | ||
360 | } | ||
361 | } | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | int omap_st_disable(struct omap_mcbsp *mcbsp) | ||
367 | { | ||
368 | struct omap_mcbsp_st_data *st_data = mcbsp->st_data; | ||
369 | int ret = 0; | ||
370 | |||
371 | if (!st_data) | ||
372 | return -ENODEV; | ||
373 | |||
374 | spin_lock_irq(&mcbsp->lock); | ||
375 | omap_st_stop(mcbsp); | ||
376 | st_data->enabled = 0; | ||
377 | spin_unlock_irq(&mcbsp->lock); | ||
378 | |||
379 | return ret; | ||
380 | } | ||
381 | |||
382 | int omap_st_is_enabled(struct omap_mcbsp *mcbsp) | ||
383 | { | ||
384 | struct omap_mcbsp_st_data *st_data = mcbsp->st_data; | ||
385 | |||
386 | if (!st_data) | ||
387 | return -ENODEV; | ||
388 | |||
389 | return st_data->enabled; | ||
390 | } | ||
391 | |||
392 | /* | ||
393 | * omap_mcbsp_set_rx_threshold configures the transmit threshold in words. | ||
394 | * The threshold parameter is 1 based, and it is converted (threshold - 1) | ||
395 | * for the THRSH2 register. | ||
396 | */ | ||
397 | void omap_mcbsp_set_tx_threshold(struct omap_mcbsp *mcbsp, u16 threshold) | ||
398 | { | ||
399 | if (mcbsp->pdata->buffer_size == 0) | ||
400 | return; | ||
401 | |||
402 | if (threshold && threshold <= mcbsp->max_tx_thres) | ||
403 | MCBSP_WRITE(mcbsp, THRSH2, threshold - 1); | ||
404 | } | ||
405 | |||
406 | /* | ||
407 | * omap_mcbsp_set_rx_threshold configures the receive threshold in words. | ||
408 | * The threshold parameter is 1 based, and it is converted (threshold - 1) | ||
409 | * for the THRSH1 register. | ||
410 | */ | ||
411 | void omap_mcbsp_set_rx_threshold(struct omap_mcbsp *mcbsp, u16 threshold) | ||
412 | { | ||
413 | if (mcbsp->pdata->buffer_size == 0) | ||
414 | return; | ||
415 | |||
416 | if (threshold && threshold <= mcbsp->max_rx_thres) | ||
417 | MCBSP_WRITE(mcbsp, THRSH1, threshold - 1); | ||
418 | } | ||
419 | |||
420 | /* | ||
421 | * omap_mcbsp_get_tx_delay returns the number of used slots in the McBSP FIFO | ||
422 | */ | ||
423 | u16 omap_mcbsp_get_tx_delay(struct omap_mcbsp *mcbsp) | ||
424 | { | ||
425 | u16 buffstat; | ||
426 | |||
427 | if (mcbsp->pdata->buffer_size == 0) | ||
428 | return 0; | ||
429 | |||
430 | /* Returns the number of free locations in the buffer */ | ||
431 | buffstat = MCBSP_READ(mcbsp, XBUFFSTAT); | ||
432 | |||
433 | /* Number of slots are different in McBSP ports */ | ||
434 | return mcbsp->pdata->buffer_size - buffstat; | ||
435 | } | ||
436 | |||
437 | /* | ||
438 | * omap_mcbsp_get_rx_delay returns the number of free slots in the McBSP FIFO | ||
439 | * to reach the threshold value (when the DMA will be triggered to read it) | ||
440 | */ | ||
441 | u16 omap_mcbsp_get_rx_delay(struct omap_mcbsp *mcbsp) | ||
442 | { | ||
443 | u16 buffstat, threshold; | ||
444 | |||
445 | if (mcbsp->pdata->buffer_size == 0) | ||
446 | return 0; | ||
447 | |||
448 | /* Returns the number of used locations in the buffer */ | ||
449 | buffstat = MCBSP_READ(mcbsp, RBUFFSTAT); | ||
450 | /* RX threshold */ | ||
451 | threshold = MCBSP_READ(mcbsp, THRSH1); | ||
452 | |||
453 | /* Return the number of location till we reach the threshold limit */ | ||
454 | if (threshold <= buffstat) | ||
455 | return 0; | ||
456 | else | ||
457 | return threshold - buffstat; | ||
458 | } | ||
459 | |||
460 | int omap_mcbsp_request(struct omap_mcbsp *mcbsp) | ||
461 | { | ||
462 | void *reg_cache; | ||
463 | int err; | ||
464 | |||
465 | reg_cache = kzalloc(mcbsp->reg_cache_size, GFP_KERNEL); | ||
466 | if (!reg_cache) { | ||
467 | return -ENOMEM; | ||
468 | } | ||
469 | |||
470 | spin_lock(&mcbsp->lock); | ||
471 | if (!mcbsp->free) { | ||
472 | dev_err(mcbsp->dev, "McBSP%d is currently in use\n", | ||
473 | mcbsp->id); | ||
474 | err = -EBUSY; | ||
475 | goto err_kfree; | ||
476 | } | ||
477 | |||
478 | mcbsp->free = false; | ||
479 | mcbsp->reg_cache = reg_cache; | ||
480 | spin_unlock(&mcbsp->lock); | ||
481 | |||
482 | if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request) | ||
483 | mcbsp->pdata->ops->request(mcbsp->id - 1); | ||
484 | |||
485 | /* | ||
486 | * Make sure that transmitter, receiver and sample-rate generator are | ||
487 | * not running before activating IRQs. | ||
488 | */ | ||
489 | MCBSP_WRITE(mcbsp, SPCR1, 0); | ||
490 | MCBSP_WRITE(mcbsp, SPCR2, 0); | ||
491 | |||
492 | err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler, | ||
493 | 0, "McBSP", (void *)mcbsp); | ||
494 | if (err != 0) { | ||
495 | dev_err(mcbsp->dev, "Unable to request TX IRQ %d " | ||
496 | "for McBSP%d\n", mcbsp->tx_irq, | ||
497 | mcbsp->id); | ||
498 | goto err_clk_disable; | ||
499 | } | ||
500 | |||
501 | if (mcbsp->rx_irq) { | ||
502 | err = request_irq(mcbsp->rx_irq, | ||
503 | omap_mcbsp_rx_irq_handler, | ||
504 | 0, "McBSP", (void *)mcbsp); | ||
505 | if (err != 0) { | ||
506 | dev_err(mcbsp->dev, "Unable to request RX IRQ %d " | ||
507 | "for McBSP%d\n", mcbsp->rx_irq, | ||
508 | mcbsp->id); | ||
509 | goto err_free_irq; | ||
510 | } | ||
511 | } | ||
512 | |||
513 | return 0; | ||
514 | err_free_irq: | ||
515 | free_irq(mcbsp->tx_irq, (void *)mcbsp); | ||
516 | err_clk_disable: | ||
517 | if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) | ||
518 | mcbsp->pdata->ops->free(mcbsp->id - 1); | ||
519 | |||
520 | /* Disable wakeup behavior */ | ||
521 | if (mcbsp->pdata->has_wakeup) | ||
522 | MCBSP_WRITE(mcbsp, WAKEUPEN, 0); | ||
523 | |||
524 | spin_lock(&mcbsp->lock); | ||
525 | mcbsp->free = true; | ||
526 | mcbsp->reg_cache = NULL; | ||
527 | err_kfree: | ||
528 | spin_unlock(&mcbsp->lock); | ||
529 | kfree(reg_cache); | ||
530 | |||
531 | return err; | ||
532 | } | ||
533 | |||
534 | void omap_mcbsp_free(struct omap_mcbsp *mcbsp) | ||
535 | { | ||
536 | void *reg_cache; | ||
537 | |||
538 | if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) | ||
539 | mcbsp->pdata->ops->free(mcbsp->id - 1); | ||
540 | |||
541 | /* Disable wakeup behavior */ | ||
542 | if (mcbsp->pdata->has_wakeup) | ||
543 | MCBSP_WRITE(mcbsp, WAKEUPEN, 0); | ||
544 | |||
545 | if (mcbsp->rx_irq) | ||
546 | free_irq(mcbsp->rx_irq, (void *)mcbsp); | ||
547 | free_irq(mcbsp->tx_irq, (void *)mcbsp); | ||
548 | |||
549 | reg_cache = mcbsp->reg_cache; | ||
550 | |||
551 | /* | ||
552 | * Select CLKS source from internal source unconditionally before | ||
553 | * marking the McBSP port as free. | ||
554 | * If the external clock source via MCBSP_CLKS pin has been selected the | ||
555 | * system will refuse to enter idle if the CLKS pin source is not reset | ||
556 | * back to internal source. | ||
557 | */ | ||
558 | if (!cpu_class_is_omap1()) | ||
559 | omap2_mcbsp_set_clks_src(mcbsp, MCBSP_CLKS_PRCM_SRC); | ||
560 | |||
561 | spin_lock(&mcbsp->lock); | ||
562 | if (mcbsp->free) | ||
563 | dev_err(mcbsp->dev, "McBSP%d was not reserved\n", mcbsp->id); | ||
564 | else | ||
565 | mcbsp->free = true; | ||
566 | mcbsp->reg_cache = NULL; | ||
567 | spin_unlock(&mcbsp->lock); | ||
568 | |||
569 | if (reg_cache) | ||
570 | kfree(reg_cache); | ||
571 | } | ||
572 | |||
573 | /* | ||
574 | * Here we start the McBSP, by enabling transmitter, receiver or both. | ||
575 | * If no transmitter or receiver is active prior calling, then sample-rate | ||
576 | * generator and frame sync are started. | ||
577 | */ | ||
578 | void omap_mcbsp_start(struct omap_mcbsp *mcbsp, int tx, int rx) | ||
579 | { | ||
580 | int enable_srg = 0; | ||
581 | u16 w; | ||
582 | |||
583 | if (mcbsp->st_data) | ||
584 | omap_st_start(mcbsp); | ||
585 | |||
586 | /* Only enable SRG, if McBSP is master */ | ||
587 | w = MCBSP_READ_CACHE(mcbsp, PCR0); | ||
588 | if (w & (FSXM | FSRM | CLKXM | CLKRM)) | ||
589 | enable_srg = !((MCBSP_READ_CACHE(mcbsp, SPCR2) | | ||
590 | MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1); | ||
591 | |||
592 | if (enable_srg) { | ||
593 | /* Start the sample generator */ | ||
594 | w = MCBSP_READ_CACHE(mcbsp, SPCR2); | ||
595 | MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 6)); | ||
596 | } | ||
597 | |||
598 | /* Enable transmitter and receiver */ | ||
599 | tx &= 1; | ||
600 | w = MCBSP_READ_CACHE(mcbsp, SPCR2); | ||
601 | MCBSP_WRITE(mcbsp, SPCR2, w | tx); | ||
602 | |||
603 | rx &= 1; | ||
604 | w = MCBSP_READ_CACHE(mcbsp, SPCR1); | ||
605 | MCBSP_WRITE(mcbsp, SPCR1, w | rx); | ||
606 | |||
607 | /* | ||
608 | * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec | ||
609 | * REVISIT: 100us may give enough time for two CLKSRG, however | ||
610 | * due to some unknown PM related, clock gating etc. reason it | ||
611 | * is now at 500us. | ||
612 | */ | ||
613 | udelay(500); | ||
614 | |||
615 | if (enable_srg) { | ||
616 | /* Start frame sync */ | ||
617 | w = MCBSP_READ_CACHE(mcbsp, SPCR2); | ||
618 | MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7)); | ||
619 | } | ||
620 | |||
621 | if (mcbsp->pdata->has_ccr) { | ||
622 | /* Release the transmitter and receiver */ | ||
623 | w = MCBSP_READ_CACHE(mcbsp, XCCR); | ||
624 | w &= ~(tx ? XDISABLE : 0); | ||
625 | MCBSP_WRITE(mcbsp, XCCR, w); | ||
626 | w = MCBSP_READ_CACHE(mcbsp, RCCR); | ||
627 | w &= ~(rx ? RDISABLE : 0); | ||
628 | MCBSP_WRITE(mcbsp, RCCR, w); | ||
629 | } | ||
630 | |||
631 | /* Dump McBSP Regs */ | ||
632 | omap_mcbsp_dump_reg(mcbsp); | ||
633 | } | ||
634 | |||
635 | void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx) | ||
636 | { | ||
637 | int idle; | ||
638 | u16 w; | ||
639 | |||
640 | /* Reset transmitter */ | ||
641 | tx &= 1; | ||
642 | if (mcbsp->pdata->has_ccr) { | ||
643 | w = MCBSP_READ_CACHE(mcbsp, XCCR); | ||
644 | w |= (tx ? XDISABLE : 0); | ||
645 | MCBSP_WRITE(mcbsp, XCCR, w); | ||
646 | } | ||
647 | w = MCBSP_READ_CACHE(mcbsp, SPCR2); | ||
648 | MCBSP_WRITE(mcbsp, SPCR2, w & ~tx); | ||
649 | |||
650 | /* Reset receiver */ | ||
651 | rx &= 1; | ||
652 | if (mcbsp->pdata->has_ccr) { | ||
653 | w = MCBSP_READ_CACHE(mcbsp, RCCR); | ||
654 | w |= (rx ? RDISABLE : 0); | ||
655 | MCBSP_WRITE(mcbsp, RCCR, w); | ||
656 | } | ||
657 | w = MCBSP_READ_CACHE(mcbsp, SPCR1); | ||
658 | MCBSP_WRITE(mcbsp, SPCR1, w & ~rx); | ||
659 | |||
660 | idle = !((MCBSP_READ_CACHE(mcbsp, SPCR2) | | ||
661 | MCBSP_READ_CACHE(mcbsp, SPCR1)) & 1); | ||
662 | |||
663 | if (idle) { | ||
664 | /* Reset the sample rate generator */ | ||
665 | w = MCBSP_READ_CACHE(mcbsp, SPCR2); | ||
666 | MCBSP_WRITE(mcbsp, SPCR2, w & ~(1 << 6)); | ||
667 | } | ||
668 | |||
669 | if (mcbsp->st_data) | ||
670 | omap_st_stop(mcbsp); | ||
671 | } | ||
672 | |||
673 | int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id) | ||
674 | { | ||
675 | const char *src; | ||
676 | |||
677 | if (fck_src_id == MCBSP_CLKS_PAD_SRC) | ||
678 | src = "clks_ext"; | ||
679 | else if (fck_src_id == MCBSP_CLKS_PRCM_SRC) | ||
680 | src = "clks_fclk"; | ||
681 | else | ||
682 | return -EINVAL; | ||
683 | |||
684 | if (mcbsp->pdata->set_clk_src) | ||
685 | return mcbsp->pdata->set_clk_src(mcbsp->dev, mcbsp->fclk, src); | ||
686 | else | ||
687 | return -EINVAL; | ||
688 | } | ||
689 | |||
690 | int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux) | ||
691 | { | ||
692 | const char *signal, *src; | ||
693 | |||
694 | if (mcbsp->pdata->mux_signal) | ||
695 | return -EINVAL; | ||
696 | |||
697 | switch (mux) { | ||
698 | case CLKR_SRC_CLKR: | ||
699 | signal = "clkr"; | ||
700 | src = "clkr"; | ||
701 | break; | ||
702 | case CLKR_SRC_CLKX: | ||
703 | signal = "clkr"; | ||
704 | src = "clkx"; | ||
705 | break; | ||
706 | case FSR_SRC_FSR: | ||
707 | signal = "fsr"; | ||
708 | src = "fsr"; | ||
709 | break; | ||
710 | case FSR_SRC_FSX: | ||
711 | signal = "fsr"; | ||
712 | src = "fsx"; | ||
713 | break; | ||
714 | default: | ||
715 | return -EINVAL; | ||
716 | } | ||
717 | |||
718 | return mcbsp->pdata->mux_signal(mcbsp->dev, signal, src); | ||
719 | } | ||
720 | |||
721 | #define max_thres(m) (mcbsp->pdata->buffer_size) | ||
722 | #define valid_threshold(m, val) ((val) <= max_thres(m)) | ||
723 | #define THRESHOLD_PROP_BUILDER(prop) \ | ||
724 | static ssize_t prop##_show(struct device *dev, \ | ||
725 | struct device_attribute *attr, char *buf) \ | ||
726 | { \ | ||
727 | struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \ | ||
728 | \ | ||
729 | return sprintf(buf, "%u\n", mcbsp->prop); \ | ||
730 | } \ | ||
731 | \ | ||
732 | static ssize_t prop##_store(struct device *dev, \ | ||
733 | struct device_attribute *attr, \ | ||
734 | const char *buf, size_t size) \ | ||
735 | { \ | ||
736 | struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \ | ||
737 | unsigned long val; \ | ||
738 | int status; \ | ||
739 | \ | ||
740 | status = strict_strtoul(buf, 0, &val); \ | ||
741 | if (status) \ | ||
742 | return status; \ | ||
743 | \ | ||
744 | if (!valid_threshold(mcbsp, val)) \ | ||
745 | return -EDOM; \ | ||
746 | \ | ||
747 | mcbsp->prop = val; \ | ||
748 | return size; \ | ||
749 | } \ | ||
750 | \ | ||
751 | static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store); | ||
752 | |||
753 | THRESHOLD_PROP_BUILDER(max_tx_thres); | ||
754 | THRESHOLD_PROP_BUILDER(max_rx_thres); | ||
755 | |||
756 | static const char *dma_op_modes[] = { | ||
757 | "element", "threshold", "frame", | ||
758 | }; | ||
759 | |||
760 | static ssize_t dma_op_mode_show(struct device *dev, | ||
761 | struct device_attribute *attr, char *buf) | ||
762 | { | ||
763 | struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); | ||
764 | int dma_op_mode, i = 0; | ||
765 | ssize_t len = 0; | ||
766 | const char * const *s; | ||
767 | |||
768 | dma_op_mode = mcbsp->dma_op_mode; | ||
769 | |||
770 | for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) { | ||
771 | if (dma_op_mode == i) | ||
772 | len += sprintf(buf + len, "[%s] ", *s); | ||
773 | else | ||
774 | len += sprintf(buf + len, "%s ", *s); | ||
775 | } | ||
776 | len += sprintf(buf + len, "\n"); | ||
777 | |||
778 | return len; | ||
779 | } | ||
780 | |||
781 | static ssize_t dma_op_mode_store(struct device *dev, | ||
782 | struct device_attribute *attr, | ||
783 | const char *buf, size_t size) | ||
784 | { | ||
785 | struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); | ||
786 | const char * const *s; | ||
787 | int i = 0; | ||
788 | |||
789 | for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) | ||
790 | if (sysfs_streq(buf, *s)) | ||
791 | break; | ||
792 | |||
793 | if (i == ARRAY_SIZE(dma_op_modes)) | ||
794 | return -EINVAL; | ||
795 | |||
796 | spin_lock_irq(&mcbsp->lock); | ||
797 | if (!mcbsp->free) { | ||
798 | size = -EBUSY; | ||
799 | goto unlock; | ||
800 | } | ||
801 | mcbsp->dma_op_mode = i; | ||
802 | |||
803 | unlock: | ||
804 | spin_unlock_irq(&mcbsp->lock); | ||
805 | |||
806 | return size; | ||
807 | } | ||
808 | |||
809 | static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store); | ||
810 | |||
811 | static const struct attribute *additional_attrs[] = { | ||
812 | &dev_attr_max_tx_thres.attr, | ||
813 | &dev_attr_max_rx_thres.attr, | ||
814 | &dev_attr_dma_op_mode.attr, | ||
815 | NULL, | ||
816 | }; | ||
817 | |||
818 | static const struct attribute_group additional_attr_group = { | ||
819 | .attrs = (struct attribute **)additional_attrs, | ||
820 | }; | ||
821 | |||
822 | static ssize_t st_taps_show(struct device *dev, | ||
823 | struct device_attribute *attr, char *buf) | ||
824 | { | ||
825 | struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); | ||
826 | struct omap_mcbsp_st_data *st_data = mcbsp->st_data; | ||
827 | ssize_t status = 0; | ||
828 | int i; | ||
829 | |||
830 | spin_lock_irq(&mcbsp->lock); | ||
831 | for (i = 0; i < st_data->nr_taps; i++) | ||
832 | status += sprintf(&buf[status], (i ? ", %d" : "%d"), | ||
833 | st_data->taps[i]); | ||
834 | if (i) | ||
835 | status += sprintf(&buf[status], "\n"); | ||
836 | spin_unlock_irq(&mcbsp->lock); | ||
837 | |||
838 | return status; | ||
839 | } | ||
840 | |||
841 | static ssize_t st_taps_store(struct device *dev, | ||
842 | struct device_attribute *attr, | ||
843 | const char *buf, size_t size) | ||
844 | { | ||
845 | struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); | ||
846 | struct omap_mcbsp_st_data *st_data = mcbsp->st_data; | ||
847 | int val, tmp, status, i = 0; | ||
848 | |||
849 | spin_lock_irq(&mcbsp->lock); | ||
850 | memset(st_data->taps, 0, sizeof(st_data->taps)); | ||
851 | st_data->nr_taps = 0; | ||
852 | |||
853 | do { | ||
854 | status = sscanf(buf, "%d%n", &val, &tmp); | ||
855 | if (status < 0 || status == 0) { | ||
856 | size = -EINVAL; | ||
857 | goto out; | ||
858 | } | ||
859 | if (val < -32768 || val > 32767) { | ||
860 | size = -EINVAL; | ||
861 | goto out; | ||
862 | } | ||
863 | st_data->taps[i++] = val; | ||
864 | buf += tmp; | ||
865 | if (*buf != ',') | ||
866 | break; | ||
867 | buf++; | ||
868 | } while (1); | ||
869 | |||
870 | st_data->nr_taps = i; | ||
871 | |||
872 | out: | ||
873 | spin_unlock_irq(&mcbsp->lock); | ||
874 | |||
875 | return size; | ||
876 | } | ||
877 | |||
878 | static DEVICE_ATTR(st_taps, 0644, st_taps_show, st_taps_store); | ||
879 | |||
880 | static const struct attribute *sidetone_attrs[] = { | ||
881 | &dev_attr_st_taps.attr, | ||
882 | NULL, | ||
883 | }; | ||
884 | |||
885 | static const struct attribute_group sidetone_attr_group = { | ||
886 | .attrs = (struct attribute **)sidetone_attrs, | ||
887 | }; | ||
888 | |||
889 | static int __devinit omap_st_add(struct omap_mcbsp *mcbsp, | ||
890 | struct resource *res) | ||
891 | { | ||
892 | struct omap_mcbsp_st_data *st_data; | ||
893 | int err; | ||
894 | |||
895 | st_data = devm_kzalloc(mcbsp->dev, sizeof(*mcbsp->st_data), GFP_KERNEL); | ||
896 | if (!st_data) | ||
897 | return -ENOMEM; | ||
898 | |||
899 | st_data->io_base_st = devm_ioremap(mcbsp->dev, res->start, | ||
900 | resource_size(res)); | ||
901 | if (!st_data->io_base_st) | ||
902 | return -ENOMEM; | ||
903 | |||
904 | err = sysfs_create_group(&mcbsp->dev->kobj, &sidetone_attr_group); | ||
905 | if (err) | ||
906 | return err; | ||
907 | |||
908 | mcbsp->st_data = st_data; | ||
909 | return 0; | ||
910 | } | ||
911 | |||
912 | /* | ||
913 | * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. | ||
914 | * 730 has only 2 McBSP, and both of them are MPU peripherals. | ||
915 | */ | ||
916 | int __devinit omap_mcbsp_init(struct platform_device *pdev) | ||
917 | { | ||
918 | struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); | ||
919 | struct resource *res; | ||
920 | int ret = 0; | ||
921 | |||
922 | spin_lock_init(&mcbsp->lock); | ||
923 | mcbsp->free = true; | ||
924 | |||
925 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mpu"); | ||
926 | if (!res) { | ||
927 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
928 | if (!res) { | ||
929 | dev_err(mcbsp->dev, "invalid memory resource\n"); | ||
930 | return -ENOMEM; | ||
931 | } | ||
932 | } | ||
933 | if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), | ||
934 | dev_name(&pdev->dev))) { | ||
935 | dev_err(mcbsp->dev, "memory region already claimed\n"); | ||
936 | return -ENODEV; | ||
937 | } | ||
938 | |||
939 | mcbsp->phys_base = res->start; | ||
940 | mcbsp->reg_cache_size = resource_size(res); | ||
941 | mcbsp->io_base = devm_ioremap(&pdev->dev, res->start, | ||
942 | resource_size(res)); | ||
943 | if (!mcbsp->io_base) | ||
944 | return -ENOMEM; | ||
945 | |||
946 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dma"); | ||
947 | if (!res) | ||
948 | mcbsp->phys_dma_base = mcbsp->phys_base; | ||
949 | else | ||
950 | mcbsp->phys_dma_base = res->start; | ||
951 | |||
952 | mcbsp->tx_irq = platform_get_irq_byname(pdev, "tx"); | ||
953 | mcbsp->rx_irq = platform_get_irq_byname(pdev, "rx"); | ||
954 | |||
955 | /* From OMAP4 there will be a single irq line */ | ||
956 | if (mcbsp->tx_irq == -ENXIO) { | ||
957 | mcbsp->tx_irq = platform_get_irq(pdev, 0); | ||
958 | mcbsp->rx_irq = 0; | ||
959 | } | ||
960 | |||
961 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); | ||
962 | if (!res) { | ||
963 | dev_err(&pdev->dev, "invalid rx DMA channel\n"); | ||
964 | return -ENODEV; | ||
965 | } | ||
966 | /* RX DMA request number, and port address configuration */ | ||
967 | mcbsp->dma_data[1].name = "Audio Capture"; | ||
968 | mcbsp->dma_data[1].dma_req = res->start; | ||
969 | mcbsp->dma_data[1].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 1); | ||
970 | |||
971 | res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); | ||
972 | if (!res) { | ||
973 | dev_err(&pdev->dev, "invalid tx DMA channel\n"); | ||
974 | return -ENODEV; | ||
975 | } | ||
976 | /* TX DMA request number, and port address configuration */ | ||
977 | mcbsp->dma_data[0].name = "Audio Playback"; | ||
978 | mcbsp->dma_data[0].dma_req = res->start; | ||
979 | mcbsp->dma_data[0].port_addr = omap_mcbsp_dma_reg_params(mcbsp, 0); | ||
980 | |||
981 | mcbsp->fclk = clk_get(&pdev->dev, "fck"); | ||
982 | if (IS_ERR(mcbsp->fclk)) { | ||
983 | ret = PTR_ERR(mcbsp->fclk); | ||
984 | dev_err(mcbsp->dev, "unable to get fck: %d\n", ret); | ||
985 | return ret; | ||
986 | } | ||
987 | |||
988 | mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT; | ||
989 | if (mcbsp->pdata->buffer_size) { | ||
990 | /* | ||
991 | * Initially configure the maximum thresholds to a safe value. | ||
992 | * The McBSP FIFO usage with these values should not go under | ||
993 | * 16 locations. | ||
994 | * If the whole FIFO without safety buffer is used, than there | ||
995 | * is a possibility that the DMA will be not able to push the | ||
996 | * new data on time, causing channel shifts in runtime. | ||
997 | */ | ||
998 | mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10; | ||
999 | mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10; | ||
1000 | |||
1001 | ret = sysfs_create_group(&mcbsp->dev->kobj, | ||
1002 | &additional_attr_group); | ||
1003 | if (ret) { | ||
1004 | dev_err(mcbsp->dev, | ||
1005 | "Unable to create additional controls\n"); | ||
1006 | goto err_thres; | ||
1007 | } | ||
1008 | } else { | ||
1009 | mcbsp->max_tx_thres = -EINVAL; | ||
1010 | mcbsp->max_rx_thres = -EINVAL; | ||
1011 | } | ||
1012 | |||
1013 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sidetone"); | ||
1014 | if (res) { | ||
1015 | ret = omap_st_add(mcbsp, res); | ||
1016 | if (ret) { | ||
1017 | dev_err(mcbsp->dev, | ||
1018 | "Unable to create sidetone controls\n"); | ||
1019 | goto err_st; | ||
1020 | } | ||
1021 | } | ||
1022 | |||
1023 | return 0; | ||
1024 | |||
1025 | err_st: | ||
1026 | if (mcbsp->pdata->buffer_size) | ||
1027 | sysfs_remove_group(&mcbsp->dev->kobj, &additional_attr_group); | ||
1028 | err_thres: | ||
1029 | clk_put(mcbsp->fclk); | ||
1030 | return ret; | ||
1031 | } | ||
1032 | |||
1033 | void __devexit omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp) | ||
1034 | { | ||
1035 | if (mcbsp->pdata->buffer_size) | ||
1036 | sysfs_remove_group(&mcbsp->dev->kobj, &additional_attr_group); | ||
1037 | |||
1038 | if (mcbsp->st_data) | ||
1039 | sysfs_remove_group(&mcbsp->dev->kobj, &sidetone_attr_group); | ||
1040 | } | ||
diff --git a/sound/soc/omap/mcbsp.h b/sound/soc/omap/mcbsp.h new file mode 100644 index 000000000000..a944fcc9073c --- /dev/null +++ b/sound/soc/omap/mcbsp.h | |||
@@ -0,0 +1,346 @@ | |||
1 | /* | ||
2 | * sound/soc/omap/mcbsp.h | ||
3 | * | ||
4 | * OMAP Multi-Channel Buffered Serial Port | ||
5 | * | ||
6 | * Contact: Jarkko Nikula <jarkko.nikula@bitmer.com> | ||
7 | * Peter Ujfalusi <peter.ujfalusi@ti.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | ||
23 | */ | ||
24 | #ifndef __ASOC_MCBSP_H | ||
25 | #define __ASOC_MCBSP_H | ||
26 | |||
27 | #include "omap-pcm.h" | ||
28 | |||
29 | /* McBSP register numbers. Register address offset = num * reg_step */ | ||
30 | enum { | ||
31 | /* Common registers */ | ||
32 | OMAP_MCBSP_REG_SPCR2 = 4, | ||
33 | OMAP_MCBSP_REG_SPCR1, | ||
34 | OMAP_MCBSP_REG_RCR2, | ||
35 | OMAP_MCBSP_REG_RCR1, | ||
36 | OMAP_MCBSP_REG_XCR2, | ||
37 | OMAP_MCBSP_REG_XCR1, | ||
38 | OMAP_MCBSP_REG_SRGR2, | ||
39 | OMAP_MCBSP_REG_SRGR1, | ||
40 | OMAP_MCBSP_REG_MCR2, | ||
41 | OMAP_MCBSP_REG_MCR1, | ||
42 | OMAP_MCBSP_REG_RCERA, | ||
43 | OMAP_MCBSP_REG_RCERB, | ||
44 | OMAP_MCBSP_REG_XCERA, | ||
45 | OMAP_MCBSP_REG_XCERB, | ||
46 | OMAP_MCBSP_REG_PCR0, | ||
47 | OMAP_MCBSP_REG_RCERC, | ||
48 | OMAP_MCBSP_REG_RCERD, | ||
49 | OMAP_MCBSP_REG_XCERC, | ||
50 | OMAP_MCBSP_REG_XCERD, | ||
51 | OMAP_MCBSP_REG_RCERE, | ||
52 | OMAP_MCBSP_REG_RCERF, | ||
53 | OMAP_MCBSP_REG_XCERE, | ||
54 | OMAP_MCBSP_REG_XCERF, | ||
55 | OMAP_MCBSP_REG_RCERG, | ||
56 | OMAP_MCBSP_REG_RCERH, | ||
57 | OMAP_MCBSP_REG_XCERG, | ||
58 | OMAP_MCBSP_REG_XCERH, | ||
59 | |||
60 | /* OMAP1-OMAP2420 registers */ | ||
61 | OMAP_MCBSP_REG_DRR2 = 0, | ||
62 | OMAP_MCBSP_REG_DRR1, | ||
63 | OMAP_MCBSP_REG_DXR2, | ||
64 | OMAP_MCBSP_REG_DXR1, | ||
65 | |||
66 | /* OMAP2430 and onwards */ | ||
67 | OMAP_MCBSP_REG_DRR = 0, | ||
68 | OMAP_MCBSP_REG_DXR = 2, | ||
69 | OMAP_MCBSP_REG_SYSCON = 35, | ||
70 | OMAP_MCBSP_REG_THRSH2, | ||
71 | OMAP_MCBSP_REG_THRSH1, | ||
72 | OMAP_MCBSP_REG_IRQST = 40, | ||
73 | OMAP_MCBSP_REG_IRQEN, | ||
74 | OMAP_MCBSP_REG_WAKEUPEN, | ||
75 | OMAP_MCBSP_REG_XCCR, | ||
76 | OMAP_MCBSP_REG_RCCR, | ||
77 | OMAP_MCBSP_REG_XBUFFSTAT, | ||
78 | OMAP_MCBSP_REG_RBUFFSTAT, | ||
79 | OMAP_MCBSP_REG_SSELCR, | ||
80 | }; | ||
81 | |||
82 | /* OMAP3 sidetone control registers */ | ||
83 | #define OMAP_ST_REG_REV 0x00 | ||
84 | #define OMAP_ST_REG_SYSCONFIG 0x10 | ||
85 | #define OMAP_ST_REG_IRQSTATUS 0x18 | ||
86 | #define OMAP_ST_REG_IRQENABLE 0x1C | ||
87 | #define OMAP_ST_REG_SGAINCR 0x24 | ||
88 | #define OMAP_ST_REG_SFIRCR 0x28 | ||
89 | #define OMAP_ST_REG_SSELCR 0x2C | ||
90 | |||
91 | /************************** McBSP SPCR1 bit definitions ***********************/ | ||
92 | #define RRST BIT(0) | ||
93 | #define RRDY BIT(1) | ||
94 | #define RFULL BIT(2) | ||
95 | #define RSYNC_ERR BIT(3) | ||
96 | #define RINTM(value) (((value) & 0x3) << 4) /* bits 4:5 */ | ||
97 | #define ABIS BIT(6) | ||
98 | #define DXENA BIT(7) | ||
99 | #define CLKSTP(value) (((value) & 0x3) << 11) /* bits 11:12 */ | ||
100 | #define RJUST(value) (((value) & 0x3) << 13) /* bits 13:14 */ | ||
101 | #define ALB BIT(15) | ||
102 | #define DLB BIT(15) | ||
103 | |||
104 | /************************** McBSP SPCR2 bit definitions ***********************/ | ||
105 | #define XRST BIT(0) | ||
106 | #define XRDY BIT(1) | ||
107 | #define XEMPTY BIT(2) | ||
108 | #define XSYNC_ERR BIT(3) | ||
109 | #define XINTM(value) (((value) & 0x3) << 4) /* bits 4:5 */ | ||
110 | #define GRST BIT(6) | ||
111 | #define FRST BIT(7) | ||
112 | #define SOFT BIT(8) | ||
113 | #define FREE BIT(9) | ||
114 | |||
115 | /************************** McBSP PCR bit definitions *************************/ | ||
116 | #define CLKRP BIT(0) | ||
117 | #define CLKXP BIT(1) | ||
118 | #define FSRP BIT(2) | ||
119 | #define FSXP BIT(3) | ||
120 | #define DR_STAT BIT(4) | ||
121 | #define DX_STAT BIT(5) | ||
122 | #define CLKS_STAT BIT(6) | ||
123 | #define SCLKME BIT(7) | ||
124 | #define CLKRM BIT(8) | ||
125 | #define CLKXM BIT(9) | ||
126 | #define FSRM BIT(10) | ||
127 | #define FSXM BIT(11) | ||
128 | #define RIOEN BIT(12) | ||
129 | #define XIOEN BIT(13) | ||
130 | #define IDLE_EN BIT(14) | ||
131 | |||
132 | /************************** McBSP RCR1 bit definitions ************************/ | ||
133 | #define RWDLEN1(value) (((value) & 0x7) << 5) /* Bits 5:7 */ | ||
134 | #define RFRLEN1(value) (((value) & 0x7f) << 8) /* Bits 8:14 */ | ||
135 | |||
136 | /************************** McBSP XCR1 bit definitions ************************/ | ||
137 | #define XWDLEN1(value) (((value) & 0x7) << 5) /* Bits 5:7 */ | ||
138 | #define XFRLEN1(value) (((value) & 0x7f) << 8) /* Bits 8:14 */ | ||
139 | |||
140 | /*************************** McBSP RCR2 bit definitions ***********************/ | ||
141 | #define RDATDLY(value) ((value) & 0x3) /* Bits 0:1 */ | ||
142 | #define RFIG BIT(2) | ||
143 | #define RCOMPAND(value) (((value) & 0x3) << 3) /* Bits 3:4 */ | ||
144 | #define RWDLEN2(value) (((value) & 0x7) << 5) /* Bits 5:7 */ | ||
145 | #define RFRLEN2(value) (((value) & 0x7f) << 8) /* Bits 8:14 */ | ||
146 | #define RPHASE BIT(15) | ||
147 | |||
148 | /*************************** McBSP XCR2 bit definitions ***********************/ | ||
149 | #define XDATDLY(value) ((value) & 0x3) /* Bits 0:1 */ | ||
150 | #define XFIG BIT(2) | ||
151 | #define XCOMPAND(value) (((value) & 0x3) << 3) /* Bits 3:4 */ | ||
152 | #define XWDLEN2(value) (((value) & 0x7) << 5) /* Bits 5:7 */ | ||
153 | #define XFRLEN2(value) (((value) & 0x7f) << 8) /* Bits 8:14 */ | ||
154 | #define XPHASE BIT(15) | ||
155 | |||
156 | /************************* McBSP SRGR1 bit definitions ************************/ | ||
157 | #define CLKGDV(value) ((value) & 0x7f) /* Bits 0:7 */ | ||
158 | #define FWID(value) (((value) & 0xff) << 8) /* Bits 8:15 */ | ||
159 | |||
160 | /************************* McBSP SRGR2 bit definitions ************************/ | ||
161 | #define FPER(value) ((value) & 0x0fff) /* Bits 0:11 */ | ||
162 | #define FSGM BIT(12) | ||
163 | #define CLKSM BIT(13) | ||
164 | #define CLKSP BIT(14) | ||
165 | #define GSYNC BIT(15) | ||
166 | |||
167 | /************************* McBSP MCR1 bit definitions *************************/ | ||
168 | #define RMCM BIT(0) | ||
169 | #define RCBLK(value) (((value) & 0x7) << 2) /* Bits 2:4 */ | ||
170 | #define RPABLK(value) (((value) & 0x3) << 5) /* Bits 5:6 */ | ||
171 | #define RPBBLK(value) (((value) & 0x3) << 7) /* Bits 7:8 */ | ||
172 | |||
173 | /************************* McBSP MCR2 bit definitions *************************/ | ||
174 | #define XMCM(value) ((value) & 0x3) /* Bits 0:1 */ | ||
175 | #define XCBLK(value) (((value) & 0x7) << 2) /* Bits 2:4 */ | ||
176 | #define XPABLK(value) (((value) & 0x3) << 5) /* Bits 5:6 */ | ||
177 | #define XPBBLK(value) (((value) & 0x3) << 7) /* Bits 7:8 */ | ||
178 | |||
179 | /*********************** McBSP XCCR bit definitions *************************/ | ||
180 | #define XDISABLE BIT(0) | ||
181 | #define XDMAEN BIT(3) | ||
182 | #define DILB BIT(5) | ||
183 | #define XFULL_CYCLE BIT(11) | ||
184 | #define DXENDLY(value) (((value) & 0x3) << 12) /* Bits 12:13 */ | ||
185 | #define PPCONNECT BIT(14) | ||
186 | #define EXTCLKGATE BIT(15) | ||
187 | |||
188 | /********************** McBSP RCCR bit definitions *************************/ | ||
189 | #define RDISABLE BIT(0) | ||
190 | #define RDMAEN BIT(3) | ||
191 | #define RFULL_CYCLE BIT(11) | ||
192 | |||
193 | /********************** McBSP SYSCONFIG bit definitions ********************/ | ||
194 | #define SOFTRST BIT(1) | ||
195 | #define ENAWAKEUP BIT(2) | ||
196 | #define SIDLEMODE(value) (((value) & 0x3) << 3) | ||
197 | #define CLOCKACTIVITY(value) (((value) & 0x3) << 8) | ||
198 | |||
199 | /********************** McBSP SSELCR bit definitions ***********************/ | ||
200 | #define SIDETONEEN BIT(10) | ||
201 | |||
202 | /********************** McBSP Sidetone SYSCONFIG bit definitions ***********/ | ||
203 | #define ST_AUTOIDLE BIT(0) | ||
204 | |||
205 | /********************** McBSP Sidetone SGAINCR bit definitions *************/ | ||
206 | #define ST_CH0GAIN(value) ((value) & 0xffff) /* Bits 0:15 */ | ||
207 | #define ST_CH1GAIN(value) (((value) & 0xffff) << 16) /* Bits 16:31 */ | ||
208 | |||
209 | /********************** McBSP Sidetone SFIRCR bit definitions **************/ | ||
210 | #define ST_FIRCOEFF(value) ((value) & 0xffff) /* Bits 0:15 */ | ||
211 | |||
212 | /********************** McBSP Sidetone SSELCR bit definitions **************/ | ||
213 | #define ST_SIDETONEEN BIT(0) | ||
214 | #define ST_COEFFWREN BIT(1) | ||
215 | #define ST_COEFFWRDONE BIT(2) | ||
216 | |||
217 | /********************** McBSP DMA operating modes **************************/ | ||
218 | #define MCBSP_DMA_MODE_ELEMENT 0 | ||
219 | #define MCBSP_DMA_MODE_THRESHOLD 1 | ||
220 | #define MCBSP_DMA_MODE_FRAME 2 | ||
221 | |||
222 | /********************** McBSP WAKEUPEN bit definitions *********************/ | ||
223 | #define RSYNCERREN BIT(0) | ||
224 | #define RFSREN BIT(1) | ||
225 | #define REOFEN BIT(2) | ||
226 | #define RRDYEN BIT(3) | ||
227 | #define XSYNCERREN BIT(7) | ||
228 | #define XFSXEN BIT(8) | ||
229 | #define XEOFEN BIT(9) | ||
230 | #define XRDYEN BIT(10) | ||
231 | #define XEMPTYEOFEN BIT(14) | ||
232 | |||
233 | /* Clock signal muxing options */ | ||
234 | #define CLKR_SRC_CLKR 0 /* CLKR signal is from the CLKR pin */ | ||
235 | #define CLKR_SRC_CLKX 1 /* CLKR signal is from the CLKX pin */ | ||
236 | #define FSR_SRC_FSR 2 /* FSR signal is from the FSR pin */ | ||
237 | #define FSR_SRC_FSX 3 /* FSR signal is from the FSX pin */ | ||
238 | |||
239 | /* McBSP functional clock sources */ | ||
240 | #define MCBSP_CLKS_PRCM_SRC 0 | ||
241 | #define MCBSP_CLKS_PAD_SRC 1 | ||
242 | |||
243 | /* we don't do multichannel for now */ | ||
244 | struct omap_mcbsp_reg_cfg { | ||
245 | u16 spcr2; | ||
246 | u16 spcr1; | ||
247 | u16 rcr2; | ||
248 | u16 rcr1; | ||
249 | u16 xcr2; | ||
250 | u16 xcr1; | ||
251 | u16 srgr2; | ||
252 | u16 srgr1; | ||
253 | u16 mcr2; | ||
254 | u16 mcr1; | ||
255 | u16 pcr0; | ||
256 | u16 rcerc; | ||
257 | u16 rcerd; | ||
258 | u16 xcerc; | ||
259 | u16 xcerd; | ||
260 | u16 rcere; | ||
261 | u16 rcerf; | ||
262 | u16 xcere; | ||
263 | u16 xcerf; | ||
264 | u16 rcerg; | ||
265 | u16 rcerh; | ||
266 | u16 xcerg; | ||
267 | u16 xcerh; | ||
268 | u16 xccr; | ||
269 | u16 rccr; | ||
270 | }; | ||
271 | |||
272 | struct omap_mcbsp_st_data { | ||
273 | void __iomem *io_base_st; | ||
274 | bool running; | ||
275 | bool enabled; | ||
276 | s16 taps[128]; /* Sidetone filter coefficients */ | ||
277 | int nr_taps; /* Number of filter coefficients in use */ | ||
278 | s16 ch0gain; | ||
279 | s16 ch1gain; | ||
280 | }; | ||
281 | |||
282 | struct omap_mcbsp { | ||
283 | struct device *dev; | ||
284 | struct clk *fclk; | ||
285 | spinlock_t lock; | ||
286 | unsigned long phys_base; | ||
287 | unsigned long phys_dma_base; | ||
288 | void __iomem *io_base; | ||
289 | u8 id; | ||
290 | /* | ||
291 | * Flags indicating is the bus already activated and configured by | ||
292 | * another substream | ||
293 | */ | ||
294 | int active; | ||
295 | int configured; | ||
296 | u8 free; | ||
297 | |||
298 | int rx_irq; | ||
299 | int tx_irq; | ||
300 | |||
301 | /* Protect the field .free, while checking if the mcbsp is in use */ | ||
302 | struct omap_mcbsp_platform_data *pdata; | ||
303 | struct omap_mcbsp_st_data *st_data; | ||
304 | struct omap_mcbsp_reg_cfg cfg_regs; | ||
305 | struct omap_pcm_dma_data dma_data[2]; | ||
306 | int dma_op_mode; | ||
307 | u16 max_tx_thres; | ||
308 | u16 max_rx_thres; | ||
309 | void *reg_cache; | ||
310 | int reg_cache_size; | ||
311 | |||
312 | unsigned int fmt; | ||
313 | unsigned int in_freq; | ||
314 | int clk_div; | ||
315 | int wlen; | ||
316 | }; | ||
317 | |||
318 | void omap_mcbsp_config(struct omap_mcbsp *mcbsp, | ||
319 | const struct omap_mcbsp_reg_cfg *config); | ||
320 | void omap_mcbsp_set_tx_threshold(struct omap_mcbsp *mcbsp, u16 threshold); | ||
321 | void omap_mcbsp_set_rx_threshold(struct omap_mcbsp *mcbsp, u16 threshold); | ||
322 | u16 omap_mcbsp_get_tx_delay(struct omap_mcbsp *mcbsp); | ||
323 | u16 omap_mcbsp_get_rx_delay(struct omap_mcbsp *mcbsp); | ||
324 | int omap_mcbsp_get_dma_op_mode(struct omap_mcbsp *mcbsp); | ||
325 | int omap_mcbsp_request(struct omap_mcbsp *mcbsp); | ||
326 | void omap_mcbsp_free(struct omap_mcbsp *mcbsp); | ||
327 | void omap_mcbsp_start(struct omap_mcbsp *mcbsp, int tx, int rx); | ||
328 | void omap_mcbsp_stop(struct omap_mcbsp *mcbsp, int tx, int rx); | ||
329 | |||
330 | /* McBSP functional clock source changing function */ | ||
331 | int omap2_mcbsp_set_clks_src(struct omap_mcbsp *mcbsp, u8 fck_src_id); | ||
332 | |||
333 | /* McBSP signal muxing API */ | ||
334 | int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux); | ||
335 | |||
336 | /* Sidetone specific API */ | ||
337 | int omap_st_set_chgain(struct omap_mcbsp *mcbsp, int channel, s16 chgain); | ||
338 | int omap_st_get_chgain(struct omap_mcbsp *mcbsp, int channel, s16 *chgain); | ||
339 | int omap_st_enable(struct omap_mcbsp *mcbsp); | ||
340 | int omap_st_disable(struct omap_mcbsp *mcbsp); | ||
341 | int omap_st_is_enabled(struct omap_mcbsp *mcbsp); | ||
342 | |||
343 | int __devinit omap_mcbsp_init(struct platform_device *pdev); | ||
344 | void __devexit omap_mcbsp_sysfs_remove(struct omap_mcbsp *mcbsp); | ||
345 | |||
346 | #endif /* __ASOC_MCBSP_H */ | ||
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 597be412f1e4..abac4b690750 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c | |||
@@ -55,9 +55,8 @@ static int n810_spk_func; | |||
55 | static int n810_jack_func; | 55 | static int n810_jack_func; |
56 | static int n810_dmic_func; | 56 | static int n810_dmic_func; |
57 | 57 | ||
58 | static void n810_ext_control(struct snd_soc_codec *codec) | 58 | static void n810_ext_control(struct snd_soc_dapm_context *dapm) |
59 | { | 59 | { |
60 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
61 | int hp = 0, line1l = 0; | 60 | int hp = 0, line1l = 0; |
62 | 61 | ||
63 | switch (n810_jack_func) { | 62 | switch (n810_jack_func) { |
@@ -102,7 +101,7 @@ static int n810_startup(struct snd_pcm_substream *substream) | |||
102 | snd_pcm_hw_constraint_minmax(runtime, | 101 | snd_pcm_hw_constraint_minmax(runtime, |
103 | SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); | 102 | SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); |
104 | 103 | ||
105 | n810_ext_control(codec); | 104 | n810_ext_control(&codec->dapm); |
106 | return clk_enable(sys_clkout2); | 105 | return clk_enable(sys_clkout2); |
107 | } | 106 | } |
108 | 107 | ||
@@ -142,13 +141,13 @@ static int n810_get_spk(struct snd_kcontrol *kcontrol, | |||
142 | static int n810_set_spk(struct snd_kcontrol *kcontrol, | 141 | static int n810_set_spk(struct snd_kcontrol *kcontrol, |
143 | struct snd_ctl_elem_value *ucontrol) | 142 | struct snd_ctl_elem_value *ucontrol) |
144 | { | 143 | { |
145 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 144 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
146 | 145 | ||
147 | if (n810_spk_func == ucontrol->value.integer.value[0]) | 146 | if (n810_spk_func == ucontrol->value.integer.value[0]) |
148 | return 0; | 147 | return 0; |
149 | 148 | ||
150 | n810_spk_func = ucontrol->value.integer.value[0]; | 149 | n810_spk_func = ucontrol->value.integer.value[0]; |
151 | n810_ext_control(codec); | 150 | n810_ext_control(&card->dapm); |
152 | 151 | ||
153 | return 1; | 152 | return 1; |
154 | } | 153 | } |
@@ -164,13 +163,13 @@ static int n810_get_jack(struct snd_kcontrol *kcontrol, | |||
164 | static int n810_set_jack(struct snd_kcontrol *kcontrol, | 163 | static int n810_set_jack(struct snd_kcontrol *kcontrol, |
165 | struct snd_ctl_elem_value *ucontrol) | 164 | struct snd_ctl_elem_value *ucontrol) |
166 | { | 165 | { |
167 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 166 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
168 | 167 | ||
169 | if (n810_jack_func == ucontrol->value.integer.value[0]) | 168 | if (n810_jack_func == ucontrol->value.integer.value[0]) |
170 | return 0; | 169 | return 0; |
171 | 170 | ||
172 | n810_jack_func = ucontrol->value.integer.value[0]; | 171 | n810_jack_func = ucontrol->value.integer.value[0]; |
173 | n810_ext_control(codec); | 172 | n810_ext_control(&card->dapm); |
174 | 173 | ||
175 | return 1; | 174 | return 1; |
176 | } | 175 | } |
@@ -186,13 +185,13 @@ static int n810_get_input(struct snd_kcontrol *kcontrol, | |||
186 | static int n810_set_input(struct snd_kcontrol *kcontrol, | 185 | static int n810_set_input(struct snd_kcontrol *kcontrol, |
187 | struct snd_ctl_elem_value *ucontrol) | 186 | struct snd_ctl_elem_value *ucontrol) |
188 | { | 187 | { |
189 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 188 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
190 | 189 | ||
191 | if (n810_dmic_func == ucontrol->value.integer.value[0]) | 190 | if (n810_dmic_func == ucontrol->value.integer.value[0]) |
192 | return 0; | 191 | return 0; |
193 | 192 | ||
194 | n810_dmic_func = ucontrol->value.integer.value[0]; | 193 | n810_dmic_func = ucontrol->value.integer.value[0]; |
195 | n810_ext_control(codec); | 194 | n810_ext_control(&card->dapm); |
196 | 195 | ||
197 | return 1; | 196 | return 1; |
198 | } | 197 | } |
@@ -276,7 +275,7 @@ static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd) | |||
276 | static struct snd_soc_dai_link n810_dai = { | 275 | static struct snd_soc_dai_link n810_dai = { |
277 | .name = "TLV320AIC33", | 276 | .name = "TLV320AIC33", |
278 | .stream_name = "AIC33", | 277 | .stream_name = "AIC33", |
279 | .cpu_dai_name = "omap-mcbsp-dai.1", | 278 | .cpu_dai_name = "omap-mcbsp.2", |
280 | .platform_name = "omap-pcm-audio", | 279 | .platform_name = "omap-pcm-audio", |
281 | .codec_name = "tlv320aic3x-codec.2-0018", | 280 | .codec_name = "tlv320aic3x-codec.2-0018", |
282 | .codec_dai_name = "tlv320aic3x-hifi", | 281 | .codec_dai_name = "tlv320aic3x-hifi", |
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c new file mode 100644 index 000000000000..93bb8eee22b3 --- /dev/null +++ b/sound/soc/omap/omap-abe-twl6040.c | |||
@@ -0,0 +1,349 @@ | |||
1 | /* | ||
2 | * omap-abe-twl6040.c -- SoC audio for TI OMAP based boards with ABE and | ||
3 | * twl6040 codec | ||
4 | * | ||
5 | * Author: Misael Lopez Cruz <misael.lopez@ti.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * version 2 as published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
19 | * 02110-1301 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/clk.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/mfd/twl6040.h> | ||
26 | #include <linux/platform_data/omap-abe-twl6040.h> | ||
27 | #include <linux/module.h> | ||
28 | |||
29 | #include <sound/core.h> | ||
30 | #include <sound/pcm.h> | ||
31 | #include <sound/soc.h> | ||
32 | #include <sound/jack.h> | ||
33 | |||
34 | #include <asm/mach-types.h> | ||
35 | #include <plat/hardware.h> | ||
36 | #include <plat/mux.h> | ||
37 | |||
38 | #include "omap-dmic.h" | ||
39 | #include "omap-mcpdm.h" | ||
40 | #include "omap-pcm.h" | ||
41 | #include "../codecs/twl6040.h" | ||
42 | |||
43 | static int omap_abe_hw_params(struct snd_pcm_substream *substream, | ||
44 | struct snd_pcm_hw_params *params) | ||
45 | { | ||
46 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
47 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
48 | struct snd_soc_codec *codec = rtd->codec; | ||
49 | struct snd_soc_card *card = codec->card; | ||
50 | struct omap_abe_twl6040_data *pdata = dev_get_platdata(card->dev); | ||
51 | int clk_id, freq; | ||
52 | int ret; | ||
53 | |||
54 | clk_id = twl6040_get_clk_id(rtd->codec); | ||
55 | if (clk_id == TWL6040_SYSCLK_SEL_HPPLL) | ||
56 | freq = pdata->mclk_freq; | ||
57 | else if (clk_id == TWL6040_SYSCLK_SEL_LPPLL) | ||
58 | freq = 32768; | ||
59 | else | ||
60 | return -EINVAL; | ||
61 | |||
62 | /* set the codec mclk */ | ||
63 | ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq, | ||
64 | SND_SOC_CLOCK_IN); | ||
65 | if (ret) { | ||
66 | printk(KERN_ERR "can't set codec system clock\n"); | ||
67 | return ret; | ||
68 | } | ||
69 | return ret; | ||
70 | } | ||
71 | |||
72 | static struct snd_soc_ops omap_abe_ops = { | ||
73 | .hw_params = omap_abe_hw_params, | ||
74 | }; | ||
75 | |||
76 | static int omap_abe_dmic_hw_params(struct snd_pcm_substream *substream, | ||
77 | struct snd_pcm_hw_params *params) | ||
78 | { | ||
79 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
80 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
81 | int ret = 0; | ||
82 | |||
83 | ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_SYSCLK_PAD_CLKS, | ||
84 | 19200000, SND_SOC_CLOCK_IN); | ||
85 | if (ret < 0) { | ||
86 | printk(KERN_ERR "can't set DMIC cpu system clock\n"); | ||
87 | return ret; | ||
88 | } | ||
89 | ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_ABE_DMIC_CLK, 2400000, | ||
90 | SND_SOC_CLOCK_OUT); | ||
91 | if (ret < 0) { | ||
92 | printk(KERN_ERR "can't set DMIC output clock\n"); | ||
93 | return ret; | ||
94 | } | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static struct snd_soc_ops omap_abe_dmic_ops = { | ||
99 | .hw_params = omap_abe_dmic_hw_params, | ||
100 | }; | ||
101 | |||
102 | /* Headset jack */ | ||
103 | static struct snd_soc_jack hs_jack; | ||
104 | |||
105 | /*Headset jack detection DAPM pins */ | ||
106 | static struct snd_soc_jack_pin hs_jack_pins[] = { | ||
107 | { | ||
108 | .pin = "Headset Mic", | ||
109 | .mask = SND_JACK_MICROPHONE, | ||
110 | }, | ||
111 | { | ||
112 | .pin = "Headset Stereophone", | ||
113 | .mask = SND_JACK_HEADPHONE, | ||
114 | }, | ||
115 | }; | ||
116 | |||
117 | /* SDP4430 machine DAPM */ | ||
118 | static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { | ||
119 | /* Outputs */ | ||
120 | SND_SOC_DAPM_HP("Headset Stereophone", NULL), | ||
121 | SND_SOC_DAPM_SPK("Earphone Spk", NULL), | ||
122 | SND_SOC_DAPM_SPK("Ext Spk", NULL), | ||
123 | SND_SOC_DAPM_LINE("Line Out", NULL), | ||
124 | SND_SOC_DAPM_SPK("Vibrator", NULL), | ||
125 | |||
126 | /* Inputs */ | ||
127 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
128 | SND_SOC_DAPM_MIC("Main Handset Mic", NULL), | ||
129 | SND_SOC_DAPM_MIC("Sub Handset Mic", NULL), | ||
130 | SND_SOC_DAPM_LINE("Line In", NULL), | ||
131 | }; | ||
132 | |||
133 | static const struct snd_soc_dapm_route audio_map[] = { | ||
134 | /* Routings for outputs */ | ||
135 | {"Headset Stereophone", NULL, "HSOL"}, | ||
136 | {"Headset Stereophone", NULL, "HSOR"}, | ||
137 | |||
138 | {"Earphone Spk", NULL, "EP"}, | ||
139 | |||
140 | {"Ext Spk", NULL, "HFL"}, | ||
141 | {"Ext Spk", NULL, "HFR"}, | ||
142 | |||
143 | {"Line Out", NULL, "AUXL"}, | ||
144 | {"Line Out", NULL, "AUXR"}, | ||
145 | |||
146 | {"Vibrator", NULL, "VIBRAL"}, | ||
147 | {"Vibrator", NULL, "VIBRAR"}, | ||
148 | |||
149 | /* Routings for inputs */ | ||
150 | {"HSMIC", NULL, "Headset Mic"}, | ||
151 | {"Headset Mic", NULL, "Headset Mic Bias"}, | ||
152 | |||
153 | {"MAINMIC", NULL, "Main Handset Mic"}, | ||
154 | {"Main Handset Mic", NULL, "Main Mic Bias"}, | ||
155 | |||
156 | {"SUBMIC", NULL, "Sub Handset Mic"}, | ||
157 | {"Sub Handset Mic", NULL, "Main Mic Bias"}, | ||
158 | |||
159 | {"AFML", NULL, "Line In"}, | ||
160 | {"AFMR", NULL, "Line In"}, | ||
161 | }; | ||
162 | |||
163 | static inline void twl6040_disconnect_pin(struct snd_soc_dapm_context *dapm, | ||
164 | int connected, char *pin) | ||
165 | { | ||
166 | if (!connected) | ||
167 | snd_soc_dapm_disable_pin(dapm, pin); | ||
168 | } | ||
169 | |||
170 | static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd) | ||
171 | { | ||
172 | struct snd_soc_codec *codec = rtd->codec; | ||
173 | struct snd_soc_card *card = codec->card; | ||
174 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
175 | struct omap_abe_twl6040_data *pdata = dev_get_platdata(card->dev); | ||
176 | int hs_trim; | ||
177 | int ret = 0; | ||
178 | |||
179 | /* Disable not connected paths if not used */ | ||
180 | twl6040_disconnect_pin(dapm, pdata->has_hs, "Headset Stereophone"); | ||
181 | twl6040_disconnect_pin(dapm, pdata->has_hf, "Ext Spk"); | ||
182 | twl6040_disconnect_pin(dapm, pdata->has_ep, "Earphone Spk"); | ||
183 | twl6040_disconnect_pin(dapm, pdata->has_aux, "Line Out"); | ||
184 | twl6040_disconnect_pin(dapm, pdata->has_vibra, "Vinrator"); | ||
185 | twl6040_disconnect_pin(dapm, pdata->has_hsmic, "Headset Mic"); | ||
186 | twl6040_disconnect_pin(dapm, pdata->has_mainmic, "Main Handset Mic"); | ||
187 | twl6040_disconnect_pin(dapm, pdata->has_submic, "Sub Handset Mic"); | ||
188 | twl6040_disconnect_pin(dapm, pdata->has_afm, "Line In"); | ||
189 | |||
190 | /* | ||
191 | * Configure McPDM offset cancellation based on the HSOTRIM value from | ||
192 | * twl6040. | ||
193 | */ | ||
194 | hs_trim = twl6040_get_trim_value(codec, TWL6040_TRIM_HSOTRIM); | ||
195 | omap_mcpdm_configure_dn_offsets(rtd, TWL6040_HSF_TRIM_LEFT(hs_trim), | ||
196 | TWL6040_HSF_TRIM_RIGHT(hs_trim)); | ||
197 | |||
198 | /* Headset jack detection only if it is supported */ | ||
199 | if (pdata->jack_detection) { | ||
200 | ret = snd_soc_jack_new(codec, "Headset Jack", | ||
201 | SND_JACK_HEADSET, &hs_jack); | ||
202 | if (ret) | ||
203 | return ret; | ||
204 | |||
205 | ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), | ||
206 | hs_jack_pins); | ||
207 | twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); | ||
208 | } | ||
209 | |||
210 | return ret; | ||
211 | } | ||
212 | |||
213 | static const struct snd_soc_dapm_widget dmic_dapm_widgets[] = { | ||
214 | SND_SOC_DAPM_MIC("Digital Mic", NULL), | ||
215 | }; | ||
216 | |||
217 | static const struct snd_soc_dapm_route dmic_audio_map[] = { | ||
218 | {"DMic", NULL, "Digital Mic"}, | ||
219 | {"Digital Mic", NULL, "Digital Mic1 Bias"}, | ||
220 | }; | ||
221 | |||
222 | static int omap_abe_dmic_init(struct snd_soc_pcm_runtime *rtd) | ||
223 | { | ||
224 | struct snd_soc_codec *codec = rtd->codec; | ||
225 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
226 | int ret; | ||
227 | |||
228 | ret = snd_soc_dapm_new_controls(dapm, dmic_dapm_widgets, | ||
229 | ARRAY_SIZE(dmic_dapm_widgets)); | ||
230 | if (ret) | ||
231 | return ret; | ||
232 | |||
233 | return snd_soc_dapm_add_routes(dapm, dmic_audio_map, | ||
234 | ARRAY_SIZE(dmic_audio_map)); | ||
235 | } | ||
236 | |||
237 | /* Digital audio interface glue - connects codec <--> CPU */ | ||
238 | static struct snd_soc_dai_link twl6040_dmic_dai[] = { | ||
239 | { | ||
240 | .name = "TWL6040", | ||
241 | .stream_name = "TWL6040", | ||
242 | .cpu_dai_name = "omap-mcpdm", | ||
243 | .codec_dai_name = "twl6040-legacy", | ||
244 | .platform_name = "omap-pcm-audio", | ||
245 | .codec_name = "twl6040-codec", | ||
246 | .init = omap_abe_twl6040_init, | ||
247 | .ops = &omap_abe_ops, | ||
248 | }, | ||
249 | { | ||
250 | .name = "DMIC", | ||
251 | .stream_name = "DMIC Capture", | ||
252 | .cpu_dai_name = "omap-dmic", | ||
253 | .codec_dai_name = "dmic-hifi", | ||
254 | .platform_name = "omap-pcm-audio", | ||
255 | .codec_name = "dmic-codec", | ||
256 | .init = omap_abe_dmic_init, | ||
257 | .ops = &omap_abe_dmic_ops, | ||
258 | }, | ||
259 | }; | ||
260 | |||
261 | static struct snd_soc_dai_link twl6040_only_dai[] = { | ||
262 | { | ||
263 | .name = "TWL6040", | ||
264 | .stream_name = "TWL6040", | ||
265 | .cpu_dai_name = "omap-mcpdm", | ||
266 | .codec_dai_name = "twl6040-legacy", | ||
267 | .platform_name = "omap-pcm-audio", | ||
268 | .codec_name = "twl6040-codec", | ||
269 | .init = omap_abe_twl6040_init, | ||
270 | .ops = &omap_abe_ops, | ||
271 | }, | ||
272 | }; | ||
273 | |||
274 | /* Audio machine driver */ | ||
275 | static struct snd_soc_card omap_abe_card = { | ||
276 | .owner = THIS_MODULE, | ||
277 | |||
278 | .dapm_widgets = twl6040_dapm_widgets, | ||
279 | .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets), | ||
280 | .dapm_routes = audio_map, | ||
281 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
282 | }; | ||
283 | |||
284 | static __devinit int omap_abe_probe(struct platform_device *pdev) | ||
285 | { | ||
286 | struct omap_abe_twl6040_data *pdata = dev_get_platdata(&pdev->dev); | ||
287 | struct snd_soc_card *card = &omap_abe_card; | ||
288 | int ret; | ||
289 | |||
290 | card->dev = &pdev->dev; | ||
291 | |||
292 | if (!pdata) { | ||
293 | dev_err(&pdev->dev, "Missing pdata\n"); | ||
294 | return -ENODEV; | ||
295 | } | ||
296 | |||
297 | if (pdata->card_name) { | ||
298 | card->name = pdata->card_name; | ||
299 | } else { | ||
300 | dev_err(&pdev->dev, "Card name is not provided\n"); | ||
301 | return -ENODEV; | ||
302 | } | ||
303 | |||
304 | if (!pdata->mclk_freq) { | ||
305 | dev_err(&pdev->dev, "MCLK frequency missing\n"); | ||
306 | return -ENODEV; | ||
307 | } | ||
308 | |||
309 | if (pdata->has_dmic) { | ||
310 | card->dai_link = twl6040_dmic_dai; | ||
311 | card->num_links = ARRAY_SIZE(twl6040_dmic_dai); | ||
312 | } else { | ||
313 | card->dai_link = twl6040_only_dai; | ||
314 | card->num_links = ARRAY_SIZE(twl6040_only_dai); | ||
315 | } | ||
316 | |||
317 | ret = snd_soc_register_card(card); | ||
318 | if (ret) | ||
319 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", | ||
320 | ret); | ||
321 | |||
322 | return ret; | ||
323 | } | ||
324 | |||
325 | static int __devexit omap_abe_remove(struct platform_device *pdev) | ||
326 | { | ||
327 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
328 | |||
329 | snd_soc_unregister_card(card); | ||
330 | |||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | static struct platform_driver omap_abe_driver = { | ||
335 | .driver = { | ||
336 | .name = "omap-abe-twl6040", | ||
337 | .owner = THIS_MODULE, | ||
338 | .pm = &snd_soc_pm_ops, | ||
339 | }, | ||
340 | .probe = omap_abe_probe, | ||
341 | .remove = __devexit_p(omap_abe_remove), | ||
342 | }; | ||
343 | |||
344 | module_platform_driver(omap_abe_driver); | ||
345 | |||
346 | MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>"); | ||
347 | MODULE_DESCRIPTION("ALSA SoC for OMAP boards with ABE and twl6040 codec"); | ||
348 | MODULE_LICENSE("GPL"); | ||
349 | MODULE_ALIAS("platform:omap-abe-twl6040"); | ||
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 0855c1cfa7fd..4dcb5a7e40e8 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c | |||
@@ -113,12 +113,10 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream, | |||
113 | 113 | ||
114 | mutex_lock(&dmic->mutex); | 114 | mutex_lock(&dmic->mutex); |
115 | 115 | ||
116 | if (!dai->active) { | 116 | if (!dai->active) |
117 | snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24); | ||
118 | dmic->active = 1; | 117 | dmic->active = 1; |
119 | } else { | 118 | else |
120 | ret = -EBUSY; | 119 | ret = -EBUSY; |
121 | } | ||
122 | 120 | ||
123 | mutex_unlock(&dmic->mutex); | 121 | mutex_unlock(&dmic->mutex); |
124 | 122 | ||
@@ -445,6 +443,7 @@ static struct snd_soc_dai_driver omap_dmic_dai = { | |||
445 | .channels_max = 6, | 443 | .channels_max = 6, |
446 | .rates = SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000, | 444 | .rates = SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000, |
447 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | 445 | .formats = SNDRV_PCM_FMTBIT_S32_LE, |
446 | .sig_bits = 24, | ||
448 | }, | 447 | }, |
449 | .ops = &omap_dmic_dai_ops, | 448 | .ops = &omap_dmic_dai_ops, |
450 | }; | 449 | }; |
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 017371913ec3..6912ac7cb625 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/device.h> | 27 | #include <linux/device.h> |
28 | #include <linux/pm_runtime.h> | ||
28 | #include <sound/core.h> | 29 | #include <sound/core.h> |
29 | #include <sound/pcm.h> | 30 | #include <sound/pcm.h> |
30 | #include <sound/pcm_params.h> | 31 | #include <sound/pcm_params.h> |
@@ -33,6 +34,7 @@ | |||
33 | 34 | ||
34 | #include <plat/dma.h> | 35 | #include <plat/dma.h> |
35 | #include <plat/mcbsp.h> | 36 | #include <plat/mcbsp.h> |
37 | #include "mcbsp.h" | ||
36 | #include "omap-mcbsp.h" | 38 | #include "omap-mcbsp.h" |
37 | #include "omap-pcm.h" | 39 | #include "omap-pcm.h" |
38 | 40 | ||
@@ -46,42 +48,31 @@ | |||
46 | .private_value = (unsigned long) &(struct soc_mixer_control) \ | 48 | .private_value = (unsigned long) &(struct soc_mixer_control) \ |
47 | {.min = xmin, .max = xmax} } | 49 | {.min = xmin, .max = xmax} } |
48 | 50 | ||
49 | struct omap_mcbsp_data { | 51 | enum { |
50 | unsigned int bus_id; | 52 | OMAP_MCBSP_WORD_8 = 0, |
51 | struct omap_mcbsp_reg_cfg regs; | 53 | OMAP_MCBSP_WORD_12, |
52 | unsigned int fmt; | 54 | OMAP_MCBSP_WORD_16, |
53 | /* | 55 | OMAP_MCBSP_WORD_20, |
54 | * Flags indicating is the bus already activated and configured by | 56 | OMAP_MCBSP_WORD_24, |
55 | * another substream | 57 | OMAP_MCBSP_WORD_32, |
56 | */ | ||
57 | int active; | ||
58 | int configured; | ||
59 | unsigned int in_freq; | ||
60 | int clk_div; | ||
61 | int wlen; | ||
62 | }; | 58 | }; |
63 | 59 | ||
64 | static struct omap_mcbsp_data mcbsp_data[NUM_LINKS]; | ||
65 | |||
66 | /* | 60 | /* |
67 | * Stream DMA parameters. DMA request line and port address are set runtime | 61 | * Stream DMA parameters. DMA request line and port address are set runtime |
68 | * since they are different between OMAP1 and later OMAPs | 62 | * since they are different between OMAP1 and later OMAPs |
69 | */ | 63 | */ |
70 | static struct omap_pcm_dma_data omap_mcbsp_dai_dma_params[NUM_LINKS][2]; | ||
71 | |||
72 | static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) | 64 | static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) |
73 | { | 65 | { |
74 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 66 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
75 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 67 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
76 | struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); | 68 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
77 | struct omap_pcm_dma_data *dma_data; | 69 | struct omap_pcm_dma_data *dma_data; |
78 | int dma_op_mode = omap_mcbsp_get_dma_op_mode(mcbsp_data->bus_id); | ||
79 | int words; | 70 | int words; |
80 | 71 | ||
81 | dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | 72 | dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); |
82 | 73 | ||
83 | /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ | 74 | /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ |
84 | if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) | 75 | if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) |
85 | /* | 76 | /* |
86 | * Configure McBSP threshold based on either: | 77 | * Configure McBSP threshold based on either: |
87 | * packet_size, when the sDMA is in packet mode, or | 78 | * packet_size, when the sDMA is in packet mode, or |
@@ -91,15 +82,15 @@ static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) | |||
91 | words = dma_data->packet_size; | 82 | words = dma_data->packet_size; |
92 | else | 83 | else |
93 | words = snd_pcm_lib_period_bytes(substream) / | 84 | words = snd_pcm_lib_period_bytes(substream) / |
94 | (mcbsp_data->wlen / 8); | 85 | (mcbsp->wlen / 8); |
95 | else | 86 | else |
96 | words = 1; | 87 | words = 1; |
97 | 88 | ||
98 | /* Configure McBSP internal buffer usage */ | 89 | /* Configure McBSP internal buffer usage */ |
99 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 90 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
100 | omap_mcbsp_set_tx_threshold(mcbsp_data->bus_id, words); | 91 | omap_mcbsp_set_tx_threshold(mcbsp, words); |
101 | else | 92 | else |
102 | omap_mcbsp_set_rx_threshold(mcbsp_data->bus_id, words); | 93 | omap_mcbsp_set_rx_threshold(mcbsp, words); |
103 | } | 94 | } |
104 | 95 | ||
105 | static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params, | 96 | static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params, |
@@ -109,12 +100,12 @@ static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params, | |||
109 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE); | 100 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE); |
110 | struct snd_interval *channels = hw_param_interval(params, | 101 | struct snd_interval *channels = hw_param_interval(params, |
111 | SNDRV_PCM_HW_PARAM_CHANNELS); | 102 | SNDRV_PCM_HW_PARAM_CHANNELS); |
112 | struct omap_mcbsp_data *mcbsp_data = rule->private; | 103 | struct omap_mcbsp *mcbsp = rule->private; |
113 | struct snd_interval frames; | 104 | struct snd_interval frames; |
114 | int size; | 105 | int size; |
115 | 106 | ||
116 | snd_interval_any(&frames); | 107 | snd_interval_any(&frames); |
117 | size = omap_mcbsp_get_fifo_size(mcbsp_data->bus_id); | 108 | size = mcbsp->pdata->buffer_size; |
118 | 109 | ||
119 | frames.min = size / channels->min; | 110 | frames.min = size / channels->min; |
120 | frames.integer = 1; | 111 | frames.integer = 1; |
@@ -124,12 +115,11 @@ static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params, | |||
124 | static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, | 115 | static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, |
125 | struct snd_soc_dai *cpu_dai) | 116 | struct snd_soc_dai *cpu_dai) |
126 | { | 117 | { |
127 | struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); | 118 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
128 | int bus_id = mcbsp_data->bus_id; | ||
129 | int err = 0; | 119 | int err = 0; |
130 | 120 | ||
131 | if (!cpu_dai->active) | 121 | if (!cpu_dai->active) |
132 | err = omap_mcbsp_request(bus_id); | 122 | err = omap_mcbsp_request(mcbsp); |
133 | 123 | ||
134 | /* | 124 | /* |
135 | * OMAP3 McBSP FIFO is word structured. | 125 | * OMAP3 McBSP FIFO is word structured. |
@@ -146,16 +136,16 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, | |||
146 | * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) | 136 | * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) |
147 | * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) | 137 | * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) |
148 | */ | 138 | */ |
149 | if (cpu_is_omap34xx() || cpu_is_omap44xx()) { | 139 | if (mcbsp->pdata->buffer_size) { |
150 | /* | 140 | /* |
151 | * Rule for the buffer size. We should not allow | 141 | * Rule for the buffer size. We should not allow |
152 | * smaller buffer than the FIFO size to avoid underruns | 142 | * smaller buffer than the FIFO size to avoid underruns |
153 | */ | 143 | */ |
154 | snd_pcm_hw_rule_add(substream->runtime, 0, | 144 | snd_pcm_hw_rule_add(substream->runtime, 0, |
155 | SNDRV_PCM_HW_PARAM_CHANNELS, | 145 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, |
156 | omap_mcbsp_hwrule_min_buffersize, | 146 | omap_mcbsp_hwrule_min_buffersize, |
157 | mcbsp_data, | 147 | mcbsp, |
158 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1); | 148 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); |
159 | 149 | ||
160 | /* Make sure, that the period size is always even */ | 150 | /* Make sure, that the period size is always even */ |
161 | snd_pcm_hw_constraint_step(substream->runtime, 0, | 151 | snd_pcm_hw_constraint_step(substream->runtime, 0, |
@@ -168,33 +158,33 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, | |||
168 | static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream, | 158 | static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream, |
169 | struct snd_soc_dai *cpu_dai) | 159 | struct snd_soc_dai *cpu_dai) |
170 | { | 160 | { |
171 | struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); | 161 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
172 | 162 | ||
173 | if (!cpu_dai->active) { | 163 | if (!cpu_dai->active) { |
174 | omap_mcbsp_free(mcbsp_data->bus_id); | 164 | omap_mcbsp_free(mcbsp); |
175 | mcbsp_data->configured = 0; | 165 | mcbsp->configured = 0; |
176 | } | 166 | } |
177 | } | 167 | } |
178 | 168 | ||
179 | static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd, | 169 | static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd, |
180 | struct snd_soc_dai *cpu_dai) | 170 | struct snd_soc_dai *cpu_dai) |
181 | { | 171 | { |
182 | struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); | 172 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
183 | int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); | 173 | int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); |
184 | 174 | ||
185 | switch (cmd) { | 175 | switch (cmd) { |
186 | case SNDRV_PCM_TRIGGER_START: | 176 | case SNDRV_PCM_TRIGGER_START: |
187 | case SNDRV_PCM_TRIGGER_RESUME: | 177 | case SNDRV_PCM_TRIGGER_RESUME: |
188 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 178 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
189 | mcbsp_data->active++; | 179 | mcbsp->active++; |
190 | omap_mcbsp_start(mcbsp_data->bus_id, play, !play); | 180 | omap_mcbsp_start(mcbsp, play, !play); |
191 | break; | 181 | break; |
192 | 182 | ||
193 | case SNDRV_PCM_TRIGGER_STOP: | 183 | case SNDRV_PCM_TRIGGER_STOP: |
194 | case SNDRV_PCM_TRIGGER_SUSPEND: | 184 | case SNDRV_PCM_TRIGGER_SUSPEND: |
195 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 185 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
196 | omap_mcbsp_stop(mcbsp_data->bus_id, play, !play); | 186 | omap_mcbsp_stop(mcbsp, play, !play); |
197 | mcbsp_data->active--; | 187 | mcbsp->active--; |
198 | break; | 188 | break; |
199 | default: | 189 | default: |
200 | err = -EINVAL; | 190 | err = -EINVAL; |
@@ -209,14 +199,14 @@ static snd_pcm_sframes_t omap_mcbsp_dai_delay( | |||
209 | { | 199 | { |
210 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 200 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
211 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 201 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
212 | struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); | 202 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
213 | u16 fifo_use; | 203 | u16 fifo_use; |
214 | snd_pcm_sframes_t delay; | 204 | snd_pcm_sframes_t delay; |
215 | 205 | ||
216 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 206 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
217 | fifo_use = omap_mcbsp_get_tx_delay(mcbsp_data->bus_id); | 207 | fifo_use = omap_mcbsp_get_tx_delay(mcbsp); |
218 | else | 208 | else |
219 | fifo_use = omap_mcbsp_get_rx_delay(mcbsp_data->bus_id); | 209 | fifo_use = omap_mcbsp_get_rx_delay(mcbsp); |
220 | 210 | ||
221 | /* | 211 | /* |
222 | * Divide the used locations with the channel count to get the | 212 | * Divide the used locations with the channel count to get the |
@@ -232,19 +222,14 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
232 | struct snd_pcm_hw_params *params, | 222 | struct snd_pcm_hw_params *params, |
233 | struct snd_soc_dai *cpu_dai) | 223 | struct snd_soc_dai *cpu_dai) |
234 | { | 224 | { |
235 | struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); | 225 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
236 | struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; | 226 | struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs; |
237 | struct omap_pcm_dma_data *dma_data; | 227 | struct omap_pcm_dma_data *dma_data; |
238 | int dma, bus_id = mcbsp_data->bus_id; | ||
239 | int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT; | 228 | int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT; |
240 | int pkt_size = 0; | 229 | int pkt_size = 0; |
241 | unsigned long port; | ||
242 | unsigned int format, div, framesize, master; | 230 | unsigned int format, div, framesize, master; |
243 | 231 | ||
244 | dma_data = &omap_mcbsp_dai_dma_params[cpu_dai->id][substream->stream]; | 232 | dma_data = &mcbsp->dma_data[substream->stream]; |
245 | |||
246 | dma = omap_mcbsp_dma_ch_params(bus_id, substream->stream); | ||
247 | port = omap_mcbsp_dma_reg_params(bus_id, substream->stream); | ||
248 | 233 | ||
249 | switch (params_format(params)) { | 234 | switch (params_format(params)) { |
250 | case SNDRV_PCM_FORMAT_S16_LE: | 235 | case SNDRV_PCM_FORMAT_S16_LE: |
@@ -258,20 +243,17 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
258 | default: | 243 | default: |
259 | return -EINVAL; | 244 | return -EINVAL; |
260 | } | 245 | } |
261 | if (cpu_is_omap34xx() || cpu_is_omap44xx()) { | 246 | if (mcbsp->pdata->buffer_size) { |
262 | dma_data->set_threshold = omap_mcbsp_set_threshold; | 247 | dma_data->set_threshold = omap_mcbsp_set_threshold; |
263 | /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ | 248 | /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ |
264 | if (omap_mcbsp_get_dma_op_mode(bus_id) == | 249 | if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) { |
265 | MCBSP_DMA_MODE_THRESHOLD) { | ||
266 | int period_words, max_thrsh; | 250 | int period_words, max_thrsh; |
267 | 251 | ||
268 | period_words = params_period_bytes(params) / (wlen / 8); | 252 | period_words = params_period_bytes(params) / (wlen / 8); |
269 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 253 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
270 | max_thrsh = omap_mcbsp_get_max_tx_threshold( | 254 | max_thrsh = mcbsp->max_tx_thres; |
271 | mcbsp_data->bus_id); | ||
272 | else | 255 | else |
273 | max_thrsh = omap_mcbsp_get_max_rx_threshold( | 256 | max_thrsh = mcbsp->max_rx_thres; |
274 | mcbsp_data->bus_id); | ||
275 | /* | 257 | /* |
276 | * If the period contains less or equal number of words, | 258 | * If the period contains less or equal number of words, |
277 | * we are using the original threshold mode setup: | 259 | * we are using the original threshold mode setup: |
@@ -304,15 +286,12 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
304 | } | 286 | } |
305 | } | 287 | } |
306 | 288 | ||
307 | dma_data->name = substream->stream ? "Audio Capture" : "Audio Playback"; | ||
308 | dma_data->dma_req = dma; | ||
309 | dma_data->port_addr = port; | ||
310 | dma_data->sync_mode = sync_mode; | 289 | dma_data->sync_mode = sync_mode; |
311 | dma_data->packet_size = pkt_size; | 290 | dma_data->packet_size = pkt_size; |
312 | 291 | ||
313 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); | 292 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); |
314 | 293 | ||
315 | if (mcbsp_data->configured) { | 294 | if (mcbsp->configured) { |
316 | /* McBSP already configured by another stream */ | 295 | /* McBSP already configured by another stream */ |
317 | return 0; | 296 | return 0; |
318 | } | 297 | } |
@@ -321,7 +300,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
321 | regs->xcr2 &= ~(RPHASE | XFRLEN2(0x7f) | XWDLEN2(7)); | 300 | regs->xcr2 &= ~(RPHASE | XFRLEN2(0x7f) | XWDLEN2(7)); |
322 | regs->rcr1 &= ~(RFRLEN1(0x7f) | RWDLEN1(7)); | 301 | regs->rcr1 &= ~(RFRLEN1(0x7f) | RWDLEN1(7)); |
323 | regs->xcr1 &= ~(XFRLEN1(0x7f) | XWDLEN1(7)); | 302 | regs->xcr1 &= ~(XFRLEN1(0x7f) | XWDLEN1(7)); |
324 | format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; | 303 | format = mcbsp->fmt & SND_SOC_DAIFMT_FORMAT_MASK; |
325 | wpf = channels = params_channels(params); | 304 | wpf = channels = params_channels(params); |
326 | if (channels == 2 && (format == SND_SOC_DAIFMT_I2S || | 305 | if (channels == 2 && (format == SND_SOC_DAIFMT_I2S || |
327 | format == SND_SOC_DAIFMT_LEFT_J)) { | 306 | format == SND_SOC_DAIFMT_LEFT_J)) { |
@@ -359,10 +338,10 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
359 | 338 | ||
360 | /* In McBSP master modes, FRAME (i.e. sample rate) is generated | 339 | /* In McBSP master modes, FRAME (i.e. sample rate) is generated |
361 | * by _counting_ BCLKs. Calculate frame size in BCLKs */ | 340 | * by _counting_ BCLKs. Calculate frame size in BCLKs */ |
362 | master = mcbsp_data->fmt & SND_SOC_DAIFMT_MASTER_MASK; | 341 | master = mcbsp->fmt & SND_SOC_DAIFMT_MASTER_MASK; |
363 | if (master == SND_SOC_DAIFMT_CBS_CFS) { | 342 | if (master == SND_SOC_DAIFMT_CBS_CFS) { |
364 | div = mcbsp_data->clk_div ? mcbsp_data->clk_div : 1; | 343 | div = mcbsp->clk_div ? mcbsp->clk_div : 1; |
365 | framesize = (mcbsp_data->in_freq / div) / params_rate(params); | 344 | framesize = (mcbsp->in_freq / div) / params_rate(params); |
366 | 345 | ||
367 | if (framesize < wlen * channels) { | 346 | if (framesize < wlen * channels) { |
368 | printk(KERN_ERR "%s: not enough bandwidth for desired rate and " | 347 | printk(KERN_ERR "%s: not enough bandwidth for desired rate and " |
@@ -388,9 +367,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
388 | break; | 367 | break; |
389 | } | 368 | } |
390 | 369 | ||
391 | omap_mcbsp_config(bus_id, &mcbsp_data->regs); | 370 | omap_mcbsp_config(mcbsp, &mcbsp->cfg_regs); |
392 | mcbsp_data->wlen = wlen; | 371 | mcbsp->wlen = wlen; |
393 | mcbsp_data->configured = 1; | 372 | mcbsp->configured = 1; |
394 | 373 | ||
395 | return 0; | 374 | return 0; |
396 | } | 375 | } |
@@ -402,14 +381,14 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
402 | static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, | 381 | static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, |
403 | unsigned int fmt) | 382 | unsigned int fmt) |
404 | { | 383 | { |
405 | struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); | 384 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
406 | struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; | 385 | struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs; |
407 | bool inv_fs = false; | 386 | bool inv_fs = false; |
408 | 387 | ||
409 | if (mcbsp_data->configured) | 388 | if (mcbsp->configured) |
410 | return 0; | 389 | return 0; |
411 | 390 | ||
412 | mcbsp_data->fmt = fmt; | 391 | mcbsp->fmt = fmt; |
413 | memset(regs, 0, sizeof(*regs)); | 392 | memset(regs, 0, sizeof(*regs)); |
414 | /* Generic McBSP register settings */ | 393 | /* Generic McBSP register settings */ |
415 | regs->spcr2 |= XINTM(3) | FREE; | 394 | regs->spcr2 |= XINTM(3) | FREE; |
@@ -504,13 +483,13 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
504 | static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai, | 483 | static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai, |
505 | int div_id, int div) | 484 | int div_id, int div) |
506 | { | 485 | { |
507 | struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); | 486 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
508 | struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; | 487 | struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs; |
509 | 488 | ||
510 | if (div_id != OMAP_MCBSP_CLKGDV) | 489 | if (div_id != OMAP_MCBSP_CLKGDV) |
511 | return -ENODEV; | 490 | return -ENODEV; |
512 | 491 | ||
513 | mcbsp_data->clk_div = div; | 492 | mcbsp->clk_div = div; |
514 | regs->srgr1 &= ~CLKGDV(0xff); | 493 | regs->srgr1 &= ~CLKGDV(0xff); |
515 | regs->srgr1 |= CLKGDV(div - 1); | 494 | regs->srgr1 |= CLKGDV(div - 1); |
516 | 495 | ||
@@ -521,28 +500,32 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
521 | int clk_id, unsigned int freq, | 500 | int clk_id, unsigned int freq, |
522 | int dir) | 501 | int dir) |
523 | { | 502 | { |
524 | struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); | 503 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
525 | struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; | 504 | struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs; |
526 | int err = 0; | 505 | int err = 0; |
527 | 506 | ||
528 | if (mcbsp_data->active) { | 507 | if (mcbsp->active) { |
529 | if (freq == mcbsp_data->in_freq) | 508 | if (freq == mcbsp->in_freq) |
530 | return 0; | 509 | return 0; |
531 | else | 510 | else |
532 | return -EBUSY; | 511 | return -EBUSY; |
533 | } | 512 | } |
534 | 513 | ||
535 | /* The McBSP signal muxing functions are only available on McBSP1 */ | 514 | if (clk_id == OMAP_MCBSP_SYSCLK_CLK || |
536 | if (clk_id == OMAP_MCBSP_CLKR_SRC_CLKR || | 515 | clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK || |
537 | clk_id == OMAP_MCBSP_CLKR_SRC_CLKX || | 516 | clk_id == OMAP_MCBSP_SYSCLK_CLKS_EXT || |
538 | clk_id == OMAP_MCBSP_FSR_SRC_FSR || | 517 | clk_id == OMAP_MCBSP_SYSCLK_CLKX_EXT || |
539 | clk_id == OMAP_MCBSP_FSR_SRC_FSX) | 518 | clk_id == OMAP_MCBSP_SYSCLK_CLKR_EXT) { |
540 | if (cpu_class_is_omap1() || mcbsp_data->bus_id != 0) | 519 | mcbsp->in_freq = freq; |
541 | return -EINVAL; | 520 | regs->srgr2 &= ~CLKSM; |
542 | 521 | regs->pcr0 &= ~SCLKME; | |
543 | mcbsp_data->in_freq = freq; | 522 | } else if (cpu_class_is_omap1()) { |
544 | regs->srgr2 &= ~CLKSM; | 523 | /* |
545 | regs->pcr0 &= ~SCLKME; | 524 | * McBSP CLKR/FSR signal muxing functions are only available on |
525 | * OMAP2 or newer versions | ||
526 | */ | ||
527 | return -EINVAL; | ||
528 | } | ||
546 | 529 | ||
547 | switch (clk_id) { | 530 | switch (clk_id) { |
548 | case OMAP_MCBSP_SYSCLK_CLK: | 531 | case OMAP_MCBSP_SYSCLK_CLK: |
@@ -553,7 +536,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
553 | err = -EINVAL; | 536 | err = -EINVAL; |
554 | break; | 537 | break; |
555 | } | 538 | } |
556 | err = omap2_mcbsp_set_clks_src(mcbsp_data->bus_id, | 539 | err = omap2_mcbsp_set_clks_src(mcbsp, |
557 | MCBSP_CLKS_PRCM_SRC); | 540 | MCBSP_CLKS_PRCM_SRC); |
558 | break; | 541 | break; |
559 | case OMAP_MCBSP_SYSCLK_CLKS_EXT: | 542 | case OMAP_MCBSP_SYSCLK_CLKS_EXT: |
@@ -561,7 +544,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
561 | err = 0; | 544 | err = 0; |
562 | break; | 545 | break; |
563 | } | 546 | } |
564 | err = omap2_mcbsp_set_clks_src(mcbsp_data->bus_id, | 547 | err = omap2_mcbsp_set_clks_src(mcbsp, |
565 | MCBSP_CLKS_PAD_SRC); | 548 | MCBSP_CLKS_PAD_SRC); |
566 | break; | 549 | break; |
567 | 550 | ||
@@ -573,24 +556,16 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
573 | 556 | ||
574 | 557 | ||
575 | case OMAP_MCBSP_CLKR_SRC_CLKR: | 558 | case OMAP_MCBSP_CLKR_SRC_CLKR: |
576 | if (cpu_class_is_omap1()) | 559 | err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKR); |
577 | break; | ||
578 | omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKR); | ||
579 | break; | 560 | break; |
580 | case OMAP_MCBSP_CLKR_SRC_CLKX: | 561 | case OMAP_MCBSP_CLKR_SRC_CLKX: |
581 | if (cpu_class_is_omap1()) | 562 | err = omap_mcbsp_6pin_src_mux(mcbsp, CLKR_SRC_CLKX); |
582 | break; | ||
583 | omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKX); | ||
584 | break; | 563 | break; |
585 | case OMAP_MCBSP_FSR_SRC_FSR: | 564 | case OMAP_MCBSP_FSR_SRC_FSR: |
586 | if (cpu_class_is_omap1()) | 565 | err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSR); |
587 | break; | ||
588 | omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSR); | ||
589 | break; | 566 | break; |
590 | case OMAP_MCBSP_FSR_SRC_FSX: | 567 | case OMAP_MCBSP_FSR_SRC_FSX: |
591 | if (cpu_class_is_omap1()) | 568 | err = omap_mcbsp_6pin_src_mux(mcbsp, FSR_SRC_FSX); |
592 | break; | ||
593 | omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSX); | ||
594 | break; | 569 | break; |
595 | default: | 570 | default: |
596 | err = -ENODEV; | 571 | err = -ENODEV; |
@@ -610,15 +585,27 @@ static const struct snd_soc_dai_ops mcbsp_dai_ops = { | |||
610 | .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, | 585 | .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, |
611 | }; | 586 | }; |
612 | 587 | ||
613 | static int mcbsp_dai_probe(struct snd_soc_dai *dai) | 588 | static int omap_mcbsp_probe(struct snd_soc_dai *dai) |
614 | { | 589 | { |
615 | mcbsp_data[dai->id].bus_id = dai->id; | 590 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(dai); |
616 | snd_soc_dai_set_drvdata(dai, &mcbsp_data[dai->id].bus_id); | 591 | |
592 | pm_runtime_enable(mcbsp->dev); | ||
593 | |||
594 | return 0; | ||
595 | } | ||
596 | |||
597 | static int omap_mcbsp_remove(struct snd_soc_dai *dai) | ||
598 | { | ||
599 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(dai); | ||
600 | |||
601 | pm_runtime_disable(mcbsp->dev); | ||
602 | |||
617 | return 0; | 603 | return 0; |
618 | } | 604 | } |
619 | 605 | ||
620 | static struct snd_soc_dai_driver omap_mcbsp_dai = { | 606 | static struct snd_soc_dai_driver omap_mcbsp_dai = { |
621 | .probe = mcbsp_dai_probe, | 607 | .probe = omap_mcbsp_probe, |
608 | .remove = omap_mcbsp_remove, | ||
622 | .playback = { | 609 | .playback = { |
623 | .channels_min = 1, | 610 | .channels_min = 1, |
624 | .channels_max = 16, | 611 | .channels_max = 16, |
@@ -649,11 +636,13 @@ static int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol, | |||
649 | return 0; | 636 | return 0; |
650 | } | 637 | } |
651 | 638 | ||
652 | #define OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(id, channel) \ | 639 | #define OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(channel) \ |
653 | static int \ | 640 | static int \ |
654 | omap_mcbsp##id##_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \ | 641 | omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \ |
655 | struct snd_ctl_elem_value *uc) \ | 642 | struct snd_ctl_elem_value *uc) \ |
656 | { \ | 643 | { \ |
644 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \ | ||
645 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); \ | ||
657 | struct soc_mixer_control *mc = \ | 646 | struct soc_mixer_control *mc = \ |
658 | (struct soc_mixer_control *)kc->private_value; \ | 647 | (struct soc_mixer_control *)kc->private_value; \ |
659 | int max = mc->max; \ | 648 | int max = mc->max; \ |
@@ -664,46 +653,44 @@ omap_mcbsp##id##_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \ | |||
664 | return -EINVAL; \ | 653 | return -EINVAL; \ |
665 | \ | 654 | \ |
666 | /* OMAP McBSP implementation uses index values 0..4 */ \ | 655 | /* OMAP McBSP implementation uses index values 0..4 */ \ |
667 | return omap_st_set_chgain((id)-1, channel, val); \ | 656 | return omap_st_set_chgain(mcbsp, channel, val); \ |
668 | } | 657 | } |
669 | 658 | ||
670 | #define OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(id, channel) \ | 659 | #define OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(channel) \ |
671 | static int \ | 660 | static int \ |
672 | omap_mcbsp##id##_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \ | 661 | omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \ |
673 | struct snd_ctl_elem_value *uc) \ | 662 | struct snd_ctl_elem_value *uc) \ |
674 | { \ | 663 | { \ |
664 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \ | ||
665 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); \ | ||
675 | s16 chgain; \ | 666 | s16 chgain; \ |
676 | \ | 667 | \ |
677 | if (omap_st_get_chgain((id)-1, channel, &chgain)) \ | 668 | if (omap_st_get_chgain(mcbsp, channel, &chgain)) \ |
678 | return -EAGAIN; \ | 669 | return -EAGAIN; \ |
679 | \ | 670 | \ |
680 | uc->value.integer.value[0] = chgain; \ | 671 | uc->value.integer.value[0] = chgain; \ |
681 | return 0; \ | 672 | return 0; \ |
682 | } | 673 | } |
683 | 674 | ||
684 | OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(2, 0) | 675 | OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(0) |
685 | OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(2, 1) | 676 | OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(1) |
686 | OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(3, 0) | 677 | OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(0) |
687 | OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(3, 1) | 678 | OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(1) |
688 | OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(2, 0) | ||
689 | OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(2, 1) | ||
690 | OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(3, 0) | ||
691 | OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(3, 1) | ||
692 | 679 | ||
693 | static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol, | 680 | static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol, |
694 | struct snd_ctl_elem_value *ucontrol) | 681 | struct snd_ctl_elem_value *ucontrol) |
695 | { | 682 | { |
696 | struct soc_mixer_control *mc = | 683 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); |
697 | (struct soc_mixer_control *)kcontrol->private_value; | 684 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
698 | u8 value = ucontrol->value.integer.value[0]; | 685 | u8 value = ucontrol->value.integer.value[0]; |
699 | 686 | ||
700 | if (value == omap_st_is_enabled(mc->reg)) | 687 | if (value == omap_st_is_enabled(mcbsp)) |
701 | return 0; | 688 | return 0; |
702 | 689 | ||
703 | if (value) | 690 | if (value) |
704 | omap_st_enable(mc->reg); | 691 | omap_st_enable(mcbsp); |
705 | else | 692 | else |
706 | omap_st_disable(mc->reg); | 693 | omap_st_disable(mcbsp); |
707 | 694 | ||
708 | return 1; | 695 | return 1; |
709 | } | 696 | } |
@@ -711,10 +698,10 @@ static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol, | |||
711 | static int omap_mcbsp_st_get_mode(struct snd_kcontrol *kcontrol, | 698 | static int omap_mcbsp_st_get_mode(struct snd_kcontrol *kcontrol, |
712 | struct snd_ctl_elem_value *ucontrol) | 699 | struct snd_ctl_elem_value *ucontrol) |
713 | { | 700 | { |
714 | struct soc_mixer_control *mc = | 701 | struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); |
715 | (struct soc_mixer_control *)kcontrol->private_value; | 702 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
716 | 703 | ||
717 | ucontrol->value.integer.value[0] = omap_st_is_enabled(mc->reg); | 704 | ucontrol->value.integer.value[0] = omap_st_is_enabled(mcbsp); |
718 | return 0; | 705 | return 0; |
719 | } | 706 | } |
720 | 707 | ||
@@ -723,12 +710,12 @@ static const struct snd_kcontrol_new omap_mcbsp2_st_controls[] = { | |||
723 | omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), | 710 | omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), |
724 | OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 0 Volume", | 711 | OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 0 Volume", |
725 | -32768, 32767, | 712 | -32768, 32767, |
726 | omap_mcbsp2_get_st_ch0_volume, | 713 | omap_mcbsp_get_st_ch0_volume, |
727 | omap_mcbsp2_set_st_ch0_volume), | 714 | omap_mcbsp_set_st_ch0_volume), |
728 | OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 1 Volume", | 715 | OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 1 Volume", |
729 | -32768, 32767, | 716 | -32768, 32767, |
730 | omap_mcbsp2_get_st_ch1_volume, | 717 | omap_mcbsp_get_st_ch1_volume, |
731 | omap_mcbsp2_set_st_ch1_volume), | 718 | omap_mcbsp_set_st_ch1_volume), |
732 | }; | 719 | }; |
733 | 720 | ||
734 | static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = { | 721 | static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = { |
@@ -736,25 +723,30 @@ static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = { | |||
736 | omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), | 723 | omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), |
737 | OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 0 Volume", | 724 | OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 0 Volume", |
738 | -32768, 32767, | 725 | -32768, 32767, |
739 | omap_mcbsp3_get_st_ch0_volume, | 726 | omap_mcbsp_get_st_ch0_volume, |
740 | omap_mcbsp3_set_st_ch0_volume), | 727 | omap_mcbsp_set_st_ch0_volume), |
741 | OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 1 Volume", | 728 | OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 1 Volume", |
742 | -32768, 32767, | 729 | -32768, 32767, |
743 | omap_mcbsp3_get_st_ch1_volume, | 730 | omap_mcbsp_get_st_ch1_volume, |
744 | omap_mcbsp3_set_st_ch1_volume), | 731 | omap_mcbsp_set_st_ch1_volume), |
745 | }; | 732 | }; |
746 | 733 | ||
747 | int omap_mcbsp_st_add_controls(struct snd_soc_codec *codec, int mcbsp_id) | 734 | int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd) |
748 | { | 735 | { |
749 | if (!cpu_is_omap34xx()) | 736 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
737 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); | ||
738 | |||
739 | if (!mcbsp->st_data) | ||
750 | return -ENODEV; | 740 | return -ENODEV; |
751 | 741 | ||
752 | switch (mcbsp_id) { | 742 | switch (cpu_dai->id) { |
753 | case 1: /* McBSP 2 */ | 743 | case 2: /* McBSP 2 */ |
754 | return snd_soc_add_controls(codec, omap_mcbsp2_st_controls, | 744 | return snd_soc_add_dai_controls(cpu_dai, |
745 | omap_mcbsp2_st_controls, | ||
755 | ARRAY_SIZE(omap_mcbsp2_st_controls)); | 746 | ARRAY_SIZE(omap_mcbsp2_st_controls)); |
756 | case 2: /* McBSP 3 */ | 747 | case 3: /* McBSP 3 */ |
757 | return snd_soc_add_controls(codec, omap_mcbsp3_st_controls, | 748 | return snd_soc_add_dai_controls(cpu_dai, |
749 | omap_mcbsp3_st_controls, | ||
758 | ARRAY_SIZE(omap_mcbsp3_st_controls)); | 750 | ARRAY_SIZE(omap_mcbsp3_st_controls)); |
759 | default: | 751 | default: |
760 | break; | 752 | break; |
@@ -766,18 +758,51 @@ EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls); | |||
766 | 758 | ||
767 | static __devinit int asoc_mcbsp_probe(struct platform_device *pdev) | 759 | static __devinit int asoc_mcbsp_probe(struct platform_device *pdev) |
768 | { | 760 | { |
769 | return snd_soc_register_dai(&pdev->dev, &omap_mcbsp_dai); | 761 | struct omap_mcbsp_platform_data *pdata = dev_get_platdata(&pdev->dev); |
762 | struct omap_mcbsp *mcbsp; | ||
763 | int ret; | ||
764 | |||
765 | if (!pdata) { | ||
766 | dev_err(&pdev->dev, "missing platform data.\n"); | ||
767 | return -EINVAL; | ||
768 | } | ||
769 | mcbsp = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcbsp), GFP_KERNEL); | ||
770 | if (!mcbsp) | ||
771 | return -ENOMEM; | ||
772 | |||
773 | mcbsp->id = pdev->id; | ||
774 | mcbsp->pdata = pdata; | ||
775 | mcbsp->dev = &pdev->dev; | ||
776 | platform_set_drvdata(pdev, mcbsp); | ||
777 | |||
778 | ret = omap_mcbsp_init(pdev); | ||
779 | if (!ret) | ||
780 | return snd_soc_register_dai(&pdev->dev, &omap_mcbsp_dai); | ||
781 | |||
782 | return ret; | ||
770 | } | 783 | } |
771 | 784 | ||
772 | static int __devexit asoc_mcbsp_remove(struct platform_device *pdev) | 785 | static int __devexit asoc_mcbsp_remove(struct platform_device *pdev) |
773 | { | 786 | { |
787 | struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev); | ||
788 | |||
774 | snd_soc_unregister_dai(&pdev->dev); | 789 | snd_soc_unregister_dai(&pdev->dev); |
790 | |||
791 | if (mcbsp->pdata->ops && mcbsp->pdata->ops->free) | ||
792 | mcbsp->pdata->ops->free(mcbsp->id); | ||
793 | |||
794 | omap_mcbsp_sysfs_remove(mcbsp); | ||
795 | |||
796 | clk_put(mcbsp->fclk); | ||
797 | |||
798 | platform_set_drvdata(pdev, NULL); | ||
799 | |||
775 | return 0; | 800 | return 0; |
776 | } | 801 | } |
777 | 802 | ||
778 | static struct platform_driver asoc_mcbsp_driver = { | 803 | static struct platform_driver asoc_mcbsp_driver = { |
779 | .driver = { | 804 | .driver = { |
780 | .name = "omap-mcbsp-dai", | 805 | .name = "omap-mcbsp", |
781 | .owner = THIS_MODULE, | 806 | .owner = THIS_MODULE, |
782 | }, | 807 | }, |
783 | 808 | ||
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h index 65cde9d3807b..f877b16f19c9 100644 --- a/sound/soc/omap/omap-mcbsp.h +++ b/sound/soc/omap/omap-mcbsp.h | |||
@@ -59,6 +59,6 @@ enum omap_mcbsp_div { | |||
59 | #define NUM_LINKS 5 | 59 | #define NUM_LINKS 5 |
60 | #endif | 60 | #endif |
61 | 61 | ||
62 | int omap_mcbsp_st_add_controls(struct snd_soc_codec *codec, int mcbsp_id); | 62 | int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd); |
63 | 63 | ||
64 | #endif | 64 | #endif |
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 0e25df4fa9e5..39705561131a 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c | |||
@@ -419,12 +419,14 @@ static struct snd_soc_dai_driver omap_mcpdm_dai = { | |||
419 | .channels_max = 5, | 419 | .channels_max = 5, |
420 | .rates = OMAP_MCPDM_RATES, | 420 | .rates = OMAP_MCPDM_RATES, |
421 | .formats = OMAP_MCPDM_FORMATS, | 421 | .formats = OMAP_MCPDM_FORMATS, |
422 | .sig_bits = 24, | ||
422 | }, | 423 | }, |
423 | .capture = { | 424 | .capture = { |
424 | .channels_min = 1, | 425 | .channels_min = 1, |
425 | .channels_max = 3, | 426 | .channels_max = 3, |
426 | .rates = OMAP_MCPDM_RATES, | 427 | .rates = OMAP_MCPDM_RATES, |
427 | .formats = OMAP_MCPDM_FORMATS, | 428 | .formats = OMAP_MCPDM_FORMATS, |
429 | .sig_bits = 24, | ||
428 | }, | 430 | }, |
429 | .ops = &omap_mcpdm_dai_ops, | 431 | .ops = &omap_mcpdm_dai_ops, |
430 | }; | 432 | }; |
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h index f95fe3064172..b92248cbd47a 100644 --- a/sound/soc/omap/omap-pcm.h +++ b/sound/soc/omap/omap-pcm.h | |||
@@ -25,6 +25,8 @@ | |||
25 | #ifndef __OMAP_PCM_H__ | 25 | #ifndef __OMAP_PCM_H__ |
26 | #define __OMAP_PCM_H__ | 26 | #define __OMAP_PCM_H__ |
27 | 27 | ||
28 | struct snd_pcm_substream; | ||
29 | |||
28 | struct omap_pcm_dma_data { | 30 | struct omap_pcm_dma_data { |
29 | char *name; /* stream identifier */ | 31 | char *name; /* stream identifier */ |
30 | int dma_req; /* DMA request line */ | 32 | int dma_req; /* DMA request line */ |
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c index 3357dcc47ed4..2830dfd05661 100644 --- a/sound/soc/omap/omap3beagle.c +++ b/sound/soc/omap/omap3beagle.c | |||
@@ -91,7 +91,7 @@ static struct snd_soc_ops omap3beagle_ops = { | |||
91 | static struct snd_soc_dai_link omap3beagle_dai = { | 91 | static struct snd_soc_dai_link omap3beagle_dai = { |
92 | .name = "TWL4030", | 92 | .name = "TWL4030", |
93 | .stream_name = "TWL4030", | 93 | .stream_name = "TWL4030", |
94 | .cpu_dai_name = "omap-mcbsp-dai.1", | 94 | .cpu_dai_name = "omap-mcbsp.2", |
95 | .platform_name = "omap-pcm-audio", | 95 | .platform_name = "omap-pcm-audio", |
96 | .codec_dai_name = "twl4030-hifi", | 96 | .codec_dai_name = "twl4030-hifi", |
97 | .codec_name = "twl4030-codec", | 97 | .codec_name = "twl4030-codec", |
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c index 071fcb09b8b2..3d468c9179d7 100644 --- a/sound/soc/omap/omap3evm.c +++ b/sound/soc/omap/omap3evm.c | |||
@@ -58,7 +58,7 @@ static struct snd_soc_ops omap3evm_ops = { | |||
58 | static struct snd_soc_dai_link omap3evm_dai = { | 58 | static struct snd_soc_dai_link omap3evm_dai = { |
59 | .name = "TWL4030", | 59 | .name = "TWL4030", |
60 | .stream_name = "TWL4030", | 60 | .stream_name = "TWL4030", |
61 | .cpu_dai_name = "omap-mcbsp-dai.1", | 61 | .cpu_dai_name = "omap-mcbsp.2", |
62 | .codec_dai_name = "twl4030-hifi", | 62 | .codec_dai_name = "twl4030-hifi", |
63 | .platform_name = "omap-pcm-audio", | 63 | .platform_name = "omap-pcm-audio", |
64 | .codec_name = "twl4030-codec", | 64 | .codec_name = "twl4030-codec", |
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index 07794bd10952..4c3a0978578a 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c | |||
@@ -208,7 +208,7 @@ static struct snd_soc_dai_link omap3pandora_dai[] = { | |||
208 | { | 208 | { |
209 | .name = "PCM1773", | 209 | .name = "PCM1773", |
210 | .stream_name = "HiFi Out", | 210 | .stream_name = "HiFi Out", |
211 | .cpu_dai_name = "omap-mcbsp-dai.1", | 211 | .cpu_dai_name = "omap-mcbsp.2", |
212 | .codec_dai_name = "twl4030-hifi", | 212 | .codec_dai_name = "twl4030-hifi", |
213 | .platform_name = "omap-pcm-audio", | 213 | .platform_name = "omap-pcm-audio", |
214 | .codec_name = "twl4030-codec", | 214 | .codec_name = "twl4030-codec", |
@@ -219,7 +219,7 @@ static struct snd_soc_dai_link omap3pandora_dai[] = { | |||
219 | }, { | 219 | }, { |
220 | .name = "TWL4030", | 220 | .name = "TWL4030", |
221 | .stream_name = "Line/Mic In", | 221 | .stream_name = "Line/Mic In", |
222 | .cpu_dai_name = "omap-mcbsp-dai.3", | 222 | .cpu_dai_name = "omap-mcbsp.4", |
223 | .codec_dai_name = "twl4030-hifi", | 223 | .codec_dai_name = "twl4030-hifi", |
224 | .platform_name = "omap-pcm-audio", | 224 | .platform_name = "omap-pcm-audio", |
225 | .codec_name = "twl4030-codec", | 225 | .codec_name = "twl4030-codec", |
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c index d859b597e7ec..b1a9d64cbc56 100644 --- a/sound/soc/omap/osk5912.c +++ b/sound/soc/omap/osk5912.c | |||
@@ -96,7 +96,7 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
96 | static struct snd_soc_dai_link osk_dai = { | 96 | static struct snd_soc_dai_link osk_dai = { |
97 | .name = "TLV320AIC23", | 97 | .name = "TLV320AIC23", |
98 | .stream_name = "AIC23", | 98 | .stream_name = "AIC23", |
99 | .cpu_dai_name = "omap-mcbsp-dai.0", | 99 | .cpu_dai_name = "omap-mcbsp.1", |
100 | .codec_dai_name = "tlv320aic23-hifi", | 100 | .codec_dai_name = "tlv320aic23-hifi", |
101 | .platform_name = "omap-pcm-audio", | 101 | .platform_name = "omap-pcm-audio", |
102 | .codec_name = "tlv320aic23-codec", | 102 | .codec_name = "tlv320aic23-codec", |
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c index 2ee889c50256..6ac3e0c3c282 100644 --- a/sound/soc/omap/overo.c +++ b/sound/soc/omap/overo.c | |||
@@ -60,7 +60,7 @@ static struct snd_soc_ops overo_ops = { | |||
60 | static struct snd_soc_dai_link overo_dai = { | 60 | static struct snd_soc_dai_link overo_dai = { |
61 | .name = "TWL4030", | 61 | .name = "TWL4030", |
62 | .stream_name = "TWL4030", | 62 | .stream_name = "TWL4030", |
63 | .cpu_dai_name = "omap-mcbsp-dai.1", | 63 | .cpu_dai_name = "omap-mcbsp.2", |
64 | .codec_dai_name = "twl4030-hifi", | 64 | .codec_dai_name = "twl4030-hifi", |
65 | .platform_name = "omap-pcm-audio", | 65 | .platform_name = "omap-pcm-audio", |
66 | .codec_name = "twl4030-codec", | 66 | .codec_name = "twl4030-codec", |
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index fada6ef43eea..2712dd232b6d 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c | |||
@@ -59,9 +59,8 @@ static int rx51_spk_func; | |||
59 | static int rx51_dmic_func; | 59 | static int rx51_dmic_func; |
60 | static int rx51_jack_func; | 60 | static int rx51_jack_func; |
61 | 61 | ||
62 | static void rx51_ext_control(struct snd_soc_codec *codec) | 62 | static void rx51_ext_control(struct snd_soc_dapm_context *dapm) |
63 | { | 63 | { |
64 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
65 | int hp = 0, hs = 0, tvout = 0; | 64 | int hp = 0, hs = 0, tvout = 0; |
66 | 65 | ||
67 | switch (rx51_jack_func) { | 66 | switch (rx51_jack_func) { |
@@ -102,11 +101,11 @@ static int rx51_startup(struct snd_pcm_substream *substream) | |||
102 | { | 101 | { |
103 | struct snd_pcm_runtime *runtime = substream->runtime; | 102 | struct snd_pcm_runtime *runtime = substream->runtime; |
104 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 103 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
105 | struct snd_soc_codec *codec = rtd->codec; | 104 | struct snd_soc_card *card = rtd->card; |
106 | 105 | ||
107 | snd_pcm_hw_constraint_minmax(runtime, | 106 | snd_pcm_hw_constraint_minmax(runtime, |
108 | SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); | 107 | SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2); |
109 | rx51_ext_control(codec); | 108 | rx51_ext_control(&card->dapm); |
110 | 109 | ||
111 | return 0; | 110 | return 0; |
112 | } | 111 | } |
@@ -138,13 +137,13 @@ static int rx51_get_spk(struct snd_kcontrol *kcontrol, | |||
138 | static int rx51_set_spk(struct snd_kcontrol *kcontrol, | 137 | static int rx51_set_spk(struct snd_kcontrol *kcontrol, |
139 | struct snd_ctl_elem_value *ucontrol) | 138 | struct snd_ctl_elem_value *ucontrol) |
140 | { | 139 | { |
141 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 140 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
142 | 141 | ||
143 | if (rx51_spk_func == ucontrol->value.integer.value[0]) | 142 | if (rx51_spk_func == ucontrol->value.integer.value[0]) |
144 | return 0; | 143 | return 0; |
145 | 144 | ||
146 | rx51_spk_func = ucontrol->value.integer.value[0]; | 145 | rx51_spk_func = ucontrol->value.integer.value[0]; |
147 | rx51_ext_control(codec); | 146 | rx51_ext_control(&card->dapm); |
148 | 147 | ||
149 | return 1; | 148 | return 1; |
150 | } | 149 | } |
@@ -184,13 +183,13 @@ static int rx51_get_input(struct snd_kcontrol *kcontrol, | |||
184 | static int rx51_set_input(struct snd_kcontrol *kcontrol, | 183 | static int rx51_set_input(struct snd_kcontrol *kcontrol, |
185 | struct snd_ctl_elem_value *ucontrol) | 184 | struct snd_ctl_elem_value *ucontrol) |
186 | { | 185 | { |
187 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 186 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
188 | 187 | ||
189 | if (rx51_dmic_func == ucontrol->value.integer.value[0]) | 188 | if (rx51_dmic_func == ucontrol->value.integer.value[0]) |
190 | return 0; | 189 | return 0; |
191 | 190 | ||
192 | rx51_dmic_func = ucontrol->value.integer.value[0]; | 191 | rx51_dmic_func = ucontrol->value.integer.value[0]; |
193 | rx51_ext_control(codec); | 192 | rx51_ext_control(&card->dapm); |
194 | 193 | ||
195 | return 1; | 194 | return 1; |
196 | } | 195 | } |
@@ -206,13 +205,13 @@ static int rx51_get_jack(struct snd_kcontrol *kcontrol, | |||
206 | static int rx51_set_jack(struct snd_kcontrol *kcontrol, | 205 | static int rx51_set_jack(struct snd_kcontrol *kcontrol, |
207 | struct snd_ctl_elem_value *ucontrol) | 206 | struct snd_ctl_elem_value *ucontrol) |
208 | { | 207 | { |
209 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 208 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
210 | 209 | ||
211 | if (rx51_jack_func == ucontrol->value.integer.value[0]) | 210 | if (rx51_jack_func == ucontrol->value.integer.value[0]) |
212 | return 0; | 211 | return 0; |
213 | 212 | ||
214 | rx51_jack_func = ucontrol->value.integer.value[0]; | 213 | rx51_jack_func = ucontrol->value.integer.value[0]; |
215 | rx51_ext_control(codec); | 214 | rx51_ext_control(&card->dapm); |
216 | 215 | ||
217 | return 1; | 216 | return 1; |
218 | } | 217 | } |
@@ -297,7 +296,7 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) | |||
297 | snd_soc_dapm_nc_pin(dapm, "LINE1R"); | 296 | snd_soc_dapm_nc_pin(dapm, "LINE1R"); |
298 | 297 | ||
299 | /* Add RX-51 specific controls */ | 298 | /* Add RX-51 specific controls */ |
300 | err = snd_soc_add_controls(codec, aic34_rx51_controls, | 299 | err = snd_soc_add_card_controls(rtd->card, aic34_rx51_controls, |
301 | ARRAY_SIZE(aic34_rx51_controls)); | 300 | ARRAY_SIZE(aic34_rx51_controls)); |
302 | if (err < 0) | 301 | if (err < 0) |
303 | return err; | 302 | return err; |
@@ -314,7 +313,7 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) | |||
314 | return err; | 313 | return err; |
315 | snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42); | 314 | snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42); |
316 | 315 | ||
317 | err = omap_mcbsp_st_add_controls(codec, 1); | 316 | err = omap_mcbsp_st_add_controls(rtd); |
318 | if (err < 0) | 317 | if (err < 0) |
319 | return err; | 318 | return err; |
320 | 319 | ||
@@ -335,7 +334,7 @@ static int rx51_aic34b_init(struct snd_soc_dapm_context *dapm) | |||
335 | { | 334 | { |
336 | int err; | 335 | int err; |
337 | 336 | ||
338 | err = snd_soc_add_controls(dapm->codec, aic34_rx51_controlsb, | 337 | err = snd_soc_add_card_controls(dapm->card, aic34_rx51_controlsb, |
339 | ARRAY_SIZE(aic34_rx51_controlsb)); | 338 | ARRAY_SIZE(aic34_rx51_controlsb)); |
340 | if (err < 0) | 339 | if (err < 0) |
341 | return err; | 340 | return err; |
@@ -354,7 +353,7 @@ static struct snd_soc_dai_link rx51_dai[] = { | |||
354 | { | 353 | { |
355 | .name = "TLV320AIC34", | 354 | .name = "TLV320AIC34", |
356 | .stream_name = "AIC34", | 355 | .stream_name = "AIC34", |
357 | .cpu_dai_name = "omap-mcbsp-dai.1", | 356 | .cpu_dai_name = "omap-mcbsp.2", |
358 | .codec_dai_name = "tlv320aic3x-hifi", | 357 | .codec_dai_name = "tlv320aic3x-hifi", |
359 | .platform_name = "omap-pcm-audio", | 358 | .platform_name = "omap-pcm-audio", |
360 | .codec_name = "tlv320aic3x-codec.2-0018", | 359 | .codec_name = "tlv320aic3x-codec.2-0018", |
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c index 2c850662ea7e..0e283226e2bf 100644 --- a/sound/soc/omap/sdp3430.c +++ b/sound/soc/omap/sdp3430.c | |||
@@ -187,7 +187,7 @@ static struct snd_soc_dai_link sdp3430_dai[] = { | |||
187 | { | 187 | { |
188 | .name = "TWL4030 I2S", | 188 | .name = "TWL4030 I2S", |
189 | .stream_name = "TWL4030 Audio", | 189 | .stream_name = "TWL4030 Audio", |
190 | .cpu_dai_name = "omap-mcbsp-dai.1", | 190 | .cpu_dai_name = "omap-mcbsp.2", |
191 | .codec_dai_name = "twl4030-hifi", | 191 | .codec_dai_name = "twl4030-hifi", |
192 | .platform_name = "omap-pcm-audio", | 192 | .platform_name = "omap-pcm-audio", |
193 | .codec_name = "twl4030-codec", | 193 | .codec_name = "twl4030-codec", |
@@ -199,7 +199,7 @@ static struct snd_soc_dai_link sdp3430_dai[] = { | |||
199 | { | 199 | { |
200 | .name = "TWL4030 PCM", | 200 | .name = "TWL4030 PCM", |
201 | .stream_name = "TWL4030 Voice", | 201 | .stream_name = "TWL4030 Voice", |
202 | .cpu_dai_name = "omap-mcbsp-dai.2", | 202 | .cpu_dai_name = "omap-mcbsp.3", |
203 | .codec_dai_name = "twl4030-voice", | 203 | .codec_dai_name = "twl4030-voice", |
204 | .platform_name = "omap-pcm-audio", | 204 | .platform_name = "omap-pcm-audio", |
205 | .codec_name = "twl4030-codec", | 205 | .codec_name = "twl4030-codec", |
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c deleted file mode 100644 index 175ba9a04edf..000000000000 --- a/sound/soc/omap/sdp4430.c +++ /dev/null | |||
@@ -1,279 +0,0 @@ | |||
1 | /* | ||
2 | * sdp4430.c -- SoC audio for TI OMAP4430 SDP | ||
3 | * | ||
4 | * Author: Misael Lopez Cruz <x0052729@ti.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/clk.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/mfd/twl6040.h> | ||
25 | #include <linux/module.h> | ||
26 | |||
27 | #include <sound/core.h> | ||
28 | #include <sound/pcm.h> | ||
29 | #include <sound/soc.h> | ||
30 | #include <sound/jack.h> | ||
31 | |||
32 | #include <asm/mach-types.h> | ||
33 | #include <plat/hardware.h> | ||
34 | #include <plat/mux.h> | ||
35 | |||
36 | #include "omap-dmic.h" | ||
37 | #include "omap-mcpdm.h" | ||
38 | #include "omap-pcm.h" | ||
39 | #include "../codecs/twl6040.h" | ||
40 | |||
41 | static int sdp4430_hw_params(struct snd_pcm_substream *substream, | ||
42 | struct snd_pcm_hw_params *params) | ||
43 | { | ||
44 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
45 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
46 | int clk_id, freq; | ||
47 | int ret; | ||
48 | |||
49 | clk_id = twl6040_get_clk_id(rtd->codec); | ||
50 | if (clk_id == TWL6040_SYSCLK_SEL_HPPLL) | ||
51 | freq = 38400000; | ||
52 | else if (clk_id == TWL6040_SYSCLK_SEL_LPPLL) | ||
53 | freq = 32768; | ||
54 | else | ||
55 | return -EINVAL; | ||
56 | |||
57 | /* set the codec mclk */ | ||
58 | ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, freq, | ||
59 | SND_SOC_CLOCK_IN); | ||
60 | if (ret) { | ||
61 | printk(KERN_ERR "can't set codec system clock\n"); | ||
62 | return ret; | ||
63 | } | ||
64 | return ret; | ||
65 | } | ||
66 | |||
67 | static struct snd_soc_ops sdp4430_ops = { | ||
68 | .hw_params = sdp4430_hw_params, | ||
69 | }; | ||
70 | |||
71 | static int sdp4430_dmic_hw_params(struct snd_pcm_substream *substream, | ||
72 | struct snd_pcm_hw_params *params) | ||
73 | { | ||
74 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
75 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
76 | int ret = 0; | ||
77 | |||
78 | ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_SYSCLK_PAD_CLKS, | ||
79 | 19200000, SND_SOC_CLOCK_IN); | ||
80 | if (ret < 0) { | ||
81 | printk(KERN_ERR "can't set DMIC cpu system clock\n"); | ||
82 | return ret; | ||
83 | } | ||
84 | ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_DMIC_ABE_DMIC_CLK, 2400000, | ||
85 | SND_SOC_CLOCK_OUT); | ||
86 | if (ret < 0) { | ||
87 | printk(KERN_ERR "can't set DMIC output clock\n"); | ||
88 | return ret; | ||
89 | } | ||
90 | return 0; | ||
91 | } | ||
92 | |||
93 | static struct snd_soc_ops sdp4430_dmic_ops = { | ||
94 | .hw_params = sdp4430_dmic_hw_params, | ||
95 | }; | ||
96 | |||
97 | /* Headset jack */ | ||
98 | static struct snd_soc_jack hs_jack; | ||
99 | |||
100 | /*Headset jack detection DAPM pins */ | ||
101 | static struct snd_soc_jack_pin hs_jack_pins[] = { | ||
102 | { | ||
103 | .pin = "Headset Mic", | ||
104 | .mask = SND_JACK_MICROPHONE, | ||
105 | }, | ||
106 | { | ||
107 | .pin = "Headset Stereophone", | ||
108 | .mask = SND_JACK_HEADPHONE, | ||
109 | }, | ||
110 | }; | ||
111 | |||
112 | /* SDP4430 machine DAPM */ | ||
113 | static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = { | ||
114 | SND_SOC_DAPM_MIC("Ext Mic", NULL), | ||
115 | SND_SOC_DAPM_SPK("Ext Spk", NULL), | ||
116 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
117 | SND_SOC_DAPM_HP("Headset Stereophone", NULL), | ||
118 | SND_SOC_DAPM_SPK("Earphone Spk", NULL), | ||
119 | SND_SOC_DAPM_INPUT("FM Stereo In"), | ||
120 | }; | ||
121 | |||
122 | static const struct snd_soc_dapm_route audio_map[] = { | ||
123 | /* External Mics: MAINMIC, SUBMIC with bias*/ | ||
124 | {"MAINMIC", NULL, "Main Mic Bias"}, | ||
125 | {"SUBMIC", NULL, "Main Mic Bias"}, | ||
126 | {"Main Mic Bias", NULL, "Ext Mic"}, | ||
127 | |||
128 | /* External Speakers: HFL, HFR */ | ||
129 | {"Ext Spk", NULL, "HFL"}, | ||
130 | {"Ext Spk", NULL, "HFR"}, | ||
131 | |||
132 | /* Headset Mic: HSMIC with bias */ | ||
133 | {"HSMIC", NULL, "Headset Mic Bias"}, | ||
134 | {"Headset Mic Bias", NULL, "Headset Mic"}, | ||
135 | |||
136 | /* Headset Stereophone (Headphone): HSOL, HSOR */ | ||
137 | {"Headset Stereophone", NULL, "HSOL"}, | ||
138 | {"Headset Stereophone", NULL, "HSOR"}, | ||
139 | |||
140 | /* Earphone speaker */ | ||
141 | {"Earphone Spk", NULL, "EP"}, | ||
142 | |||
143 | /* Aux/FM Stereo In: AFML, AFMR */ | ||
144 | {"AFML", NULL, "FM Stereo In"}, | ||
145 | {"AFMR", NULL, "FM Stereo In"}, | ||
146 | }; | ||
147 | |||
148 | static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) | ||
149 | { | ||
150 | struct snd_soc_codec *codec = rtd->codec; | ||
151 | int ret, hs_trim; | ||
152 | |||
153 | /* | ||
154 | * Configure McPDM offset cancellation based on the HSOTRIM value from | ||
155 | * twl6040. | ||
156 | */ | ||
157 | hs_trim = twl6040_get_trim_value(codec, TWL6040_TRIM_HSOTRIM); | ||
158 | omap_mcpdm_configure_dn_offsets(rtd, TWL6040_HSF_TRIM_LEFT(hs_trim), | ||
159 | TWL6040_HSF_TRIM_RIGHT(hs_trim)); | ||
160 | |||
161 | /* Headset jack detection */ | ||
162 | ret = snd_soc_jack_new(codec, "Headset Jack", | ||
163 | SND_JACK_HEADSET, &hs_jack); | ||
164 | if (ret) | ||
165 | return ret; | ||
166 | |||
167 | ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), | ||
168 | hs_jack_pins); | ||
169 | |||
170 | if (machine_is_omap_4430sdp()) | ||
171 | twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); | ||
172 | else | ||
173 | snd_soc_jack_report(&hs_jack, SND_JACK_HEADSET, SND_JACK_HEADSET); | ||
174 | |||
175 | return ret; | ||
176 | } | ||
177 | |||
178 | static const struct snd_soc_dapm_widget sdp4430_dmic_dapm_widgets[] = { | ||
179 | SND_SOC_DAPM_MIC("Digital Mic", NULL), | ||
180 | }; | ||
181 | |||
182 | static const struct snd_soc_dapm_route dmic_audio_map[] = { | ||
183 | {"DMic", NULL, "Digital Mic1 Bias"}, | ||
184 | {"Digital Mic1 Bias", NULL, "Digital Mic"}, | ||
185 | }; | ||
186 | |||
187 | static int sdp4430_dmic_init(struct snd_soc_pcm_runtime *rtd) | ||
188 | { | ||
189 | struct snd_soc_codec *codec = rtd->codec; | ||
190 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
191 | int ret; | ||
192 | |||
193 | ret = snd_soc_dapm_new_controls(dapm, sdp4430_dmic_dapm_widgets, | ||
194 | ARRAY_SIZE(sdp4430_dmic_dapm_widgets)); | ||
195 | if (ret) | ||
196 | return ret; | ||
197 | |||
198 | return snd_soc_dapm_add_routes(dapm, dmic_audio_map, | ||
199 | ARRAY_SIZE(dmic_audio_map)); | ||
200 | } | ||
201 | |||
202 | /* Digital audio interface glue - connects codec <--> CPU */ | ||
203 | static struct snd_soc_dai_link sdp4430_dai[] = { | ||
204 | { | ||
205 | .name = "TWL6040", | ||
206 | .stream_name = "TWL6040", | ||
207 | .cpu_dai_name = "omap-mcpdm", | ||
208 | .codec_dai_name = "twl6040-legacy", | ||
209 | .platform_name = "omap-pcm-audio", | ||
210 | .codec_name = "twl6040-codec", | ||
211 | .init = sdp4430_twl6040_init, | ||
212 | .ops = &sdp4430_ops, | ||
213 | }, | ||
214 | { | ||
215 | .name = "DMIC", | ||
216 | .stream_name = "DMIC Capture", | ||
217 | .cpu_dai_name = "omap-dmic", | ||
218 | .codec_dai_name = "dmic-hifi", | ||
219 | .platform_name = "omap-pcm-audio", | ||
220 | .codec_name = "dmic-codec", | ||
221 | .init = sdp4430_dmic_init, | ||
222 | .ops = &sdp4430_dmic_ops, | ||
223 | }, | ||
224 | }; | ||
225 | |||
226 | /* Audio machine driver */ | ||
227 | static struct snd_soc_card snd_soc_sdp4430 = { | ||
228 | .name = "SDP4430", | ||
229 | .owner = THIS_MODULE, | ||
230 | .dai_link = sdp4430_dai, | ||
231 | .num_links = ARRAY_SIZE(sdp4430_dai), | ||
232 | |||
233 | .dapm_widgets = sdp4430_twl6040_dapm_widgets, | ||
234 | .num_dapm_widgets = ARRAY_SIZE(sdp4430_twl6040_dapm_widgets), | ||
235 | .dapm_routes = audio_map, | ||
236 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
237 | }; | ||
238 | |||
239 | static struct platform_device *sdp4430_snd_device; | ||
240 | |||
241 | static int __init sdp4430_soc_init(void) | ||
242 | { | ||
243 | int ret; | ||
244 | |||
245 | if (!machine_is_omap_4430sdp()) | ||
246 | return -ENODEV; | ||
247 | printk(KERN_INFO "SDP4430 SoC init\n"); | ||
248 | |||
249 | sdp4430_snd_device = platform_device_alloc("soc-audio", -1); | ||
250 | if (!sdp4430_snd_device) { | ||
251 | printk(KERN_ERR "Platform device allocation failed\n"); | ||
252 | return -ENOMEM; | ||
253 | } | ||
254 | |||
255 | platform_set_drvdata(sdp4430_snd_device, &snd_soc_sdp4430); | ||
256 | |||
257 | ret = platform_device_add(sdp4430_snd_device); | ||
258 | if (ret) | ||
259 | goto err; | ||
260 | |||
261 | return 0; | ||
262 | |||
263 | err: | ||
264 | printk(KERN_ERR "Unable to add platform device\n"); | ||
265 | platform_device_put(sdp4430_snd_device); | ||
266 | return ret; | ||
267 | } | ||
268 | module_init(sdp4430_soc_init); | ||
269 | |||
270 | static void __exit sdp4430_soc_exit(void) | ||
271 | { | ||
272 | platform_device_unregister(sdp4430_snd_device); | ||
273 | } | ||
274 | module_exit(sdp4430_soc_exit); | ||
275 | |||
276 | MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>"); | ||
277 | MODULE_DESCRIPTION("ALSA SoC SDP4430"); | ||
278 | MODULE_LICENSE("GPL"); | ||
279 | |||
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c index 981616d61f67..920e0d9e03db 100644 --- a/sound/soc/omap/zoom2.c +++ b/sound/soc/omap/zoom2.c | |||
@@ -131,7 +131,7 @@ static struct snd_soc_dai_link zoom2_dai[] = { | |||
131 | { | 131 | { |
132 | .name = "TWL4030 I2S", | 132 | .name = "TWL4030 I2S", |
133 | .stream_name = "TWL4030 Audio", | 133 | .stream_name = "TWL4030 Audio", |
134 | .cpu_dai_name = "omap-mcbsp-dai.1", | 134 | .cpu_dai_name = "omap-mcbsp.2", |
135 | .codec_dai_name = "twl4030-hifi", | 135 | .codec_dai_name = "twl4030-hifi", |
136 | .platform_name = "omap-pcm-audio", | 136 | .platform_name = "omap-pcm-audio", |
137 | .codec_name = "twl4030-codec", | 137 | .codec_name = "twl4030-codec", |
@@ -143,7 +143,7 @@ static struct snd_soc_dai_link zoom2_dai[] = { | |||
143 | { | 143 | { |
144 | .name = "TWL4030 PCM", | 144 | .name = "TWL4030 PCM", |
145 | .stream_name = "TWL4030 Voice", | 145 | .stream_name = "TWL4030 Voice", |
146 | .cpu_dai_name = "omap-mcbsp-dai.2", | 146 | .cpu_dai_name = "omap-mcbsp.3", |
147 | .codec_dai_name = "twl4030-voice", | 147 | .codec_dai_name = "twl4030-voice", |
148 | .platform_name = "omap-pcm-audio", | 148 | .platform_name = "omap-pcm-audio", |
149 | .codec_name = "twl4030-codec", | 149 | .codec_name = "twl4030-codec", |
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index bc21944851c4..863367ad89ce 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c | |||
@@ -45,10 +45,8 @@ | |||
45 | static int corgi_jack_func; | 45 | static int corgi_jack_func; |
46 | static int corgi_spk_func; | 46 | static int corgi_spk_func; |
47 | 47 | ||
48 | static void corgi_ext_control(struct snd_soc_codec *codec) | 48 | static void corgi_ext_control(struct snd_soc_dapm_context *dapm) |
49 | { | 49 | { |
50 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
51 | |||
52 | /* set up jack connection */ | 50 | /* set up jack connection */ |
53 | switch (corgi_jack_func) { | 51 | switch (corgi_jack_func) { |
54 | case CORGI_HP: | 52 | case CORGI_HP: |
@@ -104,7 +102,7 @@ static int corgi_startup(struct snd_pcm_substream *substream) | |||
104 | mutex_lock(&codec->mutex); | 102 | mutex_lock(&codec->mutex); |
105 | 103 | ||
106 | /* check the jack status at stream startup */ | 104 | /* check the jack status at stream startup */ |
107 | corgi_ext_control(codec); | 105 | corgi_ext_control(&codec->dapm); |
108 | 106 | ||
109 | mutex_unlock(&codec->mutex); | 107 | mutex_unlock(&codec->mutex); |
110 | 108 | ||
@@ -173,13 +171,13 @@ static int corgi_get_jack(struct snd_kcontrol *kcontrol, | |||
173 | static int corgi_set_jack(struct snd_kcontrol *kcontrol, | 171 | static int corgi_set_jack(struct snd_kcontrol *kcontrol, |
174 | struct snd_ctl_elem_value *ucontrol) | 172 | struct snd_ctl_elem_value *ucontrol) |
175 | { | 173 | { |
176 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 174 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
177 | 175 | ||
178 | if (corgi_jack_func == ucontrol->value.integer.value[0]) | 176 | if (corgi_jack_func == ucontrol->value.integer.value[0]) |
179 | return 0; | 177 | return 0; |
180 | 178 | ||
181 | corgi_jack_func = ucontrol->value.integer.value[0]; | 179 | corgi_jack_func = ucontrol->value.integer.value[0]; |
182 | corgi_ext_control(codec); | 180 | corgi_ext_control(&card->dapm); |
183 | return 1; | 181 | return 1; |
184 | } | 182 | } |
185 | 183 | ||
@@ -193,13 +191,13 @@ static int corgi_get_spk(struct snd_kcontrol *kcontrol, | |||
193 | static int corgi_set_spk(struct snd_kcontrol *kcontrol, | 191 | static int corgi_set_spk(struct snd_kcontrol *kcontrol, |
194 | struct snd_ctl_elem_value *ucontrol) | 192 | struct snd_ctl_elem_value *ucontrol) |
195 | { | 193 | { |
196 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 194 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
197 | 195 | ||
198 | if (corgi_spk_func == ucontrol->value.integer.value[0]) | 196 | if (corgi_spk_func == ucontrol->value.integer.value[0]) |
199 | return 0; | 197 | return 0; |
200 | 198 | ||
201 | corgi_spk_func = ucontrol->value.integer.value[0]; | 199 | corgi_spk_func = ucontrol->value.integer.value[0]; |
202 | corgi_ext_control(codec); | 200 | corgi_ext_control(&card->dapm); |
203 | return 1; | 201 | return 1; |
204 | } | 202 | } |
205 | 203 | ||
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c index 3f7a8ecb9720..aace19e0fe2c 100644 --- a/sound/soc/pxa/magician.c +++ b/sound/soc/pxa/magician.c | |||
@@ -411,7 +411,7 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd) | |||
411 | snd_soc_dapm_nc_pin(dapm, "VINR"); | 411 | snd_soc_dapm_nc_pin(dapm, "VINR"); |
412 | 412 | ||
413 | /* Add magician specific controls */ | 413 | /* Add magician specific controls */ |
414 | err = snd_soc_add_controls(codec, uda1380_magician_controls, | 414 | err = snd_soc_add_codec_controls(codec, uda1380_magician_controls, |
415 | ARRAY_SIZE(uda1380_magician_controls)); | 415 | ARRAY_SIZE(uda1380_magician_controls)); |
416 | if (err < 0) | 416 | if (err < 0) |
417 | return err; | 417 | return err; |
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index fd0ed10c6fe7..d2cc81735036 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c | |||
@@ -43,10 +43,8 @@ | |||
43 | static int poodle_jack_func; | 43 | static int poodle_jack_func; |
44 | static int poodle_spk_func; | 44 | static int poodle_spk_func; |
45 | 45 | ||
46 | static void poodle_ext_control(struct snd_soc_codec *codec) | 46 | static void poodle_ext_control(struct snd_soc_dapm_context *dapm) |
47 | { | 47 | { |
48 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
49 | |||
50 | /* set up jack connection */ | 48 | /* set up jack connection */ |
51 | if (poodle_jack_func == POODLE_HP) { | 49 | if (poodle_jack_func == POODLE_HP) { |
52 | /* set = unmute headphone */ | 50 | /* set = unmute headphone */ |
@@ -81,7 +79,7 @@ static int poodle_startup(struct snd_pcm_substream *substream) | |||
81 | mutex_lock(&codec->mutex); | 79 | mutex_lock(&codec->mutex); |
82 | 80 | ||
83 | /* check the jack status at stream startup */ | 81 | /* check the jack status at stream startup */ |
84 | poodle_ext_control(codec); | 82 | poodle_ext_control(&codec->dapm); |
85 | 83 | ||
86 | mutex_unlock(&codec->mutex); | 84 | mutex_unlock(&codec->mutex); |
87 | 85 | ||
@@ -152,13 +150,13 @@ static int poodle_get_jack(struct snd_kcontrol *kcontrol, | |||
152 | static int poodle_set_jack(struct snd_kcontrol *kcontrol, | 150 | static int poodle_set_jack(struct snd_kcontrol *kcontrol, |
153 | struct snd_ctl_elem_value *ucontrol) | 151 | struct snd_ctl_elem_value *ucontrol) |
154 | { | 152 | { |
155 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 153 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
156 | 154 | ||
157 | if (poodle_jack_func == ucontrol->value.integer.value[0]) | 155 | if (poodle_jack_func == ucontrol->value.integer.value[0]) |
158 | return 0; | 156 | return 0; |
159 | 157 | ||
160 | poodle_jack_func = ucontrol->value.integer.value[0]; | 158 | poodle_jack_func = ucontrol->value.integer.value[0]; |
161 | poodle_ext_control(codec); | 159 | poodle_ext_control(&card->dapm); |
162 | return 1; | 160 | return 1; |
163 | } | 161 | } |
164 | 162 | ||
@@ -172,13 +170,13 @@ static int poodle_get_spk(struct snd_kcontrol *kcontrol, | |||
172 | static int poodle_set_spk(struct snd_kcontrol *kcontrol, | 170 | static int poodle_set_spk(struct snd_kcontrol *kcontrol, |
173 | struct snd_ctl_elem_value *ucontrol) | 171 | struct snd_ctl_elem_value *ucontrol) |
174 | { | 172 | { |
175 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 173 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
176 | 174 | ||
177 | if (poodle_spk_func == ucontrol->value.integer.value[0]) | 175 | if (poodle_spk_func == ucontrol->value.integer.value[0]) |
178 | return 0; | 176 | return 0; |
179 | 177 | ||
180 | poodle_spk_func = ucontrol->value.integer.value[0]; | 178 | poodle_spk_func = ucontrol->value.integer.value[0]; |
181 | poodle_ext_control(codec); | 179 | poodle_ext_control(&card->dapm); |
182 | return 1; | 180 | return 1; |
183 | } | 181 | } |
184 | 182 | ||
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index a57cfbc038e3..fd04ce139031 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c | |||
@@ -668,6 +668,38 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, | |||
668 | return 0; | 668 | return 0; |
669 | } | 669 | } |
670 | 670 | ||
671 | static void pxa_ssp_set_running_bit(struct snd_pcm_substream *substream, | ||
672 | struct ssp_device *ssp, int value) | ||
673 | { | ||
674 | uint32_t sscr0 = pxa_ssp_read_reg(ssp, SSCR0); | ||
675 | uint32_t sscr1 = pxa_ssp_read_reg(ssp, SSCR1); | ||
676 | uint32_t sspsp = pxa_ssp_read_reg(ssp, SSPSP); | ||
677 | uint32_t sssr = pxa_ssp_read_reg(ssp, SSSR); | ||
678 | |||
679 | if (value && (sscr0 & SSCR0_SSE)) | ||
680 | pxa_ssp_write_reg(ssp, SSCR0, sscr0 & ~SSCR0_SSE); | ||
681 | |||
682 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
683 | if (value) | ||
684 | sscr1 |= SSCR1_TSRE; | ||
685 | else | ||
686 | sscr1 &= ~SSCR1_TSRE; | ||
687 | } else { | ||
688 | if (value) | ||
689 | sscr1 |= SSCR1_RSRE; | ||
690 | else | ||
691 | sscr1 &= ~SSCR1_RSRE; | ||
692 | } | ||
693 | |||
694 | pxa_ssp_write_reg(ssp, SSCR1, sscr1); | ||
695 | |||
696 | if (value) { | ||
697 | pxa_ssp_write_reg(ssp, SSSR, sssr); | ||
698 | pxa_ssp_write_reg(ssp, SSPSP, sspsp); | ||
699 | pxa_ssp_write_reg(ssp, SSCR0, sscr0 | SSCR0_SSE); | ||
700 | } | ||
701 | } | ||
702 | |||
671 | static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd, | 703 | static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd, |
672 | struct snd_soc_dai *cpu_dai) | 704 | struct snd_soc_dai *cpu_dai) |
673 | { | 705 | { |
@@ -681,42 +713,21 @@ static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd, | |||
681 | pxa_ssp_enable(ssp); | 713 | pxa_ssp_enable(ssp); |
682 | break; | 714 | break; |
683 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 715 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
684 | val = pxa_ssp_read_reg(ssp, SSCR1); | 716 | pxa_ssp_set_running_bit(substream, ssp, 1); |
685 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
686 | val |= SSCR1_TSRE; | ||
687 | else | ||
688 | val |= SSCR1_RSRE; | ||
689 | pxa_ssp_write_reg(ssp, SSCR1, val); | ||
690 | val = pxa_ssp_read_reg(ssp, SSSR); | 717 | val = pxa_ssp_read_reg(ssp, SSSR); |
691 | pxa_ssp_write_reg(ssp, SSSR, val); | 718 | pxa_ssp_write_reg(ssp, SSSR, val); |
692 | break; | 719 | break; |
693 | case SNDRV_PCM_TRIGGER_START: | 720 | case SNDRV_PCM_TRIGGER_START: |
694 | val = pxa_ssp_read_reg(ssp, SSCR1); | 721 | pxa_ssp_set_running_bit(substream, ssp, 1); |
695 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
696 | val |= SSCR1_TSRE; | ||
697 | else | ||
698 | val |= SSCR1_RSRE; | ||
699 | pxa_ssp_write_reg(ssp, SSCR1, val); | ||
700 | pxa_ssp_enable(ssp); | ||
701 | break; | 722 | break; |
702 | case SNDRV_PCM_TRIGGER_STOP: | 723 | case SNDRV_PCM_TRIGGER_STOP: |
703 | val = pxa_ssp_read_reg(ssp, SSCR1); | 724 | pxa_ssp_set_running_bit(substream, ssp, 0); |
704 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
705 | val &= ~SSCR1_TSRE; | ||
706 | else | ||
707 | val &= ~SSCR1_RSRE; | ||
708 | pxa_ssp_write_reg(ssp, SSCR1, val); | ||
709 | break; | 725 | break; |
710 | case SNDRV_PCM_TRIGGER_SUSPEND: | 726 | case SNDRV_PCM_TRIGGER_SUSPEND: |
711 | pxa_ssp_disable(ssp); | 727 | pxa_ssp_disable(ssp); |
712 | break; | 728 | break; |
713 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 729 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
714 | val = pxa_ssp_read_reg(ssp, SSCR1); | 730 | pxa_ssp_set_running_bit(substream, ssp, 0); |
715 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
716 | val &= ~SSCR1_TSRE; | ||
717 | else | ||
718 | val &= ~SSCR1_RSRE; | ||
719 | pxa_ssp_write_reg(ssp, SSCR1, val); | ||
720 | break; | 731 | break; |
721 | 732 | ||
722 | default: | 733 | default: |
@@ -764,7 +775,8 @@ static int pxa_ssp_remove(struct snd_soc_dai *dai) | |||
764 | 775 | ||
765 | #define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ | 776 | #define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\ |
766 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ | 777 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \ |
767 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \ | 778 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ |
779 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | \ | ||
768 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) | 780 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) |
769 | 781 | ||
770 | #define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ | 782 | #define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ |
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 837ff341fd6d..4800d5fe568d 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c | |||
@@ -103,7 +103,7 @@ static int pxa2xx_ac97_resume(struct snd_soc_dai *dai) | |||
103 | #define pxa2xx_ac97_resume NULL | 103 | #define pxa2xx_ac97_resume NULL |
104 | #endif | 104 | #endif |
105 | 105 | ||
106 | static int pxa2xx_ac97_probe(struct snd_soc_dai *dai) | 106 | static int __devinit pxa2xx_ac97_probe(struct snd_soc_dai *dai) |
107 | { | 107 | { |
108 | return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev)); | 108 | return pxa2xx_ac97_hw_probe(to_platform_device(dai->dev)); |
109 | } | 109 | } |
@@ -179,7 +179,7 @@ static const struct snd_soc_dai_ops pxa_ac97_mic_dai_ops = { | |||
179 | * There is only 1 physical AC97 interface for pxa2xx, but it | 179 | * There is only 1 physical AC97 interface for pxa2xx, but it |
180 | * has extra fifo's that can be used for aux DACs and ADCs. | 180 | * has extra fifo's that can be used for aux DACs and ADCs. |
181 | */ | 181 | */ |
182 | static struct snd_soc_dai_driver pxa_ac97_dai[] = { | 182 | static struct snd_soc_dai_driver pxa_ac97_dai_driver[] = { |
183 | { | 183 | { |
184 | .name = "pxa2xx-ac97", | 184 | .name = "pxa2xx-ac97", |
185 | .ac97_control = 1, | 185 | .ac97_control = 1, |
@@ -244,13 +244,13 @@ static __devinit int pxa2xx_ac97_dev_probe(struct platform_device *pdev) | |||
244 | * driver to do interesting things with the clocking to get us up | 244 | * driver to do interesting things with the clocking to get us up |
245 | * and running. | 245 | * and running. |
246 | */ | 246 | */ |
247 | return snd_soc_register_dais(&pdev->dev, pxa_ac97_dai, | 247 | return snd_soc_register_dais(&pdev->dev, pxa_ac97_dai_driver, |
248 | ARRAY_SIZE(pxa_ac97_dai)); | 248 | ARRAY_SIZE(pxa_ac97_dai_driver)); |
249 | } | 249 | } |
250 | 250 | ||
251 | static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev) | 251 | static int __devexit pxa2xx_ac97_dev_remove(struct platform_device *pdev) |
252 | { | 252 | { |
253 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai)); | 253 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(pxa_ac97_dai_driver)); |
254 | return 0; | 254 | return 0; |
255 | } | 255 | } |
256 | 256 | ||
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c index ba1545188ec6..083706595495 100644 --- a/sound/soc/pxa/raumfeld.c +++ b/sound/soc/pxa/raumfeld.c | |||
@@ -232,7 +232,7 @@ static struct snd_soc_ops raumfeld_ak4104_ops = { | |||
232 | .cpu_dai_name = "pxa-ssp-dai.0", \ | 232 | .cpu_dai_name = "pxa-ssp-dai.0", \ |
233 | .platform_name = "pxa-pcm-audio", \ | 233 | .platform_name = "pxa-pcm-audio", \ |
234 | .codec_dai_name = "cs4270-hifi", \ | 234 | .codec_dai_name = "cs4270-hifi", \ |
235 | .codec_name = "cs4270-codec.0-0048", \ | 235 | .codec_name = "cs4270.0-0048", \ |
236 | .ops = &raumfeld_cs4270_ops, \ | 236 | .ops = &raumfeld_cs4270_ops, \ |
237 | } | 237 | } |
238 | 238 | ||
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 90c5245c4742..fc052d8247ff 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c | |||
@@ -44,10 +44,8 @@ static int spitz_jack_func; | |||
44 | static int spitz_spk_func; | 44 | static int spitz_spk_func; |
45 | static int spitz_mic_gpio; | 45 | static int spitz_mic_gpio; |
46 | 46 | ||
47 | static void spitz_ext_control(struct snd_soc_codec *codec) | 47 | static void spitz_ext_control(struct snd_soc_dapm_context *dapm) |
48 | { | 48 | { |
49 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
50 | |||
51 | if (spitz_spk_func == SPITZ_SPK_ON) | 49 | if (spitz_spk_func == SPITZ_SPK_ON) |
52 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); | 50 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); |
53 | else | 51 | else |
@@ -113,7 +111,7 @@ static int spitz_startup(struct snd_pcm_substream *substream) | |||
113 | mutex_lock(&codec->mutex); | 111 | mutex_lock(&codec->mutex); |
114 | 112 | ||
115 | /* check the jack status at stream startup */ | 113 | /* check the jack status at stream startup */ |
116 | spitz_ext_control(codec); | 114 | spitz_ext_control(&codec->dapm); |
117 | 115 | ||
118 | mutex_unlock(&codec->mutex); | 116 | mutex_unlock(&codec->mutex); |
119 | 117 | ||
@@ -173,13 +171,13 @@ static int spitz_get_jack(struct snd_kcontrol *kcontrol, | |||
173 | static int spitz_set_jack(struct snd_kcontrol *kcontrol, | 171 | static int spitz_set_jack(struct snd_kcontrol *kcontrol, |
174 | struct snd_ctl_elem_value *ucontrol) | 172 | struct snd_ctl_elem_value *ucontrol) |
175 | { | 173 | { |
176 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 174 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
177 | 175 | ||
178 | if (spitz_jack_func == ucontrol->value.integer.value[0]) | 176 | if (spitz_jack_func == ucontrol->value.integer.value[0]) |
179 | return 0; | 177 | return 0; |
180 | 178 | ||
181 | spitz_jack_func = ucontrol->value.integer.value[0]; | 179 | spitz_jack_func = ucontrol->value.integer.value[0]; |
182 | spitz_ext_control(codec); | 180 | spitz_ext_control(&card->dapm); |
183 | return 1; | 181 | return 1; |
184 | } | 182 | } |
185 | 183 | ||
@@ -193,13 +191,13 @@ static int spitz_get_spk(struct snd_kcontrol *kcontrol, | |||
193 | static int spitz_set_spk(struct snd_kcontrol *kcontrol, | 191 | static int spitz_set_spk(struct snd_kcontrol *kcontrol, |
194 | struct snd_ctl_elem_value *ucontrol) | 192 | struct snd_ctl_elem_value *ucontrol) |
195 | { | 193 | { |
196 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 194 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
197 | 195 | ||
198 | if (spitz_spk_func == ucontrol->value.integer.value[0]) | 196 | if (spitz_spk_func == ucontrol->value.integer.value[0]) |
199 | return 0; | 197 | return 0; |
200 | 198 | ||
201 | spitz_spk_func = ucontrol->value.integer.value[0]; | 199 | spitz_spk_func = ucontrol->value.integer.value[0]; |
202 | spitz_ext_control(codec); | 200 | spitz_ext_control(&card->dapm); |
203 | return 1; | 201 | return 1; |
204 | } | 202 | } |
205 | 203 | ||
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index 564ef08a89f2..2aec63f3706a 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c | |||
@@ -197,7 +197,7 @@ static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd) | |||
197 | snd_soc_dapm_nc_pin(dapm, "MONOOUT"); | 197 | snd_soc_dapm_nc_pin(dapm, "MONOOUT"); |
198 | 198 | ||
199 | /* add tosa specific controls */ | 199 | /* add tosa specific controls */ |
200 | err = snd_soc_add_controls(codec, tosa_controls, | 200 | err = snd_soc_add_codec_controls(codec, tosa_controls, |
201 | ARRAY_SIZE(tosa_controls)); | 201 | ARRAY_SIZE(tosa_controls)); |
202 | if (err < 0) | 202 | if (err < 0) |
203 | return err; | 203 | return err; |
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c index 43c014f362f6..716da861c629 100644 --- a/sound/soc/s6000/s6000-pcm.c +++ b/sound/soc/s6000/s6000-pcm.c | |||
@@ -435,7 +435,8 @@ static void s6000_pcm_free(struct snd_pcm *pcm) | |||
435 | { | 435 | { |
436 | struct snd_soc_pcm_runtime *runtime = pcm->private_data; | 436 | struct snd_soc_pcm_runtime *runtime = pcm->private_data; |
437 | struct s6000_pcm_dma_params *params = | 437 | struct s6000_pcm_dma_params *params = |
438 | snd_soc_dai_get_dma_data(runtime->cpu_dai, pcm->streams[0].substream); | 438 | snd_soc_dai_get_dma_data(runtime->cpu_dai, |
439 | pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream); | ||
439 | 440 | ||
440 | free_irq(params->irq, pcm); | 441 | free_irq(params->irq, pcm); |
441 | snd_pcm_lib_preallocate_free_for_all(pcm); | 442 | snd_pcm_lib_preallocate_free_for_all(pcm); |
@@ -451,7 +452,7 @@ static int s6000_pcm_new(struct snd_soc_pcm_runtime *runtime) | |||
451 | int res; | 452 | int res; |
452 | 453 | ||
453 | params = snd_soc_dai_get_dma_data(runtime->cpu_dai, | 454 | params = snd_soc_dai_get_dma_data(runtime->cpu_dai, |
454 | pcm->streams[0].substream); | 455 | pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream); |
455 | 456 | ||
456 | if (!card->dev->dma_mask) | 457 | if (!card->dev->dma_mask) |
457 | card->dev->dma_mask = &s6000_pcm_dmamask; | 458 | card->dev->dma_mask = &s6000_pcm_dmamask; |
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index f3417f2311b8..fe3995ce9b38 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
@@ -1,8 +1,8 @@ | |||
1 | config SND_SOC_SAMSUNG | 1 | config SND_SOC_SAMSUNG |
2 | tristate "ASoC support for Samsung" | 2 | tristate "ASoC support for Samsung" |
3 | depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_EXYNOS4 | 3 | depends on ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_EXYNOS4 |
4 | select S3C64XX_DMA if ARCH_S3C64XX | 4 | select S3C64XX_DMA if ARCH_S3C64XX |
5 | select S3C2410_DMA if ARCH_S3C2410 | 5 | select S3C2410_DMA if ARCH_S3C24XX |
6 | help | 6 | help |
7 | Say Y or M if you want to add support for codecs attached to | 7 | Say Y or M if you want to add support for codecs attached to |
8 | the Samsung SoCs' Audio interfaces. You will also need to | 8 | the Samsung SoCs' Audio interfaces. You will also need to |
@@ -84,7 +84,7 @@ config SND_SOC_SAMSUNG_SMDK2443_WM9710 | |||
84 | 84 | ||
85 | config SND_SOC_SAMSUNG_LN2440SBC_ALC650 | 85 | config SND_SOC_SAMSUNG_LN2440SBC_ALC650 |
86 | tristate "SoC AC97 Audio support for LN2440SBC - ALC650" | 86 | tristate "SoC AC97 Audio support for LN2440SBC - ALC650" |
87 | depends on SND_SOC_SAMSUNG && ARCH_S3C2410 | 87 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX |
88 | select S3C2410_DMA | 88 | select S3C2410_DMA |
89 | select AC97_BUS | 89 | select AC97_BUS |
90 | select SND_SOC_AC97_CODEC | 90 | select SND_SOC_AC97_CODEC |
@@ -95,7 +95,7 @@ config SND_SOC_SAMSUNG_LN2440SBC_ALC650 | |||
95 | 95 | ||
96 | config SND_SOC_SAMSUNG_S3C24XX_UDA134X | 96 | config SND_SOC_SAMSUNG_S3C24XX_UDA134X |
97 | tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" | 97 | tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" |
98 | depends on SND_SOC_SAMSUNG && ARCH_S3C2410 | 98 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX |
99 | select SND_S3C24XX_I2S | 99 | select SND_S3C24XX_I2S |
100 | select SND_SOC_L3 | 100 | select SND_SOC_L3 |
101 | select SND_SOC_UDA134X | 101 | select SND_SOC_UDA134X |
@@ -107,14 +107,14 @@ config SND_SOC_SAMSUNG_SIMTEC | |||
107 | 107 | ||
108 | config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23 | 108 | config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23 |
109 | tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" | 109 | tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" |
110 | depends on SND_SOC_SAMSUNG && ARCH_S3C2410 | 110 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX |
111 | select SND_S3C24XX_I2S | 111 | select SND_S3C24XX_I2S |
112 | select SND_SOC_TLV320AIC23 | 112 | select SND_SOC_TLV320AIC23 |
113 | select SND_SOC_SAMSUNG_SIMTEC | 113 | select SND_SOC_SAMSUNG_SIMTEC |
114 | 114 | ||
115 | config SND_SOC_SAMSUNG_SIMTEC_HERMES | 115 | config SND_SOC_SAMSUNG_SIMTEC_HERMES |
116 | tristate "SoC I2S Audio support for Simtec Hermes board" | 116 | tristate "SoC I2S Audio support for Simtec Hermes board" |
117 | depends on SND_SOC_SAMSUNG && ARCH_S3C2410 | 117 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX |
118 | select SND_S3C24XX_I2S | 118 | select SND_S3C24XX_I2S |
119 | select SND_SOC_TLV320AIC3X | 119 | select SND_SOC_TLV320AIC3X |
120 | select SND_SOC_SAMSUNG_SIMTEC | 120 | select SND_SOC_SAMSUNG_SIMTEC |
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 7b9bf93e3701..3d04c1fa6781 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Evolved from s3c2443-ac97.c | 4 | * Evolved from s3c2443-ac97.c |
5 | * | 5 | * |
6 | * Copyright (c) 2010 Samsung Electronics Co. Ltd | 6 | * Copyright (c) 2010 Samsung Electronics Co. Ltd |
7 | * Author: Jaswinder Singh <jassi.brar@samsung.com> | 7 | * Author: Jaswinder Singh <jassisinghbrar@gmail.com> |
8 | * Credits: Graeme Gregory, Sean Choi | 8 | * Credits: Graeme Gregory, Sean Choi |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
@@ -511,7 +511,7 @@ static struct platform_driver s3c_ac97_driver = { | |||
511 | 511 | ||
512 | module_platform_driver(s3c_ac97_driver); | 512 | module_platform_driver(s3c_ac97_driver); |
513 | 513 | ||
514 | MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); | 514 | MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>"); |
515 | MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); | 515 | MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); |
516 | MODULE_LICENSE("GPL"); | 516 | MODULE_LICENSE("GPL"); |
517 | MODULE_ALIAS("platform:samsung-ac97"); | 517 | MODULE_ALIAS("platform:samsung-ac97"); |
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index e4ba17ce6b32..ddc6cde14e2a 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c | |||
@@ -411,7 +411,7 @@ static int dma_new(struct snd_soc_pcm_runtime *rtd) | |||
411 | if (!card->dev->dma_mask) | 411 | if (!card->dev->dma_mask) |
412 | card->dev->dma_mask = &dma_mask; | 412 | card->dev->dma_mask = &dma_mask; |
413 | if (!card->dev->coherent_dma_mask) | 413 | if (!card->dev->coherent_dma_mask) |
414 | card->dev->coherent_dma_mask = 0xffffffff; | 414 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); |
415 | 415 | ||
416 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | 416 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { |
417 | ret = preallocate_dma_buffer(pcm, | 417 | ret = preallocate_dma_buffer(pcm, |
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 87a874dc7a35..6ac7b8281a02 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * ALSA SoC Audio Layer - Samsung I2S Controller driver | 3 | * ALSA SoC Audio Layer - Samsung I2S Controller driver |
4 | * | 4 | * |
5 | * Copyright (c) 2010 Samsung Electronics Co. Ltd. | 5 | * Copyright (c) 2010 Samsung Electronics Co. Ltd. |
6 | * Jaswinder Singh <jassi.brar@samsung.com> | 6 | * Jaswinder Singh <jassisinghbrar@gmail.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -559,6 +559,17 @@ static int i2s_hw_params(struct snd_pcm_substream *substream, | |||
559 | mod |= MOD_DC1_EN; | 559 | mod |= MOD_DC1_EN; |
560 | break; | 560 | break; |
561 | case 2: | 561 | case 2: |
562 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
563 | i2s->dma_playback.dma_size = 4; | ||
564 | else | ||
565 | i2s->dma_capture.dma_size = 4; | ||
566 | break; | ||
567 | case 1: | ||
568 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
569 | i2s->dma_playback.dma_size = 2; | ||
570 | else | ||
571 | i2s->dma_capture.dma_size = 2; | ||
572 | |||
562 | break; | 573 | break; |
563 | default: | 574 | default: |
564 | dev_err(&i2s->pdev->dev, "%d channels not supported\n", | 575 | dev_err(&i2s->pdev->dev, "%d channels not supported\n", |
@@ -761,15 +772,13 @@ static int i2s_trigger(struct snd_pcm_substream *substream, | |||
761 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 772 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
762 | local_irq_save(flags); | 773 | local_irq_save(flags); |
763 | 774 | ||
764 | if (capture) | 775 | if (capture) { |
765 | i2s_rxctrl(i2s, 0); | 776 | i2s_rxctrl(i2s, 0); |
766 | else | ||
767 | i2s_txctrl(i2s, 0); | ||
768 | |||
769 | if (capture) | ||
770 | i2s_fifo(i2s, FIC_RXFLUSH); | 777 | i2s_fifo(i2s, FIC_RXFLUSH); |
771 | else | 778 | } else { |
779 | i2s_txctrl(i2s, 0); | ||
772 | i2s_fifo(i2s, FIC_TXFLUSH); | 780 | i2s_fifo(i2s, FIC_TXFLUSH); |
781 | } | ||
773 | 782 | ||
774 | local_irq_restore(flags); | 783 | local_irq_restore(flags); |
775 | break; | 784 | break; |
@@ -965,7 +974,7 @@ struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) | |||
965 | i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS; | 974 | i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS; |
966 | 975 | ||
967 | if (!sec) { | 976 | if (!sec) { |
968 | i2s->i2s_dai_drv.capture.channels_min = 2; | 977 | i2s->i2s_dai_drv.capture.channels_min = 1; |
969 | i2s->i2s_dai_drv.capture.channels_max = 2; | 978 | i2s->i2s_dai_drv.capture.channels_max = 2; |
970 | i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES; | 979 | i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES; |
971 | i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; | 980 | i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; |
@@ -1143,7 +1152,7 @@ static struct platform_driver samsung_i2s_driver = { | |||
1143 | module_platform_driver(samsung_i2s_driver); | 1152 | module_platform_driver(samsung_i2s_driver); |
1144 | 1153 | ||
1145 | /* Module information */ | 1154 | /* Module information */ |
1146 | MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); | 1155 | MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>"); |
1147 | MODULE_DESCRIPTION("Samsung I2S Interface"); | 1156 | MODULE_DESCRIPTION("Samsung I2S Interface"); |
1148 | MODULE_ALIAS("platform:samsung-i2s"); | 1157 | MODULE_ALIAS("platform:samsung-i2s"); |
1149 | MODULE_LICENSE("GPL"); | 1158 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/samsung/i2s.h b/sound/soc/samsung/i2s.h index 8e15f6a616d1..d420a7ca56ca 100644 --- a/sound/soc/samsung/i2s.h +++ b/sound/soc/samsung/i2s.h | |||
@@ -3,7 +3,7 @@ | |||
3 | * ALSA SoC Audio Layer - Samsung I2S Controller driver | 3 | * ALSA SoC Audio Layer - Samsung I2S Controller driver |
4 | * | 4 | * |
5 | * Copyright (c) 2010 Samsung Electronics Co. Ltd. | 5 | * Copyright (c) 2010 Samsung Electronics Co. Ltd. |
6 | * Jaswinder Singh <jassi.brar@samsung.com> | 6 | * Jaswinder Singh <jassisinghbrar@gmail.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c index 9dd818bde06f..e7416851bf7d 100644 --- a/sound/soc/samsung/littlemill.c +++ b/sound/soc/samsung/littlemill.c | |||
@@ -189,6 +189,9 @@ static int littlemill_late_probe(struct snd_soc_card *card) | |||
189 | /* This will check device compatibility itself */ | 189 | /* This will check device compatibility itself */ |
190 | wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL); | 190 | wm8958_mic_detect(codec, &littlemill_headset, NULL, NULL); |
191 | 191 | ||
192 | /* As will this */ | ||
193 | wm8994_mic_detect(codec, &littlemill_headset, 1); | ||
194 | |||
192 | return 0; | 195 | return 0; |
193 | } | 196 | } |
194 | 197 | ||
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c index 7ac0ba2025c3..321d51134e47 100644 --- a/sound/soc/samsung/neo1973_wm8753.c +++ b/sound/soc/samsung/neo1973_wm8753.c | |||
@@ -230,8 +230,6 @@ static const struct snd_kcontrol_new neo1973_wm8753_controls[] = { | |||
230 | 230 | ||
231 | /* GTA02 specific routes and controls */ | 231 | /* GTA02 specific routes and controls */ |
232 | 232 | ||
233 | #ifdef CONFIG_MACH_NEO1973_GTA02 | ||
234 | |||
235 | static int gta02_speaker_enabled; | 233 | static int gta02_speaker_enabled; |
236 | 234 | ||
237 | static int lm4853_set_spk(struct snd_kcontrol *kcontrol, | 235 | static int lm4853_set_spk(struct snd_kcontrol *kcontrol, |
@@ -298,7 +296,7 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec) | |||
298 | if (ret) | 296 | if (ret) |
299 | return ret; | 297 | return ret; |
300 | 298 | ||
301 | ret = snd_soc_add_controls(codec, neo1973_gta02_wm8753_controls, | 299 | ret = snd_soc_add_card_controls(codec->card, neo1973_gta02_wm8753_controls, |
302 | ARRAY_SIZE(neo1973_gta02_wm8753_controls)); | 300 | ARRAY_SIZE(neo1973_gta02_wm8753_controls)); |
303 | if (ret) | 301 | if (ret) |
304 | return ret; | 302 | return ret; |
@@ -311,10 +309,6 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec) | |||
311 | return 0; | 309 | return 0; |
312 | } | 310 | } |
313 | 311 | ||
314 | #else | ||
315 | static int neo1973_gta02_wm8753_init(struct snd_soc_code *codec) { return 0; } | ||
316 | #endif | ||
317 | |||
318 | static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) | 312 | static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) |
319 | { | 313 | { |
320 | struct snd_soc_codec *codec = rtd->codec; | 314 | struct snd_soc_codec *codec = rtd->codec; |
@@ -322,10 +316,6 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) | |||
322 | int ret; | 316 | int ret; |
323 | 317 | ||
324 | /* set up NC codec pins */ | 318 | /* set up NC codec pins */ |
325 | if (machine_is_neo1973_gta01()) { | ||
326 | snd_soc_dapm_nc_pin(dapm, "LOUT2"); | ||
327 | snd_soc_dapm_nc_pin(dapm, "ROUT2"); | ||
328 | } | ||
329 | snd_soc_dapm_nc_pin(dapm, "OUT3"); | 319 | snd_soc_dapm_nc_pin(dapm, "OUT3"); |
330 | snd_soc_dapm_nc_pin(dapm, "OUT4"); | 320 | snd_soc_dapm_nc_pin(dapm, "OUT4"); |
331 | snd_soc_dapm_nc_pin(dapm, "LINE1"); | 321 | snd_soc_dapm_nc_pin(dapm, "LINE1"); |
@@ -338,7 +328,7 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) | |||
338 | return ret; | 328 | return ret; |
339 | 329 | ||
340 | /* add neo1973 specific controls */ | 330 | /* add neo1973 specific controls */ |
341 | ret = snd_soc_add_controls(codec, neo1973_wm8753_controls, | 331 | ret = snd_soc_add_card_controls(rtd->card, neo1973_wm8753_controls, |
342 | ARRAY_SIZE(neo1973_wm8753_controls)); | 332 | ARRAY_SIZE(neo1973_wm8753_controls)); |
343 | if (ret) | 333 | if (ret) |
344 | return ret; | 334 | return ret; |
@@ -370,50 +360,6 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) | |||
370 | return 0; | 360 | return 0; |
371 | } | 361 | } |
372 | 362 | ||
373 | /* GTA01 specific controls */ | ||
374 | |||
375 | #ifdef CONFIG_MACH_NEO1973_GTA01 | ||
376 | |||
377 | static const struct snd_soc_dapm_route neo1973_lm4857_routes[] = { | ||
378 | {"Amp IN", NULL, "ROUT1"}, | ||
379 | {"Amp IN", NULL, "LOUT1"}, | ||
380 | |||
381 | {"Handset Spk", NULL, "Amp EP"}, | ||
382 | {"Stereo Out", NULL, "Amp LS"}, | ||
383 | {"Headphone", NULL, "Amp HP"}, | ||
384 | }; | ||
385 | |||
386 | static const struct snd_soc_dapm_widget neo1973_lm4857_dapm_widgets[] = { | ||
387 | SND_SOC_DAPM_SPK("Handset Spk", NULL), | ||
388 | SND_SOC_DAPM_SPK("Stereo Out", NULL), | ||
389 | SND_SOC_DAPM_HP("Headphone", NULL), | ||
390 | }; | ||
391 | |||
392 | static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm) | ||
393 | { | ||
394 | int ret; | ||
395 | |||
396 | ret = snd_soc_dapm_new_controls(dapm, neo1973_lm4857_dapm_widgets, | ||
397 | ARRAY_SIZE(neo1973_lm4857_dapm_widgets)); | ||
398 | if (ret) | ||
399 | return ret; | ||
400 | |||
401 | ret = snd_soc_dapm_add_routes(dapm, neo1973_lm4857_routes, | ||
402 | ARRAY_SIZE(neo1973_lm4857_routes)); | ||
403 | if (ret) | ||
404 | return ret; | ||
405 | |||
406 | snd_soc_dapm_ignore_suspend(dapm, "Stereo Out"); | ||
407 | snd_soc_dapm_ignore_suspend(dapm, "Handset Spk"); | ||
408 | snd_soc_dapm_ignore_suspend(dapm, "Headphone"); | ||
409 | |||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | #else | ||
414 | static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm) { return 0; }; | ||
415 | #endif | ||
416 | |||
417 | static struct snd_soc_dai_link neo1973_dai[] = { | 363 | static struct snd_soc_dai_link neo1973_dai[] = { |
418 | { /* Hifi Playback - for similatious use with voice below */ | 364 | { /* Hifi Playback - for similatious use with voice below */ |
419 | .name = "WM8753", | 365 | .name = "WM8753", |
@@ -421,7 +367,7 @@ static struct snd_soc_dai_link neo1973_dai[] = { | |||
421 | .platform_name = "samsung-audio", | 367 | .platform_name = "samsung-audio", |
422 | .cpu_dai_name = "s3c24xx-iis", | 368 | .cpu_dai_name = "s3c24xx-iis", |
423 | .codec_dai_name = "wm8753-hifi", | 369 | .codec_dai_name = "wm8753-hifi", |
424 | .codec_name = "wm8753-codec.0-001a", | 370 | .codec_name = "wm8753.0-001a", |
425 | .init = neo1973_wm8753_init, | 371 | .init = neo1973_wm8753_init, |
426 | .ops = &neo1973_hifi_ops, | 372 | .ops = &neo1973_hifi_ops, |
427 | }, | 373 | }, |
@@ -430,7 +376,7 @@ static struct snd_soc_dai_link neo1973_dai[] = { | |||
430 | .stream_name = "Voice", | 376 | .stream_name = "Voice", |
431 | .cpu_dai_name = "dfbmcs320-pcm", | 377 | .cpu_dai_name = "dfbmcs320-pcm", |
432 | .codec_dai_name = "wm8753-voice", | 378 | .codec_dai_name = "wm8753-voice", |
433 | .codec_name = "wm8753-codec.0-001a", | 379 | .codec_name = "wm8753.0-001a", |
434 | .ops = &neo1973_voice_ops, | 380 | .ops = &neo1973_voice_ops, |
435 | }, | 381 | }, |
436 | }; | 382 | }; |
@@ -440,11 +386,6 @@ static struct snd_soc_aux_dev neo1973_aux_devs[] = { | |||
440 | .name = "dfbmcs320", | 386 | .name = "dfbmcs320", |
441 | .codec_name = "dfbmcs320.0", | 387 | .codec_name = "dfbmcs320.0", |
442 | }, | 388 | }, |
443 | { | ||
444 | .name = "lm4857", | ||
445 | .codec_name = "lm4857.0-007c", | ||
446 | .init = neo1973_lm4857_init, | ||
447 | }, | ||
448 | }; | 389 | }; |
449 | 390 | ||
450 | static struct snd_soc_codec_conf neo1973_codec_conf[] = { | 391 | static struct snd_soc_codec_conf neo1973_codec_conf[] = { |
@@ -454,14 +395,10 @@ static struct snd_soc_codec_conf neo1973_codec_conf[] = { | |||
454 | }, | 395 | }, |
455 | }; | 396 | }; |
456 | 397 | ||
457 | #ifdef CONFIG_MACH_NEO1973_GTA02 | ||
458 | static const struct gpio neo1973_gta02_gpios[] = { | 398 | static const struct gpio neo1973_gta02_gpios[] = { |
459 | { GTA02_GPIO_HP_IN, GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" }, | 399 | { GTA02_GPIO_HP_IN, GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" }, |
460 | { GTA02_GPIO_AMP_SHUT, GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" }, | 400 | { GTA02_GPIO_AMP_SHUT, GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" }, |
461 | }; | 401 | }; |
462 | #else | ||
463 | static const struct gpio neo1973_gta02_gpios[] = {}; | ||
464 | #endif | ||
465 | 402 | ||
466 | static struct snd_soc_card neo1973 = { | 403 | static struct snd_soc_card neo1973 = { |
467 | .name = "neo1973", | 404 | .name = "neo1973", |
@@ -480,7 +417,7 @@ static int __init neo1973_init(void) | |||
480 | { | 417 | { |
481 | int ret; | 418 | int ret; |
482 | 419 | ||
483 | if (!machine_is_neo1973_gta01() && !machine_is_neo1973_gta02()) | 420 | if (!machine_is_neo1973_gta02()) |
484 | return -ENODEV; | 421 | return -ENODEV; |
485 | 422 | ||
486 | if (machine_is_neo1973_gta02()) { | 423 | if (machine_is_neo1973_gta02()) { |
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index 56780206c000..b7b2a1f91425 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * ALSA SoC Audio Layer - S3C PCM-Controller driver | 3 | * ALSA SoC Audio Layer - S3C PCM-Controller driver |
4 | * | 4 | * |
5 | * Copyright (c) 2009 Samsung Electronics Co. Ltd | 5 | * Copyright (c) 2009 Samsung Electronics Co. Ltd |
6 | * Author: Jaswinder Singh <jassi.brar@samsung.com> | 6 | * Author: Jaswinder Singh <jassisinghbrar@gmail.com> |
7 | * based upon I2S drivers by Ben Dooks. | 7 | * based upon I2S drivers by Ben Dooks. |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
@@ -639,7 +639,7 @@ static struct platform_driver s3c_pcm_driver = { | |||
639 | module_platform_driver(s3c_pcm_driver); | 639 | module_platform_driver(s3c_pcm_driver); |
640 | 640 | ||
641 | /* Module information */ | 641 | /* Module information */ |
642 | MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); | 642 | MODULE_AUTHOR("Jaswinder Singh, <jassisinghbrar@gmail.com>"); |
643 | MODULE_DESCRIPTION("S3C PCM Controller Driver"); | 643 | MODULE_DESCRIPTION("S3C PCM Controller Driver"); |
644 | MODULE_LICENSE("GPL"); | 644 | MODULE_LICENSE("GPL"); |
645 | MODULE_ALIAS("platform:samsung-pcm"); | 645 | MODULE_ALIAS("platform:samsung-pcm"); |
diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c index a253bcc1646a..656d5afe4ca9 100644 --- a/sound/soc/samsung/s3c24xx_simtec.c +++ b/sound/soc/samsung/s3c24xx_simtec.c | |||
@@ -134,18 +134,18 @@ static const struct snd_kcontrol_new amp_unmute_controls[] = { | |||
134 | 134 | ||
135 | void simtec_audio_init(struct snd_soc_pcm_runtime *rtd) | 135 | void simtec_audio_init(struct snd_soc_pcm_runtime *rtd) |
136 | { | 136 | { |
137 | struct snd_soc_codec *codec = rtd->codec; | 137 | struct snd_soc_card *card = rtd->card; |
138 | 138 | ||
139 | if (pdata->amp_gpio > 0) { | 139 | if (pdata->amp_gpio > 0) { |
140 | pr_debug("%s: adding amp routes\n", __func__); | 140 | pr_debug("%s: adding amp routes\n", __func__); |
141 | 141 | ||
142 | snd_soc_add_controls(codec, amp_unmute_controls, | 142 | snd_soc_add_card_controls(card, amp_unmute_controls, |
143 | ARRAY_SIZE(amp_unmute_controls)); | 143 | ARRAY_SIZE(amp_unmute_controls)); |
144 | } | 144 | } |
145 | 145 | ||
146 | if (pdata->amp_gain[0] > 0) { | 146 | if (pdata->amp_gain[0] > 0) { |
147 | pr_debug("%s: adding amp controls\n", __func__); | 147 | pr_debug("%s: adding amp controls\n", __func__); |
148 | snd_soc_add_controls(codec, amp_gain_controls, | 148 | snd_soc_add_card_controls(card, amp_gain_controls, |
149 | ARRAY_SIZE(amp_gain_controls)); | 149 | ARRAY_SIZE(amp_gain_controls)); |
150 | } | 150 | } |
151 | } | 151 | } |
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index bff8758e7f20..ade2809cf393 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * smdk_wm8580.c | 2 | * smdk_wm8580.c |
3 | * | 3 | * |
4 | * Copyright (c) 2009 Samsung Electronics Co. Ltd | 4 | * Copyright (c) 2009 Samsung Electronics Co. Ltd |
5 | * Author: Jaswinder Singh <jassi.brar@samsung.com> | 5 | * Author: Jaswinder Singh <jassisinghbrar@gmail.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
@@ -253,6 +253,6 @@ static void __exit smdk_audio_exit(void) | |||
253 | } | 253 | } |
254 | module_exit(smdk_audio_exit); | 254 | module_exit(smdk_audio_exit); |
255 | 255 | ||
256 | MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com"); | 256 | MODULE_AUTHOR("Jaswinder Singh, jassisinghbrar@gmail.com"); |
257 | MODULE_DESCRIPTION("ALSA SoC SMDK WM8580"); | 257 | MODULE_DESCRIPTION("ALSA SoC SMDK WM8580"); |
258 | MODULE_LICENSE("GPL"); | 258 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/samsung/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c index 8e26a730fcdc..55b2ca7f3290 100644 --- a/sound/soc/samsung/smdk_wm9713.c +++ b/sound/soc/samsung/smdk_wm9713.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * smdk_wm9713.c -- SoC audio for SMDK | 2 | * smdk_wm9713.c -- SoC audio for SMDK |
3 | * | 3 | * |
4 | * Copyright 2010 Samsung Electronics Co. Ltd. | 4 | * Copyright 2010 Samsung Electronics Co. Ltd. |
5 | * Author: Jaswinder Singh Brar <jassi.brar@samsung.com> | 5 | * Author: Jaswinder Singh Brar <jassisinghbrar@gmail.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU General Public License as | 8 | * modify it under the terms of the GNU General Public License as |
@@ -103,6 +103,6 @@ module_init(smdk_init); | |||
103 | module_exit(smdk_exit); | 103 | module_exit(smdk_exit); |
104 | 104 | ||
105 | /* Module information */ | 105 | /* Module information */ |
106 | MODULE_AUTHOR("Jaswinder Singh Brar, jassi.brar@samsung.com"); | 106 | MODULE_AUTHOR("Jaswinder Singh Brar, jassisinghbrar@gmail.com"); |
107 | MODULE_DESCRIPTION("ALSA SoC SMDK+WM9713"); | 107 | MODULE_DESCRIPTION("ALSA SoC SMDK+WM9713"); |
108 | MODULE_LICENSE("GPL"); | 108 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index db6c89a28bda..378cc5b056d7 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -13,8 +13,11 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/dma-mapping.h> | ||
16 | #include <linux/pm_runtime.h> | 17 | #include <linux/pm_runtime.h> |
17 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/scatterlist.h> | ||
20 | #include <linux/sh_dma.h> | ||
18 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
19 | #include <linux/module.h> | 22 | #include <linux/module.h> |
20 | #include <sound/soc.h> | 23 | #include <sound/soc.h> |
@@ -53,6 +56,7 @@ | |||
53 | 56 | ||
54 | /* DO_FMT */ | 57 | /* DO_FMT */ |
55 | /* DI_FMT */ | 58 | /* DI_FMT */ |
59 | #define CR_BWS_MASK (0x3 << 20) /* FSI2 */ | ||
56 | #define CR_BWS_24 (0x0 << 20) /* FSI2 */ | 60 | #define CR_BWS_24 (0x0 << 20) /* FSI2 */ |
57 | #define CR_BWS_16 (0x1 << 20) /* FSI2 */ | 61 | #define CR_BWS_16 (0x1 << 20) /* FSI2 */ |
58 | #define CR_BWS_20 (0x2 << 20) /* FSI2 */ | 62 | #define CR_BWS_20 (0x2 << 20) /* FSI2 */ |
@@ -68,6 +72,15 @@ | |||
68 | #define CR_TDM (0x4 << 4) | 72 | #define CR_TDM (0x4 << 4) |
69 | #define CR_TDM_D (0x5 << 4) | 73 | #define CR_TDM_D (0x5 << 4) |
70 | 74 | ||
75 | /* OUT_DMAC */ | ||
76 | /* IN_DMAC */ | ||
77 | #define VDMD_MASK (0x3 << 4) | ||
78 | #define VDMD_FRONT (0x0 << 4) /* Package in front */ | ||
79 | #define VDMD_BACK (0x1 << 4) /* Package in back */ | ||
80 | #define VDMD_STREAM (0x2 << 4) /* Stream mode(16bit * 2) */ | ||
81 | |||
82 | #define DMA_ON (0x1 << 0) | ||
83 | |||
71 | /* DOFF_CTL */ | 84 | /* DOFF_CTL */ |
72 | /* DIFF_CTL */ | 85 | /* DIFF_CTL */ |
73 | #define IRQ_HALF 0x00100000 | 86 | #define IRQ_HALF 0x00100000 |
@@ -116,7 +129,7 @@ | |||
116 | 129 | ||
117 | #define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) | 130 | #define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) |
118 | 131 | ||
119 | typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int enable); | 132 | typedef int (*set_rate_func)(struct device *dev, int rate, int enable); |
120 | 133 | ||
121 | /* | 134 | /* |
122 | * FSI driver use below type name for variable | 135 | * FSI driver use below type name for variable |
@@ -159,22 +172,41 @@ typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int ena | |||
159 | * struct | 172 | * struct |
160 | */ | 173 | */ |
161 | 174 | ||
175 | struct fsi_stream_handler; | ||
162 | struct fsi_stream { | 176 | struct fsi_stream { |
163 | struct snd_pcm_substream *substream; | ||
164 | 177 | ||
178 | /* | ||
179 | * these are initialized by fsi_stream_init() | ||
180 | */ | ||
181 | struct snd_pcm_substream *substream; | ||
165 | int fifo_sample_capa; /* sample capacity of FSI FIFO */ | 182 | int fifo_sample_capa; /* sample capacity of FSI FIFO */ |
166 | int buff_sample_capa; /* sample capacity of ALSA buffer */ | 183 | int buff_sample_capa; /* sample capacity of ALSA buffer */ |
167 | int buff_sample_pos; /* sample position of ALSA buffer */ | 184 | int buff_sample_pos; /* sample position of ALSA buffer */ |
168 | int period_samples; /* sample number / 1 period */ | 185 | int period_samples; /* sample number / 1 period */ |
169 | int period_pos; /* current period position */ | 186 | int period_pos; /* current period position */ |
170 | 187 | int sample_width; /* sample width */ | |
171 | int uerr_num; | 188 | int uerr_num; |
172 | int oerr_num; | 189 | int oerr_num; |
190 | |||
191 | /* | ||
192 | * thse are initialized by fsi_handler_init() | ||
193 | */ | ||
194 | struct fsi_stream_handler *handler; | ||
195 | struct fsi_priv *priv; | ||
196 | |||
197 | /* | ||
198 | * these are for DMAEngine | ||
199 | */ | ||
200 | struct dma_chan *chan; | ||
201 | struct sh_dmae_slave slave; /* see fsi_handler_init() */ | ||
202 | struct tasklet_struct tasklet; | ||
203 | dma_addr_t dma; | ||
173 | }; | 204 | }; |
174 | 205 | ||
175 | struct fsi_priv { | 206 | struct fsi_priv { |
176 | void __iomem *base; | 207 | void __iomem *base; |
177 | struct fsi_master *master; | 208 | struct fsi_master *master; |
209 | struct sh_fsi_port_info *info; | ||
178 | 210 | ||
179 | struct fsi_stream playback; | 211 | struct fsi_stream playback; |
180 | struct fsi_stream capture; | 212 | struct fsi_stream capture; |
@@ -189,6 +221,20 @@ struct fsi_priv { | |||
189 | long rate; | 221 | long rate; |
190 | }; | 222 | }; |
191 | 223 | ||
224 | struct fsi_stream_handler { | ||
225 | int (*init)(struct fsi_priv *fsi, struct fsi_stream *io); | ||
226 | int (*quit)(struct fsi_priv *fsi, struct fsi_stream *io); | ||
227 | int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io); | ||
228 | int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io); | ||
229 | int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io); | ||
230 | void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io, | ||
231 | int enable); | ||
232 | }; | ||
233 | #define fsi_stream_handler_call(io, func, args...) \ | ||
234 | (!(io) ? -ENODEV : \ | ||
235 | !((io)->handler->func) ? 0 : \ | ||
236 | (io)->handler->func(args)) | ||
237 | |||
192 | struct fsi_core { | 238 | struct fsi_core { |
193 | int ver; | 239 | int ver; |
194 | 240 | ||
@@ -205,10 +251,11 @@ struct fsi_master { | |||
205 | struct fsi_priv fsia; | 251 | struct fsi_priv fsia; |
206 | struct fsi_priv fsib; | 252 | struct fsi_priv fsib; |
207 | struct fsi_core *core; | 253 | struct fsi_core *core; |
208 | struct sh_fsi_platform_info *info; | ||
209 | spinlock_t lock; | 254 | spinlock_t lock; |
210 | }; | 255 | }; |
211 | 256 | ||
257 | static int fsi_stream_is_play(struct fsi_priv *fsi, struct fsi_stream *io); | ||
258 | |||
212 | /* | 259 | /* |
213 | * basic read write function | 260 | * basic read write function |
214 | */ | 261 | */ |
@@ -295,6 +342,11 @@ static int fsi_is_spdif(struct fsi_priv *fsi) | |||
295 | return fsi->spdif; | 342 | return fsi->spdif; |
296 | } | 343 | } |
297 | 344 | ||
345 | static int fsi_is_play(struct snd_pcm_substream *substream) | ||
346 | { | ||
347 | return substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | ||
348 | } | ||
349 | |||
298 | static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream) | 350 | static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream) |
299 | { | 351 | { |
300 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 352 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
@@ -317,44 +369,25 @@ static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream) | |||
317 | return fsi_get_priv_frm_dai(fsi_get_dai(substream)); | 369 | return fsi_get_priv_frm_dai(fsi_get_dai(substream)); |
318 | } | 370 | } |
319 | 371 | ||
320 | static set_rate_func fsi_get_info_set_rate(struct fsi_master *master) | 372 | static set_rate_func fsi_get_info_set_rate(struct fsi_priv *fsi) |
321 | { | 373 | { |
322 | if (!master->info) | 374 | if (!fsi->info) |
323 | return NULL; | 375 | return NULL; |
324 | 376 | ||
325 | return master->info->set_rate; | 377 | return fsi->info->set_rate; |
326 | } | 378 | } |
327 | 379 | ||
328 | static u32 fsi_get_info_flags(struct fsi_priv *fsi) | 380 | static u32 fsi_get_info_flags(struct fsi_priv *fsi) |
329 | { | 381 | { |
330 | int is_porta = fsi_is_port_a(fsi); | 382 | if (!fsi->info) |
331 | struct fsi_master *master = fsi_get_master(fsi); | ||
332 | |||
333 | if (!master->info) | ||
334 | return 0; | 383 | return 0; |
335 | 384 | ||
336 | return is_porta ? master->info->porta_flags : | 385 | return fsi->info->flags; |
337 | master->info->portb_flags; | ||
338 | } | ||
339 | |||
340 | static inline int fsi_stream_is_play(int stream) | ||
341 | { | ||
342 | return stream == SNDRV_PCM_STREAM_PLAYBACK; | ||
343 | } | 386 | } |
344 | 387 | ||
345 | static inline int fsi_is_play(struct snd_pcm_substream *substream) | 388 | static u32 fsi_get_port_shift(struct fsi_priv *fsi, struct fsi_stream *io) |
346 | { | ||
347 | return fsi_stream_is_play(substream->stream); | ||
348 | } | ||
349 | |||
350 | static inline struct fsi_stream *fsi_get_stream(struct fsi_priv *fsi, | ||
351 | int is_play) | ||
352 | { | ||
353 | return is_play ? &fsi->playback : &fsi->capture; | ||
354 | } | ||
355 | |||
356 | static u32 fsi_get_port_shift(struct fsi_priv *fsi, int is_play) | ||
357 | { | 389 | { |
390 | int is_play = fsi_stream_is_play(fsi, io); | ||
358 | int is_porta = fsi_is_port_a(fsi); | 391 | int is_porta = fsi_is_port_a(fsi); |
359 | u32 shift; | 392 | u32 shift; |
360 | 393 | ||
@@ -376,26 +409,81 @@ static int fsi_sample2frame(struct fsi_priv *fsi, int samples) | |||
376 | return samples / fsi->chan_num; | 409 | return samples / fsi->chan_num; |
377 | } | 410 | } |
378 | 411 | ||
412 | static int fsi_get_current_fifo_samples(struct fsi_priv *fsi, | ||
413 | struct fsi_stream *io) | ||
414 | { | ||
415 | int is_play = fsi_stream_is_play(fsi, io); | ||
416 | u32 status; | ||
417 | int frames; | ||
418 | |||
419 | status = is_play ? | ||
420 | fsi_reg_read(fsi, DOFF_ST) : | ||
421 | fsi_reg_read(fsi, DIFF_ST); | ||
422 | |||
423 | frames = 0x1ff & (status >> 8); | ||
424 | |||
425 | return fsi_frame2sample(fsi, frames); | ||
426 | } | ||
427 | |||
428 | static void fsi_count_fifo_err(struct fsi_priv *fsi) | ||
429 | { | ||
430 | u32 ostatus = fsi_reg_read(fsi, DOFF_ST); | ||
431 | u32 istatus = fsi_reg_read(fsi, DIFF_ST); | ||
432 | |||
433 | if (ostatus & ERR_OVER) | ||
434 | fsi->playback.oerr_num++; | ||
435 | |||
436 | if (ostatus & ERR_UNDER) | ||
437 | fsi->playback.uerr_num++; | ||
438 | |||
439 | if (istatus & ERR_OVER) | ||
440 | fsi->capture.oerr_num++; | ||
441 | |||
442 | if (istatus & ERR_UNDER) | ||
443 | fsi->capture.uerr_num++; | ||
444 | |||
445 | fsi_reg_write(fsi, DOFF_ST, 0); | ||
446 | fsi_reg_write(fsi, DIFF_ST, 0); | ||
447 | } | ||
448 | |||
449 | /* | ||
450 | * fsi_stream_xx() function | ||
451 | */ | ||
452 | static inline int fsi_stream_is_play(struct fsi_priv *fsi, | ||
453 | struct fsi_stream *io) | ||
454 | { | ||
455 | return &fsi->playback == io; | ||
456 | } | ||
457 | |||
458 | static inline struct fsi_stream *fsi_stream_get(struct fsi_priv *fsi, | ||
459 | struct snd_pcm_substream *substream) | ||
460 | { | ||
461 | return fsi_is_play(substream) ? &fsi->playback : &fsi->capture; | ||
462 | } | ||
463 | |||
379 | static int fsi_stream_is_working(struct fsi_priv *fsi, | 464 | static int fsi_stream_is_working(struct fsi_priv *fsi, |
380 | int is_play) | 465 | struct fsi_stream *io) |
381 | { | 466 | { |
382 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | ||
383 | struct fsi_master *master = fsi_get_master(fsi); | 467 | struct fsi_master *master = fsi_get_master(fsi); |
384 | unsigned long flags; | 468 | unsigned long flags; |
385 | int ret; | 469 | int ret; |
386 | 470 | ||
387 | spin_lock_irqsave(&master->lock, flags); | 471 | spin_lock_irqsave(&master->lock, flags); |
388 | ret = !!io->substream; | 472 | ret = !!(io->substream && io->substream->runtime); |
389 | spin_unlock_irqrestore(&master->lock, flags); | 473 | spin_unlock_irqrestore(&master->lock, flags); |
390 | 474 | ||
391 | return ret; | 475 | return ret; |
392 | } | 476 | } |
393 | 477 | ||
394 | static void fsi_stream_push(struct fsi_priv *fsi, | 478 | static struct fsi_priv *fsi_stream_to_priv(struct fsi_stream *io) |
395 | int is_play, | 479 | { |
480 | return io->priv; | ||
481 | } | ||
482 | |||
483 | static void fsi_stream_init(struct fsi_priv *fsi, | ||
484 | struct fsi_stream *io, | ||
396 | struct snd_pcm_substream *substream) | 485 | struct snd_pcm_substream *substream) |
397 | { | 486 | { |
398 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | ||
399 | struct snd_pcm_runtime *runtime = substream->runtime; | 487 | struct snd_pcm_runtime *runtime = substream->runtime; |
400 | struct fsi_master *master = fsi_get_master(fsi); | 488 | struct fsi_master *master = fsi_get_master(fsi); |
401 | unsigned long flags; | 489 | unsigned long flags; |
@@ -406,14 +494,15 @@ static void fsi_stream_push(struct fsi_priv *fsi, | |||
406 | io->buff_sample_pos = 0; | 494 | io->buff_sample_pos = 0; |
407 | io->period_samples = fsi_frame2sample(fsi, runtime->period_size); | 495 | io->period_samples = fsi_frame2sample(fsi, runtime->period_size); |
408 | io->period_pos = 0; | 496 | io->period_pos = 0; |
497 | io->sample_width = samples_to_bytes(runtime, 1); | ||
409 | io->oerr_num = -1; /* ignore 1st err */ | 498 | io->oerr_num = -1; /* ignore 1st err */ |
410 | io->uerr_num = -1; /* ignore 1st err */ | 499 | io->uerr_num = -1; /* ignore 1st err */ |
500 | fsi_stream_handler_call(io, init, fsi, io); | ||
411 | spin_unlock_irqrestore(&master->lock, flags); | 501 | spin_unlock_irqrestore(&master->lock, flags); |
412 | } | 502 | } |
413 | 503 | ||
414 | static void fsi_stream_pop(struct fsi_priv *fsi, int is_play) | 504 | static void fsi_stream_quit(struct fsi_priv *fsi, struct fsi_stream *io) |
415 | { | 505 | { |
416 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | ||
417 | struct snd_soc_dai *dai = fsi_get_dai(io->substream); | 506 | struct snd_soc_dai *dai = fsi_get_dai(io->substream); |
418 | struct fsi_master *master = fsi_get_master(fsi); | 507 | struct fsi_master *master = fsi_get_master(fsi); |
419 | unsigned long flags; | 508 | unsigned long flags; |
@@ -426,127 +515,87 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play) | |||
426 | if (io->uerr_num > 0) | 515 | if (io->uerr_num > 0) |
427 | dev_err(dai->dev, "under_run = %d\n", io->uerr_num); | 516 | dev_err(dai->dev, "under_run = %d\n", io->uerr_num); |
428 | 517 | ||
518 | fsi_stream_handler_call(io, quit, fsi, io); | ||
429 | io->substream = NULL; | 519 | io->substream = NULL; |
430 | io->buff_sample_capa = 0; | 520 | io->buff_sample_capa = 0; |
431 | io->buff_sample_pos = 0; | 521 | io->buff_sample_pos = 0; |
432 | io->period_samples = 0; | 522 | io->period_samples = 0; |
433 | io->period_pos = 0; | 523 | io->period_pos = 0; |
524 | io->sample_width = 0; | ||
434 | io->oerr_num = 0; | 525 | io->oerr_num = 0; |
435 | io->uerr_num = 0; | 526 | io->uerr_num = 0; |
436 | spin_unlock_irqrestore(&master->lock, flags); | 527 | spin_unlock_irqrestore(&master->lock, flags); |
437 | } | 528 | } |
438 | 529 | ||
439 | static int fsi_get_current_fifo_samples(struct fsi_priv *fsi, int is_play) | 530 | static int fsi_stream_transfer(struct fsi_stream *io) |
440 | { | 531 | { |
441 | u32 status; | 532 | struct fsi_priv *fsi = fsi_stream_to_priv(io); |
442 | int frames; | 533 | if (!fsi) |
534 | return -EIO; | ||
443 | 535 | ||
444 | status = is_play ? | 536 | return fsi_stream_handler_call(io, transfer, fsi, io); |
445 | fsi_reg_read(fsi, DOFF_ST) : | ||
446 | fsi_reg_read(fsi, DIFF_ST); | ||
447 | |||
448 | frames = 0x1ff & (status >> 8); | ||
449 | |||
450 | return fsi_frame2sample(fsi, frames); | ||
451 | } | 537 | } |
452 | 538 | ||
453 | static void fsi_count_fifo_err(struct fsi_priv *fsi) | 539 | #define fsi_stream_start(fsi, io)\ |
454 | { | 540 | fsi_stream_handler_call(io, start_stop, fsi, io, 1) |
455 | u32 ostatus = fsi_reg_read(fsi, DOFF_ST); | ||
456 | u32 istatus = fsi_reg_read(fsi, DIFF_ST); | ||
457 | 541 | ||
458 | if (ostatus & ERR_OVER) | 542 | #define fsi_stream_stop(fsi, io)\ |
459 | fsi->playback.oerr_num++; | 543 | fsi_stream_handler_call(io, start_stop, fsi, io, 0) |
460 | |||
461 | if (ostatus & ERR_UNDER) | ||
462 | fsi->playback.uerr_num++; | ||
463 | |||
464 | if (istatus & ERR_OVER) | ||
465 | fsi->capture.oerr_num++; | ||
466 | |||
467 | if (istatus & ERR_UNDER) | ||
468 | fsi->capture.uerr_num++; | ||
469 | 544 | ||
470 | fsi_reg_write(fsi, DOFF_ST, 0); | 545 | static int fsi_stream_probe(struct fsi_priv *fsi) |
471 | fsi_reg_write(fsi, DIFF_ST, 0); | ||
472 | } | ||
473 | |||
474 | /* | ||
475 | * dma function | ||
476 | */ | ||
477 | |||
478 | static u8 *fsi_dma_get_area(struct fsi_priv *fsi, int stream) | ||
479 | { | 546 | { |
480 | int is_play = fsi_stream_is_play(stream); | 547 | struct fsi_stream *io; |
481 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | 548 | int ret1, ret2; |
482 | struct snd_pcm_runtime *runtime = io->substream->runtime; | ||
483 | 549 | ||
484 | return runtime->dma_area + | 550 | io = &fsi->playback; |
485 | samples_to_bytes(runtime, io->buff_sample_pos); | 551 | ret1 = fsi_stream_handler_call(io, probe, fsi, io); |
486 | } | ||
487 | 552 | ||
488 | static void fsi_dma_soft_push16(struct fsi_priv *fsi, int num) | 553 | io = &fsi->capture; |
489 | { | 554 | ret2 = fsi_stream_handler_call(io, probe, fsi, io); |
490 | u16 *start; | ||
491 | int i; | ||
492 | 555 | ||
493 | start = (u16 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK); | 556 | if (ret1 < 0) |
557 | return ret1; | ||
558 | if (ret2 < 0) | ||
559 | return ret2; | ||
494 | 560 | ||
495 | for (i = 0; i < num; i++) | 561 | return 0; |
496 | fsi_reg_write(fsi, DODT, ((u32)*(start + i) << 8)); | ||
497 | } | ||
498 | |||
499 | static void fsi_dma_soft_pop16(struct fsi_priv *fsi, int num) | ||
500 | { | ||
501 | u16 *start; | ||
502 | int i; | ||
503 | |||
504 | start = (u16 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE); | ||
505 | |||
506 | |||
507 | for (i = 0; i < num; i++) | ||
508 | *(start + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8); | ||
509 | } | 562 | } |
510 | 563 | ||
511 | static void fsi_dma_soft_push32(struct fsi_priv *fsi, int num) | 564 | static int fsi_stream_remove(struct fsi_priv *fsi) |
512 | { | 565 | { |
513 | u32 *start; | 566 | struct fsi_stream *io; |
514 | int i; | 567 | int ret1, ret2; |
515 | |||
516 | start = (u32 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_PLAYBACK); | ||
517 | 568 | ||
569 | io = &fsi->playback; | ||
570 | ret1 = fsi_stream_handler_call(io, remove, fsi, io); | ||
518 | 571 | ||
519 | for (i = 0; i < num; i++) | 572 | io = &fsi->capture; |
520 | fsi_reg_write(fsi, DODT, *(start + i)); | 573 | ret2 = fsi_stream_handler_call(io, remove, fsi, io); |
521 | } | ||
522 | |||
523 | static void fsi_dma_soft_pop32(struct fsi_priv *fsi, int num) | ||
524 | { | ||
525 | u32 *start; | ||
526 | int i; | ||
527 | 574 | ||
528 | start = (u32 *)fsi_dma_get_area(fsi, SNDRV_PCM_STREAM_CAPTURE); | 575 | if (ret1 < 0) |
576 | return ret1; | ||
577 | if (ret2 < 0) | ||
578 | return ret2; | ||
529 | 579 | ||
530 | for (i = 0; i < num; i++) | 580 | return 0; |
531 | *(start + i) = fsi_reg_read(fsi, DIDT); | ||
532 | } | 581 | } |
533 | 582 | ||
534 | /* | 583 | /* |
535 | * irq function | 584 | * irq function |
536 | */ | 585 | */ |
537 | 586 | ||
538 | static void fsi_irq_enable(struct fsi_priv *fsi, int is_play) | 587 | static void fsi_irq_enable(struct fsi_priv *fsi, struct fsi_stream *io) |
539 | { | 588 | { |
540 | u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play)); | 589 | u32 data = AB_IO(1, fsi_get_port_shift(fsi, io)); |
541 | struct fsi_master *master = fsi_get_master(fsi); | 590 | struct fsi_master *master = fsi_get_master(fsi); |
542 | 591 | ||
543 | fsi_core_mask_set(master, imsk, data, data); | 592 | fsi_core_mask_set(master, imsk, data, data); |
544 | fsi_core_mask_set(master, iemsk, data, data); | 593 | fsi_core_mask_set(master, iemsk, data, data); |
545 | } | 594 | } |
546 | 595 | ||
547 | static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) | 596 | static void fsi_irq_disable(struct fsi_priv *fsi, struct fsi_stream *io) |
548 | { | 597 | { |
549 | u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play)); | 598 | u32 data = AB_IO(1, fsi_get_port_shift(fsi, io)); |
550 | struct fsi_master *master = fsi_get_master(fsi); | 599 | struct fsi_master *master = fsi_get_master(fsi); |
551 | 600 | ||
552 | fsi_core_mask_set(master, imsk, data, 0); | 601 | fsi_core_mask_set(master, imsk, data, 0); |
@@ -563,8 +612,8 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi) | |||
563 | u32 data = 0; | 612 | u32 data = 0; |
564 | struct fsi_master *master = fsi_get_master(fsi); | 613 | struct fsi_master *master = fsi_get_master(fsi); |
565 | 614 | ||
566 | data |= AB_IO(1, fsi_get_port_shift(fsi, 0)); | 615 | data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->playback)); |
567 | data |= AB_IO(1, fsi_get_port_shift(fsi, 1)); | 616 | data |= AB_IO(1, fsi_get_port_shift(fsi, &fsi->capture)); |
568 | 617 | ||
569 | /* clear interrupt factor */ | 618 | /* clear interrupt factor */ |
570 | fsi_core_mask_set(master, int_st, data, 0); | 619 | fsi_core_mask_set(master, int_st, data, 0); |
@@ -600,11 +649,14 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, | |||
600 | long rate, int enable) | 649 | long rate, int enable) |
601 | { | 650 | { |
602 | struct fsi_master *master = fsi_get_master(fsi); | 651 | struct fsi_master *master = fsi_get_master(fsi); |
603 | set_rate_func set_rate = fsi_get_info_set_rate(master); | 652 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); |
604 | int fsi_ver = master->core->ver; | 653 | int fsi_ver = master->core->ver; |
605 | int ret; | 654 | int ret; |
606 | 655 | ||
607 | ret = set_rate(dev, fsi_is_port_a(fsi), rate, enable); | 656 | if (!set_rate) |
657 | return 0; | ||
658 | |||
659 | ret = set_rate(dev, rate, enable); | ||
608 | if (ret < 0) /* error */ | 660 | if (ret < 0) /* error */ |
609 | return ret; | 661 | return ret; |
610 | 662 | ||
@@ -671,96 +723,64 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, | |||
671 | return ret; | 723 | return ret; |
672 | } | 724 | } |
673 | 725 | ||
674 | #define fsi_port_start(f, i) __fsi_port_clk_ctrl(f, i, 1) | 726 | /* |
675 | #define fsi_port_stop(f, i) __fsi_port_clk_ctrl(f, i, 0) | 727 | * pio data transfer handler |
676 | static void __fsi_port_clk_ctrl(struct fsi_priv *fsi, int is_play, int enable) | 728 | */ |
729 | static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples) | ||
677 | { | 730 | { |
678 | struct fsi_master *master = fsi_get_master(fsi); | 731 | u16 *buf = (u16 *)_buf; |
679 | u32 clk = fsi_is_port_a(fsi) ? CRA : CRB; | 732 | int i; |
680 | 733 | ||
681 | if (enable) | 734 | for (i = 0; i < samples; i++) |
682 | fsi_irq_enable(fsi, is_play); | 735 | fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8)); |
683 | else | 736 | } |
684 | fsi_irq_disable(fsi, is_play); | ||
685 | 737 | ||
686 | if (fsi_is_clk_master(fsi)) | 738 | static void fsi_pio_pop16(struct fsi_priv *fsi, u8 *_buf, int samples) |
687 | fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); | 739 | { |
740 | u16 *buf = (u16 *)_buf; | ||
741 | int i; | ||
742 | |||
743 | for (i = 0; i < samples; i++) | ||
744 | *(buf + i) = (u16)(fsi_reg_read(fsi, DIDT) >> 8); | ||
688 | } | 745 | } |
689 | 746 | ||
690 | /* | 747 | static void fsi_pio_push32(struct fsi_priv *fsi, u8 *_buf, int samples) |
691 | * ctrl function | ||
692 | */ | ||
693 | static void fsi_fifo_init(struct fsi_priv *fsi, | ||
694 | int is_play, | ||
695 | struct device *dev) | ||
696 | { | 748 | { |
697 | struct fsi_master *master = fsi_get_master(fsi); | 749 | u32 *buf = (u32 *)_buf; |
698 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | 750 | int i; |
699 | u32 shift, i; | ||
700 | int frame_capa; | ||
701 | 751 | ||
702 | /* get on-chip RAM capacity */ | 752 | for (i = 0; i < samples; i++) |
703 | shift = fsi_master_read(master, FIFO_SZ); | 753 | fsi_reg_write(fsi, DODT, *(buf + i)); |
704 | shift >>= fsi_get_port_shift(fsi, is_play); | 754 | } |
705 | shift &= FIFO_SZ_MASK; | ||
706 | frame_capa = 256 << shift; | ||
707 | dev_dbg(dev, "fifo = %d words\n", frame_capa); | ||
708 | 755 | ||
709 | /* | 756 | static void fsi_pio_pop32(struct fsi_priv *fsi, u8 *_buf, int samples) |
710 | * The maximum number of sample data varies depending | 757 | { |
711 | * on the number of channels selected for the format. | 758 | u32 *buf = (u32 *)_buf; |
712 | * | 759 | int i; |
713 | * FIFOs are used in 4-channel units in 3-channel mode | ||
714 | * and in 8-channel units in 5- to 7-channel mode | ||
715 | * meaning that more FIFOs than the required size of DPRAM | ||
716 | * are used. | ||
717 | * | ||
718 | * ex) if 256 words of DP-RAM is connected | ||
719 | * 1 channel: 256 (256 x 1 = 256) | ||
720 | * 2 channels: 128 (128 x 2 = 256) | ||
721 | * 3 channels: 64 ( 64 x 3 = 192) | ||
722 | * 4 channels: 64 ( 64 x 4 = 256) | ||
723 | * 5 channels: 32 ( 32 x 5 = 160) | ||
724 | * 6 channels: 32 ( 32 x 6 = 192) | ||
725 | * 7 channels: 32 ( 32 x 7 = 224) | ||
726 | * 8 channels: 32 ( 32 x 8 = 256) | ||
727 | */ | ||
728 | for (i = 1; i < fsi->chan_num; i <<= 1) | ||
729 | frame_capa >>= 1; | ||
730 | dev_dbg(dev, "%d channel %d store\n", | ||
731 | fsi->chan_num, frame_capa); | ||
732 | 760 | ||
733 | io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa); | 761 | for (i = 0; i < samples; i++) |
762 | *(buf + i) = fsi_reg_read(fsi, DIDT); | ||
763 | } | ||
734 | 764 | ||
735 | /* | 765 | static u8 *fsi_pio_get_area(struct fsi_priv *fsi, struct fsi_stream *io) |
736 | * set interrupt generation factor | 766 | { |
737 | * clear FIFO | 767 | struct snd_pcm_runtime *runtime = io->substream->runtime; |
738 | */ | 768 | |
739 | if (is_play) { | 769 | return runtime->dma_area + |
740 | fsi_reg_write(fsi, DOFF_CTL, IRQ_HALF); | 770 | samples_to_bytes(runtime, io->buff_sample_pos); |
741 | fsi_reg_mask_set(fsi, DOFF_CTL, FIFO_CLR, FIFO_CLR); | ||
742 | } else { | ||
743 | fsi_reg_write(fsi, DIFF_CTL, IRQ_HALF); | ||
744 | fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR); | ||
745 | } | ||
746 | } | 771 | } |
747 | 772 | ||
748 | static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream) | 773 | static int fsi_pio_transfer(struct fsi_priv *fsi, struct fsi_stream *io, |
774 | void (*run16)(struct fsi_priv *fsi, u8 *buf, int samples), | ||
775 | void (*run32)(struct fsi_priv *fsi, u8 *buf, int samples), | ||
776 | int samples) | ||
749 | { | 777 | { |
750 | struct snd_pcm_runtime *runtime; | 778 | struct snd_pcm_runtime *runtime; |
751 | struct snd_pcm_substream *substream = NULL; | 779 | struct snd_pcm_substream *substream; |
752 | int is_play = fsi_stream_is_play(stream); | 780 | u8 *buf; |
753 | struct fsi_stream *io = fsi_get_stream(fsi, is_play); | ||
754 | int sample_residues; | ||
755 | int sample_width; | ||
756 | int samples; | ||
757 | int samples_max; | ||
758 | int over_period; | 781 | int over_period; |
759 | void (*fn)(struct fsi_priv *fsi, int size); | ||
760 | 782 | ||
761 | if (!fsi || | 783 | if (!fsi_stream_is_working(fsi, io)) |
762 | !io->substream || | ||
763 | !io->substream->runtime) | ||
764 | return -EINVAL; | 784 | return -EINVAL; |
765 | 785 | ||
766 | over_period = 0; | 786 | over_period = 0; |
@@ -780,60 +800,19 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream) | |||
780 | io->buff_sample_pos = 0; | 800 | io->buff_sample_pos = 0; |
781 | } | 801 | } |
782 | 802 | ||
783 | /* get 1 sample data width */ | 803 | buf = fsi_pio_get_area(fsi, io); |
784 | sample_width = samples_to_bytes(runtime, 1); | ||
785 | |||
786 | /* get number of residue samples */ | ||
787 | sample_residues = io->buff_sample_capa - io->buff_sample_pos; | ||
788 | 804 | ||
789 | if (is_play) { | 805 | switch (io->sample_width) { |
790 | /* | 806 | case 2: |
791 | * for play-back | 807 | run16(fsi, buf, samples); |
792 | * | 808 | break; |
793 | * samples_max : number of FSI fifo free samples space | 809 | case 4: |
794 | * samples : number of ALSA residue samples | 810 | run32(fsi, buf, samples); |
795 | */ | 811 | break; |
796 | samples_max = io->fifo_sample_capa; | 812 | default: |
797 | samples_max -= fsi_get_current_fifo_samples(fsi, is_play); | 813 | return -EINVAL; |
798 | |||
799 | samples = sample_residues; | ||
800 | |||
801 | switch (sample_width) { | ||
802 | case 2: | ||
803 | fn = fsi_dma_soft_push16; | ||
804 | break; | ||
805 | case 4: | ||
806 | fn = fsi_dma_soft_push32; | ||
807 | break; | ||
808 | default: | ||
809 | return -EINVAL; | ||
810 | } | ||
811 | } else { | ||
812 | /* | ||
813 | * for capture | ||
814 | * | ||
815 | * samples_max : number of ALSA free samples space | ||
816 | * samples : number of samples in FSI fifo | ||
817 | */ | ||
818 | samples_max = sample_residues; | ||
819 | samples = fsi_get_current_fifo_samples(fsi, is_play); | ||
820 | |||
821 | switch (sample_width) { | ||
822 | case 2: | ||
823 | fn = fsi_dma_soft_pop16; | ||
824 | break; | ||
825 | case 4: | ||
826 | fn = fsi_dma_soft_pop32; | ||
827 | break; | ||
828 | default: | ||
829 | return -EINVAL; | ||
830 | } | ||
831 | } | 814 | } |
832 | 815 | ||
833 | samples = min(samples, samples_max); | ||
834 | |||
835 | fn(fsi, samples); | ||
836 | |||
837 | /* update buff_sample_pos */ | 816 | /* update buff_sample_pos */ |
838 | io->buff_sample_pos += samples; | 817 | io->buff_sample_pos += samples; |
839 | 818 | ||
@@ -843,16 +822,66 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream) | |||
843 | return 0; | 822 | return 0; |
844 | } | 823 | } |
845 | 824 | ||
846 | static int fsi_data_pop(struct fsi_priv *fsi) | 825 | static int fsi_pio_pop(struct fsi_priv *fsi, struct fsi_stream *io) |
826 | { | ||
827 | int sample_residues; /* samples in FSI fifo */ | ||
828 | int sample_space; /* ALSA free samples space */ | ||
829 | int samples; | ||
830 | |||
831 | sample_residues = fsi_get_current_fifo_samples(fsi, io); | ||
832 | sample_space = io->buff_sample_capa - io->buff_sample_pos; | ||
833 | |||
834 | samples = min(sample_residues, sample_space); | ||
835 | |||
836 | return fsi_pio_transfer(fsi, io, | ||
837 | fsi_pio_pop16, | ||
838 | fsi_pio_pop32, | ||
839 | samples); | ||
840 | } | ||
841 | |||
842 | static int fsi_pio_push(struct fsi_priv *fsi, struct fsi_stream *io) | ||
847 | { | 843 | { |
848 | return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_CAPTURE); | 844 | int sample_residues; /* ALSA residue samples */ |
845 | int sample_space; /* FSI fifo free samples space */ | ||
846 | int samples; | ||
847 | |||
848 | sample_residues = io->buff_sample_capa - io->buff_sample_pos; | ||
849 | sample_space = io->fifo_sample_capa - | ||
850 | fsi_get_current_fifo_samples(fsi, io); | ||
851 | |||
852 | samples = min(sample_residues, sample_space); | ||
853 | |||
854 | return fsi_pio_transfer(fsi, io, | ||
855 | fsi_pio_push16, | ||
856 | fsi_pio_push32, | ||
857 | samples); | ||
849 | } | 858 | } |
850 | 859 | ||
851 | static int fsi_data_push(struct fsi_priv *fsi) | 860 | static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, |
861 | int enable) | ||
852 | { | 862 | { |
853 | return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_PLAYBACK); | 863 | struct fsi_master *master = fsi_get_master(fsi); |
864 | u32 clk = fsi_is_port_a(fsi) ? CRA : CRB; | ||
865 | |||
866 | if (enable) | ||
867 | fsi_irq_enable(fsi, io); | ||
868 | else | ||
869 | fsi_irq_disable(fsi, io); | ||
870 | |||
871 | if (fsi_is_clk_master(fsi)) | ||
872 | fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); | ||
854 | } | 873 | } |
855 | 874 | ||
875 | static struct fsi_stream_handler fsi_pio_push_handler = { | ||
876 | .transfer = fsi_pio_push, | ||
877 | .start_stop = fsi_pio_start_stop, | ||
878 | }; | ||
879 | |||
880 | static struct fsi_stream_handler fsi_pio_pop_handler = { | ||
881 | .transfer = fsi_pio_pop, | ||
882 | .start_stop = fsi_pio_start_stop, | ||
883 | }; | ||
884 | |||
856 | static irqreturn_t fsi_interrupt(int irq, void *data) | 885 | static irqreturn_t fsi_interrupt(int irq, void *data) |
857 | { | 886 | { |
858 | struct fsi_master *master = data; | 887 | struct fsi_master *master = data; |
@@ -863,13 +892,13 @@ static irqreturn_t fsi_interrupt(int irq, void *data) | |||
863 | fsi_master_mask_set(master, SOFT_RST, IR, IR); | 892 | fsi_master_mask_set(master, SOFT_RST, IR, IR); |
864 | 893 | ||
865 | if (int_st & AB_IO(1, AO_SHIFT)) | 894 | if (int_st & AB_IO(1, AO_SHIFT)) |
866 | fsi_data_push(&master->fsia); | 895 | fsi_stream_transfer(&master->fsia.playback); |
867 | if (int_st & AB_IO(1, BO_SHIFT)) | 896 | if (int_st & AB_IO(1, BO_SHIFT)) |
868 | fsi_data_push(&master->fsib); | 897 | fsi_stream_transfer(&master->fsib.playback); |
869 | if (int_st & AB_IO(1, AI_SHIFT)) | 898 | if (int_st & AB_IO(1, AI_SHIFT)) |
870 | fsi_data_pop(&master->fsia); | 899 | fsi_stream_transfer(&master->fsia.capture); |
871 | if (int_st & AB_IO(1, BI_SHIFT)) | 900 | if (int_st & AB_IO(1, BI_SHIFT)) |
872 | fsi_data_pop(&master->fsib); | 901 | fsi_stream_transfer(&master->fsib.capture); |
873 | 902 | ||
874 | fsi_count_fifo_err(&master->fsia); | 903 | fsi_count_fifo_err(&master->fsia); |
875 | fsi_count_fifo_err(&master->fsib); | 904 | fsi_count_fifo_err(&master->fsib); |
@@ -881,11 +910,271 @@ static irqreturn_t fsi_interrupt(int irq, void *data) | |||
881 | } | 910 | } |
882 | 911 | ||
883 | /* | 912 | /* |
913 | * dma data transfer handler | ||
914 | */ | ||
915 | static int fsi_dma_init(struct fsi_priv *fsi, struct fsi_stream *io) | ||
916 | { | ||
917 | struct snd_pcm_runtime *runtime = io->substream->runtime; | ||
918 | struct snd_soc_dai *dai = fsi_get_dai(io->substream); | ||
919 | enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ? | ||
920 | DMA_TO_DEVICE : DMA_FROM_DEVICE; | ||
921 | |||
922 | io->dma = dma_map_single(dai->dev, runtime->dma_area, | ||
923 | snd_pcm_lib_buffer_bytes(io->substream), dir); | ||
924 | return 0; | ||
925 | } | ||
926 | |||
927 | static int fsi_dma_quit(struct fsi_priv *fsi, struct fsi_stream *io) | ||
928 | { | ||
929 | struct snd_soc_dai *dai = fsi_get_dai(io->substream); | ||
930 | enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ? | ||
931 | DMA_TO_DEVICE : DMA_FROM_DEVICE; | ||
932 | |||
933 | dma_unmap_single(dai->dev, io->dma, | ||
934 | snd_pcm_lib_buffer_bytes(io->substream), dir); | ||
935 | return 0; | ||
936 | } | ||
937 | |||
938 | static void fsi_dma_complete(void *data) | ||
939 | { | ||
940 | struct fsi_stream *io = (struct fsi_stream *)data; | ||
941 | struct fsi_priv *fsi = fsi_stream_to_priv(io); | ||
942 | struct snd_pcm_runtime *runtime = io->substream->runtime; | ||
943 | struct snd_soc_dai *dai = fsi_get_dai(io->substream); | ||
944 | enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ? | ||
945 | DMA_TO_DEVICE : DMA_FROM_DEVICE; | ||
946 | |||
947 | dma_sync_single_for_cpu(dai->dev, io->dma, | ||
948 | samples_to_bytes(runtime, io->period_samples), dir); | ||
949 | |||
950 | io->buff_sample_pos += io->period_samples; | ||
951 | io->period_pos++; | ||
952 | |||
953 | if (io->period_pos >= runtime->periods) { | ||
954 | io->period_pos = 0; | ||
955 | io->buff_sample_pos = 0; | ||
956 | } | ||
957 | |||
958 | fsi_count_fifo_err(fsi); | ||
959 | fsi_stream_transfer(io); | ||
960 | |||
961 | snd_pcm_period_elapsed(io->substream); | ||
962 | } | ||
963 | |||
964 | static dma_addr_t fsi_dma_get_area(struct fsi_stream *io) | ||
965 | { | ||
966 | struct snd_pcm_runtime *runtime = io->substream->runtime; | ||
967 | |||
968 | return io->dma + samples_to_bytes(runtime, io->buff_sample_pos); | ||
969 | } | ||
970 | |||
971 | static void fsi_dma_do_tasklet(unsigned long data) | ||
972 | { | ||
973 | struct fsi_stream *io = (struct fsi_stream *)data; | ||
974 | struct fsi_priv *fsi = fsi_stream_to_priv(io); | ||
975 | struct dma_chan *chan; | ||
976 | struct snd_soc_dai *dai; | ||
977 | struct dma_async_tx_descriptor *desc; | ||
978 | struct scatterlist sg; | ||
979 | struct snd_pcm_runtime *runtime; | ||
980 | enum dma_data_direction dir; | ||
981 | dma_cookie_t cookie; | ||
982 | int is_play = fsi_stream_is_play(fsi, io); | ||
983 | int len; | ||
984 | dma_addr_t buf; | ||
985 | |||
986 | if (!fsi_stream_is_working(fsi, io)) | ||
987 | return; | ||
988 | |||
989 | dai = fsi_get_dai(io->substream); | ||
990 | chan = io->chan; | ||
991 | runtime = io->substream->runtime; | ||
992 | dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; | ||
993 | len = samples_to_bytes(runtime, io->period_samples); | ||
994 | buf = fsi_dma_get_area(io); | ||
995 | |||
996 | dma_sync_single_for_device(dai->dev, io->dma, len, dir); | ||
997 | |||
998 | sg_init_table(&sg, 1); | ||
999 | sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)), | ||
1000 | len , offset_in_page(buf)); | ||
1001 | sg_dma_address(&sg) = buf; | ||
1002 | sg_dma_len(&sg) = len; | ||
1003 | |||
1004 | desc = chan->device->device_prep_slave_sg(chan, &sg, 1, dir, | ||
1005 | DMA_PREP_INTERRUPT | | ||
1006 | DMA_CTRL_ACK); | ||
1007 | if (!desc) { | ||
1008 | dev_err(dai->dev, "device_prep_slave_sg() fail\n"); | ||
1009 | return; | ||
1010 | } | ||
1011 | |||
1012 | desc->callback = fsi_dma_complete; | ||
1013 | desc->callback_param = io; | ||
1014 | |||
1015 | cookie = desc->tx_submit(desc); | ||
1016 | if (cookie < 0) { | ||
1017 | dev_err(dai->dev, "tx_submit() fail\n"); | ||
1018 | return; | ||
1019 | } | ||
1020 | |||
1021 | dma_async_issue_pending(chan); | ||
1022 | |||
1023 | /* | ||
1024 | * FIXME | ||
1025 | * | ||
1026 | * In DMAEngine case, codec and FSI cannot be started simultaneously | ||
1027 | * since FSI is using tasklet. | ||
1028 | * Therefore, in capture case, probably FSI FIFO will have got | ||
1029 | * overflow error in this point. | ||
1030 | * in that case, DMA cannot start transfer until error was cleared. | ||
1031 | */ | ||
1032 | if (!is_play) { | ||
1033 | if (ERR_OVER & fsi_reg_read(fsi, DIFF_ST)) { | ||
1034 | fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR); | ||
1035 | fsi_reg_write(fsi, DIFF_ST, 0); | ||
1036 | } | ||
1037 | } | ||
1038 | } | ||
1039 | |||
1040 | static bool fsi_dma_filter(struct dma_chan *chan, void *param) | ||
1041 | { | ||
1042 | struct sh_dmae_slave *slave = param; | ||
1043 | |||
1044 | chan->private = slave; | ||
1045 | |||
1046 | return true; | ||
1047 | } | ||
1048 | |||
1049 | static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io) | ||
1050 | { | ||
1051 | tasklet_schedule(&io->tasklet); | ||
1052 | |||
1053 | return 0; | ||
1054 | } | ||
1055 | |||
1056 | static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, | ||
1057 | int start) | ||
1058 | { | ||
1059 | u32 bws; | ||
1060 | u32 dma; | ||
1061 | |||
1062 | switch (io->sample_width * start) { | ||
1063 | case 2: | ||
1064 | bws = CR_BWS_16; | ||
1065 | dma = VDMD_STREAM | DMA_ON; | ||
1066 | break; | ||
1067 | case 4: | ||
1068 | bws = CR_BWS_24; | ||
1069 | dma = VDMD_BACK | DMA_ON; | ||
1070 | break; | ||
1071 | default: | ||
1072 | bws = 0; | ||
1073 | dma = 0; | ||
1074 | } | ||
1075 | |||
1076 | fsi_reg_mask_set(fsi, DO_FMT, CR_BWS_MASK, bws); | ||
1077 | fsi_reg_write(fsi, OUT_DMAC, dma); | ||
1078 | } | ||
1079 | |||
1080 | static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io) | ||
1081 | { | ||
1082 | dma_cap_mask_t mask; | ||
1083 | |||
1084 | dma_cap_zero(mask); | ||
1085 | dma_cap_set(DMA_SLAVE, mask); | ||
1086 | |||
1087 | io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave); | ||
1088 | if (!io->chan) | ||
1089 | return -EIO; | ||
1090 | |||
1091 | tasklet_init(&io->tasklet, fsi_dma_do_tasklet, (unsigned long)io); | ||
1092 | |||
1093 | return 0; | ||
1094 | } | ||
1095 | |||
1096 | static int fsi_dma_remove(struct fsi_priv *fsi, struct fsi_stream *io) | ||
1097 | { | ||
1098 | tasklet_kill(&io->tasklet); | ||
1099 | |||
1100 | fsi_stream_stop(fsi, io); | ||
1101 | |||
1102 | if (io->chan) | ||
1103 | dma_release_channel(io->chan); | ||
1104 | |||
1105 | io->chan = NULL; | ||
1106 | return 0; | ||
1107 | } | ||
1108 | |||
1109 | static struct fsi_stream_handler fsi_dma_push_handler = { | ||
1110 | .init = fsi_dma_init, | ||
1111 | .quit = fsi_dma_quit, | ||
1112 | .probe = fsi_dma_probe, | ||
1113 | .transfer = fsi_dma_transfer, | ||
1114 | .remove = fsi_dma_remove, | ||
1115 | .start_stop = fsi_dma_push_start_stop, | ||
1116 | }; | ||
1117 | |||
1118 | /* | ||
884 | * dai ops | 1119 | * dai ops |
885 | */ | 1120 | */ |
1121 | static void fsi_fifo_init(struct fsi_priv *fsi, | ||
1122 | struct fsi_stream *io, | ||
1123 | struct device *dev) | ||
1124 | { | ||
1125 | struct fsi_master *master = fsi_get_master(fsi); | ||
1126 | int is_play = fsi_stream_is_play(fsi, io); | ||
1127 | u32 shift, i; | ||
1128 | int frame_capa; | ||
1129 | |||
1130 | /* get on-chip RAM capacity */ | ||
1131 | shift = fsi_master_read(master, FIFO_SZ); | ||
1132 | shift >>= fsi_get_port_shift(fsi, io); | ||
1133 | shift &= FIFO_SZ_MASK; | ||
1134 | frame_capa = 256 << shift; | ||
1135 | dev_dbg(dev, "fifo = %d words\n", frame_capa); | ||
1136 | |||
1137 | /* | ||
1138 | * The maximum number of sample data varies depending | ||
1139 | * on the number of channels selected for the format. | ||
1140 | * | ||
1141 | * FIFOs are used in 4-channel units in 3-channel mode | ||
1142 | * and in 8-channel units in 5- to 7-channel mode | ||
1143 | * meaning that more FIFOs than the required size of DPRAM | ||
1144 | * are used. | ||
1145 | * | ||
1146 | * ex) if 256 words of DP-RAM is connected | ||
1147 | * 1 channel: 256 (256 x 1 = 256) | ||
1148 | * 2 channels: 128 (128 x 2 = 256) | ||
1149 | * 3 channels: 64 ( 64 x 3 = 192) | ||
1150 | * 4 channels: 64 ( 64 x 4 = 256) | ||
1151 | * 5 channels: 32 ( 32 x 5 = 160) | ||
1152 | * 6 channels: 32 ( 32 x 6 = 192) | ||
1153 | * 7 channels: 32 ( 32 x 7 = 224) | ||
1154 | * 8 channels: 32 ( 32 x 8 = 256) | ||
1155 | */ | ||
1156 | for (i = 1; i < fsi->chan_num; i <<= 1) | ||
1157 | frame_capa >>= 1; | ||
1158 | dev_dbg(dev, "%d channel %d store\n", | ||
1159 | fsi->chan_num, frame_capa); | ||
1160 | |||
1161 | io->fifo_sample_capa = fsi_frame2sample(fsi, frame_capa); | ||
1162 | |||
1163 | /* | ||
1164 | * set interrupt generation factor | ||
1165 | * clear FIFO | ||
1166 | */ | ||
1167 | if (is_play) { | ||
1168 | fsi_reg_write(fsi, DOFF_CTL, IRQ_HALF); | ||
1169 | fsi_reg_mask_set(fsi, DOFF_CTL, FIFO_CLR, FIFO_CLR); | ||
1170 | } else { | ||
1171 | fsi_reg_write(fsi, DIFF_CTL, IRQ_HALF); | ||
1172 | fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR); | ||
1173 | } | ||
1174 | } | ||
886 | 1175 | ||
887 | static int fsi_hw_startup(struct fsi_priv *fsi, | 1176 | static int fsi_hw_startup(struct fsi_priv *fsi, |
888 | int is_play, | 1177 | struct fsi_stream *io, |
889 | struct device *dev) | 1178 | struct device *dev) |
890 | { | 1179 | { |
891 | struct fsi_master *master = fsi_get_master(fsi); | 1180 | struct fsi_master *master = fsi_get_master(fsi); |
@@ -934,17 +1223,16 @@ static int fsi_hw_startup(struct fsi_priv *fsi, | |||
934 | } | 1223 | } |
935 | 1224 | ||
936 | /* irq clear */ | 1225 | /* irq clear */ |
937 | fsi_irq_disable(fsi, is_play); | 1226 | fsi_irq_disable(fsi, io); |
938 | fsi_irq_clear_status(fsi); | 1227 | fsi_irq_clear_status(fsi); |
939 | 1228 | ||
940 | /* fifo init */ | 1229 | /* fifo init */ |
941 | fsi_fifo_init(fsi, is_play, dev); | 1230 | fsi_fifo_init(fsi, io, dev); |
942 | 1231 | ||
943 | return 0; | 1232 | return 0; |
944 | } | 1233 | } |
945 | 1234 | ||
946 | static void fsi_hw_shutdown(struct fsi_priv *fsi, | 1235 | static void fsi_hw_shutdown(struct fsi_priv *fsi, |
947 | int is_play, | ||
948 | struct device *dev) | 1236 | struct device *dev) |
949 | { | 1237 | { |
950 | if (fsi_is_clk_master(fsi)) | 1238 | if (fsi_is_clk_master(fsi)) |
@@ -955,18 +1243,16 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, | |||
955 | struct snd_soc_dai *dai) | 1243 | struct snd_soc_dai *dai) |
956 | { | 1244 | { |
957 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1245 | struct fsi_priv *fsi = fsi_get_priv(substream); |
958 | int is_play = fsi_is_play(substream); | ||
959 | 1246 | ||
960 | return fsi_hw_startup(fsi, is_play, dai->dev); | 1247 | return fsi_hw_startup(fsi, fsi_stream_get(fsi, substream), dai->dev); |
961 | } | 1248 | } |
962 | 1249 | ||
963 | static void fsi_dai_shutdown(struct snd_pcm_substream *substream, | 1250 | static void fsi_dai_shutdown(struct snd_pcm_substream *substream, |
964 | struct snd_soc_dai *dai) | 1251 | struct snd_soc_dai *dai) |
965 | { | 1252 | { |
966 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1253 | struct fsi_priv *fsi = fsi_get_priv(substream); |
967 | int is_play = fsi_is_play(substream); | ||
968 | 1254 | ||
969 | fsi_hw_shutdown(fsi, is_play, dai->dev); | 1255 | fsi_hw_shutdown(fsi, dai->dev); |
970 | fsi->rate = 0; | 1256 | fsi->rate = 0; |
971 | } | 1257 | } |
972 | 1258 | ||
@@ -974,18 +1260,19 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
974 | struct snd_soc_dai *dai) | 1260 | struct snd_soc_dai *dai) |
975 | { | 1261 | { |
976 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1262 | struct fsi_priv *fsi = fsi_get_priv(substream); |
977 | int is_play = fsi_is_play(substream); | 1263 | struct fsi_stream *io = fsi_stream_get(fsi, substream); |
978 | int ret = 0; | 1264 | int ret = 0; |
979 | 1265 | ||
980 | switch (cmd) { | 1266 | switch (cmd) { |
981 | case SNDRV_PCM_TRIGGER_START: | 1267 | case SNDRV_PCM_TRIGGER_START: |
982 | fsi_stream_push(fsi, is_play, substream); | 1268 | fsi_stream_init(fsi, io, substream); |
983 | ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); | 1269 | ret = fsi_stream_transfer(io); |
984 | fsi_port_start(fsi, is_play); | 1270 | if (0 == ret) |
1271 | fsi_stream_start(fsi, io); | ||
985 | break; | 1272 | break; |
986 | case SNDRV_PCM_TRIGGER_STOP: | 1273 | case SNDRV_PCM_TRIGGER_STOP: |
987 | fsi_port_stop(fsi, is_play); | 1274 | fsi_stream_stop(fsi, io); |
988 | fsi_stream_pop(fsi, is_play); | 1275 | fsi_stream_quit(fsi, io); |
989 | break; | 1276 | break; |
990 | } | 1277 | } |
991 | 1278 | ||
@@ -1036,8 +1323,7 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi) | |||
1036 | static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | 1323 | static int fsi_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
1037 | { | 1324 | { |
1038 | struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); | 1325 | struct fsi_priv *fsi = fsi_get_priv_frm_dai(dai); |
1039 | struct fsi_master *master = fsi_get_master(fsi); | 1326 | set_rate_func set_rate = fsi_get_info_set_rate(fsi); |
1040 | set_rate_func set_rate = fsi_get_info_set_rate(master); | ||
1041 | u32 flags = fsi_get_info_flags(fsi); | 1327 | u32 flags = fsi_get_info_flags(fsi); |
1042 | int ret; | 1328 | int ret; |
1043 | 1329 | ||
@@ -1151,13 +1437,9 @@ static int fsi_hw_free(struct snd_pcm_substream *substream) | |||
1151 | static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) | 1437 | static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) |
1152 | { | 1438 | { |
1153 | struct fsi_priv *fsi = fsi_get_priv(substream); | 1439 | struct fsi_priv *fsi = fsi_get_priv(substream); |
1154 | struct fsi_stream *io = fsi_get_stream(fsi, fsi_is_play(substream)); | 1440 | struct fsi_stream *io = fsi_stream_get(fsi, substream); |
1155 | int samples_pos = io->buff_sample_pos - 1; | ||
1156 | |||
1157 | if (samples_pos < 0) | ||
1158 | samples_pos = 0; | ||
1159 | 1441 | ||
1160 | return fsi_sample2frame(fsi, samples_pos); | 1442 | return fsi_sample2frame(fsi, io->buff_sample_pos); |
1161 | } | 1443 | } |
1162 | 1444 | ||
1163 | static struct snd_pcm_ops fsi_pcm_ops = { | 1445 | static struct snd_pcm_ops fsi_pcm_ops = { |
@@ -1243,11 +1525,24 @@ static struct snd_soc_platform_driver fsi_soc_platform = { | |||
1243 | /* | 1525 | /* |
1244 | * platform function | 1526 | * platform function |
1245 | */ | 1527 | */ |
1528 | static void fsi_handler_init(struct fsi_priv *fsi) | ||
1529 | { | ||
1530 | fsi->playback.handler = &fsi_pio_push_handler; /* default PIO */ | ||
1531 | fsi->playback.priv = fsi; | ||
1532 | fsi->capture.handler = &fsi_pio_pop_handler; /* default PIO */ | ||
1533 | fsi->capture.priv = fsi; | ||
1534 | |||
1535 | if (fsi->info->tx_id) { | ||
1536 | fsi->playback.slave.slave_id = fsi->info->tx_id; | ||
1537 | fsi->playback.handler = &fsi_dma_push_handler; | ||
1538 | } | ||
1539 | } | ||
1246 | 1540 | ||
1247 | static int fsi_probe(struct platform_device *pdev) | 1541 | static int fsi_probe(struct platform_device *pdev) |
1248 | { | 1542 | { |
1249 | struct fsi_master *master; | 1543 | struct fsi_master *master; |
1250 | const struct platform_device_id *id_entry; | 1544 | const struct platform_device_id *id_entry; |
1545 | struct sh_fsi_platform_info *info = pdev->dev.platform_data; | ||
1251 | struct resource *res; | 1546 | struct resource *res; |
1252 | unsigned int irq; | 1547 | unsigned int irq; |
1253 | int ret; | 1548 | int ret; |
@@ -1282,17 +1577,30 @@ static int fsi_probe(struct platform_device *pdev) | |||
1282 | 1577 | ||
1283 | /* master setting */ | 1578 | /* master setting */ |
1284 | master->irq = irq; | 1579 | master->irq = irq; |
1285 | master->info = pdev->dev.platform_data; | ||
1286 | master->core = (struct fsi_core *)id_entry->driver_data; | 1580 | master->core = (struct fsi_core *)id_entry->driver_data; |
1287 | spin_lock_init(&master->lock); | 1581 | spin_lock_init(&master->lock); |
1288 | 1582 | ||
1289 | /* FSI A setting */ | 1583 | /* FSI A setting */ |
1290 | master->fsia.base = master->base; | 1584 | master->fsia.base = master->base; |
1291 | master->fsia.master = master; | 1585 | master->fsia.master = master; |
1586 | master->fsia.info = &info->port_a; | ||
1587 | fsi_handler_init(&master->fsia); | ||
1588 | ret = fsi_stream_probe(&master->fsia); | ||
1589 | if (ret < 0) { | ||
1590 | dev_err(&pdev->dev, "FSIA stream probe failed\n"); | ||
1591 | goto exit_iounmap; | ||
1592 | } | ||
1292 | 1593 | ||
1293 | /* FSI B setting */ | 1594 | /* FSI B setting */ |
1294 | master->fsib.base = master->base + 0x40; | 1595 | master->fsib.base = master->base + 0x40; |
1295 | master->fsib.master = master; | 1596 | master->fsib.master = master; |
1597 | master->fsib.info = &info->port_b; | ||
1598 | fsi_handler_init(&master->fsib); | ||
1599 | ret = fsi_stream_probe(&master->fsib); | ||
1600 | if (ret < 0) { | ||
1601 | dev_err(&pdev->dev, "FSIB stream probe failed\n"); | ||
1602 | goto exit_fsia; | ||
1603 | } | ||
1296 | 1604 | ||
1297 | pm_runtime_enable(&pdev->dev); | 1605 | pm_runtime_enable(&pdev->dev); |
1298 | dev_set_drvdata(&pdev->dev, master); | 1606 | dev_set_drvdata(&pdev->dev, master); |
@@ -1301,7 +1609,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
1301 | id_entry->name, master); | 1609 | id_entry->name, master); |
1302 | if (ret) { | 1610 | if (ret) { |
1303 | dev_err(&pdev->dev, "irq request err\n"); | 1611 | dev_err(&pdev->dev, "irq request err\n"); |
1304 | goto exit_iounmap; | 1612 | goto exit_fsib; |
1305 | } | 1613 | } |
1306 | 1614 | ||
1307 | ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform); | 1615 | ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform); |
@@ -1323,6 +1631,10 @@ exit_snd_soc: | |||
1323 | snd_soc_unregister_platform(&pdev->dev); | 1631 | snd_soc_unregister_platform(&pdev->dev); |
1324 | exit_free_irq: | 1632 | exit_free_irq: |
1325 | free_irq(irq, master); | 1633 | free_irq(irq, master); |
1634 | exit_fsib: | ||
1635 | fsi_stream_remove(&master->fsib); | ||
1636 | exit_fsia: | ||
1637 | fsi_stream_remove(&master->fsia); | ||
1326 | exit_iounmap: | 1638 | exit_iounmap: |
1327 | iounmap(master->base); | 1639 | iounmap(master->base); |
1328 | pm_runtime_disable(&pdev->dev); | 1640 | pm_runtime_disable(&pdev->dev); |
@@ -1345,6 +1657,9 @@ static int fsi_remove(struct platform_device *pdev) | |||
1345 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); | 1657 | snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); |
1346 | snd_soc_unregister_platform(&pdev->dev); | 1658 | snd_soc_unregister_platform(&pdev->dev); |
1347 | 1659 | ||
1660 | fsi_stream_remove(&master->fsia); | ||
1661 | fsi_stream_remove(&master->fsib); | ||
1662 | |||
1348 | iounmap(master->base); | 1663 | iounmap(master->base); |
1349 | kfree(master); | 1664 | kfree(master); |
1350 | 1665 | ||
@@ -1352,30 +1667,29 @@ static int fsi_remove(struct platform_device *pdev) | |||
1352 | } | 1667 | } |
1353 | 1668 | ||
1354 | static void __fsi_suspend(struct fsi_priv *fsi, | 1669 | static void __fsi_suspend(struct fsi_priv *fsi, |
1355 | int is_play, | 1670 | struct fsi_stream *io, |
1356 | struct device *dev) | 1671 | struct device *dev) |
1357 | { | 1672 | { |
1358 | if (!fsi_stream_is_working(fsi, is_play)) | 1673 | if (!fsi_stream_is_working(fsi, io)) |
1359 | return; | 1674 | return; |
1360 | 1675 | ||
1361 | fsi_port_stop(fsi, is_play); | 1676 | fsi_stream_stop(fsi, io); |
1362 | fsi_hw_shutdown(fsi, is_play, dev); | 1677 | fsi_hw_shutdown(fsi, dev); |
1363 | } | 1678 | } |
1364 | 1679 | ||
1365 | static void __fsi_resume(struct fsi_priv *fsi, | 1680 | static void __fsi_resume(struct fsi_priv *fsi, |
1366 | int is_play, | 1681 | struct fsi_stream *io, |
1367 | struct device *dev) | 1682 | struct device *dev) |
1368 | { | 1683 | { |
1369 | if (!fsi_stream_is_working(fsi, is_play)) | 1684 | if (!fsi_stream_is_working(fsi, io)) |
1370 | return; | 1685 | return; |
1371 | 1686 | ||
1372 | fsi_hw_startup(fsi, is_play, dev); | 1687 | fsi_hw_startup(fsi, io, dev); |
1373 | 1688 | ||
1374 | if (fsi_is_clk_master(fsi) && fsi->rate) | 1689 | if (fsi_is_clk_master(fsi) && fsi->rate) |
1375 | fsi_set_master_clk(dev, fsi, fsi->rate, 1); | 1690 | fsi_set_master_clk(dev, fsi, fsi->rate, 1); |
1376 | 1691 | ||
1377 | fsi_port_start(fsi, is_play); | 1692 | fsi_stream_start(fsi, io); |
1378 | |||
1379 | } | 1693 | } |
1380 | 1694 | ||
1381 | static int fsi_suspend(struct device *dev) | 1695 | static int fsi_suspend(struct device *dev) |
@@ -1384,11 +1698,11 @@ static int fsi_suspend(struct device *dev) | |||
1384 | struct fsi_priv *fsia = &master->fsia; | 1698 | struct fsi_priv *fsia = &master->fsia; |
1385 | struct fsi_priv *fsib = &master->fsib; | 1699 | struct fsi_priv *fsib = &master->fsib; |
1386 | 1700 | ||
1387 | __fsi_suspend(fsia, 1, dev); | 1701 | __fsi_suspend(fsia, &fsia->playback, dev); |
1388 | __fsi_suspend(fsia, 0, dev); | 1702 | __fsi_suspend(fsia, &fsia->capture, dev); |
1389 | 1703 | ||
1390 | __fsi_suspend(fsib, 1, dev); | 1704 | __fsi_suspend(fsib, &fsib->playback, dev); |
1391 | __fsi_suspend(fsib, 0, dev); | 1705 | __fsi_suspend(fsib, &fsib->capture, dev); |
1392 | 1706 | ||
1393 | return 0; | 1707 | return 0; |
1394 | } | 1708 | } |
@@ -1399,32 +1713,18 @@ static int fsi_resume(struct device *dev) | |||
1399 | struct fsi_priv *fsia = &master->fsia; | 1713 | struct fsi_priv *fsia = &master->fsia; |
1400 | struct fsi_priv *fsib = &master->fsib; | 1714 | struct fsi_priv *fsib = &master->fsib; |
1401 | 1715 | ||
1402 | __fsi_resume(fsia, 1, dev); | 1716 | __fsi_resume(fsia, &fsia->playback, dev); |
1403 | __fsi_resume(fsia, 0, dev); | 1717 | __fsi_resume(fsia, &fsia->capture, dev); |
1404 | 1718 | ||
1405 | __fsi_resume(fsib, 1, dev); | 1719 | __fsi_resume(fsib, &fsib->playback, dev); |
1406 | __fsi_resume(fsib, 0, dev); | 1720 | __fsi_resume(fsib, &fsib->capture, dev); |
1407 | 1721 | ||
1408 | return 0; | 1722 | return 0; |
1409 | } | 1723 | } |
1410 | 1724 | ||
1411 | static int fsi_runtime_nop(struct device *dev) | ||
1412 | { | ||
1413 | /* Runtime PM callback shared between ->runtime_suspend() | ||
1414 | * and ->runtime_resume(). Simply returns success. | ||
1415 | * | ||
1416 | * This driver re-initializes all registers after | ||
1417 | * pm_runtime_get_sync() anyway so there is no need | ||
1418 | * to save and restore registers here. | ||
1419 | */ | ||
1420 | return 0; | ||
1421 | } | ||
1422 | |||
1423 | static struct dev_pm_ops fsi_pm_ops = { | 1725 | static struct dev_pm_ops fsi_pm_ops = { |
1424 | .suspend = fsi_suspend, | 1726 | .suspend = fsi_suspend, |
1425 | .resume = fsi_resume, | 1727 | .resume = fsi_resume, |
1426 | .runtime_suspend = fsi_runtime_nop, | ||
1427 | .runtime_resume = fsi_runtime_nop, | ||
1428 | }; | 1728 | }; |
1429 | 1729 | ||
1430 | static struct fsi_core fsi1_core = { | 1730 | static struct fsi_core fsi1_core = { |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b5ecf6d23214..a4deebc0801a 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -277,8 +277,7 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec) | |||
277 | codec->debugfs_codec_root = debugfs_create_dir(codec->name, | 277 | codec->debugfs_codec_root = debugfs_create_dir(codec->name, |
278 | debugfs_card_root); | 278 | debugfs_card_root); |
279 | if (!codec->debugfs_codec_root) { | 279 | if (!codec->debugfs_codec_root) { |
280 | printk(KERN_WARNING | 280 | dev_warn(codec->dev, "Failed to create codec debugfs directory\n"); |
281 | "ASoC: Failed to create codec debugfs directory\n"); | ||
282 | return; | 281 | return; |
283 | } | 282 | } |
284 | 283 | ||
@@ -291,8 +290,7 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec) | |||
291 | codec->debugfs_codec_root, | 290 | codec->debugfs_codec_root, |
292 | codec, &codec_reg_fops); | 291 | codec, &codec_reg_fops); |
293 | if (!codec->debugfs_reg) | 292 | if (!codec->debugfs_reg) |
294 | printk(KERN_WARNING | 293 | dev_warn(codec->dev, "Failed to create codec register debugfs file\n"); |
295 | "ASoC: Failed to create codec register debugfs file\n"); | ||
296 | 294 | ||
297 | snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root); | 295 | snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root); |
298 | } | 296 | } |
@@ -302,6 +300,27 @@ static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) | |||
302 | debugfs_remove_recursive(codec->debugfs_codec_root); | 300 | debugfs_remove_recursive(codec->debugfs_codec_root); |
303 | } | 301 | } |
304 | 302 | ||
303 | static void soc_init_platform_debugfs(struct snd_soc_platform *platform) | ||
304 | { | ||
305 | struct dentry *debugfs_card_root = platform->card->debugfs_card_root; | ||
306 | |||
307 | platform->debugfs_platform_root = debugfs_create_dir(platform->name, | ||
308 | debugfs_card_root); | ||
309 | if (!platform->debugfs_platform_root) { | ||
310 | dev_warn(platform->dev, | ||
311 | "Failed to create platform debugfs directory\n"); | ||
312 | return; | ||
313 | } | ||
314 | |||
315 | snd_soc_dapm_debugfs_init(&platform->dapm, | ||
316 | platform->debugfs_platform_root); | ||
317 | } | ||
318 | |||
319 | static void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform) | ||
320 | { | ||
321 | debugfs_remove_recursive(platform->debugfs_platform_root); | ||
322 | } | ||
323 | |||
305 | static ssize_t codec_list_read_file(struct file *file, char __user *user_buf, | 324 | static ssize_t codec_list_read_file(struct file *file, char __user *user_buf, |
306 | size_t count, loff_t *ppos) | 325 | size_t count, loff_t *ppos) |
307 | { | 326 | { |
@@ -435,6 +454,14 @@ static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) | |||
435 | { | 454 | { |
436 | } | 455 | } |
437 | 456 | ||
457 | static inline void soc_init_platform_debugfs(struct snd_soc_platform *platform) | ||
458 | { | ||
459 | } | ||
460 | |||
461 | static inline void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform) | ||
462 | { | ||
463 | } | ||
464 | |||
438 | static inline void soc_init_card_debugfs(struct snd_soc_card *card) | 465 | static inline void soc_init_card_debugfs(struct snd_soc_card *card) |
439 | { | 466 | { |
440 | } | 467 | } |
@@ -546,18 +573,20 @@ int snd_soc_suspend(struct device *dev) | |||
546 | } | 573 | } |
547 | 574 | ||
548 | for (i = 0; i < card->num_rtd; i++) { | 575 | for (i = 0; i < card->num_rtd; i++) { |
549 | struct snd_soc_dai_driver *driver = card->rtd[i].codec_dai->driver; | 576 | struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai; |
550 | 577 | ||
551 | if (card->rtd[i].dai_link->ignore_suspend) | 578 | if (card->rtd[i].dai_link->ignore_suspend) |
552 | continue; | 579 | continue; |
553 | 580 | ||
554 | if (driver->playback.stream_name != NULL) | 581 | snd_soc_dapm_stream_event(&card->rtd[i], |
555 | snd_soc_dapm_stream_event(&card->rtd[i], driver->playback.stream_name, | 582 | SNDRV_PCM_STREAM_PLAYBACK, |
556 | SND_SOC_DAPM_STREAM_SUSPEND); | 583 | codec_dai, |
584 | SND_SOC_DAPM_STREAM_SUSPEND); | ||
557 | 585 | ||
558 | if (driver->capture.stream_name != NULL) | 586 | snd_soc_dapm_stream_event(&card->rtd[i], |
559 | snd_soc_dapm_stream_event(&card->rtd[i], driver->capture.stream_name, | 587 | SNDRV_PCM_STREAM_CAPTURE, |
560 | SND_SOC_DAPM_STREAM_SUSPEND); | 588 | codec_dai, |
589 | SND_SOC_DAPM_STREAM_SUSPEND); | ||
561 | } | 590 | } |
562 | 591 | ||
563 | /* suspend all CODECs */ | 592 | /* suspend all CODECs */ |
@@ -567,6 +596,17 @@ int snd_soc_suspend(struct device *dev) | |||
567 | if (!codec->suspended && codec->driver->suspend) { | 596 | if (!codec->suspended && codec->driver->suspend) { |
568 | switch (codec->dapm.bias_level) { | 597 | switch (codec->dapm.bias_level) { |
569 | case SND_SOC_BIAS_STANDBY: | 598 | case SND_SOC_BIAS_STANDBY: |
599 | /* | ||
600 | * If the CODEC is capable of idle | ||
601 | * bias off then being in STANDBY | ||
602 | * means it's doing something, | ||
603 | * otherwise fall through. | ||
604 | */ | ||
605 | if (codec->dapm.idle_bias_off) { | ||
606 | dev_dbg(codec->dev, | ||
607 | "idle_bias_off CODEC on over suspend\n"); | ||
608 | break; | ||
609 | } | ||
570 | case SND_SOC_BIAS_OFF: | 610 | case SND_SOC_BIAS_OFF: |
571 | codec->driver->suspend(codec); | 611 | codec->driver->suspend(codec); |
572 | codec->suspended = 1; | 612 | codec->suspended = 1; |
@@ -649,18 +689,18 @@ static void soc_resume_deferred(struct work_struct *work) | |||
649 | } | 689 | } |
650 | 690 | ||
651 | for (i = 0; i < card->num_rtd; i++) { | 691 | for (i = 0; i < card->num_rtd; i++) { |
652 | struct snd_soc_dai_driver *driver = card->rtd[i].codec_dai->driver; | 692 | struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai; |
653 | 693 | ||
654 | if (card->rtd[i].dai_link->ignore_suspend) | 694 | if (card->rtd[i].dai_link->ignore_suspend) |
655 | continue; | 695 | continue; |
656 | 696 | ||
657 | if (driver->playback.stream_name != NULL) | 697 | snd_soc_dapm_stream_event(&card->rtd[i], |
658 | snd_soc_dapm_stream_event(&card->rtd[i], driver->playback.stream_name, | 698 | SNDRV_PCM_STREAM_PLAYBACK, codec_dai, |
659 | SND_SOC_DAPM_STREAM_RESUME); | 699 | SND_SOC_DAPM_STREAM_RESUME); |
660 | 700 | ||
661 | if (driver->capture.stream_name != NULL) | 701 | snd_soc_dapm_stream_event(&card->rtd[i], |
662 | snd_soc_dapm_stream_event(&card->rtd[i], driver->capture.stream_name, | 702 | SNDRV_PCM_STREAM_CAPTURE, codec_dai, |
663 | SND_SOC_DAPM_STREAM_RESUME); | 703 | SND_SOC_DAPM_STREAM_RESUME); |
664 | } | 704 | } |
665 | 705 | ||
666 | /* unmute any active DACs */ | 706 | /* unmute any active DACs */ |
@@ -893,7 +933,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order) | |||
893 | if (codec_dai->driver->remove) { | 933 | if (codec_dai->driver->remove) { |
894 | err = codec_dai->driver->remove(codec_dai); | 934 | err = codec_dai->driver->remove(codec_dai); |
895 | if (err < 0) | 935 | if (err < 0) |
896 | printk(KERN_ERR "asoc: failed to remove %s\n", codec_dai->name); | 936 | pr_err("asoc: failed to remove %s: %d\n", |
937 | codec_dai->name, err); | ||
897 | } | 938 | } |
898 | codec_dai->probed = 0; | 939 | codec_dai->probed = 0; |
899 | list_del(&codec_dai->card_list); | 940 | list_del(&codec_dai->card_list); |
@@ -905,12 +946,14 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order) | |||
905 | if (platform->driver->remove) { | 946 | if (platform->driver->remove) { |
906 | err = platform->driver->remove(platform); | 947 | err = platform->driver->remove(platform); |
907 | if (err < 0) | 948 | if (err < 0) |
908 | printk(KERN_ERR "asoc: failed to remove %s\n", platform->name); | 949 | pr_err("asoc: failed to remove %s: %d\n", |
950 | platform->name, err); | ||
909 | } | 951 | } |
910 | 952 | ||
911 | /* Make sure all DAPM widgets are freed */ | 953 | /* Make sure all DAPM widgets are freed */ |
912 | snd_soc_dapm_free(&platform->dapm); | 954 | snd_soc_dapm_free(&platform->dapm); |
913 | 955 | ||
956 | soc_cleanup_platform_debugfs(platform); | ||
914 | platform->probed = 0; | 957 | platform->probed = 0; |
915 | list_del(&platform->card_list); | 958 | list_del(&platform->card_list); |
916 | module_put(platform->dev->driver->owner); | 959 | module_put(platform->dev->driver->owner); |
@@ -927,7 +970,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order) | |||
927 | if (cpu_dai->driver->remove) { | 970 | if (cpu_dai->driver->remove) { |
928 | err = cpu_dai->driver->remove(cpu_dai); | 971 | err = cpu_dai->driver->remove(cpu_dai); |
929 | if (err < 0) | 972 | if (err < 0) |
930 | printk(KERN_ERR "asoc: failed to remove %s\n", cpu_dai->name); | 973 | pr_err("asoc: failed to remove %s: %d\n", |
974 | cpu_dai->name, err); | ||
931 | } | 975 | } |
932 | cpu_dai->probed = 0; | 976 | cpu_dai->probed = 0; |
933 | list_del(&cpu_dai->card_list); | 977 | list_del(&cpu_dai->card_list); |
@@ -969,6 +1013,7 @@ static int soc_probe_codec(struct snd_soc_card *card, | |||
969 | { | 1013 | { |
970 | int ret = 0; | 1014 | int ret = 0; |
971 | const struct snd_soc_codec_driver *driver = codec->driver; | 1015 | const struct snd_soc_codec_driver *driver = codec->driver; |
1016 | struct snd_soc_dai *dai; | ||
972 | 1017 | ||
973 | codec->card = card; | 1018 | codec->card = card; |
974 | codec->dapm.card = card; | 1019 | codec->dapm.card = card; |
@@ -983,6 +1028,14 @@ static int soc_probe_codec(struct snd_soc_card *card, | |||
983 | snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, | 1028 | snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, |
984 | driver->num_dapm_widgets); | 1029 | driver->num_dapm_widgets); |
985 | 1030 | ||
1031 | /* Create DAPM widgets for each DAI stream */ | ||
1032 | list_for_each_entry(dai, &dai_list, list) { | ||
1033 | if (dai->dev != codec->dev) | ||
1034 | continue; | ||
1035 | |||
1036 | snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); | ||
1037 | } | ||
1038 | |||
986 | codec->dapm.idle_bias_off = driver->idle_bias_off; | 1039 | codec->dapm.idle_bias_off = driver->idle_bias_off; |
987 | 1040 | ||
988 | if (driver->probe) { | 1041 | if (driver->probe) { |
@@ -996,7 +1049,7 @@ static int soc_probe_codec(struct snd_soc_card *card, | |||
996 | } | 1049 | } |
997 | 1050 | ||
998 | if (driver->controls) | 1051 | if (driver->controls) |
999 | snd_soc_add_controls(codec, driver->controls, | 1052 | snd_soc_add_codec_controls(codec, driver->controls, |
1000 | driver->num_controls); | 1053 | driver->num_controls); |
1001 | if (driver->dapm_routes) | 1054 | if (driver->dapm_routes) |
1002 | snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes, | 1055 | snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes, |
@@ -1028,6 +1081,8 @@ static int soc_probe_platform(struct snd_soc_card *card, | |||
1028 | if (!try_module_get(platform->dev->driver->owner)) | 1081 | if (!try_module_get(platform->dev->driver->owner)) |
1029 | return -ENODEV; | 1082 | return -ENODEV; |
1030 | 1083 | ||
1084 | soc_init_platform_debugfs(platform); | ||
1085 | |||
1031 | if (driver->dapm_widgets) | 1086 | if (driver->dapm_widgets) |
1032 | snd_soc_dapm_new_controls(&platform->dapm, | 1087 | snd_soc_dapm_new_controls(&platform->dapm, |
1033 | driver->dapm_widgets, driver->num_dapm_widgets); | 1088 | driver->dapm_widgets, driver->num_dapm_widgets); |
@@ -1057,6 +1112,7 @@ static int soc_probe_platform(struct snd_soc_card *card, | |||
1057 | return 0; | 1112 | return 0; |
1058 | 1113 | ||
1059 | err_probe: | 1114 | err_probe: |
1115 | soc_cleanup_platform_debugfs(platform); | ||
1060 | module_put(platform->dev->driver->owner); | 1116 | module_put(platform->dev->driver->owner); |
1061 | 1117 | ||
1062 | return ret; | 1118 | return ret; |
@@ -1172,8 +1228,8 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order) | |||
1172 | if (cpu_dai->driver->probe) { | 1228 | if (cpu_dai->driver->probe) { |
1173 | ret = cpu_dai->driver->probe(cpu_dai); | 1229 | ret = cpu_dai->driver->probe(cpu_dai); |
1174 | if (ret < 0) { | 1230 | if (ret < 0) { |
1175 | printk(KERN_ERR "asoc: failed to probe CPU DAI %s\n", | 1231 | pr_err("asoc: failed to probe CPU DAI %s: %d\n", |
1176 | cpu_dai->name); | 1232 | cpu_dai->name, ret); |
1177 | module_put(cpu_dai->dev->driver->owner); | 1233 | module_put(cpu_dai->dev->driver->owner); |
1178 | return ret; | 1234 | return ret; |
1179 | } | 1235 | } |
@@ -1204,8 +1260,8 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order) | |||
1204 | if (codec_dai->driver->probe) { | 1260 | if (codec_dai->driver->probe) { |
1205 | ret = codec_dai->driver->probe(codec_dai); | 1261 | ret = codec_dai->driver->probe(codec_dai); |
1206 | if (ret < 0) { | 1262 | if (ret < 0) { |
1207 | printk(KERN_ERR "asoc: failed to probe CODEC DAI %s\n", | 1263 | pr_err("asoc: failed to probe CODEC DAI %s: %d\n", |
1208 | codec_dai->name); | 1264 | codec_dai->name, ret); |
1209 | return ret; | 1265 | return ret; |
1210 | } | 1266 | } |
1211 | } | 1267 | } |
@@ -1225,12 +1281,13 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order) | |||
1225 | 1281 | ||
1226 | ret = device_create_file(rtd->dev, &dev_attr_pmdown_time); | 1282 | ret = device_create_file(rtd->dev, &dev_attr_pmdown_time); |
1227 | if (ret < 0) | 1283 | if (ret < 0) |
1228 | printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n"); | 1284 | pr_warn("asoc: failed to add pmdown_time sysfs:%d\n", ret); |
1229 | 1285 | ||
1230 | /* create the pcm */ | 1286 | /* create the pcm */ |
1231 | ret = soc_new_pcm(rtd, num); | 1287 | ret = soc_new_pcm(rtd, num); |
1232 | if (ret < 0) { | 1288 | if (ret < 0) { |
1233 | printk(KERN_ERR "asoc: can't create pcm %s\n", dai_link->stream_name); | 1289 | pr_err("asoc: can't create pcm %s :%d\n", |
1290 | dai_link->stream_name, ret); | ||
1234 | return ret; | 1291 | return ret; |
1235 | } | 1292 | } |
1236 | 1293 | ||
@@ -1263,7 +1320,7 @@ static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) | |||
1263 | 1320 | ||
1264 | ret = soc_ac97_dev_register(rtd->codec); | 1321 | ret = soc_ac97_dev_register(rtd->codec); |
1265 | if (ret < 0) { | 1322 | if (ret < 0) { |
1266 | printk(KERN_ERR "asoc: AC97 device register failed\n"); | 1323 | pr_err("asoc: AC97 device register failed:%d\n", ret); |
1267 | return ret; | 1324 | return ret; |
1268 | } | 1325 | } |
1269 | 1326 | ||
@@ -1403,8 +1460,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1403 | ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, | 1460 | ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, |
1404 | card->owner, 0, &card->snd_card); | 1461 | card->owner, 0, &card->snd_card); |
1405 | if (ret < 0) { | 1462 | if (ret < 0) { |
1406 | printk(KERN_ERR "asoc: can't create sound card for card %s\n", | 1463 | pr_err("asoc: can't create sound card for card %s: %d\n", |
1407 | card->name); | 1464 | card->name, ret); |
1408 | mutex_unlock(&card->mutex); | 1465 | mutex_unlock(&card->mutex); |
1409 | return; | 1466 | return; |
1410 | } | 1467 | } |
@@ -1457,13 +1514,10 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1457 | } | 1514 | } |
1458 | } | 1515 | } |
1459 | 1516 | ||
1460 | /* We should have a non-codec control add function but we don't */ | 1517 | snd_soc_dapm_link_dai_widgets(card); |
1518 | |||
1461 | if (card->controls) | 1519 | if (card->controls) |
1462 | snd_soc_add_controls(list_first_entry(&card->codec_dev_list, | 1520 | snd_soc_add_card_controls(card, card->controls, card->num_controls); |
1463 | struct snd_soc_codec, | ||
1464 | card_list), | ||
1465 | card->controls, | ||
1466 | card->num_controls); | ||
1467 | 1521 | ||
1468 | if (card->dapm_routes) | 1522 | if (card->dapm_routes) |
1469 | snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, | 1523 | snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, |
@@ -1477,14 +1531,14 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1477 | if (dai_link->dai_fmt) { | 1531 | if (dai_link->dai_fmt) { |
1478 | ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai, | 1532 | ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai, |
1479 | dai_link->dai_fmt); | 1533 | dai_link->dai_fmt); |
1480 | if (ret != 0) | 1534 | if (ret != 0 && ret != -ENOTSUPP) |
1481 | dev_warn(card->rtd[i].codec_dai->dev, | 1535 | dev_warn(card->rtd[i].codec_dai->dev, |
1482 | "Failed to set DAI format: %d\n", | 1536 | "Failed to set DAI format: %d\n", |
1483 | ret); | 1537 | ret); |
1484 | 1538 | ||
1485 | ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai, | 1539 | ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai, |
1486 | dai_link->dai_fmt); | 1540 | dai_link->dai_fmt); |
1487 | if (ret != 0) | 1541 | if (ret != 0 && ret != -ENOTSUPP) |
1488 | dev_warn(card->rtd[i].cpu_dai->dev, | 1542 | dev_warn(card->rtd[i].cpu_dai->dev, |
1489 | "Failed to set DAI format: %d\n", | 1543 | "Failed to set DAI format: %d\n", |
1490 | ret); | 1544 | ret); |
@@ -1527,7 +1581,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1527 | 1581 | ||
1528 | ret = snd_card_register(card->snd_card); | 1582 | ret = snd_card_register(card->snd_card); |
1529 | if (ret < 0) { | 1583 | if (ret < 0) { |
1530 | printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name); | 1584 | pr_err("asoc: failed to register soundcard for %s: %d\n", |
1585 | card->name, ret); | ||
1531 | goto probe_aux_dev_err; | 1586 | goto probe_aux_dev_err; |
1532 | } | 1587 | } |
1533 | 1588 | ||
@@ -1536,7 +1591,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1536 | for (i = 0; i < card->num_rtd; i++) { | 1591 | for (i = 0; i < card->num_rtd; i++) { |
1537 | ret = soc_register_ac97_dai_link(&card->rtd[i]); | 1592 | ret = soc_register_ac97_dai_link(&card->rtd[i]); |
1538 | if (ret < 0) { | 1593 | if (ret < 0) { |
1539 | printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name); | 1594 | pr_err("asoc: failed to register AC97 %s: %d\n", |
1595 | card->name, ret); | ||
1540 | while (--i >= 0) | 1596 | while (--i >= 0) |
1541 | soc_unregister_ac97_dai_link(card->rtd[i].codec); | 1597 | soc_unregister_ac97_dai_link(card->rtd[i].codec); |
1542 | goto probe_aux_dev_err; | 1598 | goto probe_aux_dev_err; |
@@ -1589,6 +1645,10 @@ static int soc_probe(struct platform_device *pdev) | |||
1589 | if (!card) | 1645 | if (!card) |
1590 | return -EINVAL; | 1646 | return -EINVAL; |
1591 | 1647 | ||
1648 | dev_warn(&pdev->dev, | ||
1649 | "ASoC machine %s should use snd_soc_register_card()\n", | ||
1650 | card->name); | ||
1651 | |||
1592 | /* Bodge while we unpick instantiation */ | 1652 | /* Bodge while we unpick instantiation */ |
1593 | card->dev = &pdev->dev; | 1653 | card->dev = &pdev->dev; |
1594 | 1654 | ||
@@ -1626,7 +1686,6 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card) | |||
1626 | 1686 | ||
1627 | snd_soc_dapm_free(&card->dapm); | 1687 | snd_soc_dapm_free(&card->dapm); |
1628 | 1688 | ||
1629 | kfree(card->rtd); | ||
1630 | snd_card_free(card->snd_card); | 1689 | snd_card_free(card->snd_card); |
1631 | return 0; | 1690 | return 0; |
1632 | 1691 | ||
@@ -1665,7 +1724,10 @@ EXPORT_SYMBOL_GPL(snd_soc_poweroff); | |||
1665 | const struct dev_pm_ops snd_soc_pm_ops = { | 1724 | const struct dev_pm_ops snd_soc_pm_ops = { |
1666 | .suspend = snd_soc_suspend, | 1725 | .suspend = snd_soc_suspend, |
1667 | .resume = snd_soc_resume, | 1726 | .resume = snd_soc_resume, |
1727 | .freeze = snd_soc_suspend, | ||
1728 | .thaw = snd_soc_resume, | ||
1668 | .poweroff = snd_soc_poweroff, | 1729 | .poweroff = snd_soc_poweroff, |
1730 | .restore = snd_soc_resume, | ||
1669 | }; | 1731 | }; |
1670 | EXPORT_SYMBOL_GPL(snd_soc_pm_ops); | 1732 | EXPORT_SYMBOL_GPL(snd_soc_pm_ops); |
1671 | 1733 | ||
@@ -1869,23 +1931,28 @@ EXPORT_SYMBOL_GPL(snd_soc_bulk_write_raw); | |||
1869 | int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, | 1931 | int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, |
1870 | unsigned int mask, unsigned int value) | 1932 | unsigned int mask, unsigned int value) |
1871 | { | 1933 | { |
1872 | int change; | 1934 | bool change; |
1873 | unsigned int old, new; | 1935 | unsigned int old, new; |
1874 | int ret; | 1936 | int ret; |
1875 | 1937 | ||
1876 | ret = snd_soc_read(codec, reg); | 1938 | if (codec->using_regmap) { |
1877 | if (ret < 0) | 1939 | ret = regmap_update_bits_check(codec->control_data, reg, |
1878 | return ret; | 1940 | mask, value, &change); |
1879 | 1941 | } else { | |
1880 | old = ret; | 1942 | ret = snd_soc_read(codec, reg); |
1881 | new = (old & ~mask) | (value & mask); | ||
1882 | change = old != new; | ||
1883 | if (change) { | ||
1884 | ret = snd_soc_write(codec, reg, new); | ||
1885 | if (ret < 0) | 1943 | if (ret < 0) |
1886 | return ret; | 1944 | return ret; |
1945 | |||
1946 | old = ret; | ||
1947 | new = (old & ~mask) | (value & mask); | ||
1948 | change = old != new; | ||
1949 | if (change) | ||
1950 | ret = snd_soc_write(codec, reg, new); | ||
1887 | } | 1951 | } |
1888 | 1952 | ||
1953 | if (ret < 0) | ||
1954 | return ret; | ||
1955 | |||
1889 | return change; | 1956 | return change; |
1890 | } | 1957 | } |
1891 | EXPORT_SYMBOL_GPL(snd_soc_update_bits); | 1958 | EXPORT_SYMBOL_GPL(snd_soc_update_bits); |
@@ -1976,7 +2043,7 @@ EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams); | |||
1976 | * Returns 0 for success, else error. | 2043 | * Returns 0 for success, else error. |
1977 | */ | 2044 | */ |
1978 | struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, | 2045 | struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, |
1979 | void *data, char *long_name, | 2046 | void *data, const char *long_name, |
1980 | const char *prefix) | 2047 | const char *prefix) |
1981 | { | 2048 | { |
1982 | struct snd_kcontrol_new template; | 2049 | struct snd_kcontrol_new template; |
@@ -2011,9 +2078,28 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template, | |||
2011 | } | 2078 | } |
2012 | EXPORT_SYMBOL_GPL(snd_soc_cnew); | 2079 | EXPORT_SYMBOL_GPL(snd_soc_cnew); |
2013 | 2080 | ||
2081 | static int snd_soc_add_controls(struct snd_card *card, struct device *dev, | ||
2082 | const struct snd_kcontrol_new *controls, int num_controls, | ||
2083 | const char *prefix, void *data) | ||
2084 | { | ||
2085 | int err, i; | ||
2086 | |||
2087 | for (i = 0; i < num_controls; i++) { | ||
2088 | const struct snd_kcontrol_new *control = &controls[i]; | ||
2089 | err = snd_ctl_add(card, snd_soc_cnew(control, data, | ||
2090 | control->name, prefix)); | ||
2091 | if (err < 0) { | ||
2092 | dev_err(dev, "Failed to add %s: %d\n", control->name, err); | ||
2093 | return err; | ||
2094 | } | ||
2095 | } | ||
2096 | |||
2097 | return 0; | ||
2098 | } | ||
2099 | |||
2014 | /** | 2100 | /** |
2015 | * snd_soc_add_controls - add an array of controls to a codec. | 2101 | * snd_soc_add_codec_controls - add an array of controls to a codec. |
2016 | * Convienience function to add a list of controls. Many codecs were | 2102 | * Convenience function to add a list of controls. Many codecs were |
2017 | * duplicating this code. | 2103 | * duplicating this code. |
2018 | * | 2104 | * |
2019 | * @codec: codec to add controls to | 2105 | * @codec: codec to add controls to |
@@ -2022,31 +2108,19 @@ EXPORT_SYMBOL_GPL(snd_soc_cnew); | |||
2022 | * | 2108 | * |
2023 | * Return 0 for success, else error. | 2109 | * Return 0 for success, else error. |
2024 | */ | 2110 | */ |
2025 | int snd_soc_add_controls(struct snd_soc_codec *codec, | 2111 | int snd_soc_add_codec_controls(struct snd_soc_codec *codec, |
2026 | const struct snd_kcontrol_new *controls, int num_controls) | 2112 | const struct snd_kcontrol_new *controls, int num_controls) |
2027 | { | 2113 | { |
2028 | struct snd_card *card = codec->card->snd_card; | 2114 | struct snd_card *card = codec->card->snd_card; |
2029 | int err, i; | ||
2030 | |||
2031 | for (i = 0; i < num_controls; i++) { | ||
2032 | const struct snd_kcontrol_new *control = &controls[i]; | ||
2033 | err = snd_ctl_add(card, snd_soc_cnew(control, codec, | ||
2034 | control->name, | ||
2035 | codec->name_prefix)); | ||
2036 | if (err < 0) { | ||
2037 | dev_err(codec->dev, "%s: Failed to add %s: %d\n", | ||
2038 | codec->name, control->name, err); | ||
2039 | return err; | ||
2040 | } | ||
2041 | } | ||
2042 | 2115 | ||
2043 | return 0; | 2116 | return snd_soc_add_controls(card, codec->dev, controls, num_controls, |
2117 | codec->name_prefix, codec); | ||
2044 | } | 2118 | } |
2045 | EXPORT_SYMBOL_GPL(snd_soc_add_controls); | 2119 | EXPORT_SYMBOL_GPL(snd_soc_add_codec_controls); |
2046 | 2120 | ||
2047 | /** | 2121 | /** |
2048 | * snd_soc_add_platform_controls - add an array of controls to a platform. | 2122 | * snd_soc_add_platform_controls - add an array of controls to a platform. |
2049 | * Convienience function to add a list of controls. | 2123 | * Convenience function to add a list of controls. |
2050 | * | 2124 | * |
2051 | * @platform: platform to add controls to | 2125 | * @platform: platform to add controls to |
2052 | * @controls: array of controls to add | 2126 | * @controls: array of controls to add |
@@ -2058,23 +2132,53 @@ int snd_soc_add_platform_controls(struct snd_soc_platform *platform, | |||
2058 | const struct snd_kcontrol_new *controls, int num_controls) | 2132 | const struct snd_kcontrol_new *controls, int num_controls) |
2059 | { | 2133 | { |
2060 | struct snd_card *card = platform->card->snd_card; | 2134 | struct snd_card *card = platform->card->snd_card; |
2061 | int err, i; | ||
2062 | |||
2063 | for (i = 0; i < num_controls; i++) { | ||
2064 | const struct snd_kcontrol_new *control = &controls[i]; | ||
2065 | err = snd_ctl_add(card, snd_soc_cnew(control, platform, | ||
2066 | control->name, NULL)); | ||
2067 | if (err < 0) { | ||
2068 | dev_err(platform->dev, "Failed to add %s %d\n",control->name, err); | ||
2069 | return err; | ||
2070 | } | ||
2071 | } | ||
2072 | 2135 | ||
2073 | return 0; | 2136 | return snd_soc_add_controls(card, platform->dev, controls, num_controls, |
2137 | NULL, platform); | ||
2074 | } | 2138 | } |
2075 | EXPORT_SYMBOL_GPL(snd_soc_add_platform_controls); | 2139 | EXPORT_SYMBOL_GPL(snd_soc_add_platform_controls); |
2076 | 2140 | ||
2077 | /** | 2141 | /** |
2142 | * snd_soc_add_card_controls - add an array of controls to a SoC card. | ||
2143 | * Convenience function to add a list of controls. | ||
2144 | * | ||
2145 | * @soc_card: SoC card to add controls to | ||
2146 | * @controls: array of controls to add | ||
2147 | * @num_controls: number of elements in the array | ||
2148 | * | ||
2149 | * Return 0 for success, else error. | ||
2150 | */ | ||
2151 | int snd_soc_add_card_controls(struct snd_soc_card *soc_card, | ||
2152 | const struct snd_kcontrol_new *controls, int num_controls) | ||
2153 | { | ||
2154 | struct snd_card *card = soc_card->snd_card; | ||
2155 | |||
2156 | return snd_soc_add_controls(card, soc_card->dev, controls, num_controls, | ||
2157 | NULL, soc_card); | ||
2158 | } | ||
2159 | EXPORT_SYMBOL_GPL(snd_soc_add_card_controls); | ||
2160 | |||
2161 | /** | ||
2162 | * snd_soc_add_dai_controls - add an array of controls to a DAI. | ||
2163 | * Convienience function to add a list of controls. | ||
2164 | * | ||
2165 | * @dai: DAI to add controls to | ||
2166 | * @controls: array of controls to add | ||
2167 | * @num_controls: number of elements in the array | ||
2168 | * | ||
2169 | * Return 0 for success, else error. | ||
2170 | */ | ||
2171 | int snd_soc_add_dai_controls(struct snd_soc_dai *dai, | ||
2172 | const struct snd_kcontrol_new *controls, int num_controls) | ||
2173 | { | ||
2174 | struct snd_card *card = dai->card->snd_card; | ||
2175 | |||
2176 | return snd_soc_add_controls(card, dai->dev, controls, num_controls, | ||
2177 | NULL, dai); | ||
2178 | } | ||
2179 | EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls); | ||
2180 | |||
2181 | /** | ||
2078 | * snd_soc_info_enum_double - enumerated double mixer info callback | 2182 | * snd_soc_info_enum_double - enumerated double mixer info callback |
2079 | * @kcontrol: mixer control | 2183 | * @kcontrol: mixer control |
2080 | * @uinfo: control element information | 2184 | * @uinfo: control element information |
@@ -2640,6 +2744,115 @@ int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol, | |||
2640 | } | 2744 | } |
2641 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx); | 2745 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r_sx); |
2642 | 2746 | ||
2747 | int snd_soc_bytes_info(struct snd_kcontrol *kcontrol, | ||
2748 | struct snd_ctl_elem_info *uinfo) | ||
2749 | { | ||
2750 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2751 | struct soc_bytes *params = (void *)kcontrol->private_value; | ||
2752 | |||
2753 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; | ||
2754 | uinfo->count = params->num_regs * codec->val_bytes; | ||
2755 | |||
2756 | return 0; | ||
2757 | } | ||
2758 | EXPORT_SYMBOL_GPL(snd_soc_bytes_info); | ||
2759 | |||
2760 | int snd_soc_bytes_get(struct snd_kcontrol *kcontrol, | ||
2761 | struct snd_ctl_elem_value *ucontrol) | ||
2762 | { | ||
2763 | struct soc_bytes *params = (void *)kcontrol->private_value; | ||
2764 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2765 | int ret; | ||
2766 | |||
2767 | if (codec->using_regmap) | ||
2768 | ret = regmap_raw_read(codec->control_data, params->base, | ||
2769 | ucontrol->value.bytes.data, | ||
2770 | params->num_regs * codec->val_bytes); | ||
2771 | else | ||
2772 | ret = -EINVAL; | ||
2773 | |||
2774 | /* Hide any masked bytes to ensure consistent data reporting */ | ||
2775 | if (ret == 0 && params->mask) { | ||
2776 | switch (codec->val_bytes) { | ||
2777 | case 1: | ||
2778 | ucontrol->value.bytes.data[0] &= ~params->mask; | ||
2779 | break; | ||
2780 | case 2: | ||
2781 | ((u16 *)(&ucontrol->value.bytes.data))[0] | ||
2782 | &= ~params->mask; | ||
2783 | break; | ||
2784 | case 4: | ||
2785 | ((u32 *)(&ucontrol->value.bytes.data))[0] | ||
2786 | &= ~params->mask; | ||
2787 | break; | ||
2788 | default: | ||
2789 | return -EINVAL; | ||
2790 | } | ||
2791 | } | ||
2792 | |||
2793 | return ret; | ||
2794 | } | ||
2795 | EXPORT_SYMBOL_GPL(snd_soc_bytes_get); | ||
2796 | |||
2797 | int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, | ||
2798 | struct snd_ctl_elem_value *ucontrol) | ||
2799 | { | ||
2800 | struct soc_bytes *params = (void *)kcontrol->private_value; | ||
2801 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2802 | int ret, len; | ||
2803 | unsigned int val; | ||
2804 | void *data; | ||
2805 | |||
2806 | if (!codec->using_regmap) | ||
2807 | return -EINVAL; | ||
2808 | |||
2809 | data = ucontrol->value.bytes.data; | ||
2810 | len = params->num_regs * codec->val_bytes; | ||
2811 | |||
2812 | /* | ||
2813 | * If we've got a mask then we need to preserve the register | ||
2814 | * bits. We shouldn't modify the incoming data so take a | ||
2815 | * copy. | ||
2816 | */ | ||
2817 | if (params->mask) { | ||
2818 | ret = regmap_read(codec->control_data, params->base, &val); | ||
2819 | if (ret != 0) | ||
2820 | return ret; | ||
2821 | |||
2822 | val &= params->mask; | ||
2823 | |||
2824 | data = kmemdup(data, len, GFP_KERNEL); | ||
2825 | if (!data) | ||
2826 | return -ENOMEM; | ||
2827 | |||
2828 | switch (codec->val_bytes) { | ||
2829 | case 1: | ||
2830 | ((u8 *)data)[0] &= ~params->mask; | ||
2831 | ((u8 *)data)[0] |= val; | ||
2832 | break; | ||
2833 | case 2: | ||
2834 | ((u16 *)data)[0] &= cpu_to_be16(~params->mask); | ||
2835 | ((u16 *)data)[0] |= cpu_to_be16(val); | ||
2836 | break; | ||
2837 | case 4: | ||
2838 | ((u32 *)data)[0] &= cpu_to_be32(~params->mask); | ||
2839 | ((u32 *)data)[0] |= cpu_to_be32(val); | ||
2840 | break; | ||
2841 | default: | ||
2842 | return -EINVAL; | ||
2843 | } | ||
2844 | } | ||
2845 | |||
2846 | ret = regmap_raw_write(codec->control_data, params->base, | ||
2847 | data, len); | ||
2848 | |||
2849 | if (params->mask) | ||
2850 | kfree(data); | ||
2851 | |||
2852 | return ret; | ||
2853 | } | ||
2854 | EXPORT_SYMBOL_GPL(snd_soc_bytes_put); | ||
2855 | |||
2643 | /** | 2856 | /** |
2644 | * snd_soc_dai_set_sysclk - configure DAI system or master clock. | 2857 | * snd_soc_dai_set_sysclk - configure DAI system or master clock. |
2645 | * @dai: DAI | 2858 | * @dai: DAI |
@@ -2757,10 +2970,11 @@ EXPORT_SYMBOL_GPL(snd_soc_codec_set_pll); | |||
2757 | */ | 2970 | */ |
2758 | int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | 2971 | int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
2759 | { | 2972 | { |
2760 | if (dai->driver && dai->driver->ops->set_fmt) | 2973 | if (dai->driver == NULL) |
2761 | return dai->driver->ops->set_fmt(dai, fmt); | ||
2762 | else | ||
2763 | return -EINVAL; | 2974 | return -EINVAL; |
2975 | if (dai->driver->ops->set_fmt == NULL) | ||
2976 | return -ENOTSUPP; | ||
2977 | return dai->driver->ops->set_fmt(dai, fmt); | ||
2764 | } | 2978 | } |
2765 | EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); | 2979 | EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); |
2766 | 2980 | ||
@@ -2864,7 +3078,8 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
2864 | */ | 3078 | */ |
2865 | if (!!link->codec_name == !!link->codec_of_node) { | 3079 | if (!!link->codec_name == !!link->codec_of_node) { |
2866 | dev_err(card->dev, | 3080 | dev_err(card->dev, |
2867 | "Neither/both codec name/of_node are set\n"); | 3081 | "Neither/both codec name/of_node are set for %s\n", |
3082 | link->name); | ||
2868 | return -EINVAL; | 3083 | return -EINVAL; |
2869 | } | 3084 | } |
2870 | 3085 | ||
@@ -2874,7 +3089,7 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
2874 | */ | 3089 | */ |
2875 | if (link->platform_name && link->platform_of_node) { | 3090 | if (link->platform_name && link->platform_of_node) { |
2876 | dev_err(card->dev, | 3091 | dev_err(card->dev, |
2877 | "Both platform name/of_node are set\n"); | 3092 | "Both platform name/of_node are set for %s\n", link->name); |
2878 | return -EINVAL; | 3093 | return -EINVAL; |
2879 | } | 3094 | } |
2880 | 3095 | ||
@@ -2884,7 +3099,8 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
2884 | */ | 3099 | */ |
2885 | if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) { | 3100 | if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) { |
2886 | dev_err(card->dev, | 3101 | dev_err(card->dev, |
2887 | "Neither/both cpu_dai name/of_node are set\n"); | 3102 | "Neither/both cpu_dai name/of_node are set for %s\n", |
3103 | link->name); | ||
2888 | return -EINVAL; | 3104 | return -EINVAL; |
2889 | } | 3105 | } |
2890 | } | 3106 | } |
@@ -2895,9 +3111,10 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
2895 | 3111 | ||
2896 | soc_init_card_debugfs(card); | 3112 | soc_init_card_debugfs(card); |
2897 | 3113 | ||
2898 | card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) * | 3114 | card->rtd = devm_kzalloc(card->dev, |
2899 | (card->num_links + card->num_aux_devs), | 3115 | sizeof(struct snd_soc_pcm_runtime) * |
2900 | GFP_KERNEL); | 3116 | (card->num_links + card->num_aux_devs), |
3117 | GFP_KERNEL); | ||
2901 | if (card->rtd == NULL) | 3118 | if (card->rtd == NULL) |
2902 | return -ENOMEM; | 3119 | return -ENOMEM; |
2903 | card->rtd_aux = &card->rtd[card->num_links]; | 3120 | card->rtd_aux = &card->rtd[card->num_links]; |
@@ -2991,7 +3208,7 @@ static inline char *fmt_multiple_name(struct device *dev, | |||
2991 | struct snd_soc_dai_driver *dai_drv) | 3208 | struct snd_soc_dai_driver *dai_drv) |
2992 | { | 3209 | { |
2993 | if (dai_drv->name == NULL) { | 3210 | if (dai_drv->name == NULL) { |
2994 | printk(KERN_ERR "asoc: error - multiple DAI %s registered with no name\n", | 3211 | pr_err("asoc: error - multiple DAI %s registered with no name\n", |
2995 | dev_name(dev)); | 3212 | dev_name(dev)); |
2996 | return NULL; | 3213 | return NULL; |
2997 | } | 3214 | } |
@@ -3166,6 +3383,7 @@ int snd_soc_register_platform(struct device *dev, | |||
3166 | platform->dapm.dev = dev; | 3383 | platform->dapm.dev = dev; |
3167 | platform->dapm.platform = platform; | 3384 | platform->dapm.platform = platform; |
3168 | platform->dapm.stream_event = platform_drv->stream_event; | 3385 | platform->dapm.stream_event = platform_drv->stream_event; |
3386 | mutex_init(&platform->mutex); | ||
3169 | 3387 | ||
3170 | mutex_lock(&client_mutex); | 3388 | mutex_lock(&client_mutex); |
3171 | list_add(&platform->list, &platform_list); | 3389 | list_add(&platform->list, &platform_list); |
@@ -3274,6 +3492,7 @@ int snd_soc_register_codec(struct device *dev, | |||
3274 | codec->volatile_register = codec_drv->volatile_register; | 3492 | codec->volatile_register = codec_drv->volatile_register; |
3275 | codec->readable_register = codec_drv->readable_register; | 3493 | codec->readable_register = codec_drv->readable_register; |
3276 | codec->writable_register = codec_drv->writable_register; | 3494 | codec->writable_register = codec_drv->writable_register; |
3495 | codec->ignore_pmdown_time = codec_drv->ignore_pmdown_time; | ||
3277 | codec->dapm.bias_level = SND_SOC_BIAS_OFF; | 3496 | codec->dapm.bias_level = SND_SOC_BIAS_OFF; |
3278 | codec->dapm.dev = dev; | 3497 | codec->dapm.dev = dev; |
3279 | codec->dapm.codec = codec; | 3498 | codec->dapm.codec = codec; |
@@ -3462,8 +3681,7 @@ static int __init snd_soc_init(void) | |||
3462 | #ifdef CONFIG_DEBUG_FS | 3681 | #ifdef CONFIG_DEBUG_FS |
3463 | snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL); | 3682 | snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL); |
3464 | if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) { | 3683 | if (IS_ERR(snd_soc_debugfs_root) || !snd_soc_debugfs_root) { |
3465 | printk(KERN_WARNING | 3684 | pr_warn("ASoC: Failed to create debugfs directory\n"); |
3466 | "ASoC: Failed to create debugfs directory\n"); | ||
3467 | snd_soc_debugfs_root = NULL; | 3685 | snd_soc_debugfs_root = NULL; |
3468 | } | 3686 | } |
3469 | 3687 | ||
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 1f55ded4047f..6241490fff30 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -14,19 +14,13 @@ | |||
14 | * dynamic configuration of codec internal audio paths and active | 14 | * dynamic configuration of codec internal audio paths and active |
15 | * DACs/ADCs. | 15 | * DACs/ADCs. |
16 | * o Platform power domain - can support external components i.e. amps and | 16 | * o Platform power domain - can support external components i.e. amps and |
17 | * mic/meadphone insertion events. | 17 | * mic/headphone insertion events. |
18 | * o Automatic Mic Bias support | 18 | * o Automatic Mic Bias support |
19 | * o Jack insertion power event initiation - e.g. hp insertion will enable | 19 | * o Jack insertion power event initiation - e.g. hp insertion will enable |
20 | * sinks, dacs, etc | 20 | * sinks, dacs, etc |
21 | * o Delayed powerdown of audio susbsystem to reduce pops between a quick | 21 | * o Delayed power down of audio subsystem to reduce pops between a quick |
22 | * device reopen. | 22 | * device reopen. |
23 | * | 23 | * |
24 | * Todo: | ||
25 | * o DAPM power change sequencing - allow for configurable per | ||
26 | * codec sequences. | ||
27 | * o Support for analogue bias optimisation. | ||
28 | * o Support for reduced codec oversampling rates. | ||
29 | * o Support for reduced codec bias currents. | ||
30 | */ | 24 | */ |
31 | 25 | ||
32 | #include <linux/module.h> | 26 | #include <linux/module.h> |
@@ -40,6 +34,7 @@ | |||
40 | #include <linux/jiffies.h> | 34 | #include <linux/jiffies.h> |
41 | #include <linux/debugfs.h> | 35 | #include <linux/debugfs.h> |
42 | #include <linux/pm_runtime.h> | 36 | #include <linux/pm_runtime.h> |
37 | #include <linux/regulator/consumer.h> | ||
43 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
44 | #include <sound/core.h> | 39 | #include <sound/core.h> |
45 | #include <sound/pcm.h> | 40 | #include <sound/pcm.h> |
@@ -55,7 +50,9 @@ | |||
55 | static int dapm_up_seq[] = { | 50 | static int dapm_up_seq[] = { |
56 | [snd_soc_dapm_pre] = 0, | 51 | [snd_soc_dapm_pre] = 0, |
57 | [snd_soc_dapm_supply] = 1, | 52 | [snd_soc_dapm_supply] = 1, |
53 | [snd_soc_dapm_regulator_supply] = 1, | ||
58 | [snd_soc_dapm_micbias] = 2, | 54 | [snd_soc_dapm_micbias] = 2, |
55 | [snd_soc_dapm_dai] = 3, | ||
59 | [snd_soc_dapm_aif_in] = 3, | 56 | [snd_soc_dapm_aif_in] = 3, |
60 | [snd_soc_dapm_aif_out] = 3, | 57 | [snd_soc_dapm_aif_out] = 3, |
61 | [snd_soc_dapm_mic] = 4, | 58 | [snd_soc_dapm_mic] = 4, |
@@ -90,6 +87,8 @@ static int dapm_down_seq[] = { | |||
90 | [snd_soc_dapm_value_mux] = 9, | 87 | [snd_soc_dapm_value_mux] = 9, |
91 | [snd_soc_dapm_aif_in] = 10, | 88 | [snd_soc_dapm_aif_in] = 10, |
92 | [snd_soc_dapm_aif_out] = 10, | 89 | [snd_soc_dapm_aif_out] = 10, |
90 | [snd_soc_dapm_dai] = 10, | ||
91 | [snd_soc_dapm_regulator_supply] = 11, | ||
93 | [snd_soc_dapm_supply] = 11, | 92 | [snd_soc_dapm_supply] = 11, |
94 | [snd_soc_dapm_post] = 12, | 93 | [snd_soc_dapm_post] = 12, |
95 | }; | 94 | }; |
@@ -172,6 +171,19 @@ static inline struct snd_soc_card *dapm_get_soc_card( | |||
172 | return NULL; | 171 | return NULL; |
173 | } | 172 | } |
174 | 173 | ||
174 | static void dapm_reset(struct snd_soc_card *card) | ||
175 | { | ||
176 | struct snd_soc_dapm_widget *w; | ||
177 | |||
178 | memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); | ||
179 | |||
180 | list_for_each_entry(w, &card->widgets, list) { | ||
181 | w->power_checked = false; | ||
182 | w->inputs = -1; | ||
183 | w->outputs = -1; | ||
184 | } | ||
185 | } | ||
186 | |||
175 | static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg) | 187 | static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg) |
176 | { | 188 | { |
177 | if (w->codec) | 189 | if (w->codec) |
@@ -197,21 +209,28 @@ static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val) | |||
197 | static int soc_widget_update_bits(struct snd_soc_dapm_widget *w, | 209 | static int soc_widget_update_bits(struct snd_soc_dapm_widget *w, |
198 | unsigned short reg, unsigned int mask, unsigned int value) | 210 | unsigned short reg, unsigned int mask, unsigned int value) |
199 | { | 211 | { |
200 | int change; | 212 | bool change; |
201 | unsigned int old, new; | 213 | unsigned int old, new; |
202 | int ret; | 214 | int ret; |
203 | 215 | ||
204 | ret = soc_widget_read(w, reg); | 216 | if (w->codec && w->codec->using_regmap) { |
205 | if (ret < 0) | 217 | ret = regmap_update_bits_check(w->codec->control_data, |
206 | return ret; | 218 | reg, mask, value, &change); |
207 | 219 | if (ret != 0) | |
208 | old = ret; | 220 | return ret; |
209 | new = (old & ~mask) | (value & mask); | 221 | } else { |
210 | change = old != new; | 222 | ret = soc_widget_read(w, reg); |
211 | if (change) { | ||
212 | ret = soc_widget_write(w, reg, new); | ||
213 | if (ret < 0) | 223 | if (ret < 0) |
214 | return ret; | 224 | return ret; |
225 | |||
226 | old = ret; | ||
227 | new = (old & ~mask) | (value & mask); | ||
228 | change = old != new; | ||
229 | if (change) { | ||
230 | ret = soc_widget_write(w, reg, new); | ||
231 | if (ret < 0) | ||
232 | return ret; | ||
233 | } | ||
215 | } | 234 | } |
216 | 235 | ||
217 | return change; | 236 | return change; |
@@ -345,8 +364,10 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, | |||
345 | case snd_soc_dapm_micbias: | 364 | case snd_soc_dapm_micbias: |
346 | case snd_soc_dapm_vmid: | 365 | case snd_soc_dapm_vmid: |
347 | case snd_soc_dapm_supply: | 366 | case snd_soc_dapm_supply: |
367 | case snd_soc_dapm_regulator_supply: | ||
348 | case snd_soc_dapm_aif_in: | 368 | case snd_soc_dapm_aif_in: |
349 | case snd_soc_dapm_aif_out: | 369 | case snd_soc_dapm_aif_out: |
370 | case snd_soc_dapm_dai: | ||
350 | case snd_soc_dapm_hp: | 371 | case snd_soc_dapm_hp: |
351 | case snd_soc_dapm_mic: | 372 | case snd_soc_dapm_mic: |
352 | case snd_soc_dapm_spk: | 373 | case snd_soc_dapm_spk: |
@@ -504,17 +525,17 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w) | |||
504 | * for widgets so cut the prefix off | 525 | * for widgets so cut the prefix off |
505 | * the front of the widget name. | 526 | * the front of the widget name. |
506 | */ | 527 | */ |
507 | snprintf(path->long_name, name_len, "%s %s", | 528 | snprintf((char *)path->long_name, name_len, |
508 | w->name + prefix_len, | 529 | "%s %s", w->name + prefix_len, |
509 | w->kcontrol_news[i].name); | 530 | w->kcontrol_news[i].name); |
510 | break; | 531 | break; |
511 | case snd_soc_dapm_mixer_named_ctl: | 532 | case snd_soc_dapm_mixer_named_ctl: |
512 | snprintf(path->long_name, name_len, "%s", | 533 | snprintf((char *)path->long_name, name_len, |
513 | w->kcontrol_news[i].name); | 534 | "%s", w->kcontrol_news[i].name); |
514 | break; | 535 | break; |
515 | } | 536 | } |
516 | 537 | ||
517 | path->long_name[name_len - 1] = '\0'; | 538 | ((char *)path->long_name)[name_len - 1] = '\0'; |
518 | 539 | ||
519 | path->kcontrol = snd_soc_cnew(&w->kcontrol_news[i], | 540 | path->kcontrol = snd_soc_cnew(&w->kcontrol_news[i], |
520 | wlist, path->long_name, | 541 | wlist, path->long_name, |
@@ -548,7 +569,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) | |||
548 | struct snd_soc_dapm_widget_list *wlist; | 569 | struct snd_soc_dapm_widget_list *wlist; |
549 | int shared, wlistentries; | 570 | int shared, wlistentries; |
550 | size_t wlistsize; | 571 | size_t wlistsize; |
551 | char *name; | 572 | const char *name; |
552 | 573 | ||
553 | if (w->num_kcontrols != 1) { | 574 | if (w->num_kcontrols != 1) { |
554 | dev_err(dapm->dev, | 575 | dev_err(dapm->dev, |
@@ -673,12 +694,18 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget) | |||
673 | 694 | ||
674 | DAPM_UPDATE_STAT(widget, path_checks); | 695 | DAPM_UPDATE_STAT(widget, path_checks); |
675 | 696 | ||
676 | if (widget->id == snd_soc_dapm_supply) | 697 | switch (widget->id) { |
698 | case snd_soc_dapm_supply: | ||
699 | case snd_soc_dapm_regulator_supply: | ||
677 | return 0; | 700 | return 0; |
701 | default: | ||
702 | break; | ||
703 | } | ||
678 | 704 | ||
679 | switch (widget->id) { | 705 | switch (widget->id) { |
680 | case snd_soc_dapm_adc: | 706 | case snd_soc_dapm_adc: |
681 | case snd_soc_dapm_aif_out: | 707 | case snd_soc_dapm_aif_out: |
708 | case snd_soc_dapm_dai: | ||
682 | if (widget->active) { | 709 | if (widget->active) { |
683 | widget->outputs = snd_soc_dapm_suspend_check(widget); | 710 | widget->outputs = snd_soc_dapm_suspend_check(widget); |
684 | return widget->outputs; | 711 | return widget->outputs; |
@@ -738,13 +765,19 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) | |||
738 | 765 | ||
739 | DAPM_UPDATE_STAT(widget, path_checks); | 766 | DAPM_UPDATE_STAT(widget, path_checks); |
740 | 767 | ||
741 | if (widget->id == snd_soc_dapm_supply) | 768 | switch (widget->id) { |
769 | case snd_soc_dapm_supply: | ||
770 | case snd_soc_dapm_regulator_supply: | ||
742 | return 0; | 771 | return 0; |
772 | default: | ||
773 | break; | ||
774 | } | ||
743 | 775 | ||
744 | /* active stream ? */ | 776 | /* active stream ? */ |
745 | switch (widget->id) { | 777 | switch (widget->id) { |
746 | case snd_soc_dapm_dac: | 778 | case snd_soc_dapm_dac: |
747 | case snd_soc_dapm_aif_in: | 779 | case snd_soc_dapm_aif_in: |
780 | case snd_soc_dapm_dai: | ||
748 | if (widget->active) { | 781 | if (widget->active) { |
749 | widget->inputs = snd_soc_dapm_suspend_check(widget); | 782 | widget->inputs = snd_soc_dapm_suspend_check(widget); |
750 | return widget->inputs; | 783 | return widget->inputs; |
@@ -821,6 +854,19 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w, | |||
821 | } | 854 | } |
822 | EXPORT_SYMBOL_GPL(dapm_reg_event); | 855 | EXPORT_SYMBOL_GPL(dapm_reg_event); |
823 | 856 | ||
857 | /* | ||
858 | * Handler for regulator supply widget. | ||
859 | */ | ||
860 | int dapm_regulator_event(struct snd_soc_dapm_widget *w, | ||
861 | struct snd_kcontrol *kcontrol, int event) | ||
862 | { | ||
863 | if (SND_SOC_DAPM_EVENT_ON(event)) | ||
864 | return regulator_enable(w->priv); | ||
865 | else | ||
866 | return regulator_disable_deferred(w->priv, w->shift); | ||
867 | } | ||
868 | EXPORT_SYMBOL_GPL(dapm_regulator_event); | ||
869 | |||
824 | static int dapm_widget_power_check(struct snd_soc_dapm_widget *w) | 870 | static int dapm_widget_power_check(struct snd_soc_dapm_widget *w) |
825 | { | 871 | { |
826 | if (w->power_checked) | 872 | if (w->power_checked) |
@@ -851,6 +897,13 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) | |||
851 | return out != 0 && in != 0; | 897 | return out != 0 && in != 0; |
852 | } | 898 | } |
853 | 899 | ||
900 | static int dapm_dai_check_power(struct snd_soc_dapm_widget *w) | ||
901 | { | ||
902 | DAPM_UPDATE_STAT(w, power_checks); | ||
903 | |||
904 | return w->active; | ||
905 | } | ||
906 | |||
854 | /* Check to see if an ADC has power */ | 907 | /* Check to see if an ADC has power */ |
855 | static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) | 908 | static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) |
856 | { | 909 | { |
@@ -1251,7 +1304,7 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) | |||
1251 | dev_err(d->dev, "Failed to turn off bias: %d\n", ret); | 1304 | dev_err(d->dev, "Failed to turn off bias: %d\n", ret); |
1252 | 1305 | ||
1253 | if (d->dev) | 1306 | if (d->dev) |
1254 | pm_runtime_put_sync(d->dev); | 1307 | pm_runtime_put(d->dev); |
1255 | } | 1308 | } |
1256 | 1309 | ||
1257 | /* If we just powered up then move to active bias */ | 1310 | /* If we just powered up then move to active bias */ |
@@ -1301,6 +1354,7 @@ static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power, | |||
1301 | } | 1354 | } |
1302 | switch (w->id) { | 1355 | switch (w->id) { |
1303 | case snd_soc_dapm_supply: | 1356 | case snd_soc_dapm_supply: |
1357 | case snd_soc_dapm_regulator_supply: | ||
1304 | /* Supplies can't affect their outputs, only their inputs */ | 1358 | /* Supplies can't affect their outputs, only their inputs */ |
1305 | break; | 1359 | break; |
1306 | default: | 1360 | default: |
@@ -1373,13 +1427,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) | |||
1373 | } | 1427 | } |
1374 | } | 1428 | } |
1375 | 1429 | ||
1376 | memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); | 1430 | dapm_reset(card); |
1377 | |||
1378 | list_for_each_entry(w, &card->widgets, list) { | ||
1379 | w->power_checked = false; | ||
1380 | w->inputs = -1; | ||
1381 | w->outputs = -1; | ||
1382 | } | ||
1383 | 1431 | ||
1384 | /* Check which widgets we need to power and store them in | 1432 | /* Check which widgets we need to power and store them in |
1385 | * lists indicating if they should be powered up or down. We | 1433 | * lists indicating if they should be powered up or down. We |
@@ -1400,10 +1448,15 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) | |||
1400 | /* Supplies and micbiases only bring the | 1448 | /* Supplies and micbiases only bring the |
1401 | * context up to STANDBY as unless something | 1449 | * context up to STANDBY as unless something |
1402 | * else is active and passing audio they | 1450 | * else is active and passing audio they |
1403 | * generally don't require full power. | 1451 | * generally don't require full power. Signal |
1452 | * generators are virtual pins and have no | ||
1453 | * power impact themselves. | ||
1404 | */ | 1454 | */ |
1405 | switch (w->id) { | 1455 | switch (w->id) { |
1456 | case snd_soc_dapm_siggen: | ||
1457 | break; | ||
1406 | case snd_soc_dapm_supply: | 1458 | case snd_soc_dapm_supply: |
1459 | case snd_soc_dapm_regulator_supply: | ||
1407 | case snd_soc_dapm_micbias: | 1460 | case snd_soc_dapm_micbias: |
1408 | if (d->target_bias_level < SND_SOC_BIAS_STANDBY) | 1461 | if (d->target_bias_level < SND_SOC_BIAS_STANDBY) |
1409 | d->target_bias_level = SND_SOC_BIAS_STANDBY; | 1462 | d->target_bias_level = SND_SOC_BIAS_STANDBY; |
@@ -1475,6 +1528,12 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) | |||
1475 | &async_domain); | 1528 | &async_domain); |
1476 | async_synchronize_full_domain(&async_domain); | 1529 | async_synchronize_full_domain(&async_domain); |
1477 | 1530 | ||
1531 | /* do we need to notify any clients that DAPM event is complete */ | ||
1532 | list_for_each_entry(d, &card->dapm_list, list) { | ||
1533 | if (d->stream_event) | ||
1534 | d->stream_event(d, event); | ||
1535 | } | ||
1536 | |||
1478 | pop_dbg(dapm->dev, card->pop_time, | 1537 | pop_dbg(dapm->dev, card->pop_time, |
1479 | "DAPM sequencing finished, waiting %dms\n", card->pop_time); | 1538 | "DAPM sequencing finished, waiting %dms\n", card->pop_time); |
1480 | pop_wait(card->pop_time); | 1539 | pop_wait(card->pop_time); |
@@ -1510,8 +1569,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file, | |||
1510 | out = is_connected_output_ep(w); | 1569 | out = is_connected_output_ep(w); |
1511 | dapm_clear_walk(w->dapm); | 1570 | dapm_clear_walk(w->dapm); |
1512 | 1571 | ||
1513 | ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d", | 1572 | ret = snprintf(buf, PAGE_SIZE, "%s: %s%s in %d out %d", |
1514 | w->name, w->power ? "On" : "Off", in, out); | 1573 | w->name, w->power ? "On" : "Off", |
1574 | w->force ? " (forced)" : "", in, out); | ||
1515 | 1575 | ||
1516 | if (w->reg >= 0) | 1576 | if (w->reg >= 0) |
1517 | ret += snprintf(buf + ret, PAGE_SIZE - ret, | 1577 | ret += snprintf(buf + ret, PAGE_SIZE - ret, |
@@ -1607,7 +1667,7 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm, | |||
1607 | dapm->debugfs_dapm = debugfs_create_dir("dapm", parent); | 1667 | dapm->debugfs_dapm = debugfs_create_dir("dapm", parent); |
1608 | 1668 | ||
1609 | if (!dapm->debugfs_dapm) { | 1669 | if (!dapm->debugfs_dapm) { |
1610 | printk(KERN_WARNING | 1670 | dev_warn(dapm->dev, |
1611 | "Failed to create DAPM debugfs directory\n"); | 1671 | "Failed to create DAPM debugfs directory\n"); |
1612 | return; | 1672 | return; |
1613 | } | 1673 | } |
@@ -1659,9 +1719,8 @@ static inline void dapm_debugfs_cleanup(struct snd_soc_dapm_context *dapm) | |||
1659 | #endif | 1719 | #endif |
1660 | 1720 | ||
1661 | /* test and update the power status of a mux widget */ | 1721 | /* test and update the power status of a mux widget */ |
1662 | static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, | 1722 | int snd_soc_dapm_mux_update_power(struct snd_soc_dapm_widget *widget, |
1663 | struct snd_kcontrol *kcontrol, int change, | 1723 | struct snd_kcontrol *kcontrol, int mux, struct soc_enum *e) |
1664 | int mux, struct soc_enum *e) | ||
1665 | { | 1724 | { |
1666 | struct snd_soc_dapm_path *path; | 1725 | struct snd_soc_dapm_path *path; |
1667 | int found = 0; | 1726 | int found = 0; |
@@ -1671,9 +1730,6 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, | |||
1671 | widget->id != snd_soc_dapm_value_mux) | 1730 | widget->id != snd_soc_dapm_value_mux) |
1672 | return -ENODEV; | 1731 | return -ENODEV; |
1673 | 1732 | ||
1674 | if (!change) | ||
1675 | return 0; | ||
1676 | |||
1677 | /* find dapm widget path assoc with kcontrol */ | 1733 | /* find dapm widget path assoc with kcontrol */ |
1678 | list_for_each_entry(path, &widget->dapm->card->paths, list) { | 1734 | list_for_each_entry(path, &widget->dapm->card->paths, list) { |
1679 | if (path->kcontrol != kcontrol) | 1735 | if (path->kcontrol != kcontrol) |
@@ -1702,9 +1758,10 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, | |||
1702 | 1758 | ||
1703 | return 0; | 1759 | return 0; |
1704 | } | 1760 | } |
1761 | EXPORT_SYMBOL_GPL(snd_soc_dapm_mux_update_power); | ||
1705 | 1762 | ||
1706 | /* test and update the power status of a mixer or switch widget */ | 1763 | /* test and update the power status of a mixer or switch widget */ |
1707 | static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, | 1764 | int snd_soc_dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, |
1708 | struct snd_kcontrol *kcontrol, int connect) | 1765 | struct snd_kcontrol *kcontrol, int connect) |
1709 | { | 1766 | { |
1710 | struct snd_soc_dapm_path *path; | 1767 | struct snd_soc_dapm_path *path; |
@@ -1733,6 +1790,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, | |||
1733 | 1790 | ||
1734 | return 0; | 1791 | return 0; |
1735 | } | 1792 | } |
1793 | EXPORT_SYMBOL_GPL(snd_soc_dapm_mixer_update_power); | ||
1736 | 1794 | ||
1737 | /* show dapm widget status in sys fs */ | 1795 | /* show dapm widget status in sys fs */ |
1738 | static ssize_t dapm_widget_show(struct device *dev, | 1796 | static ssize_t dapm_widget_show(struct device *dev, |
@@ -1762,6 +1820,7 @@ static ssize_t dapm_widget_show(struct device *dev, | |||
1762 | case snd_soc_dapm_mixer: | 1820 | case snd_soc_dapm_mixer: |
1763 | case snd_soc_dapm_mixer_named_ctl: | 1821 | case snd_soc_dapm_mixer_named_ctl: |
1764 | case snd_soc_dapm_supply: | 1822 | case snd_soc_dapm_supply: |
1823 | case snd_soc_dapm_regulator_supply: | ||
1765 | if (w->name) | 1824 | if (w->name) |
1766 | count += sprintf(buf + count, "%s: %s\n", | 1825 | count += sprintf(buf + count, "%s: %s\n", |
1767 | w->name, w->power ? "On":"Off"); | 1826 | w->name, w->power ? "On":"Off"); |
@@ -1869,10 +1928,12 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, | |||
1869 | return -EINVAL; | 1928 | return -EINVAL; |
1870 | } | 1929 | } |
1871 | 1930 | ||
1931 | if (w->connected != status) | ||
1932 | dapm_mark_dirty(w, "pin configuration"); | ||
1933 | |||
1872 | w->connected = status; | 1934 | w->connected = status; |
1873 | if (status == 0) | 1935 | if (status == 0) |
1874 | w->force = 0; | 1936 | w->force = 0; |
1875 | dapm_mark_dirty(w, "pin configuration"); | ||
1876 | 1937 | ||
1877 | return 0; | 1938 | return 0; |
1878 | } | 1939 | } |
@@ -2000,8 +2061,10 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, | |||
2000 | case snd_soc_dapm_pre: | 2061 | case snd_soc_dapm_pre: |
2001 | case snd_soc_dapm_post: | 2062 | case snd_soc_dapm_post: |
2002 | case snd_soc_dapm_supply: | 2063 | case snd_soc_dapm_supply: |
2064 | case snd_soc_dapm_regulator_supply: | ||
2003 | case snd_soc_dapm_aif_in: | 2065 | case snd_soc_dapm_aif_in: |
2004 | case snd_soc_dapm_aif_out: | 2066 | case snd_soc_dapm_aif_out: |
2067 | case snd_soc_dapm_dai: | ||
2005 | list_add(&path->list, &dapm->card->paths); | 2068 | list_add(&path->list, &dapm->card->paths); |
2006 | list_add(&path->list_sink, &wsink->sources); | 2069 | list_add(&path->list_sink, &wsink->sources); |
2007 | list_add(&path->list_source, &wsource->sinks); | 2070 | list_add(&path->list_source, &wsource->sinks); |
@@ -2315,7 +2378,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, | |||
2315 | update.val = val; | 2378 | update.val = val; |
2316 | widget->dapm->update = &update; | 2379 | widget->dapm->update = &update; |
2317 | 2380 | ||
2318 | dapm_mixer_update_power(widget, kcontrol, connect); | 2381 | snd_soc_dapm_mixer_update_power(widget, kcontrol, connect); |
2319 | 2382 | ||
2320 | widget->dapm->update = NULL; | 2383 | widget->dapm->update = NULL; |
2321 | } | 2384 | } |
@@ -2406,7 +2469,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, | |||
2406 | update.val = val; | 2469 | update.val = val; |
2407 | widget->dapm->update = &update; | 2470 | widget->dapm->update = &update; |
2408 | 2471 | ||
2409 | dapm_mux_update_power(widget, kcontrol, change, mux, e); | 2472 | snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e); |
2410 | 2473 | ||
2411 | widget->dapm->update = NULL; | 2474 | widget->dapm->update = NULL; |
2412 | } | 2475 | } |
@@ -2467,8 +2530,7 @@ int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol, | |||
2467 | 2530 | ||
2468 | widget->value = ucontrol->value.enumerated.item[0]; | 2531 | widget->value = ucontrol->value.enumerated.item[0]; |
2469 | 2532 | ||
2470 | dapm_mux_update_power(widget, kcontrol, change, | 2533 | snd_soc_dapm_mux_update_power(widget, kcontrol, widget->value, e); |
2471 | widget->value, e); | ||
2472 | } | 2534 | } |
2473 | } | 2535 | } |
2474 | 2536 | ||
@@ -2571,7 +2633,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, | |||
2571 | update.val = val; | 2633 | update.val = val; |
2572 | widget->dapm->update = &update; | 2634 | widget->dapm->update = &update; |
2573 | 2635 | ||
2574 | dapm_mux_update_power(widget, kcontrol, change, mux, e); | 2636 | snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e); |
2575 | 2637 | ||
2576 | widget->dapm->update = NULL; | 2638 | widget->dapm->update = NULL; |
2577 | } | 2639 | } |
@@ -2611,15 +2673,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch); | |||
2611 | int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, | 2673 | int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, |
2612 | struct snd_ctl_elem_value *ucontrol) | 2674 | struct snd_ctl_elem_value *ucontrol) |
2613 | { | 2675 | { |
2614 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2676 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
2615 | const char *pin = (const char *)kcontrol->private_value; | 2677 | const char *pin = (const char *)kcontrol->private_value; |
2616 | 2678 | ||
2617 | mutex_lock(&codec->mutex); | 2679 | mutex_lock(&card->mutex); |
2618 | 2680 | ||
2619 | ucontrol->value.integer.value[0] = | 2681 | ucontrol->value.integer.value[0] = |
2620 | snd_soc_dapm_get_pin_status(&codec->dapm, pin); | 2682 | snd_soc_dapm_get_pin_status(&card->dapm, pin); |
2621 | 2683 | ||
2622 | mutex_unlock(&codec->mutex); | 2684 | mutex_unlock(&card->mutex); |
2623 | 2685 | ||
2624 | return 0; | 2686 | return 0; |
2625 | } | 2687 | } |
@@ -2634,41 +2696,48 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch); | |||
2634 | int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, | 2696 | int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, |
2635 | struct snd_ctl_elem_value *ucontrol) | 2697 | struct snd_ctl_elem_value *ucontrol) |
2636 | { | 2698 | { |
2637 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2699 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
2638 | const char *pin = (const char *)kcontrol->private_value; | 2700 | const char *pin = (const char *)kcontrol->private_value; |
2639 | 2701 | ||
2640 | mutex_lock(&codec->mutex); | 2702 | mutex_lock(&card->mutex); |
2641 | 2703 | ||
2642 | if (ucontrol->value.integer.value[0]) | 2704 | if (ucontrol->value.integer.value[0]) |
2643 | snd_soc_dapm_enable_pin(&codec->dapm, pin); | 2705 | snd_soc_dapm_enable_pin(&card->dapm, pin); |
2644 | else | 2706 | else |
2645 | snd_soc_dapm_disable_pin(&codec->dapm, pin); | 2707 | snd_soc_dapm_disable_pin(&card->dapm, pin); |
2646 | 2708 | ||
2647 | snd_soc_dapm_sync(&codec->dapm); | 2709 | snd_soc_dapm_sync(&card->dapm); |
2648 | 2710 | ||
2649 | mutex_unlock(&codec->mutex); | 2711 | mutex_unlock(&card->mutex); |
2650 | 2712 | ||
2651 | return 0; | 2713 | return 0; |
2652 | } | 2714 | } |
2653 | EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); | 2715 | EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); |
2654 | 2716 | ||
2655 | /** | 2717 | static struct snd_soc_dapm_widget * |
2656 | * snd_soc_dapm_new_control - create new dapm control | 2718 | snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, |
2657 | * @dapm: DAPM context | 2719 | const struct snd_soc_dapm_widget *widget) |
2658 | * @widget: widget template | ||
2659 | * | ||
2660 | * Creates a new dapm control based upon the template. | ||
2661 | * | ||
2662 | * Returns 0 for success else error. | ||
2663 | */ | ||
2664 | int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | ||
2665 | const struct snd_soc_dapm_widget *widget) | ||
2666 | { | 2720 | { |
2667 | struct snd_soc_dapm_widget *w; | 2721 | struct snd_soc_dapm_widget *w; |
2668 | size_t name_len; | 2722 | size_t name_len; |
2723 | int ret; | ||
2669 | 2724 | ||
2670 | if ((w = dapm_cnew_widget(widget)) == NULL) | 2725 | if ((w = dapm_cnew_widget(widget)) == NULL) |
2671 | return -ENOMEM; | 2726 | return NULL; |
2727 | |||
2728 | switch (w->id) { | ||
2729 | case snd_soc_dapm_regulator_supply: | ||
2730 | w->priv = devm_regulator_get(dapm->dev, w->name); | ||
2731 | if (IS_ERR(w->priv)) { | ||
2732 | ret = PTR_ERR(w->priv); | ||
2733 | dev_err(dapm->dev, "Failed to request %s: %d\n", | ||
2734 | w->name, ret); | ||
2735 | return NULL; | ||
2736 | } | ||
2737 | break; | ||
2738 | default: | ||
2739 | break; | ||
2740 | } | ||
2672 | 2741 | ||
2673 | name_len = strlen(widget->name) + 1; | 2742 | name_len = strlen(widget->name) + 1; |
2674 | if (dapm->codec && dapm->codec->name_prefix) | 2743 | if (dapm->codec && dapm->codec->name_prefix) |
@@ -2676,13 +2745,13 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
2676 | w->name = kmalloc(name_len, GFP_KERNEL); | 2745 | w->name = kmalloc(name_len, GFP_KERNEL); |
2677 | if (w->name == NULL) { | 2746 | if (w->name == NULL) { |
2678 | kfree(w); | 2747 | kfree(w); |
2679 | return -ENOMEM; | 2748 | return NULL; |
2680 | } | 2749 | } |
2681 | if (dapm->codec && dapm->codec->name_prefix) | 2750 | if (dapm->codec && dapm->codec->name_prefix) |
2682 | snprintf(w->name, name_len, "%s %s", | 2751 | snprintf((char *)w->name, name_len, "%s %s", |
2683 | dapm->codec->name_prefix, widget->name); | 2752 | dapm->codec->name_prefix, widget->name); |
2684 | else | 2753 | else |
2685 | snprintf(w->name, name_len, "%s", widget->name); | 2754 | snprintf((char *)w->name, name_len, "%s", widget->name); |
2686 | 2755 | ||
2687 | switch (w->id) { | 2756 | switch (w->id) { |
2688 | case snd_soc_dapm_switch: | 2757 | case snd_soc_dapm_switch: |
@@ -2715,8 +2784,12 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
2715 | w->power_check = dapm_generic_check_power; | 2784 | w->power_check = dapm_generic_check_power; |
2716 | break; | 2785 | break; |
2717 | case snd_soc_dapm_supply: | 2786 | case snd_soc_dapm_supply: |
2787 | case snd_soc_dapm_regulator_supply: | ||
2718 | w->power_check = dapm_supply_check_power; | 2788 | w->power_check = dapm_supply_check_power; |
2719 | break; | 2789 | break; |
2790 | case snd_soc_dapm_dai: | ||
2791 | w->power_check = dapm_dai_check_power; | ||
2792 | break; | ||
2720 | default: | 2793 | default: |
2721 | w->power_check = dapm_always_on_check_power; | 2794 | w->power_check = dapm_always_on_check_power; |
2722 | break; | 2795 | break; |
@@ -2734,9 +2807,8 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
2734 | 2807 | ||
2735 | /* machine layer set ups unconnected pins and insertions */ | 2808 | /* machine layer set ups unconnected pins and insertions */ |
2736 | w->connected = 1; | 2809 | w->connected = 1; |
2737 | return 0; | 2810 | return w; |
2738 | } | 2811 | } |
2739 | EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control); | ||
2740 | 2812 | ||
2741 | /** | 2813 | /** |
2742 | * snd_soc_dapm_new_controls - create new dapm controls | 2814 | * snd_soc_dapm_new_controls - create new dapm controls |
@@ -2752,15 +2824,16 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, | |||
2752 | const struct snd_soc_dapm_widget *widget, | 2824 | const struct snd_soc_dapm_widget *widget, |
2753 | int num) | 2825 | int num) |
2754 | { | 2826 | { |
2755 | int i, ret; | 2827 | struct snd_soc_dapm_widget *w; |
2828 | int i; | ||
2756 | 2829 | ||
2757 | for (i = 0; i < num; i++) { | 2830 | for (i = 0; i < num; i++) { |
2758 | ret = snd_soc_dapm_new_control(dapm, widget); | 2831 | w = snd_soc_dapm_new_control(dapm, widget); |
2759 | if (ret < 0) { | 2832 | if (!w) { |
2760 | dev_err(dapm->dev, | 2833 | dev_err(dapm->dev, |
2761 | "ASoC: Failed to create DAPM control %s: %d\n", | 2834 | "ASoC: Failed to create DAPM control %s\n", |
2762 | widget->name, ret); | 2835 | widget->name); |
2763 | return ret; | 2836 | return -ENOMEM; |
2764 | } | 2837 | } |
2765 | widget++; | 2838 | widget++; |
2766 | } | 2839 | } |
@@ -2768,40 +2841,140 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, | |||
2768 | } | 2841 | } |
2769 | EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); | 2842 | EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); |
2770 | 2843 | ||
2771 | static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm, | 2844 | int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, |
2772 | const char *stream, int event) | 2845 | struct snd_soc_dai *dai) |
2773 | { | 2846 | { |
2847 | struct snd_soc_dapm_widget template; | ||
2774 | struct snd_soc_dapm_widget *w; | 2848 | struct snd_soc_dapm_widget *w; |
2775 | 2849 | ||
2776 | list_for_each_entry(w, &dapm->card->widgets, list) | 2850 | WARN_ON(dapm->dev != dai->dev); |
2777 | { | 2851 | |
2778 | if (!w->sname || w->dapm != dapm) | 2852 | memset(&template, 0, sizeof(template)); |
2853 | template.reg = SND_SOC_NOPM; | ||
2854 | |||
2855 | if (dai->driver->playback.stream_name) { | ||
2856 | template.id = snd_soc_dapm_dai; | ||
2857 | template.name = dai->driver->playback.stream_name; | ||
2858 | template.sname = dai->driver->playback.stream_name; | ||
2859 | |||
2860 | dev_dbg(dai->dev, "adding %s widget\n", | ||
2861 | template.name); | ||
2862 | |||
2863 | w = snd_soc_dapm_new_control(dapm, &template); | ||
2864 | if (!w) { | ||
2865 | dev_err(dapm->dev, "Failed to create %s widget\n", | ||
2866 | dai->driver->playback.stream_name); | ||
2867 | } | ||
2868 | |||
2869 | w->priv = dai; | ||
2870 | dai->playback_widget = w; | ||
2871 | } | ||
2872 | |||
2873 | if (dai->driver->capture.stream_name) { | ||
2874 | template.id = snd_soc_dapm_dai; | ||
2875 | template.name = dai->driver->capture.stream_name; | ||
2876 | template.sname = dai->driver->capture.stream_name; | ||
2877 | |||
2878 | dev_dbg(dai->dev, "adding %s widget\n", | ||
2879 | template.name); | ||
2880 | |||
2881 | w = snd_soc_dapm_new_control(dapm, &template); | ||
2882 | if (!w) { | ||
2883 | dev_err(dapm->dev, "Failed to create %s widget\n", | ||
2884 | dai->driver->capture.stream_name); | ||
2885 | } | ||
2886 | |||
2887 | w->priv = dai; | ||
2888 | dai->capture_widget = w; | ||
2889 | } | ||
2890 | |||
2891 | return 0; | ||
2892 | } | ||
2893 | |||
2894 | int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card) | ||
2895 | { | ||
2896 | struct snd_soc_dapm_widget *dai_w, *w; | ||
2897 | struct snd_soc_dai *dai; | ||
2898 | struct snd_soc_dapm_route r; | ||
2899 | |||
2900 | memset(&r, 0, sizeof(r)); | ||
2901 | |||
2902 | /* For each DAI widget... */ | ||
2903 | list_for_each_entry(dai_w, &card->widgets, list) { | ||
2904 | if (dai_w->id != snd_soc_dapm_dai) | ||
2779 | continue; | 2905 | continue; |
2780 | dev_vdbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n", | 2906 | |
2781 | w->name, w->sname, stream, event); | 2907 | dai = dai_w->priv; |
2782 | if (strstr(w->sname, stream)) { | 2908 | |
2783 | dapm_mark_dirty(w, "stream event"); | 2909 | /* ...find all widgets with the same stream and link them */ |
2784 | switch(event) { | 2910 | list_for_each_entry(w, &card->widgets, list) { |
2785 | case SND_SOC_DAPM_STREAM_START: | 2911 | if (w->dapm != dai_w->dapm) |
2786 | w->active = 1; | 2912 | continue; |
2787 | break; | 2913 | |
2788 | case SND_SOC_DAPM_STREAM_STOP: | 2914 | if (w->id == snd_soc_dapm_dai) |
2789 | w->active = 0; | 2915 | continue; |
2790 | break; | 2916 | |
2791 | case SND_SOC_DAPM_STREAM_SUSPEND: | 2917 | if (!w->sname) |
2792 | case SND_SOC_DAPM_STREAM_RESUME: | 2918 | continue; |
2793 | case SND_SOC_DAPM_STREAM_PAUSE_PUSH: | 2919 | |
2794 | case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: | 2920 | if (dai->driver->playback.stream_name && |
2795 | break; | 2921 | strstr(w->sname, |
2922 | dai->driver->playback.stream_name)) { | ||
2923 | r.source = dai->playback_widget->name; | ||
2924 | r.sink = w->name; | ||
2925 | dev_dbg(dai->dev, "%s -> %s\n", | ||
2926 | r.source, r.sink); | ||
2927 | |||
2928 | snd_soc_dapm_add_route(w->dapm, &r); | ||
2929 | } | ||
2930 | |||
2931 | if (dai->driver->capture.stream_name && | ||
2932 | strstr(w->sname, | ||
2933 | dai->driver->capture.stream_name)) { | ||
2934 | r.source = w->name; | ||
2935 | r.sink = dai->capture_widget->name; | ||
2936 | dev_dbg(dai->dev, "%s -> %s\n", | ||
2937 | r.source, r.sink); | ||
2938 | |||
2939 | snd_soc_dapm_add_route(w->dapm, &r); | ||
2796 | } | 2940 | } |
2797 | } | 2941 | } |
2798 | } | 2942 | } |
2799 | 2943 | ||
2800 | dapm_power_widgets(dapm, event); | 2944 | return 0; |
2945 | } | ||
2801 | 2946 | ||
2802 | /* do we need to notify any clients that DAPM stream is complete */ | 2947 | static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm, |
2803 | if (dapm->stream_event) | 2948 | int stream, struct snd_soc_dai *dai, |
2804 | dapm->stream_event(dapm, event); | 2949 | int event) |
2950 | { | ||
2951 | struct snd_soc_dapm_widget *w; | ||
2952 | |||
2953 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
2954 | w = dai->playback_widget; | ||
2955 | else | ||
2956 | w = dai->capture_widget; | ||
2957 | |||
2958 | if (!w) | ||
2959 | return; | ||
2960 | |||
2961 | dapm_mark_dirty(w, "stream event"); | ||
2962 | |||
2963 | switch (event) { | ||
2964 | case SND_SOC_DAPM_STREAM_START: | ||
2965 | w->active = 1; | ||
2966 | break; | ||
2967 | case SND_SOC_DAPM_STREAM_STOP: | ||
2968 | w->active = 0; | ||
2969 | break; | ||
2970 | case SND_SOC_DAPM_STREAM_SUSPEND: | ||
2971 | case SND_SOC_DAPM_STREAM_RESUME: | ||
2972 | case SND_SOC_DAPM_STREAM_PAUSE_PUSH: | ||
2973 | case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: | ||
2974 | break; | ||
2975 | } | ||
2976 | |||
2977 | dapm_power_widgets(dapm, event); | ||
2805 | } | 2978 | } |
2806 | 2979 | ||
2807 | /** | 2980 | /** |
@@ -2815,16 +2988,13 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm, | |||
2815 | * | 2988 | * |
2816 | * Returns 0 for success else error. | 2989 | * Returns 0 for success else error. |
2817 | */ | 2990 | */ |
2818 | int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, | 2991 | int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, |
2819 | const char *stream, int event) | 2992 | struct snd_soc_dai *dai, int event) |
2820 | { | 2993 | { |
2821 | struct snd_soc_codec *codec = rtd->codec; | 2994 | struct snd_soc_codec *codec = rtd->codec; |
2822 | 2995 | ||
2823 | if (stream == NULL) | ||
2824 | return 0; | ||
2825 | |||
2826 | mutex_lock(&codec->mutex); | 2996 | mutex_lock(&codec->mutex); |
2827 | soc_dapm_stream_event(&codec->dapm, stream, event); | 2997 | soc_dapm_stream_event(&codec->dapm, stream, dai, event); |
2828 | mutex_unlock(&codec->mutex); | 2998 | mutex_unlock(&codec->mutex); |
2829 | return 0; | 2999 | return 0; |
2830 | } | 3000 | } |
@@ -3068,9 +3238,13 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm) | |||
3068 | * standby. | 3238 | * standby. |
3069 | */ | 3239 | */ |
3070 | if (powerdown) { | 3240 | if (powerdown) { |
3071 | snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_PREPARE); | 3241 | if (dapm->bias_level == SND_SOC_BIAS_ON) |
3242 | snd_soc_dapm_set_bias_level(dapm, | ||
3243 | SND_SOC_BIAS_PREPARE); | ||
3072 | dapm_seq_run(dapm, &down_list, 0, false); | 3244 | dapm_seq_run(dapm, &down_list, 0, false); |
3073 | snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_STANDBY); | 3245 | if (dapm->bias_level == SND_SOC_BIAS_PREPARE) |
3246 | snd_soc_dapm_set_bias_level(dapm, | ||
3247 | SND_SOC_BIAS_STANDBY); | ||
3074 | } | 3248 | } |
3075 | } | 3249 | } |
3076 | 3250 | ||
@@ -3083,7 +3257,9 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card) | |||
3083 | 3257 | ||
3084 | list_for_each_entry(codec, &card->codec_dev_list, list) { | 3258 | list_for_each_entry(codec, &card->codec_dev_list, list) { |
3085 | soc_dapm_shutdown_codec(&codec->dapm); | 3259 | soc_dapm_shutdown_codec(&codec->dapm); |
3086 | snd_soc_dapm_set_bias_level(&codec->dapm, SND_SOC_BIAS_OFF); | 3260 | if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) |
3261 | snd_soc_dapm_set_bias_level(&codec->dapm, | ||
3262 | SND_SOC_BIAS_OFF); | ||
3087 | } | 3263 | } |
3088 | } | 3264 | } |
3089 | 3265 | ||
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c new file mode 100644 index 000000000000..4420b7030c83 --- /dev/null +++ b/sound/soc/soc-dmaengine-pcm.c | |||
@@ -0,0 +1,288 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012, Analog Devices Inc. | ||
3 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
4 | * | ||
5 | * Based on: | ||
6 | * imx-pcm-dma-mx2.c, Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de> | ||
7 | * mxs-pcm.c, Copyright (C) 2011 Freescale Semiconductor, Inc. | ||
8 | * ep93xx-pcm.c, Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> | ||
9 | * Copyright (C) 2006 Applied Data Systems | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | * | ||
20 | */ | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/dmaengine.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <sound/pcm.h> | ||
26 | #include <sound/pcm_params.h> | ||
27 | #include <sound/soc.h> | ||
28 | |||
29 | #include <sound/dmaengine_pcm.h> | ||
30 | |||
31 | struct dmaengine_pcm_runtime_data { | ||
32 | struct dma_chan *dma_chan; | ||
33 | |||
34 | unsigned int pos; | ||
35 | |||
36 | void *data; | ||
37 | }; | ||
38 | |||
39 | static inline struct dmaengine_pcm_runtime_data *substream_to_prtd( | ||
40 | const struct snd_pcm_substream *substream) | ||
41 | { | ||
42 | return substream->runtime->private_data; | ||
43 | } | ||
44 | |||
45 | /** | ||
46 | * snd_dmaengine_pcm_set_data - Set dmaengine substream private data | ||
47 | * @substream: PCM substream | ||
48 | * @data: Data to set | ||
49 | */ | ||
50 | void snd_dmaengine_pcm_set_data(struct snd_pcm_substream *substream, void *data) | ||
51 | { | ||
52 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); | ||
53 | |||
54 | prtd->data = data; | ||
55 | } | ||
56 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_data); | ||
57 | |||
58 | /** | ||
59 | * snd_dmaengine_pcm_get_data - Get dmaeinge substream private data | ||
60 | * @substream: PCM substream | ||
61 | * | ||
62 | * Returns the data previously set with snd_dmaengine_pcm_set_data | ||
63 | */ | ||
64 | void *snd_dmaengine_pcm_get_data(struct snd_pcm_substream *substream) | ||
65 | { | ||
66 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); | ||
67 | |||
68 | return prtd->data; | ||
69 | } | ||
70 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_data); | ||
71 | |||
72 | struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream) | ||
73 | { | ||
74 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); | ||
75 | |||
76 | return prtd->dma_chan; | ||
77 | } | ||
78 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_get_chan); | ||
79 | |||
80 | /** | ||
81 | * snd_hwparams_to_dma_slave_config - Convert hw_params to dma_slave_config | ||
82 | * @substream: PCM substream | ||
83 | * @params: hw_params | ||
84 | * @slave_config: DMA slave config | ||
85 | * | ||
86 | * This function can be used to initialize a dma_slave_config from a substream | ||
87 | * and hw_params in a dmaengine based PCM driver implementation. | ||
88 | */ | ||
89 | int snd_hwparams_to_dma_slave_config(const struct snd_pcm_substream *substream, | ||
90 | const struct snd_pcm_hw_params *params, | ||
91 | struct dma_slave_config *slave_config) | ||
92 | { | ||
93 | enum dma_slave_buswidth buswidth; | ||
94 | |||
95 | switch (params_format(params)) { | ||
96 | case SNDRV_PCM_FORMAT_S8: | ||
97 | buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE; | ||
98 | break; | ||
99 | case SNDRV_PCM_FORMAT_S16_LE: | ||
100 | buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES; | ||
101 | break; | ||
102 | case SNDRV_PCM_FORMAT_S18_3LE: | ||
103 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
104 | case SNDRV_PCM_FORMAT_S24_LE: | ||
105 | case SNDRV_PCM_FORMAT_S32_LE: | ||
106 | buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
107 | break; | ||
108 | default: | ||
109 | return -EINVAL; | ||
110 | } | ||
111 | |||
112 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
113 | slave_config->direction = DMA_MEM_TO_DEV; | ||
114 | slave_config->dst_addr_width = buswidth; | ||
115 | } else { | ||
116 | slave_config->direction = DMA_DEV_TO_MEM; | ||
117 | slave_config->src_addr_width = buswidth; | ||
118 | } | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | EXPORT_SYMBOL_GPL(snd_hwparams_to_dma_slave_config); | ||
123 | |||
124 | static void dmaengine_pcm_dma_complete(void *arg) | ||
125 | { | ||
126 | struct snd_pcm_substream *substream = arg; | ||
127 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); | ||
128 | |||
129 | prtd->pos += snd_pcm_lib_period_bytes(substream); | ||
130 | if (prtd->pos >= snd_pcm_lib_buffer_bytes(substream)) | ||
131 | prtd->pos = 0; | ||
132 | |||
133 | snd_pcm_period_elapsed(substream); | ||
134 | } | ||
135 | |||
136 | static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream) | ||
137 | { | ||
138 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); | ||
139 | struct dma_chan *chan = prtd->dma_chan; | ||
140 | struct dma_async_tx_descriptor *desc; | ||
141 | enum dma_transfer_direction direction; | ||
142 | |||
143 | direction = snd_pcm_substream_to_dma_direction(substream); | ||
144 | |||
145 | prtd->pos = 0; | ||
146 | desc = chan->device->device_prep_dma_cyclic(chan, | ||
147 | substream->runtime->dma_addr, | ||
148 | snd_pcm_lib_buffer_bytes(substream), | ||
149 | snd_pcm_lib_period_bytes(substream), direction); | ||
150 | |||
151 | if (!desc) | ||
152 | return -ENOMEM; | ||
153 | |||
154 | desc->callback = dmaengine_pcm_dma_complete; | ||
155 | desc->callback_param = substream; | ||
156 | dmaengine_submit(desc); | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * snd_dmaengine_pcm_trigger - dmaengine based PCM trigger implementation | ||
163 | * @substream: PCM substream | ||
164 | * @cmd: Trigger command | ||
165 | * | ||
166 | * Returns 0 on success, a negative error code otherwise. | ||
167 | * | ||
168 | * This function can be used as the PCM trigger callback for dmaengine based PCM | ||
169 | * driver implementations. | ||
170 | */ | ||
171 | int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
172 | { | ||
173 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); | ||
174 | int ret; | ||
175 | |||
176 | switch (cmd) { | ||
177 | case SNDRV_PCM_TRIGGER_START: | ||
178 | ret = dmaengine_pcm_prepare_and_submit(substream); | ||
179 | if (ret) | ||
180 | return ret; | ||
181 | dma_async_issue_pending(prtd->dma_chan); | ||
182 | break; | ||
183 | case SNDRV_PCM_TRIGGER_RESUME: | ||
184 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
185 | dmaengine_resume(prtd->dma_chan); | ||
186 | break; | ||
187 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
188 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
189 | dmaengine_pause(prtd->dma_chan); | ||
190 | break; | ||
191 | case SNDRV_PCM_TRIGGER_STOP: | ||
192 | dmaengine_terminate_all(prtd->dma_chan); | ||
193 | break; | ||
194 | default: | ||
195 | return -EINVAL; | ||
196 | } | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger); | ||
201 | |||
202 | /** | ||
203 | * snd_dmaengine_pcm_pointer - dmaengine based PCM pointer implementation | ||
204 | * @substream: PCM substream | ||
205 | * | ||
206 | * This function can be used as the PCM pointer callback for dmaengine based PCM | ||
207 | * driver implementations. | ||
208 | */ | ||
209 | snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream) | ||
210 | { | ||
211 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); | ||
212 | return bytes_to_frames(substream->runtime, prtd->pos); | ||
213 | } | ||
214 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer); | ||
215 | |||
216 | static int dmaengine_pcm_request_channel(struct dmaengine_pcm_runtime_data *prtd, | ||
217 | dma_filter_fn filter_fn, void *filter_data) | ||
218 | { | ||
219 | dma_cap_mask_t mask; | ||
220 | |||
221 | dma_cap_zero(mask); | ||
222 | dma_cap_set(DMA_SLAVE, mask); | ||
223 | dma_cap_set(DMA_CYCLIC, mask); | ||
224 | prtd->dma_chan = dma_request_channel(mask, filter_fn, filter_data); | ||
225 | |||
226 | if (!prtd->dma_chan) | ||
227 | return -ENXIO; | ||
228 | |||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | /** | ||
233 | * snd_dmaengine_pcm_open - Open a dmaengine based PCM substream | ||
234 | * @substream: PCM substream | ||
235 | * @filter_fn: Filter function used to request the DMA channel | ||
236 | * @filter_data: Data passed to the DMA filter function | ||
237 | * | ||
238 | * Returns 0 on success, a negative error code otherwise. | ||
239 | * | ||
240 | * This function will request a DMA channel using the passed filter function and | ||
241 | * data. The function should usually be called from the pcm open callback. | ||
242 | * | ||
243 | * Note that this function will use private_data field of the substream's | ||
244 | * runtime. So it is not availabe to your pcm driver implementation. If you need | ||
245 | * to keep additional data attached to a substream use | ||
246 | * snd_dmaeinge_pcm_{set,get}_data. | ||
247 | */ | ||
248 | int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, | ||
249 | dma_filter_fn filter_fn, void *filter_data) | ||
250 | { | ||
251 | struct dmaengine_pcm_runtime_data *prtd; | ||
252 | int ret; | ||
253 | |||
254 | ret = snd_pcm_hw_constraint_integer(substream->runtime, | ||
255 | SNDRV_PCM_HW_PARAM_PERIODS); | ||
256 | if (ret < 0) | ||
257 | return ret; | ||
258 | |||
259 | prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); | ||
260 | if (!prtd) | ||
261 | return -ENOMEM; | ||
262 | |||
263 | ret = dmaengine_pcm_request_channel(prtd, filter_fn, filter_data); | ||
264 | if (ret < 0) { | ||
265 | kfree(prtd); | ||
266 | return ret; | ||
267 | } | ||
268 | |||
269 | substream->runtime->private_data = prtd; | ||
270 | |||
271 | return 0; | ||
272 | } | ||
273 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_open); | ||
274 | |||
275 | /** | ||
276 | * snd_dmaengine_pcm_close - Close a dmaengine based PCM substream | ||
277 | * @substream: PCM substream | ||
278 | */ | ||
279 | int snd_dmaengine_pcm_close(struct snd_pcm_substream *substream) | ||
280 | { | ||
281 | struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); | ||
282 | |||
283 | dma_release_channel(prtd->dma_chan); | ||
284 | kfree(prtd); | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_close); | ||
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index c8610cbf34a5..4d8dc6a27d4d 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c | |||
@@ -114,6 +114,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, | |||
114 | enum snd_soc_control_type control) | 114 | enum snd_soc_control_type control) |
115 | { | 115 | { |
116 | struct regmap_config config; | 116 | struct regmap_config config; |
117 | int ret; | ||
117 | 118 | ||
118 | memset(&config, 0, sizeof(config)); | 119 | memset(&config, 0, sizeof(config)); |
119 | codec->write = hw_write; | 120 | codec->write = hw_write; |
@@ -140,6 +141,12 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, | |||
140 | 141 | ||
141 | case SND_SOC_REGMAP: | 142 | case SND_SOC_REGMAP: |
142 | /* Device has made its own regmap arrangements */ | 143 | /* Device has made its own regmap arrangements */ |
144 | codec->using_regmap = true; | ||
145 | |||
146 | ret = regmap_get_val_bytes(codec->control_data); | ||
147 | /* Errors are legitimate for non-integer byte multiples */ | ||
148 | if (ret > 0) | ||
149 | codec->val_bytes = ret; | ||
143 | break; | 150 | break; |
144 | 151 | ||
145 | default: | 152 | default: |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index cdc860a5ff37..0ad8dcacd2f3 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
@@ -63,6 +63,41 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, | |||
63 | } | 63 | } |
64 | 64 | ||
65 | /* | 65 | /* |
66 | * List of sample sizes that might go over the bus for parameter | ||
67 | * application. There ought to be a wildcard sample size for things | ||
68 | * like the DAC/ADC resolution to use but there isn't right now. | ||
69 | */ | ||
70 | static int sample_sizes[] = { | ||
71 | 24, 32, | ||
72 | }; | ||
73 | |||
74 | static void soc_pcm_apply_msb(struct snd_pcm_substream *substream, | ||
75 | struct snd_soc_dai *dai) | ||
76 | { | ||
77 | int ret, i, bits; | ||
78 | |||
79 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
80 | bits = dai->driver->playback.sig_bits; | ||
81 | else | ||
82 | bits = dai->driver->capture.sig_bits; | ||
83 | |||
84 | if (!bits) | ||
85 | return; | ||
86 | |||
87 | for (i = 0; i < ARRAY_SIZE(sample_sizes); i++) { | ||
88 | if (bits >= sample_sizes[i]) | ||
89 | continue; | ||
90 | |||
91 | ret = snd_pcm_hw_constraint_msbits(substream->runtime, 0, | ||
92 | sample_sizes[i], bits); | ||
93 | if (ret != 0) | ||
94 | dev_warn(dai->dev, | ||
95 | "Failed to set MSB %d/%d: %d\n", | ||
96 | bits, sample_sizes[i], ret); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | /* | ||
66 | * Called by ALSA when a PCM substream is opened, the runtime->hw record is | 101 | * Called by ALSA when a PCM substream is opened, the runtime->hw record is |
67 | * then initialized and any private data can be allocated. This also calls | 102 | * then initialized and any private data can be allocated. This also calls |
68 | * startup for the cpu DAI, platform, machine and codec DAI. | 103 | * startup for the cpu DAI, platform, machine and codec DAI. |
@@ -88,8 +123,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
88 | if (cpu_dai->driver->ops->startup) { | 123 | if (cpu_dai->driver->ops->startup) { |
89 | ret = cpu_dai->driver->ops->startup(substream, cpu_dai); | 124 | ret = cpu_dai->driver->ops->startup(substream, cpu_dai); |
90 | if (ret < 0) { | 125 | if (ret < 0) { |
91 | printk(KERN_ERR "asoc: can't open interface %s\n", | 126 | dev_err(cpu_dai->dev, "can't open interface %s: %d\n", |
92 | cpu_dai->name); | 127 | cpu_dai->name, ret); |
93 | goto out; | 128 | goto out; |
94 | } | 129 | } |
95 | } | 130 | } |
@@ -97,7 +132,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
97 | if (platform->driver->ops && platform->driver->ops->open) { | 132 | if (platform->driver->ops && platform->driver->ops->open) { |
98 | ret = platform->driver->ops->open(substream); | 133 | ret = platform->driver->ops->open(substream); |
99 | if (ret < 0) { | 134 | if (ret < 0) { |
100 | printk(KERN_ERR "asoc: can't open platform %s\n", platform->name); | 135 | dev_err(platform->dev, "can't open platform %s: %d\n", |
136 | platform->name, ret); | ||
101 | goto platform_err; | 137 | goto platform_err; |
102 | } | 138 | } |
103 | } | 139 | } |
@@ -105,8 +141,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
105 | if (codec_dai->driver->ops->startup) { | 141 | if (codec_dai->driver->ops->startup) { |
106 | ret = codec_dai->driver->ops->startup(substream, codec_dai); | 142 | ret = codec_dai->driver->ops->startup(substream, codec_dai); |
107 | if (ret < 0) { | 143 | if (ret < 0) { |
108 | printk(KERN_ERR "asoc: can't open codec %s\n", | 144 | dev_err(codec_dai->dev, "can't open codec %s: %d\n", |
109 | codec_dai->name); | 145 | codec_dai->name, ret); |
110 | goto codec_dai_err; | 146 | goto codec_dai_err; |
111 | } | 147 | } |
112 | } | 148 | } |
@@ -114,7 +150,8 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
114 | if (rtd->dai_link->ops && rtd->dai_link->ops->startup) { | 150 | if (rtd->dai_link->ops && rtd->dai_link->ops->startup) { |
115 | ret = rtd->dai_link->ops->startup(substream); | 151 | ret = rtd->dai_link->ops->startup(substream); |
116 | if (ret < 0) { | 152 | if (ret < 0) { |
117 | printk(KERN_ERR "asoc: %s startup failed\n", rtd->dai_link->name); | 153 | pr_err("asoc: %s startup failed: %d\n", |
154 | rtd->dai_link->name, ret); | ||
118 | goto machine_err; | 155 | goto machine_err; |
119 | } | 156 | } |
120 | } | 157 | } |
@@ -187,6 +224,9 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
187 | goto config_err; | 224 | goto config_err; |
188 | } | 225 | } |
189 | 226 | ||
227 | soc_pcm_apply_msb(substream, codec_dai); | ||
228 | soc_pcm_apply_msb(substream, cpu_dai); | ||
229 | |||
190 | /* Symmetry only applies if we've already got an active stream. */ | 230 | /* Symmetry only applies if we've already got an active stream. */ |
191 | if (cpu_dai->active) { | 231 | if (cpu_dai->active) { |
192 | ret = soc_pcm_apply_symmetry(substream, cpu_dai); | 232 | ret = soc_pcm_apply_symmetry(substream, cpu_dai); |
@@ -267,9 +307,8 @@ static void close_delayed_work(struct work_struct *work) | |||
267 | /* are we waiting on this codec DAI stream */ | 307 | /* are we waiting on this codec DAI stream */ |
268 | if (codec_dai->pop_wait == 1) { | 308 | if (codec_dai->pop_wait == 1) { |
269 | codec_dai->pop_wait = 0; | 309 | codec_dai->pop_wait = 0; |
270 | snd_soc_dapm_stream_event(rtd, | 310 | snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_PLAYBACK, |
271 | codec_dai->driver->playback.stream_name, | 311 | codec_dai, SND_SOC_DAPM_STREAM_STOP); |
272 | SND_SOC_DAPM_STREAM_STOP); | ||
273 | } | 312 | } |
274 | 313 | ||
275 | mutex_unlock(&rtd->pcm_mutex); | 314 | mutex_unlock(&rtd->pcm_mutex); |
@@ -329,12 +368,13 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) | |||
329 | cpu_dai->runtime = NULL; | 368 | cpu_dai->runtime = NULL; |
330 | 369 | ||
331 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 370 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
332 | if (codec->ignore_pmdown_time || | 371 | if (!rtd->pmdown_time || codec->ignore_pmdown_time || |
333 | rtd->dai_link->ignore_pmdown_time) { | 372 | rtd->dai_link->ignore_pmdown_time) { |
334 | /* powered down playback stream now */ | 373 | /* powered down playback stream now */ |
335 | snd_soc_dapm_stream_event(rtd, | 374 | snd_soc_dapm_stream_event(rtd, |
336 | codec_dai->driver->playback.stream_name, | 375 | SNDRV_PCM_STREAM_PLAYBACK, |
337 | SND_SOC_DAPM_STREAM_STOP); | 376 | codec_dai, |
377 | SND_SOC_DAPM_STREAM_STOP); | ||
338 | } else { | 378 | } else { |
339 | /* start delayed pop wq here for playback streams */ | 379 | /* start delayed pop wq here for playback streams */ |
340 | codec_dai->pop_wait = 1; | 380 | codec_dai->pop_wait = 1; |
@@ -343,9 +383,8 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) | |||
343 | } | 383 | } |
344 | } else { | 384 | } else { |
345 | /* capture streams can be powered down now */ | 385 | /* capture streams can be powered down now */ |
346 | snd_soc_dapm_stream_event(rtd, | 386 | snd_soc_dapm_stream_event(rtd, SNDRV_PCM_STREAM_CAPTURE, |
347 | codec_dai->driver->capture.stream_name, | 387 | codec_dai, SND_SOC_DAPM_STREAM_STOP); |
348 | SND_SOC_DAPM_STREAM_STOP); | ||
349 | } | 388 | } |
350 | 389 | ||
351 | mutex_unlock(&rtd->pcm_mutex); | 390 | mutex_unlock(&rtd->pcm_mutex); |
@@ -375,7 +414,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
375 | if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) { | 414 | if (rtd->dai_link->ops && rtd->dai_link->ops->prepare) { |
376 | ret = rtd->dai_link->ops->prepare(substream); | 415 | ret = rtd->dai_link->ops->prepare(substream); |
377 | if (ret < 0) { | 416 | if (ret < 0) { |
378 | printk(KERN_ERR "asoc: machine prepare error\n"); | 417 | pr_err("asoc: machine prepare error: %d\n", ret); |
379 | goto out; | 418 | goto out; |
380 | } | 419 | } |
381 | } | 420 | } |
@@ -383,7 +422,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
383 | if (platform->driver->ops && platform->driver->ops->prepare) { | 422 | if (platform->driver->ops && platform->driver->ops->prepare) { |
384 | ret = platform->driver->ops->prepare(substream); | 423 | ret = platform->driver->ops->prepare(substream); |
385 | if (ret < 0) { | 424 | if (ret < 0) { |
386 | printk(KERN_ERR "asoc: platform prepare error\n"); | 425 | dev_err(platform->dev, "platform prepare error: %d\n", |
426 | ret); | ||
387 | goto out; | 427 | goto out; |
388 | } | 428 | } |
389 | } | 429 | } |
@@ -391,7 +431,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
391 | if (codec_dai->driver->ops->prepare) { | 431 | if (codec_dai->driver->ops->prepare) { |
392 | ret = codec_dai->driver->ops->prepare(substream, codec_dai); | 432 | ret = codec_dai->driver->ops->prepare(substream, codec_dai); |
393 | if (ret < 0) { | 433 | if (ret < 0) { |
394 | printk(KERN_ERR "asoc: codec DAI prepare error\n"); | 434 | dev_err(codec_dai->dev, "DAI prepare error: %d\n", |
435 | ret); | ||
395 | goto out; | 436 | goto out; |
396 | } | 437 | } |
397 | } | 438 | } |
@@ -399,7 +440,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
399 | if (cpu_dai->driver->ops->prepare) { | 440 | if (cpu_dai->driver->ops->prepare) { |
400 | ret = cpu_dai->driver->ops->prepare(substream, cpu_dai); | 441 | ret = cpu_dai->driver->ops->prepare(substream, cpu_dai); |
401 | if (ret < 0) { | 442 | if (ret < 0) { |
402 | printk(KERN_ERR "asoc: cpu DAI prepare error\n"); | 443 | dev_err(cpu_dai->dev, "DAI prepare error: %d\n", |
444 | ret); | ||
403 | goto out; | 445 | goto out; |
404 | } | 446 | } |
405 | } | 447 | } |
@@ -411,14 +453,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) | |||
411 | cancel_delayed_work(&rtd->delayed_work); | 453 | cancel_delayed_work(&rtd->delayed_work); |
412 | } | 454 | } |
413 | 455 | ||
414 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 456 | snd_soc_dapm_stream_event(rtd, substream->stream, codec_dai, |
415 | snd_soc_dapm_stream_event(rtd, | 457 | SND_SOC_DAPM_STREAM_START); |
416 | codec_dai->driver->playback.stream_name, | ||
417 | SND_SOC_DAPM_STREAM_START); | ||
418 | else | ||
419 | snd_soc_dapm_stream_event(rtd, | ||
420 | codec_dai->driver->capture.stream_name, | ||
421 | SND_SOC_DAPM_STREAM_START); | ||
422 | 458 | ||
423 | snd_soc_dai_digital_mute(codec_dai, 0); | 459 | snd_soc_dai_digital_mute(codec_dai, 0); |
424 | 460 | ||
@@ -446,7 +482,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
446 | if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) { | 482 | if (rtd->dai_link->ops && rtd->dai_link->ops->hw_params) { |
447 | ret = rtd->dai_link->ops->hw_params(substream, params); | 483 | ret = rtd->dai_link->ops->hw_params(substream, params); |
448 | if (ret < 0) { | 484 | if (ret < 0) { |
449 | printk(KERN_ERR "asoc: machine hw_params failed\n"); | 485 | pr_err("asoc: machine hw_params failed: %d\n", ret); |
450 | goto out; | 486 | goto out; |
451 | } | 487 | } |
452 | } | 488 | } |
@@ -454,8 +490,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
454 | if (codec_dai->driver->ops->hw_params) { | 490 | if (codec_dai->driver->ops->hw_params) { |
455 | ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); | 491 | ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); |
456 | if (ret < 0) { | 492 | if (ret < 0) { |
457 | printk(KERN_ERR "asoc: can't set codec %s hw params\n", | 493 | dev_err(codec_dai->dev, "can't set %s hw params: %d\n", |
458 | codec_dai->name); | 494 | codec_dai->name, ret); |
459 | goto codec_err; | 495 | goto codec_err; |
460 | } | 496 | } |
461 | } | 497 | } |
@@ -463,8 +499,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
463 | if (cpu_dai->driver->ops->hw_params) { | 499 | if (cpu_dai->driver->ops->hw_params) { |
464 | ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai); | 500 | ret = cpu_dai->driver->ops->hw_params(substream, params, cpu_dai); |
465 | if (ret < 0) { | 501 | if (ret < 0) { |
466 | printk(KERN_ERR "asoc: interface %s hw params failed\n", | 502 | dev_err(cpu_dai->dev, "%s hw params failed: %d\n", |
467 | cpu_dai->name); | 503 | cpu_dai->name, ret); |
468 | goto interface_err; | 504 | goto interface_err; |
469 | } | 505 | } |
470 | } | 506 | } |
@@ -472,8 +508,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
472 | if (platform->driver->ops && platform->driver->ops->hw_params) { | 508 | if (platform->driver->ops && platform->driver->ops->hw_params) { |
473 | ret = platform->driver->ops->hw_params(substream, params); | 509 | ret = platform->driver->ops->hw_params(substream, params); |
474 | if (ret < 0) { | 510 | if (ret < 0) { |
475 | printk(KERN_ERR "asoc: platform %s hw params failed\n", | 511 | dev_err(platform->dev, "%s hw params failed: %d\n", |
476 | platform->name); | 512 | platform->name, ret); |
477 | goto platform_err; | 513 | goto platform_err; |
478 | } | 514 | } |
479 | } | 515 | } |
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 4220bb0f2730..60053709e417 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c | |||
@@ -89,14 +89,32 @@ static struct snd_soc_platform_driver dummy_platform = { | |||
89 | .ops = &dummy_dma_ops, | 89 | .ops = &dummy_dma_ops, |
90 | }; | 90 | }; |
91 | 91 | ||
92 | static struct snd_soc_codec_driver dummy_codec; | ||
93 | static struct snd_soc_dai_driver dummy_dai = { | ||
94 | .name = "snd-soc-dummy-dai", | ||
95 | }; | ||
96 | |||
92 | static __devinit int snd_soc_dummy_probe(struct platform_device *pdev) | 97 | static __devinit int snd_soc_dummy_probe(struct platform_device *pdev) |
93 | { | 98 | { |
94 | return snd_soc_register_platform(&pdev->dev, &dummy_platform); | 99 | int ret; |
100 | |||
101 | ret = snd_soc_register_codec(&pdev->dev, &dummy_codec, &dummy_dai, 1); | ||
102 | if (ret < 0) | ||
103 | return ret; | ||
104 | |||
105 | ret = snd_soc_register_platform(&pdev->dev, &dummy_platform); | ||
106 | if (ret < 0) { | ||
107 | snd_soc_unregister_codec(&pdev->dev); | ||
108 | return ret; | ||
109 | } | ||
110 | |||
111 | return ret; | ||
95 | } | 112 | } |
96 | 113 | ||
97 | static __devexit int snd_soc_dummy_remove(struct platform_device *pdev) | 114 | static __devexit int snd_soc_dummy_remove(struct platform_device *pdev) |
98 | { | 115 | { |
99 | snd_soc_unregister_platform(&pdev->dev); | 116 | snd_soc_unregister_platform(&pdev->dev); |
117 | snd_soc_unregister_codec(&pdev->dev); | ||
100 | 118 | ||
101 | return 0; | 119 | return 0; |
102 | } | 120 | } |
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index 4a0e805c4edd..e45ccd851f6a 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
21 | #include <linux/of_gpio.h> | ||
21 | 22 | ||
22 | #include <sound/core.h> | 23 | #include <sound/core.h> |
23 | #include <sound/jack.h> | 24 | #include <sound/jack.h> |
@@ -34,8 +35,13 @@ | |||
34 | 35 | ||
35 | #define DRV_NAME "tegra-alc5632" | 36 | #define DRV_NAME "tegra-alc5632" |
36 | 37 | ||
38 | #define GPIO_HP_DET BIT(0) | ||
39 | |||
37 | struct tegra_alc5632 { | 40 | struct tegra_alc5632 { |
38 | struct tegra_asoc_utils_data util_data; | 41 | struct tegra_asoc_utils_data util_data; |
42 | struct platform_device *pcm_dev; | ||
43 | int gpio_requested; | ||
44 | int gpio_hp_det; | ||
39 | }; | 45 | }; |
40 | 46 | ||
41 | static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream, | 47 | static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream, |
@@ -85,24 +91,18 @@ static struct snd_soc_jack_pin tegra_alc5632_hs_jack_pins[] = { | |||
85 | }, | 91 | }, |
86 | }; | 92 | }; |
87 | 93 | ||
94 | static struct snd_soc_jack_gpio tegra_alc5632_hp_jack_gpio = { | ||
95 | .name = "Headset detection", | ||
96 | .report = SND_JACK_HEADSET, | ||
97 | .debounce_time = 150, | ||
98 | .invert = 1, | ||
99 | }; | ||
100 | |||
88 | static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = { | 101 | static const struct snd_soc_dapm_widget tegra_alc5632_dapm_widgets[] = { |
89 | SND_SOC_DAPM_SPK("Int Spk", NULL), | 102 | SND_SOC_DAPM_SPK("Int Spk", NULL), |
90 | SND_SOC_DAPM_HP("Headset Stereophone", NULL), | 103 | SND_SOC_DAPM_HP("Headset Stereophone", NULL), |
91 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | 104 | SND_SOC_DAPM_MIC("Headset Mic", NULL), |
92 | }; | 105 | SND_SOC_DAPM_MIC("Digital Mic", NULL), |
93 | |||
94 | static const struct snd_soc_dapm_route tegra_alc5632_audio_map[] = { | ||
95 | /* Internal Speaker */ | ||
96 | {"Int Spk", NULL, "SPKOUT"}, | ||
97 | {"Int Spk", NULL, "SPKOUTN"}, | ||
98 | |||
99 | /* Headset Mic */ | ||
100 | {"MIC1", NULL, "MICBIAS1"}, | ||
101 | {"MICBIAS1", NULL, "Headset Mic"}, | ||
102 | |||
103 | /* Headset Stereophone */ | ||
104 | {"Headset Stereophone", NULL, "HPR"}, | ||
105 | {"Headset Stereophone", NULL, "HPL"}, | ||
106 | }; | 106 | }; |
107 | 107 | ||
108 | static const struct snd_kcontrol_new tegra_alc5632_controls[] = { | 108 | static const struct snd_kcontrol_new tegra_alc5632_controls[] = { |
@@ -113,6 +113,8 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) | |||
113 | { | 113 | { |
114 | struct snd_soc_codec *codec = rtd->codec; | 114 | struct snd_soc_codec *codec = rtd->codec; |
115 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 115 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
116 | struct device_node *np = codec->card->dev->of_node; | ||
117 | struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card); | ||
116 | 118 | ||
117 | snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, | 119 | snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, |
118 | &tegra_alc5632_hs_jack); | 120 | &tegra_alc5632_hs_jack); |
@@ -120,6 +122,16 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) | |||
120 | ARRAY_SIZE(tegra_alc5632_hs_jack_pins), | 122 | ARRAY_SIZE(tegra_alc5632_hs_jack_pins), |
121 | tegra_alc5632_hs_jack_pins); | 123 | tegra_alc5632_hs_jack_pins); |
122 | 124 | ||
125 | machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); | ||
126 | |||
127 | if (gpio_is_valid(machine->gpio_hp_det)) { | ||
128 | tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det; | ||
129 | snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack, | ||
130 | 1, | ||
131 | &tegra_alc5632_hp_jack_gpio); | ||
132 | machine->gpio_requested |= GPIO_HP_DET; | ||
133 | } | ||
134 | |||
123 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); | 135 | snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); |
124 | 136 | ||
125 | return 0; | 137 | return 0; |
@@ -128,9 +140,7 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) | |||
128 | static struct snd_soc_dai_link tegra_alc5632_dai = { | 140 | static struct snd_soc_dai_link tegra_alc5632_dai = { |
129 | .name = "ALC5632", | 141 | .name = "ALC5632", |
130 | .stream_name = "ALC5632 PCM", | 142 | .stream_name = "ALC5632 PCM", |
131 | .codec_name = "alc5632.0-001e", | ||
132 | .platform_name = "tegra-pcm-audio", | 143 | .platform_name = "tegra-pcm-audio", |
133 | .cpu_dai_name = "tegra-i2s.0", | ||
134 | .codec_dai_name = "alc5632-hifi", | 144 | .codec_dai_name = "alc5632-hifi", |
135 | .init = tegra_alc5632_asoc_init, | 145 | .init = tegra_alc5632_asoc_init, |
136 | .ops = &tegra_alc5632_asoc_ops, | 146 | .ops = &tegra_alc5632_asoc_ops, |
@@ -148,8 +158,6 @@ static struct snd_soc_card snd_soc_tegra_alc5632 = { | |||
148 | .num_controls = ARRAY_SIZE(tegra_alc5632_controls), | 158 | .num_controls = ARRAY_SIZE(tegra_alc5632_controls), |
149 | .dapm_widgets = tegra_alc5632_dapm_widgets, | 159 | .dapm_widgets = tegra_alc5632_dapm_widgets, |
150 | .num_dapm_widgets = ARRAY_SIZE(tegra_alc5632_dapm_widgets), | 160 | .num_dapm_widgets = ARRAY_SIZE(tegra_alc5632_dapm_widgets), |
151 | .dapm_routes = tegra_alc5632_audio_map, | ||
152 | .num_dapm_routes = ARRAY_SIZE(tegra_alc5632_audio_map), | ||
153 | .fully_routed = true, | 161 | .fully_routed = true, |
154 | }; | 162 | }; |
155 | 163 | ||
@@ -163,45 +171,111 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev) | |||
163 | sizeof(struct tegra_alc5632), GFP_KERNEL); | 171 | sizeof(struct tegra_alc5632), GFP_KERNEL); |
164 | if (!alc5632) { | 172 | if (!alc5632) { |
165 | dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n"); | 173 | dev_err(&pdev->dev, "Can't allocate tegra_alc5632\n"); |
166 | return -ENOMEM; | 174 | ret = -ENOMEM; |
175 | goto err; | ||
167 | } | 176 | } |
168 | 177 | ||
169 | ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); | ||
170 | if (ret) | ||
171 | return ret; | ||
172 | |||
173 | card->dev = &pdev->dev; | 178 | card->dev = &pdev->dev; |
174 | platform_set_drvdata(pdev, card); | 179 | platform_set_drvdata(pdev, card); |
175 | snd_soc_card_set_drvdata(card, alc5632); | 180 | snd_soc_card_set_drvdata(card, alc5632); |
176 | 181 | ||
182 | alc5632->pcm_dev = ERR_PTR(-EINVAL); | ||
183 | |||
184 | if (!(pdev->dev.of_node)) { | ||
185 | dev_err(&pdev->dev, "Must be instantiated using device tree\n"); | ||
186 | ret = -EINVAL; | ||
187 | goto err; | ||
188 | } | ||
189 | |||
190 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); | ||
191 | if (ret) | ||
192 | goto err; | ||
193 | |||
194 | ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing"); | ||
195 | if (ret) | ||
196 | goto err; | ||
197 | |||
198 | tegra_alc5632_dai.codec_of_node = of_parse_phandle( | ||
199 | pdev->dev.of_node, "nvidia,audio-codec", 0); | ||
200 | |||
201 | if (!tegra_alc5632_dai.codec_of_node) { | ||
202 | dev_err(&pdev->dev, | ||
203 | "Property 'nvidia,audio-codec' missing or invalid\n"); | ||
204 | ret = -EINVAL; | ||
205 | goto err; | ||
206 | } | ||
207 | |||
208 | tegra_alc5632_dai.cpu_dai_of_node = of_parse_phandle( | ||
209 | pdev->dev.of_node, "nvidia,i2s-controller", 0); | ||
210 | if (!tegra_alc5632_dai.cpu_dai_of_node) { | ||
211 | dev_err(&pdev->dev, | ||
212 | "Property 'nvidia,i2s-controller' missing or invalid\n"); | ||
213 | ret = -EINVAL; | ||
214 | goto err; | ||
215 | } | ||
216 | |||
217 | alc5632->pcm_dev = platform_device_register_simple( | ||
218 | "tegra-pcm-audio", -1, NULL, 0); | ||
219 | if (IS_ERR(alc5632->pcm_dev)) { | ||
220 | dev_err(&pdev->dev, | ||
221 | "Can't instantiate tegra-pcm-audio\n"); | ||
222 | ret = PTR_ERR(alc5632->pcm_dev); | ||
223 | goto err; | ||
224 | } | ||
225 | |||
226 | ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); | ||
227 | if (ret) | ||
228 | goto err_unregister; | ||
229 | |||
177 | ret = snd_soc_register_card(card); | 230 | ret = snd_soc_register_card(card); |
178 | if (ret) { | 231 | if (ret) { |
179 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", | 232 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", |
180 | ret); | 233 | ret); |
181 | tegra_asoc_utils_fini(&alc5632->util_data); | 234 | goto err_fini_utils; |
182 | return ret; | ||
183 | } | 235 | } |
184 | 236 | ||
185 | return 0; | 237 | return 0; |
238 | |||
239 | err_fini_utils: | ||
240 | tegra_asoc_utils_fini(&alc5632->util_data); | ||
241 | err_unregister: | ||
242 | if (!IS_ERR(alc5632->pcm_dev)) | ||
243 | platform_device_unregister(alc5632->pcm_dev); | ||
244 | err: | ||
245 | return ret; | ||
186 | } | 246 | } |
187 | 247 | ||
188 | static int __devexit tegra_alc5632_remove(struct platform_device *pdev) | 248 | static int __devexit tegra_alc5632_remove(struct platform_device *pdev) |
189 | { | 249 | { |
190 | struct snd_soc_card *card = platform_get_drvdata(pdev); | 250 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
191 | struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card); | 251 | struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card); |
252 | |||
253 | if (machine->gpio_requested & GPIO_HP_DET) | ||
254 | snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack, | ||
255 | 1, | ||
256 | &tegra_alc5632_hp_jack_gpio); | ||
257 | machine->gpio_requested = 0; | ||
192 | 258 | ||
193 | snd_soc_unregister_card(card); | 259 | snd_soc_unregister_card(card); |
194 | 260 | ||
195 | tegra_asoc_utils_fini(&alc5632->util_data); | 261 | tegra_asoc_utils_fini(&machine->util_data); |
262 | if (!IS_ERR(machine->pcm_dev)) | ||
263 | platform_device_unregister(machine->pcm_dev); | ||
196 | 264 | ||
197 | return 0; | 265 | return 0; |
198 | } | 266 | } |
199 | 267 | ||
268 | static const struct of_device_id tegra_alc5632_of_match[] __devinitconst = { | ||
269 | { .compatible = "nvidia,tegra-audio-alc5632", }, | ||
270 | {}, | ||
271 | }; | ||
272 | |||
200 | static struct platform_driver tegra_alc5632_driver = { | 273 | static struct platform_driver tegra_alc5632_driver = { |
201 | .driver = { | 274 | .driver = { |
202 | .name = DRV_NAME, | 275 | .name = DRV_NAME, |
203 | .owner = THIS_MODULE, | 276 | .owner = THIS_MODULE, |
204 | .pm = &snd_soc_pm_ops, | 277 | .pm = &snd_soc_pm_ops, |
278 | .of_match_table = tegra_alc5632_of_match, | ||
205 | }, | 279 | }, |
206 | .probe = tegra_alc5632_probe, | 280 | .probe = tegra_alc5632_probe, |
207 | .remove = __devexit_p(tegra_alc5632_remove), | 281 | .remove = __devexit_p(tegra_alc5632_remove), |
@@ -212,3 +286,4 @@ MODULE_AUTHOR("Leon Romanovsky <leon@leon.nu>"); | |||
212 | MODULE_DESCRIPTION("Tegra+ALC5632 machine ASoC driver"); | 286 | MODULE_DESCRIPTION("Tegra+ALC5632 machine ASoC driver"); |
213 | MODULE_LICENSE("GPL"); | 287 | MODULE_LICENSE("GPL"); |
214 | MODULE_ALIAS("platform:" DRV_NAME); | 288 | MODULE_ALIAS("platform:" DRV_NAME); |
289 | MODULE_DEVICE_TABLE(of, tegra_alc5632_of_match); | ||
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index c22431516ab2..8b4457137c7c 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c | |||
@@ -336,7 +336,7 @@ static int tegra_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
336 | if (!card->dev->dma_mask) | 336 | if (!card->dev->dma_mask) |
337 | card->dev->dma_mask = &tegra_dma_mask; | 337 | card->dev->dma_mask = &tegra_dma_mask; |
338 | if (!card->dev->coherent_dma_mask) | 338 | if (!card->dev->coherent_dma_mask) |
339 | card->dev->coherent_dma_mask = 0xffffffff; | 339 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); |
340 | 340 | ||
341 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | 341 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { |
342 | ret = tegra_pcm_preallocate_dma_buffer(pcm, | 342 | ret = tegra_pcm_preallocate_dma_buffer(pcm, |
diff --git a/sound/spi/at73c213.c b/sound/spi/at73c213.c index 4dd051bdf4fd..c6500d00053b 100644 --- a/sound/spi/at73c213.c +++ b/sound/spi/at73c213.c | |||
@@ -1112,17 +1112,7 @@ static struct spi_driver at73c213_driver = { | |||
1112 | .remove = __devexit_p(snd_at73c213_remove), | 1112 | .remove = __devexit_p(snd_at73c213_remove), |
1113 | }; | 1113 | }; |
1114 | 1114 | ||
1115 | static int __init at73c213_init(void) | 1115 | module_spi_driver(at73c213_driver); |
1116 | { | ||
1117 | return spi_register_driver(&at73c213_driver); | ||
1118 | } | ||
1119 | module_init(at73c213_init); | ||
1120 | |||
1121 | static void __exit at73c213_exit(void) | ||
1122 | { | ||
1123 | spi_unregister_driver(&at73c213_driver); | ||
1124 | } | ||
1125 | module_exit(at73c213_exit); | ||
1126 | 1116 | ||
1127 | MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>"); | 1117 | MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>"); |
1128 | MODULE_DESCRIPTION("Sound driver for AT73C213 with Atmel SSC"); | 1118 | MODULE_DESCRIPTION("Sound driver for AT73C213 with Atmel SSC"); |
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c index 8af92e3e9c18..fc8cc823e438 100644 --- a/sound/usb/6fire/chip.c +++ b/sound/usb/6fire/chip.c | |||
@@ -5,7 +5,6 @@ | |||
5 | * | 5 | * |
6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> | 6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> |
7 | * Created: Jan 01, 2011 | 7 | * Created: Jan 01, 2011 |
8 | * Version: 0.3.0 | ||
9 | * Copyright: (C) Torsten Schenk | 8 | * Copyright: (C) Torsten Schenk |
10 | * | 9 | * |
11 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
@@ -29,7 +28,7 @@ | |||
29 | #include <sound/initval.h> | 28 | #include <sound/initval.h> |
30 | 29 | ||
31 | MODULE_AUTHOR("Torsten Schenk <torsten.schenk@zoho.com>"); | 30 | MODULE_AUTHOR("Torsten Schenk <torsten.schenk@zoho.com>"); |
32 | MODULE_DESCRIPTION("TerraTec DMX 6Fire USB audio driver, version 0.3.0"); | 31 | MODULE_DESCRIPTION("TerraTec DMX 6Fire USB audio driver"); |
33 | MODULE_LICENSE("GPL v2"); | 32 | MODULE_LICENSE("GPL v2"); |
34 | MODULE_SUPPORTED_DEVICE("{{TerraTec, DMX 6Fire USB}}"); | 33 | MODULE_SUPPORTED_DEVICE("{{TerraTec, DMX 6Fire USB}}"); |
35 | 34 | ||
diff --git a/sound/usb/6fire/chip.h b/sound/usb/6fire/chip.h index d11e5cb520f0..bde02d105a51 100644 --- a/sound/usb/6fire/chip.h +++ b/sound/usb/6fire/chip.h | |||
@@ -3,7 +3,6 @@ | |||
3 | * | 3 | * |
4 | * Author: Torsten Schenk <torsten.schenk@zoho.com> | 4 | * Author: Torsten Schenk <torsten.schenk@zoho.com> |
5 | * Created: Jan 01, 2011 | 5 | * Created: Jan 01, 2011 |
6 | * Version: 0.3.0 | ||
7 | * Copyright: (C) Torsten Schenk | 6 | * Copyright: (C) Torsten Schenk |
8 | * | 7 | * |
9 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
diff --git a/sound/usb/6fire/comm.c b/sound/usb/6fire/comm.c index c994daa57af2..6c3d531a250e 100644 --- a/sound/usb/6fire/comm.c +++ b/sound/usb/6fire/comm.c | |||
@@ -5,7 +5,6 @@ | |||
5 | * | 5 | * |
6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> | 6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> |
7 | * Created: Jan 01, 2011 | 7 | * Created: Jan 01, 2011 |
8 | * Version: 0.3.0 | ||
9 | * Copyright: (C) Torsten Schenk | 8 | * Copyright: (C) Torsten Schenk |
10 | * | 9 | * |
11 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
diff --git a/sound/usb/6fire/comm.h b/sound/usb/6fire/comm.h index edc5dc84b888..d2af0a5ddcf3 100644 --- a/sound/usb/6fire/comm.h +++ b/sound/usb/6fire/comm.h | |||
@@ -3,7 +3,6 @@ | |||
3 | * | 3 | * |
4 | * Author: Torsten Schenk <torsten.schenk@zoho.com> | 4 | * Author: Torsten Schenk <torsten.schenk@zoho.com> |
5 | * Created: Jan 01, 2011 | 5 | * Created: Jan 01, 2011 |
6 | * Version: 0.3.0 | ||
7 | * Copyright: (C) Torsten Schenk | 6 | * Copyright: (C) Torsten Schenk |
8 | * | 7 | * |
9 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
diff --git a/sound/usb/6fire/common.h b/sound/usb/6fire/common.h index 7dbeb4a37831..b6eb03ed1c2c 100644 --- a/sound/usb/6fire/common.h +++ b/sound/usb/6fire/common.h | |||
@@ -3,7 +3,6 @@ | |||
3 | * | 3 | * |
4 | * Author: Torsten Schenk <torsten.schenk@zoho.com> | 4 | * Author: Torsten Schenk <torsten.schenk@zoho.com> |
5 | * Created: Jan 01, 2011 | 5 | * Created: Jan 01, 2011 |
6 | * Version: 0.3.0 | ||
7 | * Copyright: (C) Torsten Schenk | 6 | * Copyright: (C) Torsten Schenk |
8 | * | 7 | * |
9 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c index ac828eff1a63..07ed914d5e71 100644 --- a/sound/usb/6fire/control.c +++ b/sound/usb/6fire/control.c | |||
@@ -5,9 +5,12 @@ | |||
5 | * | 5 | * |
6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> | 6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> |
7 | * Created: Jan 01, 2011 | 7 | * Created: Jan 01, 2011 |
8 | * Version: 0.3.0 | ||
9 | * Copyright: (C) Torsten Schenk | 8 | * Copyright: (C) Torsten Schenk |
10 | * | 9 | * |
10 | * Thanks to: | ||
11 | * - Holger Ruckdeschel: he found out how to control individual channel | ||
12 | * volumes and introduced mute switch | ||
13 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | 14 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 15 | * it under the terms of the GNU General Public License as published by |
13 | * the Free Software Foundation; either version 2 of the License, or | 16 | * the Free Software Foundation; either version 2 of the License, or |
@@ -16,6 +19,7 @@ | |||
16 | 19 | ||
17 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
18 | #include <sound/control.h> | 21 | #include <sound/control.h> |
22 | #include <sound/tlv.h> | ||
19 | 23 | ||
20 | #include "control.h" | 24 | #include "control.h" |
21 | #include "comm.h" | 25 | #include "comm.h" |
@@ -25,26 +29,6 @@ static char *opt_coax_texts[2] = { "Optical", "Coax" }; | |||
25 | static char *line_phono_texts[2] = { "Line", "Phono" }; | 29 | static char *line_phono_texts[2] = { "Line", "Phono" }; |
26 | 30 | ||
27 | /* | 31 | /* |
28 | * calculated with $value\[i\] = 128 \cdot sqrt[3]{\frac{i}{128}}$ | ||
29 | * this is done because the linear values cause rapid degredation | ||
30 | * of volume in the uppermost region. | ||
31 | */ | ||
32 | static const u8 log_volume_table[128] = { | ||
33 | 0x00, 0x19, 0x20, 0x24, 0x28, 0x2b, 0x2e, 0x30, 0x32, 0x34, | ||
34 | 0x36, 0x38, 0x3a, 0x3b, 0x3d, 0x3e, 0x40, 0x41, 0x42, 0x43, | ||
35 | 0x44, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, | ||
36 | 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x53, 0x54, 0x55, 0x56, | ||
37 | 0x56, 0x57, 0x58, 0x58, 0x59, 0x5a, 0x5b, 0x5b, 0x5c, 0x5c, | ||
38 | 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x60, 0x61, 0x61, 0x62, 0x62, | ||
39 | 0x63, 0x63, 0x64, 0x65, 0x65, 0x66, 0x66, 0x67, 0x67, 0x68, | ||
40 | 0x68, 0x69, 0x69, 0x6a, 0x6a, 0x6b, 0x6b, 0x6c, 0x6c, 0x6c, | ||
41 | 0x6d, 0x6d, 0x6e, 0x6e, 0x6f, 0x6f, 0x70, 0x70, 0x70, 0x71, | ||
42 | 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x74, 0x75, 0x75, | ||
43 | 0x75, 0x76, 0x76, 0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, | ||
44 | 0x79, 0x7a, 0x7a, 0x7a, 0x7b, 0x7b, 0x7b, 0x7c, 0x7c, 0x7c, | ||
45 | 0x7d, 0x7d, 0x7d, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f }; | ||
46 | |||
47 | /* | ||
48 | * data that needs to be sent to device. sets up card internal stuff. | 32 | * data that needs to be sent to device. sets up card internal stuff. |
49 | * values dumped from windows driver and filtered by trial'n'error. | 33 | * values dumped from windows driver and filtered by trial'n'error. |
50 | */ | 34 | */ |
@@ -59,7 +43,7 @@ init_data[] = { | |||
59 | { 0x22, 0x03, 0x00 }, { 0x20, 0x03, 0x08 }, { 0x22, 0x04, 0x00 }, | 43 | { 0x22, 0x03, 0x00 }, { 0x20, 0x03, 0x08 }, { 0x22, 0x04, 0x00 }, |
60 | { 0x20, 0x04, 0x08 }, { 0x22, 0x05, 0x01 }, { 0x20, 0x05, 0x08 }, | 44 | { 0x20, 0x04, 0x08 }, { 0x22, 0x05, 0x01 }, { 0x20, 0x05, 0x08 }, |
61 | { 0x22, 0x04, 0x01 }, { 0x12, 0x04, 0x00 }, { 0x12, 0x05, 0x00 }, | 45 | { 0x22, 0x04, 0x01 }, { 0x12, 0x04, 0x00 }, { 0x12, 0x05, 0x00 }, |
62 | { 0x12, 0x0d, 0x78 }, { 0x12, 0x21, 0x82 }, { 0x12, 0x22, 0x80 }, | 46 | { 0x12, 0x0d, 0x38 }, { 0x12, 0x21, 0x82 }, { 0x12, 0x22, 0x80 }, |
63 | { 0x12, 0x23, 0x00 }, { 0x12, 0x06, 0x02 }, { 0x12, 0x03, 0x00 }, | 47 | { 0x12, 0x23, 0x00 }, { 0x12, 0x06, 0x02 }, { 0x12, 0x03, 0x00 }, |
64 | { 0x12, 0x02, 0x00 }, { 0x22, 0x03, 0x01 }, | 48 | { 0x12, 0x02, 0x00 }, { 0x22, 0x03, 0x01 }, |
65 | { 0 } /* TERMINATING ENTRY */ | 49 | { 0 } /* TERMINATING ENTRY */ |
@@ -70,20 +54,47 @@ static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 }; | |||
70 | static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}; | 54 | static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}; |
71 | static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00}; | 55 | static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00}; |
72 | 56 | ||
57 | static DECLARE_TLV_DB_MINMAX(tlv_output, -9000, 0); | ||
58 | static DECLARE_TLV_DB_MINMAX(tlv_input, -1500, 1500); | ||
59 | |||
73 | enum { | 60 | enum { |
74 | DIGITAL_THRU_ONLY_SAMPLERATE = 3 | 61 | DIGITAL_THRU_ONLY_SAMPLERATE = 3 |
75 | }; | 62 | }; |
76 | 63 | ||
77 | static void usb6fire_control_master_vol_update(struct control_runtime *rt) | 64 | static void usb6fire_control_output_vol_update(struct control_runtime *rt) |
78 | { | 65 | { |
79 | struct comm_runtime *comm_rt = rt->chip->comm; | 66 | struct comm_runtime *comm_rt = rt->chip->comm; |
80 | if (comm_rt) { | 67 | int i; |
81 | /* set volume */ | 68 | |
82 | comm_rt->write8(comm_rt, 0x12, 0x0f, 0x7f - | 69 | if (comm_rt) |
83 | log_volume_table[rt->master_vol]); | 70 | for (i = 0; i < 6; i++) |
84 | /* unmute */ | 71 | if (!(rt->ovol_updated & (1 << i))) { |
85 | comm_rt->write8(comm_rt, 0x12, 0x0e, 0x00); | 72 | comm_rt->write8(comm_rt, 0x12, 0x0f + i, |
86 | } | 73 | 180 - rt->output_vol[i]); |
74 | rt->ovol_updated |= 1 << i; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | static void usb6fire_control_output_mute_update(struct control_runtime *rt) | ||
79 | { | ||
80 | struct comm_runtime *comm_rt = rt->chip->comm; | ||
81 | |||
82 | if (comm_rt) | ||
83 | comm_rt->write8(comm_rt, 0x12, 0x0e, ~rt->output_mute); | ||
84 | } | ||
85 | |||
86 | static void usb6fire_control_input_vol_update(struct control_runtime *rt) | ||
87 | { | ||
88 | struct comm_runtime *comm_rt = rt->chip->comm; | ||
89 | int i; | ||
90 | |||
91 | if (comm_rt) | ||
92 | for (i = 0; i < 2; i++) | ||
93 | if (!(rt->ivol_updated & (1 << i))) { | ||
94 | comm_rt->write8(comm_rt, 0x12, 0x1c + i, | ||
95 | rt->input_vol[i] & 0x3f); | ||
96 | rt->ivol_updated |= 1 << i; | ||
97 | } | ||
87 | } | 98 | } |
88 | 99 | ||
89 | static void usb6fire_control_line_phono_update(struct control_runtime *rt) | 100 | static void usb6fire_control_line_phono_update(struct control_runtime *rt) |
@@ -165,34 +176,147 @@ static int usb6fire_control_streaming_update(struct control_runtime *rt) | |||
165 | return -EINVAL; | 176 | return -EINVAL; |
166 | } | 177 | } |
167 | 178 | ||
168 | static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol, | 179 | static int usb6fire_control_output_vol_info(struct snd_kcontrol *kcontrol, |
169 | struct snd_ctl_elem_info *uinfo) | 180 | struct snd_ctl_elem_info *uinfo) |
170 | { | 181 | { |
171 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 182 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
172 | uinfo->count = 1; | 183 | uinfo->count = 2; |
173 | uinfo->value.integer.min = 0; | 184 | uinfo->value.integer.min = 0; |
174 | uinfo->value.integer.max = 127; | 185 | uinfo->value.integer.max = 180; |
175 | return 0; | 186 | return 0; |
176 | } | 187 | } |
177 | 188 | ||
178 | static int usb6fire_control_master_vol_put(struct snd_kcontrol *kcontrol, | 189 | static int usb6fire_control_output_vol_put(struct snd_kcontrol *kcontrol, |
179 | struct snd_ctl_elem_value *ucontrol) | 190 | struct snd_ctl_elem_value *ucontrol) |
180 | { | 191 | { |
181 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); | 192 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); |
193 | unsigned int ch = kcontrol->private_value; | ||
182 | int changed = 0; | 194 | int changed = 0; |
183 | if (rt->master_vol != ucontrol->value.integer.value[0]) { | 195 | |
184 | rt->master_vol = ucontrol->value.integer.value[0]; | 196 | if (ch > 4) { |
185 | usb6fire_control_master_vol_update(rt); | 197 | snd_printk(KERN_ERR PREFIX "Invalid channel in volume control."); |
198 | return -EINVAL; | ||
199 | } | ||
200 | |||
201 | if (rt->output_vol[ch] != ucontrol->value.integer.value[0]) { | ||
202 | rt->output_vol[ch] = ucontrol->value.integer.value[0]; | ||
203 | rt->ovol_updated &= ~(1 << ch); | ||
186 | changed = 1; | 204 | changed = 1; |
187 | } | 205 | } |
206 | if (rt->output_vol[ch + 1] != ucontrol->value.integer.value[1]) { | ||
207 | rt->output_vol[ch + 1] = ucontrol->value.integer.value[1]; | ||
208 | rt->ovol_updated &= ~(2 << ch); | ||
209 | changed = 1; | ||
210 | } | ||
211 | |||
212 | if (changed) | ||
213 | usb6fire_control_output_vol_update(rt); | ||
214 | |||
188 | return changed; | 215 | return changed; |
189 | } | 216 | } |
190 | 217 | ||
191 | static int usb6fire_control_master_vol_get(struct snd_kcontrol *kcontrol, | 218 | static int usb6fire_control_output_vol_get(struct snd_kcontrol *kcontrol, |
192 | struct snd_ctl_elem_value *ucontrol) | 219 | struct snd_ctl_elem_value *ucontrol) |
193 | { | 220 | { |
194 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); | 221 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); |
195 | ucontrol->value.integer.value[0] = rt->master_vol; | 222 | unsigned int ch = kcontrol->private_value; |
223 | |||
224 | if (ch > 4) { | ||
225 | snd_printk(KERN_ERR PREFIX "Invalid channel in volume control."); | ||
226 | return -EINVAL; | ||
227 | } | ||
228 | |||
229 | ucontrol->value.integer.value[0] = rt->output_vol[ch]; | ||
230 | ucontrol->value.integer.value[1] = rt->output_vol[ch + 1]; | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static int usb6fire_control_output_mute_put(struct snd_kcontrol *kcontrol, | ||
235 | struct snd_ctl_elem_value *ucontrol) | ||
236 | { | ||
237 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); | ||
238 | unsigned int ch = kcontrol->private_value; | ||
239 | u8 old = rt->output_mute; | ||
240 | u8 value = 0; | ||
241 | |||
242 | if (ch > 4) { | ||
243 | snd_printk(KERN_ERR PREFIX "Invalid channel in volume control."); | ||
244 | return -EINVAL; | ||
245 | } | ||
246 | |||
247 | rt->output_mute &= ~(3 << ch); | ||
248 | if (ucontrol->value.integer.value[0]) | ||
249 | value |= 1; | ||
250 | if (ucontrol->value.integer.value[1]) | ||
251 | value |= 2; | ||
252 | rt->output_mute |= value << ch; | ||
253 | |||
254 | if (rt->output_mute != old) | ||
255 | usb6fire_control_output_mute_update(rt); | ||
256 | |||
257 | return rt->output_mute != old; | ||
258 | } | ||
259 | |||
260 | static int usb6fire_control_output_mute_get(struct snd_kcontrol *kcontrol, | ||
261 | struct snd_ctl_elem_value *ucontrol) | ||
262 | { | ||
263 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); | ||
264 | unsigned int ch = kcontrol->private_value; | ||
265 | u8 value = rt->output_mute >> ch; | ||
266 | |||
267 | if (ch > 4) { | ||
268 | snd_printk(KERN_ERR PREFIX "Invalid channel in volume control."); | ||
269 | return -EINVAL; | ||
270 | } | ||
271 | |||
272 | ucontrol->value.integer.value[0] = 1 & value; | ||
273 | value >>= 1; | ||
274 | ucontrol->value.integer.value[1] = 1 & value; | ||
275 | |||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static int usb6fire_control_input_vol_info(struct snd_kcontrol *kcontrol, | ||
280 | struct snd_ctl_elem_info *uinfo) | ||
281 | { | ||
282 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
283 | uinfo->count = 2; | ||
284 | uinfo->value.integer.min = 0; | ||
285 | uinfo->value.integer.max = 30; | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int usb6fire_control_input_vol_put(struct snd_kcontrol *kcontrol, | ||
290 | struct snd_ctl_elem_value *ucontrol) | ||
291 | { | ||
292 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); | ||
293 | int changed = 0; | ||
294 | |||
295 | if (rt->input_vol[0] != ucontrol->value.integer.value[0]) { | ||
296 | rt->input_vol[0] = ucontrol->value.integer.value[0] - 15; | ||
297 | rt->ivol_updated &= ~(1 << 0); | ||
298 | changed = 1; | ||
299 | } | ||
300 | if (rt->input_vol[1] != ucontrol->value.integer.value[1]) { | ||
301 | rt->input_vol[1] = ucontrol->value.integer.value[1] - 15; | ||
302 | rt->ivol_updated &= ~(1 << 1); | ||
303 | changed = 1; | ||
304 | } | ||
305 | |||
306 | if (changed) | ||
307 | usb6fire_control_input_vol_update(rt); | ||
308 | |||
309 | return changed; | ||
310 | } | ||
311 | |||
312 | static int usb6fire_control_input_vol_get(struct snd_kcontrol *kcontrol, | ||
313 | struct snd_ctl_elem_value *ucontrol) | ||
314 | { | ||
315 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); | ||
316 | |||
317 | ucontrol->value.integer.value[0] = rt->input_vol[0] + 15; | ||
318 | ucontrol->value.integer.value[1] = rt->input_vol[1] + 15; | ||
319 | |||
196 | return 0; | 320 | return 0; |
197 | } | 321 | } |
198 | 322 | ||
@@ -287,18 +411,83 @@ static int usb6fire_control_digital_thru_get(struct snd_kcontrol *kcontrol, | |||
287 | return 0; | 411 | return 0; |
288 | } | 412 | } |
289 | 413 | ||
290 | static struct __devinitdata snd_kcontrol_new elements[] = { | 414 | static struct __devinitdata snd_kcontrol_new vol_elements[] = { |
291 | { | 415 | { |
292 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 416 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
293 | .name = "Master Playback Volume", | 417 | .name = "Analog Playback Volume", |
294 | .index = 0, | 418 | .index = 0, |
419 | .private_value = 0, | ||
420 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
421 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
422 | .info = usb6fire_control_output_vol_info, | ||
423 | .get = usb6fire_control_output_vol_get, | ||
424 | .put = usb6fire_control_output_vol_put, | ||
425 | .tlv = { .p = tlv_output } | ||
426 | }, | ||
427 | { | ||
428 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
429 | .name = "Analog Playback Volume", | ||
430 | .index = 1, | ||
431 | .private_value = 2, | ||
432 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
433 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
434 | .info = usb6fire_control_output_vol_info, | ||
435 | .get = usb6fire_control_output_vol_get, | ||
436 | .put = usb6fire_control_output_vol_put, | ||
437 | .tlv = { .p = tlv_output } | ||
438 | }, | ||
439 | { | ||
440 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
441 | .name = "Analog Playback Volume", | ||
442 | .index = 2, | ||
443 | .private_value = 4, | ||
444 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
445 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
446 | .info = usb6fire_control_output_vol_info, | ||
447 | .get = usb6fire_control_output_vol_get, | ||
448 | .put = usb6fire_control_output_vol_put, | ||
449 | .tlv = { .p = tlv_output } | ||
450 | }, | ||
451 | {} | ||
452 | }; | ||
453 | |||
454 | static struct __devinitdata snd_kcontrol_new mute_elements[] = { | ||
455 | { | ||
456 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
457 | .name = "Analog Playback Switch", | ||
458 | .index = 0, | ||
459 | .private_value = 0, | ||
460 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
461 | .info = snd_ctl_boolean_stereo_info, | ||
462 | .get = usb6fire_control_output_mute_get, | ||
463 | .put = usb6fire_control_output_mute_put, | ||
464 | }, | ||
465 | { | ||
466 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
467 | .name = "Analog Playback Switch", | ||
468 | .index = 1, | ||
469 | .private_value = 2, | ||
295 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 470 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
296 | .info = usb6fire_control_master_vol_info, | 471 | .info = snd_ctl_boolean_stereo_info, |
297 | .get = usb6fire_control_master_vol_get, | 472 | .get = usb6fire_control_output_mute_get, |
298 | .put = usb6fire_control_master_vol_put | 473 | .put = usb6fire_control_output_mute_put, |
299 | }, | 474 | }, |
300 | { | 475 | { |
301 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 476 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
477 | .name = "Analog Playback Switch", | ||
478 | .index = 2, | ||
479 | .private_value = 4, | ||
480 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
481 | .info = snd_ctl_boolean_stereo_info, | ||
482 | .get = usb6fire_control_output_mute_get, | ||
483 | .put = usb6fire_control_output_mute_put, | ||
484 | }, | ||
485 | {} | ||
486 | }; | ||
487 | |||
488 | static struct __devinitdata snd_kcontrol_new elements[] = { | ||
489 | { | ||
490 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
302 | .name = "Line/Phono Capture Route", | 491 | .name = "Line/Phono Capture Route", |
303 | .index = 0, | 492 | .index = 0, |
304 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 493 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
@@ -324,9 +513,54 @@ static struct __devinitdata snd_kcontrol_new elements[] = { | |||
324 | .get = usb6fire_control_digital_thru_get, | 513 | .get = usb6fire_control_digital_thru_get, |
325 | .put = usb6fire_control_digital_thru_put | 514 | .put = usb6fire_control_digital_thru_put |
326 | }, | 515 | }, |
516 | { | ||
517 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
518 | .name = "Analog Capture Volume", | ||
519 | .index = 0, | ||
520 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
521 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
522 | .info = usb6fire_control_input_vol_info, | ||
523 | .get = usb6fire_control_input_vol_get, | ||
524 | .put = usb6fire_control_input_vol_put, | ||
525 | .tlv = { .p = tlv_input } | ||
526 | }, | ||
327 | {} | 527 | {} |
328 | }; | 528 | }; |
329 | 529 | ||
530 | static int usb6fire_control_add_virtual( | ||
531 | struct control_runtime *rt, | ||
532 | struct snd_card *card, | ||
533 | char *name, | ||
534 | struct snd_kcontrol_new *elems) | ||
535 | { | ||
536 | int ret; | ||
537 | int i; | ||
538 | struct snd_kcontrol *vmaster = | ||
539 | snd_ctl_make_virtual_master(name, tlv_output); | ||
540 | struct snd_kcontrol *control; | ||
541 | |||
542 | if (!vmaster) | ||
543 | return -ENOMEM; | ||
544 | ret = snd_ctl_add(card, vmaster); | ||
545 | if (ret < 0) | ||
546 | return ret; | ||
547 | |||
548 | i = 0; | ||
549 | while (elems[i].name) { | ||
550 | control = snd_ctl_new1(&elems[i], rt); | ||
551 | if (!control) | ||
552 | return -ENOMEM; | ||
553 | ret = snd_ctl_add(card, control); | ||
554 | if (ret < 0) | ||
555 | return ret; | ||
556 | ret = snd_ctl_add_slave(vmaster, control); | ||
557 | if (ret < 0) | ||
558 | return ret; | ||
559 | i++; | ||
560 | } | ||
561 | return 0; | ||
562 | } | ||
563 | |||
330 | int __devinit usb6fire_control_init(struct sfire_chip *chip) | 564 | int __devinit usb6fire_control_init(struct sfire_chip *chip) |
331 | { | 565 | { |
332 | int i; | 566 | int i; |
@@ -352,9 +586,26 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip) | |||
352 | 586 | ||
353 | usb6fire_control_opt_coax_update(rt); | 587 | usb6fire_control_opt_coax_update(rt); |
354 | usb6fire_control_line_phono_update(rt); | 588 | usb6fire_control_line_phono_update(rt); |
355 | usb6fire_control_master_vol_update(rt); | 589 | usb6fire_control_output_vol_update(rt); |
590 | usb6fire_control_output_mute_update(rt); | ||
591 | usb6fire_control_input_vol_update(rt); | ||
356 | usb6fire_control_streaming_update(rt); | 592 | usb6fire_control_streaming_update(rt); |
357 | 593 | ||
594 | ret = usb6fire_control_add_virtual(rt, chip->card, | ||
595 | "Master Playback Volume", vol_elements); | ||
596 | if (ret) { | ||
597 | snd_printk(KERN_ERR PREFIX "cannot add control.\n"); | ||
598 | kfree(rt); | ||
599 | return ret; | ||
600 | } | ||
601 | ret = usb6fire_control_add_virtual(rt, chip->card, | ||
602 | "Master Playback Switch", mute_elements); | ||
603 | if (ret) { | ||
604 | snd_printk(KERN_ERR PREFIX "cannot add control.\n"); | ||
605 | kfree(rt); | ||
606 | return ret; | ||
607 | } | ||
608 | |||
358 | i = 0; | 609 | i = 0; |
359 | while (elements[i].name) { | 610 | while (elements[i].name) { |
360 | ret = snd_ctl_add(chip->card, snd_ctl_new1(&elements[i], rt)); | 611 | ret = snd_ctl_add(chip->card, snd_ctl_new1(&elements[i], rt)); |
diff --git a/sound/usb/6fire/control.h b/sound/usb/6fire/control.h index 8f5aeead2e3d..9a596d95474a 100644 --- a/sound/usb/6fire/control.h +++ b/sound/usb/6fire/control.h | |||
@@ -3,7 +3,6 @@ | |||
3 | * | 3 | * |
4 | * Author: Torsten Schenk <torsten.schenk@zoho.com> | 4 | * Author: Torsten Schenk <torsten.schenk@zoho.com> |
5 | * Created: Jan 01, 2011 | 5 | * Created: Jan 01, 2011 |
6 | * Version: 0.3.0 | ||
7 | * Copyright: (C) Torsten Schenk | 6 | * Copyright: (C) Torsten Schenk |
8 | * | 7 | * |
9 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
@@ -44,7 +43,11 @@ struct control_runtime { | |||
44 | bool line_phono_switch; | 43 | bool line_phono_switch; |
45 | bool digital_thru_switch; | 44 | bool digital_thru_switch; |
46 | bool usb_streaming; | 45 | bool usb_streaming; |
47 | u8 master_vol; | 46 | u8 output_vol[6]; |
47 | u8 ovol_updated; | ||
48 | u8 output_mute; | ||
49 | s8 input_vol[2]; | ||
50 | u8 ivol_updated; | ||
48 | }; | 51 | }; |
49 | 52 | ||
50 | int __devinit usb6fire_control_init(struct sfire_chip *chip); | 53 | int __devinit usb6fire_control_init(struct sfire_chip *chip); |
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index 3b5f517a3972..6f9715ab32fe 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c | |||
@@ -5,7 +5,6 @@ | |||
5 | * | 5 | * |
6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> | 6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> |
7 | * Created: Jan 01, 2011 | 7 | * Created: Jan 01, 2011 |
8 | * Version: 0.3.0 | ||
9 | * Copyright: (C) Torsten Schenk | 8 | * Copyright: (C) Torsten Schenk |
10 | * | 9 | * |
11 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
diff --git a/sound/usb/6fire/midi.c b/sound/usb/6fire/midi.c index 13f4509dce2b..f0e5179b242b 100644 --- a/sound/usb/6fire/midi.c +++ b/sound/usb/6fire/midi.c | |||
@@ -5,7 +5,6 @@ | |||
5 | * | 5 | * |
6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> | 6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> |
7 | * Created: Jan 01, 2011 | 7 | * Created: Jan 01, 2011 |
8 | * Version: 0.3.0 | ||
9 | * Copyright: (C) Torsten Schenk | 8 | * Copyright: (C) Torsten Schenk |
10 | * | 9 | * |
11 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
diff --git a/sound/usb/6fire/midi.h b/sound/usb/6fire/midi.h index 97a7bf669135..5114eccc1d8e 100644 --- a/sound/usb/6fire/midi.h +++ b/sound/usb/6fire/midi.h | |||
@@ -3,7 +3,6 @@ | |||
3 | * | 3 | * |
4 | * Author: Torsten Schenk <torsten.schenk@zoho.com> | 4 | * Author: Torsten Schenk <torsten.schenk@zoho.com> |
5 | * Created: Jan 01, 2011 | 5 | * Created: Jan 01, 2011 |
6 | * Version: 0.3.0 | ||
7 | * Copyright: (C) Torsten Schenk | 6 | * Copyright: (C) Torsten Schenk |
8 | * | 7 | * |
9 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index d144cdb2f159..c97d05f0e966 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c | |||
@@ -5,7 +5,6 @@ | |||
5 | * | 5 | * |
6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> | 6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> |
7 | * Created: Jan 01, 2011 | 7 | * Created: Jan 01, 2011 |
8 | * Version: 0.3.0 | ||
9 | * Copyright: (C) Torsten Schenk | 8 | * Copyright: (C) Torsten Schenk |
10 | * | 9 | * |
11 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
diff --git a/sound/usb/6fire/pcm.h b/sound/usb/6fire/pcm.h index 2bee81374002..3104301b257d 100644 --- a/sound/usb/6fire/pcm.h +++ b/sound/usb/6fire/pcm.h | |||
@@ -3,7 +3,6 @@ | |||
3 | * | 3 | * |
4 | * Author: Torsten Schenk <torsten.schenk@zoho.com> | 4 | * Author: Torsten Schenk <torsten.schenk@zoho.com> |
5 | * Created: Jan 01, 2011 | 5 | * Created: Jan 01, 2011 |
6 | * Version: 0.3.0 | ||
7 | * Copyright: (C) Torsten Schenk | 6 | * Copyright: (C) Torsten Schenk |
8 | * | 7 | * |
9 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index 3efc21c3d67c..ff77b28f3da1 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig | |||
@@ -106,6 +106,7 @@ config SND_USB_6FIRE | |||
106 | select BITREVERSE | 106 | select BITREVERSE |
107 | select SND_RAWMIDI | 107 | select SND_RAWMIDI |
108 | select SND_PCM | 108 | select SND_PCM |
109 | select SND_VMASTER | ||
109 | help | 110 | help |
110 | Say Y here to include support for TerraTec 6fire DMX USB interface. | 111 | Say Y here to include support for TerraTec 6fire DMX USB interface. |
111 | 112 | ||
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index 2cf87f5afed4..fde9a7a29cb6 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c | |||
@@ -311,8 +311,10 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) | |||
311 | 311 | ||
312 | spin_lock(&dev->spinlock); | 312 | spin_lock(&dev->spinlock); |
313 | 313 | ||
314 | if (dev->input_panic || dev->output_panic) | 314 | if (dev->input_panic || dev->output_panic) { |
315 | ptr = SNDRV_PCM_POS_XRUN; | 315 | ptr = SNDRV_PCM_POS_XRUN; |
316 | goto unlock; | ||
317 | } | ||
316 | 318 | ||
317 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) | 319 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) |
318 | ptr = bytes_to_frames(sub->runtime, | 320 | ptr = bytes_to_frames(sub->runtime, |
@@ -321,6 +323,7 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) | |||
321 | ptr = bytes_to_frames(sub->runtime, | 323 | ptr = bytes_to_frames(sub->runtime, |
322 | dev->audio_in_buf_pos[index]); | 324 | dev->audio_in_buf_pos[index]); |
323 | 325 | ||
326 | unlock: | ||
324 | spin_unlock(&dev->spinlock); | 327 | spin_unlock(&dev->spinlock); |
325 | return ptr; | 328 | return ptr; |
326 | } | 329 | } |
diff --git a/sound/usb/card.h b/sound/usb/card.h index a39edcc32a93..da5fa1ac4eda 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef __USBAUDIO_CARD_H | 1 | #ifndef __USBAUDIO_CARD_H |
2 | #define __USBAUDIO_CARD_H | 2 | #define __USBAUDIO_CARD_H |
3 | 3 | ||
4 | #define MAX_NR_RATES 1024 | ||
4 | #define MAX_PACKS 20 | 5 | #define MAX_PACKS 20 |
5 | #define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */ | 6 | #define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */ |
6 | #define MAX_URBS 8 | 7 | #define MAX_URBS 8 |
diff --git a/sound/usb/format.c b/sound/usb/format.c index e09aba19375c..ddfef57c4c9f 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c | |||
@@ -209,8 +209,6 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof | |||
209 | return 0; | 209 | return 0; |
210 | } | 210 | } |
211 | 211 | ||
212 | #define MAX_UAC2_NR_RATES 1024 | ||
213 | |||
214 | /* | 212 | /* |
215 | * Helper function to walk the array of sample rate triplets reported by | 213 | * Helper function to walk the array of sample rate triplets reported by |
216 | * the device. The problem is that we need to parse whole array first to | 214 | * the device. The problem is that we need to parse whole array first to |
@@ -255,7 +253,7 @@ static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets, | |||
255 | fp->rates |= snd_pcm_rate_to_rate_bit(rate); | 253 | fp->rates |= snd_pcm_rate_to_rate_bit(rate); |
256 | 254 | ||
257 | nr_rates++; | 255 | nr_rates++; |
258 | if (nr_rates >= MAX_UAC2_NR_RATES) { | 256 | if (nr_rates >= MAX_NR_RATES) { |
259 | snd_printk(KERN_ERR "invalid uac2 rates\n"); | 257 | snd_printk(KERN_ERR "invalid uac2 rates\n"); |
260 | break; | 258 | break; |
261 | } | 259 | } |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 0220b0f335b9..0eed6115c2d4 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -695,6 +695,7 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, | |||
695 | struct snd_usb_substream *subs) | 695 | struct snd_usb_substream *subs) |
696 | { | 696 | { |
697 | struct audioformat *fp; | 697 | struct audioformat *fp; |
698 | int *rate_list; | ||
698 | int count = 0, needs_knot = 0; | 699 | int count = 0, needs_knot = 0; |
699 | int err; | 700 | int err; |
700 | 701 | ||
@@ -708,7 +709,8 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, | |||
708 | if (!needs_knot) | 709 | if (!needs_knot) |
709 | return 0; | 710 | return 0; |
710 | 711 | ||
711 | subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL); | 712 | subs->rate_list.list = rate_list = |
713 | kmalloc(sizeof(int) * count, GFP_KERNEL); | ||
712 | if (!subs->rate_list.list) | 714 | if (!subs->rate_list.list) |
713 | return -ENOMEM; | 715 | return -ENOMEM; |
714 | subs->rate_list.count = count; | 716 | subs->rate_list.count = count; |
@@ -717,7 +719,7 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, | |||
717 | list_for_each_entry(fp, &subs->fmt_list, list) { | 719 | list_for_each_entry(fp, &subs->fmt_list, list) { |
718 | int i; | 720 | int i; |
719 | for (i = 0; i < fp->nr_rates; i++) | 721 | for (i = 0; i < fp->nr_rates; i++) |
720 | subs->rate_list.list[count++] = fp->rate_table[i]; | 722 | rate_list[count++] = fp->rate_table[i]; |
721 | } | 723 | } |
722 | err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 724 | err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
723 | &subs->rate_list); | 725 | &subs->rate_list); |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 8edc5035fc8f..d89ab4c7d44b 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -1618,6 +1618,14 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1618 | } | 1618 | } |
1619 | }, | 1619 | }, |
1620 | { | 1620 | { |
1621 | /* Edirol UM-3G */ | ||
1622 | USB_DEVICE_VENDOR_SPEC(0x0582, 0x0108), | ||
1623 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1624 | .ifnum = 0, | ||
1625 | .type = QUIRK_MIDI_STANDARD_INTERFACE | ||
1626 | } | ||
1627 | }, | ||
1628 | { | ||
1621 | /* Boss JS-8 Jam Station */ | 1629 | /* Boss JS-8 Jam Station */ |
1622 | USB_DEVICE(0x0582, 0x0109), | 1630 | USB_DEVICE(0x0582, 0x0109), |
1623 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 1631 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index a3ddac0deffd..27817266867a 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -132,10 +132,14 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, | |||
132 | unsigned *rate_table = NULL; | 132 | unsigned *rate_table = NULL; |
133 | 133 | ||
134 | fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL); | 134 | fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL); |
135 | if (! fp) { | 135 | if (!fp) { |
136 | snd_printk(KERN_ERR "cannot memdup\n"); | 136 | snd_printk(KERN_ERR "cannot memdup\n"); |
137 | return -ENOMEM; | 137 | return -ENOMEM; |
138 | } | 138 | } |
139 | if (fp->nr_rates > MAX_NR_RATES) { | ||
140 | kfree(fp); | ||
141 | return -EINVAL; | ||
142 | } | ||
139 | if (fp->nr_rates > 0) { | 143 | if (fp->nr_rates > 0) { |
140 | rate_table = kmemdup(fp->rate_table, | 144 | rate_table = kmemdup(fp->rate_table, |
141 | sizeof(int) * fp->nr_rates, GFP_KERNEL); | 145 | sizeof(int) * fp->nr_rates, GFP_KERNEL); |
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index 6ffb3713b60c..520ef96d7c75 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c | |||
@@ -80,7 +80,7 @@ static int usX2Y_urb_capt_retire(struct snd_usX2Y_substream *subs) | |||
80 | cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset; | 80 | cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset; |
81 | if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */ | 81 | if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */ |
82 | snd_printk(KERN_ERR "active frame status %i. " | 82 | snd_printk(KERN_ERR "active frame status %i. " |
83 | "Most propably some hardware problem.\n", | 83 | "Most probably some hardware problem.\n", |
84 | urb->iso_frame_desc[i].status); | 84 | urb->iso_frame_desc[i].status); |
85 | return urb->iso_frame_desc[i].status; | 85 | return urb->iso_frame_desc[i].status; |
86 | } | 86 | } |
@@ -300,7 +300,7 @@ static void usX2Y_error_sequence(struct usX2Ydev *usX2Y, | |||
300 | { | 300 | { |
301 | snd_printk(KERN_ERR | 301 | snd_printk(KERN_ERR |
302 | "Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n" | 302 | "Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n" |
303 | "Most propably some urb of usb-frame %i is still missing.\n" | 303 | "Most probably some urb of usb-frame %i is still missing.\n" |
304 | "Cause could be too long delays in usb-hcd interrupt handling.\n", | 304 | "Cause could be too long delays in usb-hcd interrupt handling.\n", |
305 | usb_get_current_frame_number(usX2Y->dev), | 305 | usb_get_current_frame_number(usX2Y->dev), |
306 | subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", | 306 | subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", |
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index a51340f6f2db..8e40b6e67e9e 100644 --- a/sound/usb/usx2y/usx2yhwdeppcm.c +++ b/sound/usb/usx2y/usx2yhwdeppcm.c | |||
@@ -74,7 +74,7 @@ static int usX2Y_usbpcm_urb_capt_retire(struct snd_usX2Y_substream *subs) | |||
74 | } | 74 | } |
75 | for (i = 0; i < nr_of_packs(); i++) { | 75 | for (i = 0; i < nr_of_packs(); i++) { |
76 | if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */ | 76 | if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */ |
77 | snd_printk(KERN_ERR "activ frame status %i. Most propably some hardware problem.\n", urb->iso_frame_desc[i].status); | 77 | snd_printk(KERN_ERR "active frame status %i. Most probably some hardware problem.\n", urb->iso_frame_desc[i].status); |
78 | return urb->iso_frame_desc[i].status; | 78 | return urb->iso_frame_desc[i].status; |
79 | } | 79 | } |
80 | lens += urb->iso_frame_desc[i].actual_length / usX2Y->stride; | 80 | lens += urb->iso_frame_desc[i].actual_length / usX2Y->stride; |