|
32 | 32 | #include <linux/module.h> |
33 | 33 | #include <linux/of.h> |
34 | 34 | #include <linux/slab.h> |
| 35 | +#include <sound/asoundef.h> |
35 | 36 | MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); |
36 | 37 | MODULE_LICENSE("GPL"); |
37 | 38 | MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa"); |
@@ -514,8 +515,36 @@ static int onyx_spdif_put(struct snd_kcontrol *kcontrol, |
514 | 515 | return 1; |
515 | 516 | } |
516 | 517 |
|
| 518 | +static int onyx_set_spdif_pcm_rate(struct onyx *onyx, unsigned int rate) |
| 519 | +{ |
| 520 | + u8 dig_info3, fs; |
| 521 | + |
| 522 | + switch (rate) { |
| 523 | + case 32000: |
| 524 | + fs = IEC958_AES3_CON_FS_32000; |
| 525 | + break; |
| 526 | + case 44100: |
| 527 | + fs = IEC958_AES3_CON_FS_44100; |
| 528 | + break; |
| 529 | + case 48000: |
| 530 | + fs = IEC958_AES3_CON_FS_48000; |
| 531 | + break; |
| 532 | + default: |
| 533 | + return -EINVAL; |
| 534 | + } |
| 535 | + |
| 536 | + if (onyx_read_register(onyx, ONYX_REG_DIG_INFO3, &dig_info3)) |
| 537 | + return -EBUSY; |
| 538 | + dig_info3 = (dig_info3 & ~IEC958_AES3_CON_FS) | fs; |
| 539 | + if (onyx_write_register(onyx, ONYX_REG_DIG_INFO3, dig_info3)) |
| 540 | + return -EBUSY; |
| 541 | + |
| 542 | + return 0; |
| 543 | +} |
| 544 | + |
517 | 545 | static const struct snd_kcontrol_new onyx_spdif_ctrl = { |
518 | | - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
| 546 | + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | |
| 547 | + SNDRV_CTL_ELEM_ACCESS_VOLATILE, |
519 | 548 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, |
520 | 549 | .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), |
521 | 550 | .info = onyx_spdif_info, |
@@ -695,9 +724,9 @@ static int onyx_prepare(struct codec_info_item *cii, |
695 | 724 | case 32000: |
696 | 725 | case 44100: |
697 | 726 | case 48000: |
698 | | - /* these rates are ok for all outputs */ |
699 | | - /* FIXME: program spdif channel control bits here so that |
700 | | - * userspace doesn't have to if it only plays pcm! */ |
| 727 | + if (onyx->codec.connected & 2) |
| 728 | + return onyx_set_spdif_pcm_rate(onyx, |
| 729 | + substream->runtime->rate); |
701 | 730 | return 0; |
702 | 731 | default: |
703 | 732 | /* got some rate that the digital output can't do, |
@@ -980,10 +1009,12 @@ static int onyx_i2c_probe(struct i2c_client *client) |
980 | 1009 | onyx->codec.node = of_node_get(node); |
981 | 1010 |
|
982 | 1011 | if (aoa_codec_register(&onyx->codec)) { |
983 | | - goto fail; |
| 1012 | + goto fail_put; |
984 | 1013 | } |
985 | 1014 | printk(KERN_DEBUG PFX "created and attached onyx instance\n"); |
986 | 1015 | return 0; |
| 1016 | + fail_put: |
| 1017 | + of_node_put(onyx->codec.node); |
987 | 1018 | fail: |
988 | 1019 | kfree(onyx); |
989 | 1020 | return -ENODEV; |
|
0 commit comments