diff options
author | Takashi Iwai <tiwai@suse.de> | 2014-10-27 09:11:07 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-10-27 09:11:07 -0400 |
commit | 85c24cd8d3676cbae9e8809e894e68025c6d497e (patch) | |
tree | 024c4b655c1a8e6943ed8e75b64be38980508cfe /sound/firewire/bebob | |
parent | 49d776ffb50f2e428aafb6a6576e58e80f1e886c (diff) | |
parent | d1d0b6b668818571122d30d68a0b3f768bd83a52 (diff) |
Merge branch 'for-linus' into for-next
Merged upstream branch to make further fireworks development easier
(and avoid conflicts earlier).
Conflicts:
sound/firewire/bebob/bebob_focusrite.c
Diffstat (limited to 'sound/firewire/bebob')
-rw-r--r-- | sound/firewire/bebob/bebob_focusrite.c | 62 | ||||
-rw-r--r-- | sound/firewire/bebob/bebob_stream.c | 18 | ||||
-rw-r--r-- | sound/firewire/bebob/bebob_terratec.c | 7 |
3 files changed, 69 insertions, 18 deletions
diff --git a/sound/firewire/bebob/bebob_focusrite.c b/sound/firewire/bebob/bebob_focusrite.c index a45a86952a41..fc67c1b7cb5b 100644 --- a/sound/firewire/bebob/bebob_focusrite.c +++ b/sound/firewire/bebob/bebob_focusrite.c | |||
@@ -27,12 +27,14 @@ | |||
27 | #define SAFFIRE_CLOCK_SOURCE_INTERNAL 0 | 27 | #define SAFFIRE_CLOCK_SOURCE_INTERNAL 0 |
28 | #define SAFFIRE_CLOCK_SOURCE_SPDIF 1 | 28 | #define SAFFIRE_CLOCK_SOURCE_SPDIF 1 |
29 | 29 | ||
30 | /* '1' is absent, why... */ | 30 | /* clock sources as returned from register of Saffire Pro 10 and 26 */ |
31 | #define SAFFIREPRO_CLOCK_SOURCE_INTERNAL 0 | 31 | #define SAFFIREPRO_CLOCK_SOURCE_INTERNAL 0 |
32 | #define SAFFIREPRO_CLOCK_SOURCE_SKIP 1 /* never used on hardware */ | ||
32 | #define SAFFIREPRO_CLOCK_SOURCE_SPDIF 2 | 33 | #define SAFFIREPRO_CLOCK_SOURCE_SPDIF 2 |
33 | #define SAFFIREPRO_CLOCK_SOURCE_ADAT1 3 | 34 | #define SAFFIREPRO_CLOCK_SOURCE_ADAT1 3 /* not used on s.pro. 10 */ |
34 | #define SAFFIREPRO_CLOCK_SOURCE_ADAT2 4 | 35 | #define SAFFIREPRO_CLOCK_SOURCE_ADAT2 4 /* not used on s.pro. 10 */ |
35 | #define SAFFIREPRO_CLOCK_SOURCE_WORDCLOCK 5 | 36 | #define SAFFIREPRO_CLOCK_SOURCE_WORDCLOCK 5 |
37 | #define SAFFIREPRO_CLOCK_SOURCE_COUNT 6 | ||
36 | 38 | ||
37 | /* S/PDIF, ADAT1, ADAT2 is enabled or not. three quadlets */ | 39 | /* S/PDIF, ADAT1, ADAT2 is enabled or not. three quadlets */ |
38 | #define SAFFIREPRO_ENABLE_DIG_IFACES 0x01a4 | 40 | #define SAFFIREPRO_ENABLE_DIG_IFACES 0x01a4 |
@@ -101,13 +103,34 @@ saffire_write_quad(struct snd_bebob *bebob, u64 offset, u32 value) | |||
101 | &data, sizeof(__be32), 0); | 103 | &data, sizeof(__be32), 0); |
102 | } | 104 | } |
103 | 105 | ||
106 | static const char *const saffirepro_10_clk_src_labels[] = { | ||
107 | SND_BEBOB_CLOCK_INTERNAL, "S/PDIF", "Word Clock" | ||
108 | }; | ||
104 | static const char *const saffirepro_26_clk_src_labels[] = { | 109 | static const char *const saffirepro_26_clk_src_labels[] = { |
105 | SND_BEBOB_CLOCK_INTERNAL, "S/PDIF", "ADAT1", "ADAT2", "Word Clock" | 110 | SND_BEBOB_CLOCK_INTERNAL, "S/PDIF", "ADAT1", "ADAT2", "Word Clock" |
106 | }; | 111 | }; |
107 | 112 | /* Value maps between registers and labels for SaffirePro 10/26. */ | |
108 | static const char *const saffirepro_10_clk_src_labels[] = { | 113 | static const signed char saffirepro_clk_maps[][SAFFIREPRO_CLOCK_SOURCE_COUNT] = { |
109 | SND_BEBOB_CLOCK_INTERNAL, "S/PDIF", "Word Clock" | 114 | /* SaffirePro 10 */ |
115 | [0] = { | ||
116 | [SAFFIREPRO_CLOCK_SOURCE_INTERNAL] = 0, | ||
117 | [SAFFIREPRO_CLOCK_SOURCE_SKIP] = -1, /* not supported */ | ||
118 | [SAFFIREPRO_CLOCK_SOURCE_SPDIF] = 1, | ||
119 | [SAFFIREPRO_CLOCK_SOURCE_ADAT1] = -1, /* not supported */ | ||
120 | [SAFFIREPRO_CLOCK_SOURCE_ADAT2] = -1, /* not supported */ | ||
121 | [SAFFIREPRO_CLOCK_SOURCE_WORDCLOCK] = 2, | ||
122 | }, | ||
123 | /* SaffirePro 26 */ | ||
124 | [1] = { | ||
125 | [SAFFIREPRO_CLOCK_SOURCE_INTERNAL] = 0, | ||
126 | [SAFFIREPRO_CLOCK_SOURCE_SKIP] = -1, /* not supported */ | ||
127 | [SAFFIREPRO_CLOCK_SOURCE_SPDIF] = 1, | ||
128 | [SAFFIREPRO_CLOCK_SOURCE_ADAT1] = 2, | ||
129 | [SAFFIREPRO_CLOCK_SOURCE_ADAT2] = 3, | ||
130 | [SAFFIREPRO_CLOCK_SOURCE_WORDCLOCK] = 4, | ||
131 | } | ||
110 | }; | 132 | }; |
133 | |||
111 | static int | 134 | static int |
112 | saffirepro_both_clk_freq_get(struct snd_bebob *bebob, unsigned int *rate) | 135 | saffirepro_both_clk_freq_get(struct snd_bebob *bebob, unsigned int *rate) |
113 | { | 136 | { |
@@ -138,24 +161,35 @@ saffirepro_both_clk_freq_set(struct snd_bebob *bebob, unsigned int rate) | |||
138 | 161 | ||
139 | return saffire_write_quad(bebob, SAFFIREPRO_RATE_NOREBOOT, id); | 162 | return saffire_write_quad(bebob, SAFFIREPRO_RATE_NOREBOOT, id); |
140 | } | 163 | } |
164 | |||
165 | /* | ||
166 | * query hardware for current clock source, return our internally | ||
167 | * used clock index in *id, depending on hardware. | ||
168 | */ | ||
141 | static int | 169 | static int |
142 | saffirepro_both_clk_src_get(struct snd_bebob *bebob, unsigned int *id) | 170 | saffirepro_both_clk_src_get(struct snd_bebob *bebob, unsigned int *id) |
143 | { | 171 | { |
144 | int err; | 172 | int err; |
145 | u32 value; | 173 | u32 value; /* clock source read from hw register */ |
174 | const signed char *map; | ||
146 | 175 | ||
147 | err = saffire_read_quad(bebob, SAFFIREPRO_OFFSET_CLOCK_SOURCE, &value); | 176 | err = saffire_read_quad(bebob, SAFFIREPRO_OFFSET_CLOCK_SOURCE, &value); |
148 | if (err < 0) | 177 | if (err < 0) |
149 | goto end; | 178 | goto end; |
150 | 179 | ||
151 | if (bebob->spec->clock->labels == saffirepro_10_clk_src_labels) { | 180 | /* depending on hardware, use a different mapping */ |
152 | if (value == SAFFIREPRO_CLOCK_SOURCE_WORDCLOCK) | 181 | if (bebob->spec->clock->labels == saffirepro_10_clk_src_labels) |
153 | *id = 2; | 182 | map = saffirepro_clk_maps[0]; |
154 | else if (value == SAFFIREPRO_CLOCK_SOURCE_SPDIF) | 183 | else |
155 | *id = 1; | 184 | map = saffirepro_clk_maps[1]; |
156 | } else if (value > 1) { | 185 | |
157 | *id = value - 1; | 186 | /* In a case that this driver cannot handle the value of register. */ |
187 | if (value >= SAFFIREPRO_CLOCK_SOURCE_COUNT || map[value] < 0) { | ||
188 | err = -EIO; | ||
189 | goto end; | ||
158 | } | 190 | } |
191 | |||
192 | *id = (unsigned int)map[value]; | ||
159 | end: | 193 | end: |
160 | return err; | 194 | return err; |
161 | } | 195 | } |
diff --git a/sound/firewire/bebob/bebob_stream.c b/sound/firewire/bebob/bebob_stream.c index ef4d0c9f6578..1aab0a32870c 100644 --- a/sound/firewire/bebob/bebob_stream.c +++ b/sound/firewire/bebob/bebob_stream.c | |||
@@ -129,12 +129,24 @@ snd_bebob_stream_check_internal_clock(struct snd_bebob *bebob, bool *internal) | |||
129 | /* 1.The device has its own operation to switch source of clock */ | 129 | /* 1.The device has its own operation to switch source of clock */ |
130 | if (clk_spec) { | 130 | if (clk_spec) { |
131 | err = clk_spec->get(bebob, &id); | 131 | err = clk_spec->get(bebob, &id); |
132 | if (err < 0) | 132 | if (err < 0) { |
133 | dev_err(&bebob->unit->device, | 133 | dev_err(&bebob->unit->device, |
134 | "fail to get clock source: %d\n", err); | 134 | "fail to get clock source: %d\n", err); |
135 | else if (strncmp(clk_spec->labels[id], SND_BEBOB_CLOCK_INTERNAL, | 135 | goto end; |
136 | strlen(SND_BEBOB_CLOCK_INTERNAL)) == 0) | 136 | } |
137 | |||
138 | if (id >= clk_spec->num) { | ||
139 | dev_err(&bebob->unit->device, | ||
140 | "clock source %d out of range 0..%d\n", | ||
141 | id, clk_spec->num - 1); | ||
142 | err = -EIO; | ||
143 | goto end; | ||
144 | } | ||
145 | |||
146 | if (strncmp(clk_spec->labels[id], SND_BEBOB_CLOCK_INTERNAL, | ||
147 | strlen(SND_BEBOB_CLOCK_INTERNAL)) == 0) | ||
137 | *internal = true; | 148 | *internal = true; |
149 | |||
138 | goto end; | 150 | goto end; |
139 | } | 151 | } |
140 | 152 | ||
diff --git a/sound/firewire/bebob/bebob_terratec.c b/sound/firewire/bebob/bebob_terratec.c index 83b677224f1f..ad635004d699 100644 --- a/sound/firewire/bebob/bebob_terratec.c +++ b/sound/firewire/bebob/bebob_terratec.c | |||
@@ -24,7 +24,12 @@ phase88_rack_clk_src_get(struct snd_bebob *bebob, unsigned int *id) | |||
24 | if (err < 0) | 24 | if (err < 0) |
25 | goto end; | 25 | goto end; |
26 | 26 | ||
27 | *id = (enable_ext & 0x01) | ((enable_word & 0x01) << 1); | 27 | if (enable_ext == 0) |
28 | *id = 0; | ||
29 | else if (enable_word == 0) | ||
30 | *id = 1; | ||
31 | else | ||
32 | *id = 2; | ||
28 | end: | 33 | end: |
29 | return err; | 34 | return err; |
30 | } | 35 | } |