diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /sound/usb | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'sound/usb')
48 files changed, 832 insertions, 4846 deletions
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c index 4394ae79635..c7dca7b0b9f 100644 --- a/sound/usb/6fire/chip.c +++ b/sound/usb/6fire/chip.c | |||
@@ -5,6 +5,7 @@ | |||
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 | ||
8 | * Copyright: (C) Torsten Schenk | 9 | * Copyright: (C) Torsten Schenk |
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
@@ -28,13 +29,13 @@ | |||
28 | #include <sound/initval.h> | 29 | #include <sound/initval.h> |
29 | 30 | ||
30 | MODULE_AUTHOR("Torsten Schenk <torsten.schenk@zoho.com>"); | 31 | MODULE_AUTHOR("Torsten Schenk <torsten.schenk@zoho.com>"); |
31 | MODULE_DESCRIPTION("TerraTec DMX 6Fire USB audio driver"); | 32 | MODULE_DESCRIPTION("TerraTec DMX 6Fire USB audio driver, version 0.3.0"); |
32 | MODULE_LICENSE("GPL v2"); | 33 | MODULE_LICENSE("GPL v2"); |
33 | MODULE_SUPPORTED_DEVICE("{{TerraTec, DMX 6Fire USB}}"); | 34 | MODULE_SUPPORTED_DEVICE("{{TerraTec, DMX 6Fire USB}}"); |
34 | 35 | ||
35 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ | 36 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ |
36 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for card */ | 37 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for card */ |
37 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable card */ | 38 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable card */ |
38 | static struct sfire_chip *chips[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; | 39 | static struct sfire_chip *chips[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; |
39 | static struct usb_device *devices[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; | 40 | static struct usb_device *devices[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; |
40 | 41 | ||
@@ -82,8 +83,8 @@ static void usb6fire_chip_destroy(struct sfire_chip *chip) | |||
82 | } | 83 | } |
83 | } | 84 | } |
84 | 85 | ||
85 | static int usb6fire_chip_probe(struct usb_interface *intf, | 86 | static int __devinit usb6fire_chip_probe(struct usb_interface *intf, |
86 | const struct usb_device_id *usb_id) | 87 | const struct usb_device_id *usb_id) |
87 | { | 88 | { |
88 | int ret; | 89 | int ret; |
89 | int i; | 90 | int i; |
@@ -210,11 +211,22 @@ static struct usb_device_id device_table[] = { | |||
210 | 211 | ||
211 | MODULE_DEVICE_TABLE(usb, device_table); | 212 | MODULE_DEVICE_TABLE(usb, device_table); |
212 | 213 | ||
213 | static struct usb_driver usb_driver = { | 214 | static struct usb_driver driver = { |
214 | .name = "snd-usb-6fire", | 215 | .name = "snd-usb-6fire", |
215 | .probe = usb6fire_chip_probe, | 216 | .probe = usb6fire_chip_probe, |
216 | .disconnect = usb6fire_chip_disconnect, | 217 | .disconnect = usb6fire_chip_disconnect, |
217 | .id_table = device_table, | 218 | .id_table = device_table, |
218 | }; | 219 | }; |
219 | 220 | ||
220 | module_usb_driver(usb_driver); | 221 | static int __init usb6fire_chip_init(void) |
222 | { | ||
223 | return usb_register(&driver); | ||
224 | } | ||
225 | |||
226 | static void __exit usb6fire_chip_cleanup(void) | ||
227 | { | ||
228 | usb_deregister(&driver); | ||
229 | } | ||
230 | |||
231 | module_init(usb6fire_chip_init); | ||
232 | module_exit(usb6fire_chip_cleanup); | ||
diff --git a/sound/usb/6fire/chip.h b/sound/usb/6fire/chip.h index bde02d105a5..d11e5cb520f 100644 --- a/sound/usb/6fire/chip.h +++ b/sound/usb/6fire/chip.h | |||
@@ -3,6 +3,7 @@ | |||
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 | ||
6 | * Copyright: (C) Torsten Schenk | 7 | * Copyright: (C) Torsten Schenk |
7 | * | 8 | * |
8 | * 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 |
diff --git a/sound/usb/6fire/comm.c b/sound/usb/6fire/comm.c index 9e6e3ffd86b..c994daa57af 100644 --- a/sound/usb/6fire/comm.c +++ b/sound/usb/6fire/comm.c | |||
@@ -5,6 +5,7 @@ | |||
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 | ||
8 | * Copyright: (C) Torsten Schenk | 9 | * Copyright: (C) Torsten Schenk |
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
@@ -125,17 +126,16 @@ static int usb6fire_comm_write16(struct comm_runtime *rt, u8 request, | |||
125 | return usb6fire_comm_send_buffer(buffer, rt->chip->dev); | 126 | return usb6fire_comm_send_buffer(buffer, rt->chip->dev); |
126 | } | 127 | } |
127 | 128 | ||
128 | int usb6fire_comm_init(struct sfire_chip *chip) | 129 | int __devinit usb6fire_comm_init(struct sfire_chip *chip) |
129 | { | 130 | { |
130 | struct comm_runtime *rt = kzalloc(sizeof(struct comm_runtime), | 131 | struct comm_runtime *rt = kzalloc(sizeof(struct comm_runtime), |
131 | GFP_KERNEL); | 132 | GFP_KERNEL); |
132 | struct urb *urb; | 133 | struct urb *urb = &rt->receiver; |
133 | int ret; | 134 | int ret; |
134 | 135 | ||
135 | if (!rt) | 136 | if (!rt) |
136 | return -ENOMEM; | 137 | return -ENOMEM; |
137 | 138 | ||
138 | urb = &rt->receiver; | ||
139 | rt->serial = 1; | 139 | rt->serial = 1; |
140 | rt->chip = chip; | 140 | rt->chip = chip; |
141 | usb_init_urb(urb); | 141 | usb_init_urb(urb); |
diff --git a/sound/usb/6fire/comm.h b/sound/usb/6fire/comm.h index 6a0840b0dcf..edc5dc84b88 100644 --- a/sound/usb/6fire/comm.h +++ b/sound/usb/6fire/comm.h | |||
@@ -3,6 +3,7 @@ | |||
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 | ||
6 | * Copyright: (C) Torsten Schenk | 7 | * Copyright: (C) Torsten Schenk |
7 | * | 8 | * |
8 | * 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 |
@@ -36,7 +37,7 @@ struct comm_runtime { | |||
36 | u8 vh, u8 vl); | 37 | u8 vh, u8 vl); |
37 | }; | 38 | }; |
38 | 39 | ||
39 | int usb6fire_comm_init(struct sfire_chip *chip); | 40 | int __devinit usb6fire_comm_init(struct sfire_chip *chip); |
40 | void usb6fire_comm_abort(struct sfire_chip *chip); | 41 | void usb6fire_comm_abort(struct sfire_chip *chip); |
41 | void usb6fire_comm_destroy(struct sfire_chip *chip); | 42 | void usb6fire_comm_destroy(struct sfire_chip *chip); |
42 | #endif /* USB6FIRE_COMM_H */ | 43 | #endif /* USB6FIRE_COMM_H */ |
diff --git a/sound/usb/6fire/common.h b/sound/usb/6fire/common.h index b6eb03ed1c2..7dbeb4a3783 100644 --- a/sound/usb/6fire/common.h +++ b/sound/usb/6fire/common.h | |||
@@ -3,6 +3,7 @@ | |||
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 | ||
6 | * Copyright: (C) Torsten Schenk | 7 | * Copyright: (C) Torsten Schenk |
7 | * | 8 | * |
8 | * 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 |
diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c index f6434c24572..ac828eff1a6 100644 --- a/sound/usb/6fire/control.c +++ b/sound/usb/6fire/control.c | |||
@@ -5,12 +5,9 @@ | |||
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 | ||
8 | * Copyright: (C) Torsten Schenk | 9 | * Copyright: (C) Torsten Schenk |
9 | * | 10 | * |
10 | * Thanks to: | ||
11 | * - Holger Ruckdeschel: he found out how to control individual channel | ||
12 | * volumes and introduced mute switch | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
15 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
16 | * the Free Software Foundation; either version 2 of the License, or | 13 | * the Free Software Foundation; either version 2 of the License, or |
@@ -19,7 +16,6 @@ | |||
19 | 16 | ||
20 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
21 | #include <sound/control.h> | 18 | #include <sound/control.h> |
22 | #include <sound/tlv.h> | ||
23 | 19 | ||
24 | #include "control.h" | 20 | #include "control.h" |
25 | #include "comm.h" | 21 | #include "comm.h" |
@@ -29,6 +25,26 @@ static char *opt_coax_texts[2] = { "Optical", "Coax" }; | |||
29 | static char *line_phono_texts[2] = { "Line", "Phono" }; | 25 | static char *line_phono_texts[2] = { "Line", "Phono" }; |
30 | 26 | ||
31 | /* | 27 | /* |
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 | /* | ||
32 | * data that needs to be sent to device. sets up card internal stuff. | 48 | * data that needs to be sent to device. sets up card internal stuff. |
33 | * values dumped from windows driver and filtered by trial'n'error. | 49 | * values dumped from windows driver and filtered by trial'n'error. |
34 | */ | 50 | */ |
@@ -43,7 +59,7 @@ init_data[] = { | |||
43 | { 0x22, 0x03, 0x00 }, { 0x20, 0x03, 0x08 }, { 0x22, 0x04, 0x00 }, | 59 | { 0x22, 0x03, 0x00 }, { 0x20, 0x03, 0x08 }, { 0x22, 0x04, 0x00 }, |
44 | { 0x20, 0x04, 0x08 }, { 0x22, 0x05, 0x01 }, { 0x20, 0x05, 0x08 }, | 60 | { 0x20, 0x04, 0x08 }, { 0x22, 0x05, 0x01 }, { 0x20, 0x05, 0x08 }, |
45 | { 0x22, 0x04, 0x01 }, { 0x12, 0x04, 0x00 }, { 0x12, 0x05, 0x00 }, | 61 | { 0x22, 0x04, 0x01 }, { 0x12, 0x04, 0x00 }, { 0x12, 0x05, 0x00 }, |
46 | { 0x12, 0x0d, 0x38 }, { 0x12, 0x21, 0x82 }, { 0x12, 0x22, 0x80 }, | 62 | { 0x12, 0x0d, 0x78 }, { 0x12, 0x21, 0x82 }, { 0x12, 0x22, 0x80 }, |
47 | { 0x12, 0x23, 0x00 }, { 0x12, 0x06, 0x02 }, { 0x12, 0x03, 0x00 }, | 63 | { 0x12, 0x23, 0x00 }, { 0x12, 0x06, 0x02 }, { 0x12, 0x03, 0x00 }, |
48 | { 0x12, 0x02, 0x00 }, { 0x22, 0x03, 0x01 }, | 64 | { 0x12, 0x02, 0x00 }, { 0x22, 0x03, 0x01 }, |
49 | { 0 } /* TERMINATING ENTRY */ | 65 | { 0 } /* TERMINATING ENTRY */ |
@@ -54,47 +70,20 @@ static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 }; | |||
54 | static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}; | 70 | static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}; |
55 | static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00}; | 71 | static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00}; |
56 | 72 | ||
57 | static DECLARE_TLV_DB_MINMAX(tlv_output, -9000, 0); | ||
58 | static DECLARE_TLV_DB_MINMAX(tlv_input, -1500, 1500); | ||
59 | |||
60 | enum { | 73 | enum { |
61 | DIGITAL_THRU_ONLY_SAMPLERATE = 3 | 74 | DIGITAL_THRU_ONLY_SAMPLERATE = 3 |
62 | }; | 75 | }; |
63 | 76 | ||
64 | static void usb6fire_control_output_vol_update(struct control_runtime *rt) | 77 | static void usb6fire_control_master_vol_update(struct control_runtime *rt) |
65 | { | 78 | { |
66 | struct comm_runtime *comm_rt = rt->chip->comm; | 79 | struct comm_runtime *comm_rt = rt->chip->comm; |
67 | int i; | 80 | if (comm_rt) { |
68 | 81 | /* set volume */ | |
69 | if (comm_rt) | 82 | comm_rt->write8(comm_rt, 0x12, 0x0f, 0x7f - |
70 | for (i = 0; i < 6; i++) | 83 | log_volume_table[rt->master_vol]); |
71 | if (!(rt->ovol_updated & (1 << i))) { | 84 | /* unmute */ |
72 | comm_rt->write8(comm_rt, 0x12, 0x0f + i, | 85 | comm_rt->write8(comm_rt, 0x12, 0x0e, 0x00); |
73 | 180 - rt->output_vol[i]); | 86 | } |
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 | } | ||
98 | } | 87 | } |
99 | 88 | ||
100 | static void usb6fire_control_line_phono_update(struct control_runtime *rt) | 89 | static void usb6fire_control_line_phono_update(struct control_runtime *rt) |
@@ -176,147 +165,34 @@ static int usb6fire_control_streaming_update(struct control_runtime *rt) | |||
176 | return -EINVAL; | 165 | return -EINVAL; |
177 | } | 166 | } |
178 | 167 | ||
179 | static int usb6fire_control_output_vol_info(struct snd_kcontrol *kcontrol, | 168 | static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol, |
180 | struct snd_ctl_elem_info *uinfo) | 169 | struct snd_ctl_elem_info *uinfo) |
181 | { | 170 | { |
182 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 171 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
183 | uinfo->count = 2; | 172 | uinfo->count = 1; |
184 | uinfo->value.integer.min = 0; | ||
185 | uinfo->value.integer.max = 180; | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static int usb6fire_control_output_vol_put(struct snd_kcontrol *kcontrol, | ||
190 | struct snd_ctl_elem_value *ucontrol) | ||
191 | { | ||
192 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); | ||
193 | unsigned int ch = kcontrol->private_value; | ||
194 | int changed = 0; | ||
195 | |||
196 | if (ch > 4) { | ||
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); | ||
204 | changed = 1; | ||
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 | |||
215 | return changed; | ||
216 | } | ||
217 | |||
218 | static int usb6fire_control_output_vol_get(struct snd_kcontrol *kcontrol, | ||
219 | struct snd_ctl_elem_value *ucontrol) | ||
220 | { | ||
221 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); | ||
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; | 173 | uinfo->value.integer.min = 0; |
285 | uinfo->value.integer.max = 30; | 174 | uinfo->value.integer.max = 127; |
286 | return 0; | 175 | return 0; |
287 | } | 176 | } |
288 | 177 | ||
289 | static int usb6fire_control_input_vol_put(struct snd_kcontrol *kcontrol, | 178 | static int usb6fire_control_master_vol_put(struct snd_kcontrol *kcontrol, |
290 | struct snd_ctl_elem_value *ucontrol) | 179 | struct snd_ctl_elem_value *ucontrol) |
291 | { | 180 | { |
292 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); | 181 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); |
293 | int changed = 0; | 182 | int changed = 0; |
294 | 183 | if (rt->master_vol != ucontrol->value.integer.value[0]) { | |
295 | if (rt->input_vol[0] != ucontrol->value.integer.value[0]) { | 184 | rt->master_vol = ucontrol->value.integer.value[0]; |
296 | rt->input_vol[0] = ucontrol->value.integer.value[0] - 15; | 185 | usb6fire_control_master_vol_update(rt); |
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; | 186 | changed = 1; |
304 | } | 187 | } |
305 | |||
306 | if (changed) | ||
307 | usb6fire_control_input_vol_update(rt); | ||
308 | |||
309 | return changed; | 188 | return changed; |
310 | } | 189 | } |
311 | 190 | ||
312 | static int usb6fire_control_input_vol_get(struct snd_kcontrol *kcontrol, | 191 | static int usb6fire_control_master_vol_get(struct snd_kcontrol *kcontrol, |
313 | struct snd_ctl_elem_value *ucontrol) | 192 | struct snd_ctl_elem_value *ucontrol) |
314 | { | 193 | { |
315 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); | 194 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); |
316 | 195 | ucontrol->value.integer.value[0] = rt->master_vol; | |
317 | ucontrol->value.integer.value[0] = rt->input_vol[0] + 15; | ||
318 | ucontrol->value.integer.value[1] = rt->input_vol[1] + 15; | ||
319 | |||
320 | return 0; | 196 | return 0; |
321 | } | 197 | } |
322 | 198 | ||
@@ -411,83 +287,18 @@ static int usb6fire_control_digital_thru_get(struct snd_kcontrol *kcontrol, | |||
411 | return 0; | 287 | return 0; |
412 | } | 288 | } |
413 | 289 | ||
414 | static struct snd_kcontrol_new vol_elements[] = { | 290 | static struct __devinitdata snd_kcontrol_new elements[] = { |
415 | { | 291 | { |
416 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 292 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
417 | .name = "Analog Playback Volume", | 293 | .name = "Master Playback Volume", |
418 | .index = 0, | 294 | .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 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, | ||
470 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 295 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
471 | .info = snd_ctl_boolean_stereo_info, | 296 | .info = usb6fire_control_master_vol_info, |
472 | .get = usb6fire_control_output_mute_get, | 297 | .get = usb6fire_control_master_vol_get, |
473 | .put = usb6fire_control_output_mute_put, | 298 | .put = usb6fire_control_master_vol_put |
474 | }, | 299 | }, |
475 | { | 300 | { |
476 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 301 | .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 snd_kcontrol_new elements[] = { | ||
489 | { | ||
490 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
491 | .name = "Line/Phono Capture Route", | 302 | .name = "Line/Phono Capture Route", |
492 | .index = 0, | 303 | .index = 0, |
493 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 304 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
@@ -513,55 +324,10 @@ static struct snd_kcontrol_new elements[] = { | |||
513 | .get = usb6fire_control_digital_thru_get, | 324 | .get = usb6fire_control_digital_thru_get, |
514 | .put = usb6fire_control_digital_thru_put | 325 | .put = usb6fire_control_digital_thru_put |
515 | }, | 326 | }, |
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 | }, | ||
527 | {} | 327 | {} |
528 | }; | 328 | }; |
529 | 329 | ||
530 | static int usb6fire_control_add_virtual( | 330 | int __devinit usb6fire_control_init(struct sfire_chip *chip) |
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 | |||
564 | int usb6fire_control_init(struct sfire_chip *chip) | ||
565 | { | 331 | { |
566 | int i; | 332 | int i; |
567 | int ret; | 333 | int ret; |
@@ -586,26 +352,9 @@ int usb6fire_control_init(struct sfire_chip *chip) | |||
586 | 352 | ||
587 | usb6fire_control_opt_coax_update(rt); | 353 | usb6fire_control_opt_coax_update(rt); |
588 | usb6fire_control_line_phono_update(rt); | 354 | usb6fire_control_line_phono_update(rt); |
589 | usb6fire_control_output_vol_update(rt); | 355 | usb6fire_control_master_vol_update(rt); |
590 | usb6fire_control_output_mute_update(rt); | ||
591 | usb6fire_control_input_vol_update(rt); | ||
592 | usb6fire_control_streaming_update(rt); | 356 | usb6fire_control_streaming_update(rt); |
593 | 357 | ||
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 | |||
609 | i = 0; | 358 | i = 0; |
610 | while (elements[i].name) { | 359 | while (elements[i].name) { |
611 | ret = snd_ctl_add(chip->card, snd_ctl_new1(&elements[i], rt)); | 360 | 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 5a40ba14348..8f5aeead2e3 100644 --- a/sound/usb/6fire/control.h +++ b/sound/usb/6fire/control.h | |||
@@ -3,6 +3,7 @@ | |||
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 | ||
6 | * Copyright: (C) Torsten Schenk | 7 | * Copyright: (C) Torsten Schenk |
7 | * | 8 | * |
8 | * 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 |
@@ -43,14 +44,10 @@ struct control_runtime { | |||
43 | bool line_phono_switch; | 44 | bool line_phono_switch; |
44 | bool digital_thru_switch; | 45 | bool digital_thru_switch; |
45 | bool usb_streaming; | 46 | bool usb_streaming; |
46 | u8 output_vol[6]; | 47 | u8 master_vol; |
47 | u8 ovol_updated; | ||
48 | u8 output_mute; | ||
49 | s8 input_vol[2]; | ||
50 | u8 ivol_updated; | ||
51 | }; | 48 | }; |
52 | 49 | ||
53 | int usb6fire_control_init(struct sfire_chip *chip); | 50 | int __devinit usb6fire_control_init(struct sfire_chip *chip); |
54 | void usb6fire_control_abort(struct sfire_chip *chip); | 51 | void usb6fire_control_abort(struct sfire_chip *chip); |
55 | void usb6fire_control_destroy(struct sfire_chip *chip); | 52 | void usb6fire_control_destroy(struct sfire_chip *chip); |
56 | #endif /* USB6FIRE_CONTROL_H */ | 53 | #endif /* USB6FIRE_CONTROL_H */ |
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index a1d9b0792a1..1e3ae3327dd 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c | |||
@@ -5,6 +5,7 @@ | |||
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 | ||
8 | * Copyright: (C) Torsten Schenk | 9 | * Copyright: (C) Torsten Schenk |
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
@@ -14,9 +15,7 @@ | |||
14 | */ | 15 | */ |
15 | 16 | ||
16 | #include <linux/firmware.h> | 17 | #include <linux/firmware.h> |
17 | #include <linux/module.h> | ||
18 | #include <linux/bitrev.h> | 18 | #include <linux/bitrev.h> |
19 | #include <linux/kernel.h> | ||
20 | 19 | ||
21 | #include "firmware.h" | 20 | #include "firmware.h" |
22 | #include "chip.h" | 21 | #include "chip.h" |
@@ -60,19 +59,21 @@ struct ihex_record { | |||
60 | unsigned int txt_offset; /* current position in txt_data */ | 59 | unsigned int txt_offset; /* current position in txt_data */ |
61 | }; | 60 | }; |
62 | 61 | ||
63 | static u8 usb6fire_fw_ihex_hex(const u8 *data, u8 *crc) | 62 | static u8 usb6fire_fw_ihex_nibble(const u8 n) |
64 | { | 63 | { |
65 | u8 val = 0; | 64 | if (n >= '0' && n <= '9') |
66 | int hval; | 65 | return n - '0'; |
67 | 66 | else if (n >= 'A' && n <= 'F') | |
68 | hval = hex_to_bin(data[0]); | 67 | return n - ('A' - 10); |
69 | if (hval >= 0) | 68 | else if (n >= 'a' && n <= 'f') |
70 | val |= (hval << 4); | 69 | return n - ('a' - 10); |
71 | 70 | return 0; | |
72 | hval = hex_to_bin(data[1]); | 71 | } |
73 | if (hval >= 0) | ||
74 | val |= hval; | ||
75 | 72 | ||
73 | static u8 usb6fire_fw_ihex_hex(const u8 *data, u8 *crc) | ||
74 | { | ||
75 | u8 val = (usb6fire_fw_ihex_nibble(data[0]) << 4) | | ||
76 | usb6fire_fw_ihex_nibble(data[1]); | ||
76 | *crc += val; | 77 | *crc += val; |
77 | return val; | 78 | return val; |
78 | } | 79 | } |
@@ -209,7 +210,7 @@ static int usb6fire_fw_ezusb_upload( | |||
209 | int ret; | 210 | int ret; |
210 | u8 data; | 211 | u8 data; |
211 | struct usb_device *device = interface_to_usbdev(intf); | 212 | struct usb_device *device = interface_to_usbdev(intf); |
212 | const struct firmware *fw = NULL; | 213 | const struct firmware *fw = 0; |
213 | struct ihex_record *rec = kmalloc(sizeof(struct ihex_record), | 214 | struct ihex_record *rec = kmalloc(sizeof(struct ihex_record), |
214 | GFP_KERNEL); | 215 | GFP_KERNEL); |
215 | 216 | ||
@@ -346,10 +347,11 @@ static int usb6fire_fw_check(u8 *version) | |||
346 | if (!memcmp(version, known_fw_versions + i, 4)) | 347 | if (!memcmp(version, known_fw_versions + i, 4)) |
347 | return 0; | 348 | return 0; |
348 | 349 | ||
349 | snd_printk(KERN_ERR PREFIX "invalid fimware version in device: %*ph. " | 350 | snd_printk(KERN_ERR PREFIX "invalid fimware version in device: " |
351 | "%02x %02x %02x %02x. " | ||
350 | "please reconnect to power. if this failure " | 352 | "please reconnect to power. if this failure " |
351 | "still happens, check your firmware installation.", | 353 | "still happens, check your firmware installation.", |
352 | 4, version); | 354 | version[0], version[1], version[2], version[3]); |
353 | return -EINVAL; | 355 | return -EINVAL; |
354 | } | 356 | } |
355 | 357 | ||
diff --git a/sound/usb/6fire/firmware.h b/sound/usb/6fire/firmware.h index c109c4f75ab..00856989538 100644 --- a/sound/usb/6fire/firmware.h +++ b/sound/usb/6fire/firmware.h | |||
@@ -22,6 +22,6 @@ enum /* firmware state of device */ | |||
22 | FW_NOT_READY = 1 | 22 | FW_NOT_READY = 1 |
23 | }; | 23 | }; |
24 | 24 | ||
25 | int usb6fire_fw_init(struct usb_interface *intf); | 25 | int __devinit usb6fire_fw_init(struct usb_interface *intf); |
26 | #endif /* USB6FIRE_FIRMWARE_H */ | 26 | #endif /* USB6FIRE_FIRMWARE_H */ |
27 | 27 | ||
diff --git a/sound/usb/6fire/midi.c b/sound/usb/6fire/midi.c index 26722423330..13f4509dce2 100644 --- a/sound/usb/6fire/midi.c +++ b/sound/usb/6fire/midi.c | |||
@@ -5,6 +5,7 @@ | |||
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 | ||
8 | * Copyright: (C) Torsten Schenk | 9 | * Copyright: (C) Torsten Schenk |
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
@@ -146,7 +147,7 @@ static struct snd_rawmidi_ops in_ops = { | |||
146 | .trigger = usb6fire_midi_in_trigger | 147 | .trigger = usb6fire_midi_in_trigger |
147 | }; | 148 | }; |
148 | 149 | ||
149 | int usb6fire_midi_init(struct sfire_chip *chip) | 150 | int __devinit usb6fire_midi_init(struct sfire_chip *chip) |
150 | { | 151 | { |
151 | int ret; | 152 | int ret; |
152 | struct midi_runtime *rt = kzalloc(sizeof(struct midi_runtime), | 153 | struct midi_runtime *rt = kzalloc(sizeof(struct midi_runtime), |
diff --git a/sound/usb/6fire/midi.h b/sound/usb/6fire/midi.h index c321006e543..97a7bf66913 100644 --- a/sound/usb/6fire/midi.h +++ b/sound/usb/6fire/midi.h | |||
@@ -3,6 +3,7 @@ | |||
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 | ||
6 | * Copyright: (C) Torsten Schenk | 7 | * Copyright: (C) Torsten Schenk |
7 | * | 8 | * |
8 | * 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 |
@@ -38,7 +39,7 @@ struct midi_runtime { | |||
38 | void (*in_received)(struct midi_runtime *rt, u8 *data, int length); | 39 | void (*in_received)(struct midi_runtime *rt, u8 *data, int length); |
39 | }; | 40 | }; |
40 | 41 | ||
41 | int usb6fire_midi_init(struct sfire_chip *chip); | 42 | int __devinit usb6fire_midi_init(struct sfire_chip *chip); |
42 | void usb6fire_midi_abort(struct sfire_chip *chip); | 43 | void usb6fire_midi_abort(struct sfire_chip *chip); |
43 | void usb6fire_midi_destroy(struct sfire_chip *chip); | 44 | void usb6fire_midi_destroy(struct sfire_chip *chip); |
44 | #endif /* USB6FIRE_MIDI_H */ | 45 | #endif /* USB6FIRE_MIDI_H */ |
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index e2ca12fe92e..d144cdb2f15 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c | |||
@@ -5,6 +5,7 @@ | |||
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 | ||
8 | * Copyright: (C) Torsten Schenk | 9 | * Copyright: (C) Torsten Schenk |
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
@@ -135,9 +136,6 @@ static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt) | |||
135 | struct control_runtime *ctrl_rt = rt->chip->control; | 136 | struct control_runtime *ctrl_rt = rt->chip->control; |
136 | 137 | ||
137 | if (rt->stream_state != STREAM_DISABLED) { | 138 | if (rt->stream_state != STREAM_DISABLED) { |
138 | |||
139 | rt->stream_state = STREAM_STOPPING; | ||
140 | |||
141 | for (i = 0; i < PCM_N_URBS; i++) { | 139 | for (i = 0; i < PCM_N_URBS; i++) { |
142 | usb_kill_urb(&rt->in_urbs[i].instance); | 140 | usb_kill_urb(&rt->in_urbs[i].instance); |
143 | usb_kill_urb(&rt->out_urbs[i].instance); | 141 | usb_kill_urb(&rt->out_urbs[i].instance); |
@@ -562,9 +560,9 @@ static struct snd_pcm_ops pcm_ops = { | |||
562 | .pointer = usb6fire_pcm_pointer, | 560 | .pointer = usb6fire_pcm_pointer, |
563 | }; | 561 | }; |
564 | 562 | ||
565 | static void usb6fire_pcm_init_urb(struct pcm_urb *urb, | 563 | static void __devinit usb6fire_pcm_init_urb(struct pcm_urb *urb, |
566 | struct sfire_chip *chip, bool in, int ep, | 564 | struct sfire_chip *chip, bool in, int ep, |
567 | void (*handler)(struct urb *)) | 565 | void (*handler)(struct urb *)) |
568 | { | 566 | { |
569 | urb->chip = chip; | 567 | urb->chip = chip; |
570 | usb_init_urb(&urb->instance); | 568 | usb_init_urb(&urb->instance); |
@@ -581,7 +579,7 @@ static void usb6fire_pcm_init_urb(struct pcm_urb *urb, | |||
581 | urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB; | 579 | urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB; |
582 | } | 580 | } |
583 | 581 | ||
584 | int usb6fire_pcm_init(struct sfire_chip *chip) | 582 | int __devinit usb6fire_pcm_init(struct sfire_chip *chip) |
585 | { | 583 | { |
586 | int i; | 584 | int i; |
587 | int ret; | 585 | int ret; |
diff --git a/sound/usb/6fire/pcm.h b/sound/usb/6fire/pcm.h index 9b01133ee3f..2bee8137400 100644 --- a/sound/usb/6fire/pcm.h +++ b/sound/usb/6fire/pcm.h | |||
@@ -3,6 +3,7 @@ | |||
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 | ||
6 | * Copyright: (C) Torsten Schenk | 7 | * Copyright: (C) Torsten Schenk |
7 | * | 8 | * |
8 | * 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 |
@@ -69,7 +70,7 @@ struct pcm_runtime { | |||
69 | bool stream_wait_cond; | 70 | bool stream_wait_cond; |
70 | }; | 71 | }; |
71 | 72 | ||
72 | int usb6fire_pcm_init(struct sfire_chip *chip); | 73 | int __devinit usb6fire_pcm_init(struct sfire_chip *chip); |
73 | void usb6fire_pcm_abort(struct sfire_chip *chip); | 74 | void usb6fire_pcm_abort(struct sfire_chip *chip); |
74 | void usb6fire_pcm_destroy(struct sfire_chip *chip); | 75 | void usb6fire_pcm_destroy(struct sfire_chip *chip); |
75 | #endif /* USB6FIRE_PCM_H */ | 76 | #endif /* USB6FIRE_PCM_H */ |
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index 225dfd73726..8beb77563da 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig | |||
@@ -67,7 +67,6 @@ config SND_USB_CAIAQ | |||
67 | * Native Instruments Guitar Rig mobile | 67 | * Native Instruments Guitar Rig mobile |
68 | * Native Instruments Traktor Kontrol X1 | 68 | * Native Instruments Traktor Kontrol X1 |
69 | * Native Instruments Traktor Kontrol S4 | 69 | * Native Instruments Traktor Kontrol S4 |
70 | * Native Instruments Maschine Controller | ||
71 | 70 | ||
72 | To compile this driver as a module, choose M here: the module | 71 | To compile this driver as a module, choose M here: the module |
73 | will be called snd-usb-caiaq. | 72 | will be called snd-usb-caiaq. |
@@ -86,11 +85,10 @@ config SND_USB_CAIAQ_INPUT | |||
86 | * Native Instruments Kore Controller 2 | 85 | * Native Instruments Kore Controller 2 |
87 | * Native Instruments Audio Kontrol 1 | 86 | * Native Instruments Audio Kontrol 1 |
88 | * Native Instruments Traktor Kontrol S4 | 87 | * Native Instruments Traktor Kontrol S4 |
89 | * Native Instruments Maschine Controller | ||
90 | 88 | ||
91 | config SND_USB_US122L | 89 | config SND_USB_US122L |
92 | tristate "Tascam US-122L USB driver" | 90 | tristate "Tascam US-122L USB driver" |
93 | depends on X86 | 91 | depends on X86 && EXPERIMENTAL |
94 | select SND_HWDEP | 92 | select SND_HWDEP |
95 | select SND_RAWMIDI | 93 | select SND_RAWMIDI |
96 | help | 94 | help |
@@ -106,7 +104,6 @@ config SND_USB_6FIRE | |||
106 | select BITREVERSE | 104 | select BITREVERSE |
107 | select SND_RAWMIDI | 105 | select SND_RAWMIDI |
108 | select SND_PCM | 106 | select SND_PCM |
109 | select SND_VMASTER | ||
110 | help | 107 | help |
111 | Say Y here to include support for TerraTec 6fire DMX USB interface. | 108 | Say Y here to include support for TerraTec 6fire DMX USB interface. |
112 | 109 | ||
diff --git a/sound/usb/Makefile b/sound/usb/Makefile index ac256dc4c6b..cf9ed66445f 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile | |||
@@ -3,16 +3,16 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | snd-usb-audio-objs := card.o \ | 5 | snd-usb-audio-objs := card.o \ |
6 | clock.o \ | ||
7 | endpoint.o \ | ||
8 | format.o \ | ||
9 | helper.o \ | ||
10 | mixer.o \ | 6 | mixer.o \ |
11 | mixer_quirks.o \ | 7 | mixer_quirks.o \ |
12 | pcm.o \ | ||
13 | proc.o \ | 8 | proc.o \ |
14 | quirks.o \ | 9 | quirks.o \ |
15 | stream.o | 10 | format.o \ |
11 | endpoint.o \ | ||
12 | urb.o \ | ||
13 | pcm.o \ | ||
14 | helper.o \ | ||
15 | clock.o | ||
16 | 16 | ||
17 | snd-usbmidi-lib-objs := midi.o | 17 | snd-usbmidi-lib-objs := midi.o |
18 | 18 | ||
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index fde9a7a29cb..2cf87f5afed 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c | |||
@@ -311,10 +311,8 @@ 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 | } | ||
318 | 316 | ||
319 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) | 317 | if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) |
320 | ptr = bytes_to_frames(sub->runtime, | 318 | ptr = bytes_to_frames(sub->runtime, |
@@ -323,7 +321,6 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub) | |||
323 | ptr = bytes_to_frames(sub->runtime, | 321 | ptr = bytes_to_frames(sub->runtime, |
324 | dev->audio_in_buf_pos[index]); | 322 | dev->audio_in_buf_pos[index]); |
325 | 323 | ||
326 | unlock: | ||
327 | spin_unlock(&dev->spinlock); | 324 | spin_unlock(&dev->spinlock); |
328 | return ptr; | 325 | return ptr; |
329 | } | 326 | } |
diff --git a/sound/usb/caiaq/control.c b/sound/usb/caiaq/control.c index adb8d03267a..00e5d0a469e 100644 --- a/sound/usb/caiaq/control.c +++ b/sound/usb/caiaq/control.c | |||
@@ -137,7 +137,7 @@ static int control_put(struct snd_kcontrol *kcontrol, | |||
137 | return 1; | 137 | return 1; |
138 | } | 138 | } |
139 | 139 | ||
140 | static struct snd_kcontrol_new kcontrol_template = { | 140 | static struct snd_kcontrol_new kcontrol_template __devinitdata = { |
141 | .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, | 141 | .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, |
142 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 142 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
143 | .index = 0, | 143 | .index = 0, |
@@ -489,8 +489,8 @@ static struct caiaq_controller kontrols4_controller[] = { | |||
489 | { "LED: FX2: Mode", 133 | CNT_INTVAL }, | 489 | { "LED: FX2: Mode", 133 | CNT_INTVAL }, |
490 | }; | 490 | }; |
491 | 491 | ||
492 | static int add_controls(struct caiaq_controller *c, int num, | 492 | static int __devinit add_controls(struct caiaq_controller *c, int num, |
493 | struct snd_usb_caiaqdev *dev) | 493 | struct snd_usb_caiaqdev *dev) |
494 | { | 494 | { |
495 | int i, ret; | 495 | int i, ret; |
496 | struct snd_kcontrol *kc; | 496 | struct snd_kcontrol *kc; |
@@ -507,7 +507,7 @@ static int add_controls(struct caiaq_controller *c, int num, | |||
507 | return 0; | 507 | return 0; |
508 | } | 508 | } |
509 | 509 | ||
510 | int snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev) | 510 | int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev) |
511 | { | 511 | { |
512 | int ret = 0; | 512 | int ret = 0; |
513 | 513 | ||
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index c828f8189c2..45bc4a2dc6f 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c | |||
@@ -50,12 +50,11 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," | |||
50 | "{Native Instruments, Session I/O}," | 50 | "{Native Instruments, Session I/O}," |
51 | "{Native Instruments, GuitarRig mobile}" | 51 | "{Native Instruments, GuitarRig mobile}" |
52 | "{Native Instruments, Traktor Kontrol X1}" | 52 | "{Native Instruments, Traktor Kontrol X1}" |
53 | "{Native Instruments, Traktor Kontrol S4}" | 53 | "{Native Instruments, Traktor Kontrol S4}"); |
54 | "{Native Instruments, Maschine Controller}"); | ||
55 | 54 | ||
56 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ | 55 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ |
57 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ | 56 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ |
58 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ | 57 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ |
59 | static int snd_card_used[SNDRV_CARDS]; | 58 | static int snd_card_used[SNDRV_CARDS]; |
60 | 59 | ||
61 | module_param_array(index, int, NULL, 0444); | 60 | module_param_array(index, int, NULL, 0444); |
@@ -147,11 +146,6 @@ static struct usb_device_id snd_usb_id_table[] = { | |||
147 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 146 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
148 | .idProduct = USB_PID_TRAKTORAUDIO2 | 147 | .idProduct = USB_PID_TRAKTORAUDIO2 |
149 | }, | 148 | }, |
150 | { | ||
151 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | ||
152 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | ||
153 | .idProduct = USB_PID_MASCHINECONTROLLER | ||
154 | }, | ||
155 | { /* terminator */ } | 149 | { /* terminator */ } |
156 | }; | 150 | }; |
157 | 151 | ||
@@ -289,7 +283,7 @@ int snd_usb_caiaq_set_auto_msg(struct snd_usb_caiaqdev *dev, | |||
289 | tmp, sizeof(tmp)); | 283 | tmp, sizeof(tmp)); |
290 | } | 284 | } |
291 | 285 | ||
292 | static void setup_card(struct snd_usb_caiaqdev *dev) | 286 | static void __devinit setup_card(struct snd_usb_caiaqdev *dev) |
293 | { | 287 | { |
294 | int ret; | 288 | int ret; |
295 | char val[4]; | 289 | char val[4]; |
@@ -407,7 +401,7 @@ static int create_card(struct usb_device *usb_dev, | |||
407 | return 0; | 401 | return 0; |
408 | } | 402 | } |
409 | 403 | ||
410 | static int init_card(struct snd_usb_caiaqdev *dev) | 404 | static int __devinit init_card(struct snd_usb_caiaqdev *dev) |
411 | { | 405 | { |
412 | char *c, usbpath[32]; | 406 | char *c, usbpath[32]; |
413 | struct usb_device *usb_dev = dev->chip.dev; | 407 | struct usb_device *usb_dev = dev->chip.dev; |
@@ -481,11 +475,11 @@ static int init_card(struct snd_usb_caiaqdev *dev) | |||
481 | return 0; | 475 | return 0; |
482 | } | 476 | } |
483 | 477 | ||
484 | static int snd_probe(struct usb_interface *intf, | 478 | static int __devinit snd_probe(struct usb_interface *intf, |
485 | const struct usb_device_id *id) | 479 | const struct usb_device_id *id) |
486 | { | 480 | { |
487 | int ret; | 481 | int ret; |
488 | struct snd_card *card = NULL; | 482 | struct snd_card *card; |
489 | struct usb_device *device = interface_to_usbdev(intf); | 483 | struct usb_device *device = interface_to_usbdev(intf); |
490 | 484 | ||
491 | ret = create_card(device, intf, &card); | 485 | ret = create_card(device, intf, &card); |
@@ -538,5 +532,16 @@ static struct usb_driver snd_usb_driver = { | |||
538 | .id_table = snd_usb_id_table, | 532 | .id_table = snd_usb_id_table, |
539 | }; | 533 | }; |
540 | 534 | ||
541 | module_usb_driver(snd_usb_driver); | 535 | static int __init snd_module_init(void) |
536 | { | ||
537 | return usb_register(&snd_usb_driver); | ||
538 | } | ||
539 | |||
540 | static void __exit snd_module_exit(void) | ||
541 | { | ||
542 | usb_deregister(&snd_usb_driver); | ||
543 | } | ||
544 | |||
545 | module_init(snd_module_init) | ||
546 | module_exit(snd_module_exit) | ||
542 | 547 | ||
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h index 562b0bff9c4..3f9c6339ae9 100644 --- a/sound/usb/caiaq/device.h +++ b/sound/usb/caiaq/device.h | |||
@@ -18,7 +18,6 @@ | |||
18 | #define USB_PID_TRAKTORKONTROLX1 0x2305 | 18 | #define USB_PID_TRAKTORKONTROLX1 0x2305 |
19 | #define USB_PID_TRAKTORKONTROLS4 0xbaff | 19 | #define USB_PID_TRAKTORKONTROLS4 0xbaff |
20 | #define USB_PID_TRAKTORAUDIO2 0x041d | 20 | #define USB_PID_TRAKTORAUDIO2 0x041d |
21 | #define USB_PID_MASCHINECONTROLLER 0x0808 | ||
22 | 21 | ||
23 | #define EP1_BUFSIZE 64 | 22 | #define EP1_BUFSIZE 64 |
24 | #define EP4_BUFSIZE 512 | 23 | #define EP4_BUFSIZE 512 |
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c index 26a121b42c3..a213813487b 100644 --- a/sound/usb/caiaq/input.c +++ b/sound/usb/caiaq/input.c | |||
@@ -67,61 +67,6 @@ static unsigned short keycode_kore[] = { | |||
67 | KEY_BRL_DOT5 | 67 | KEY_BRL_DOT5 |
68 | }; | 68 | }; |
69 | 69 | ||
70 | #define MASCHINE_BUTTONS (42) | ||
71 | #define MASCHINE_BUTTON(X) ((X) + BTN_MISC) | ||
72 | #define MASCHINE_PADS (16) | ||
73 | #define MASCHINE_PAD(X) ((X) + ABS_PRESSURE) | ||
74 | |||
75 | static unsigned short keycode_maschine[] = { | ||
76 | MASCHINE_BUTTON(40), /* mute */ | ||
77 | MASCHINE_BUTTON(39), /* solo */ | ||
78 | MASCHINE_BUTTON(38), /* select */ | ||
79 | MASCHINE_BUTTON(37), /* duplicate */ | ||
80 | MASCHINE_BUTTON(36), /* navigate */ | ||
81 | MASCHINE_BUTTON(35), /* pad mode */ | ||
82 | MASCHINE_BUTTON(34), /* pattern */ | ||
83 | MASCHINE_BUTTON(33), /* scene */ | ||
84 | KEY_RESERVED, /* spacer */ | ||
85 | |||
86 | MASCHINE_BUTTON(30), /* rec */ | ||
87 | MASCHINE_BUTTON(31), /* erase */ | ||
88 | MASCHINE_BUTTON(32), /* shift */ | ||
89 | MASCHINE_BUTTON(28), /* grid */ | ||
90 | MASCHINE_BUTTON(27), /* > */ | ||
91 | MASCHINE_BUTTON(26), /* < */ | ||
92 | MASCHINE_BUTTON(25), /* restart */ | ||
93 | |||
94 | MASCHINE_BUTTON(21), /* E */ | ||
95 | MASCHINE_BUTTON(22), /* F */ | ||
96 | MASCHINE_BUTTON(23), /* G */ | ||
97 | MASCHINE_BUTTON(24), /* H */ | ||
98 | MASCHINE_BUTTON(20), /* D */ | ||
99 | MASCHINE_BUTTON(19), /* C */ | ||
100 | MASCHINE_BUTTON(18), /* B */ | ||
101 | MASCHINE_BUTTON(17), /* A */ | ||
102 | |||
103 | MASCHINE_BUTTON(0), /* control */ | ||
104 | MASCHINE_BUTTON(2), /* browse */ | ||
105 | MASCHINE_BUTTON(4), /* < */ | ||
106 | MASCHINE_BUTTON(6), /* snap */ | ||
107 | MASCHINE_BUTTON(7), /* autowrite */ | ||
108 | MASCHINE_BUTTON(5), /* > */ | ||
109 | MASCHINE_BUTTON(3), /* sampling */ | ||
110 | MASCHINE_BUTTON(1), /* step */ | ||
111 | |||
112 | MASCHINE_BUTTON(15), /* 8 softkeys */ | ||
113 | MASCHINE_BUTTON(14), | ||
114 | MASCHINE_BUTTON(13), | ||
115 | MASCHINE_BUTTON(12), | ||
116 | MASCHINE_BUTTON(11), | ||
117 | MASCHINE_BUTTON(10), | ||
118 | MASCHINE_BUTTON(9), | ||
119 | MASCHINE_BUTTON(8), | ||
120 | |||
121 | MASCHINE_BUTTON(16), /* note repeat */ | ||
122 | MASCHINE_BUTTON(29) /* play */ | ||
123 | }; | ||
124 | |||
125 | #define KONTROLX1_INPUTS (40) | 70 | #define KONTROLX1_INPUTS (40) |
126 | #define KONTROLS4_BUTTONS (12 * 8) | 71 | #define KONTROLS4_BUTTONS (12 * 8) |
127 | #define KONTROLS4_AXIS (46) | 72 | #define KONTROLS4_AXIS (46) |
@@ -273,29 +218,6 @@ static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, | |||
273 | input_report_abs(input_dev, ABS_HAT3Y, i); | 218 | input_report_abs(input_dev, ABS_HAT3Y, i); |
274 | input_sync(input_dev); | 219 | input_sync(input_dev); |
275 | break; | 220 | break; |
276 | |||
277 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | ||
278 | /* 4 under the left screen */ | ||
279 | input_report_abs(input_dev, ABS_HAT0X, decode_erp(buf[21], buf[20])); | ||
280 | input_report_abs(input_dev, ABS_HAT0Y, decode_erp(buf[15], buf[14])); | ||
281 | input_report_abs(input_dev, ABS_HAT1X, decode_erp(buf[9], buf[8])); | ||
282 | input_report_abs(input_dev, ABS_HAT1Y, decode_erp(buf[3], buf[2])); | ||
283 | |||
284 | /* 4 under the right screen */ | ||
285 | input_report_abs(input_dev, ABS_HAT2X, decode_erp(buf[19], buf[18])); | ||
286 | input_report_abs(input_dev, ABS_HAT2Y, decode_erp(buf[13], buf[12])); | ||
287 | input_report_abs(input_dev, ABS_HAT3X, decode_erp(buf[7], buf[6])); | ||
288 | input_report_abs(input_dev, ABS_HAT3Y, decode_erp(buf[1], buf[0])); | ||
289 | |||
290 | /* volume */ | ||
291 | input_report_abs(input_dev, ABS_RX, decode_erp(buf[17], buf[16])); | ||
292 | /* tempo */ | ||
293 | input_report_abs(input_dev, ABS_RY, decode_erp(buf[11], buf[10])); | ||
294 | /* swing */ | ||
295 | input_report_abs(input_dev, ABS_RZ, decode_erp(buf[5], buf[4])); | ||
296 | |||
297 | input_sync(input_dev); | ||
298 | break; | ||
299 | } | 221 | } |
300 | } | 222 | } |
301 | 223 | ||
@@ -478,25 +400,6 @@ static void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *dev, | |||
478 | input_sync(dev->input_dev); | 400 | input_sync(dev->input_dev); |
479 | } | 401 | } |
480 | 402 | ||
481 | #define MASCHINE_MSGBLOCK_SIZE 2 | ||
482 | |||
483 | static void snd_usb_caiaq_maschine_dispatch(struct snd_usb_caiaqdev *dev, | ||
484 | const unsigned char *buf, | ||
485 | unsigned int len) | ||
486 | { | ||
487 | unsigned int i, pad_id; | ||
488 | uint16_t pressure; | ||
489 | |||
490 | for (i = 0; i < MASCHINE_PADS; i++) { | ||
491 | pressure = be16_to_cpu(buf[i * 2] << 8 | buf[(i * 2) + 1]); | ||
492 | pad_id = pressure >> 12; | ||
493 | |||
494 | input_report_abs(dev->input_dev, MASCHINE_PAD(pad_id), pressure & 0xfff); | ||
495 | } | ||
496 | |||
497 | input_sync(dev->input_dev); | ||
498 | } | ||
499 | |||
500 | static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) | 403 | static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) |
501 | { | 404 | { |
502 | struct snd_usb_caiaqdev *dev = urb->context; | 405 | struct snd_usb_caiaqdev *dev = urb->context; |
@@ -522,13 +425,6 @@ static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) | |||
522 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | 425 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): |
523 | snd_usb_caiaq_tks4_dispatch(dev, buf, urb->actual_length); | 426 | snd_usb_caiaq_tks4_dispatch(dev, buf, urb->actual_length); |
524 | break; | 427 | break; |
525 | |||
526 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | ||
527 | if (urb->actual_length < (MASCHINE_PADS * MASCHINE_MSGBLOCK_SIZE)) | ||
528 | goto requeue; | ||
529 | |||
530 | snd_usb_caiaq_maschine_dispatch(dev, buf, urb->actual_length); | ||
531 | break; | ||
532 | } | 428 | } |
533 | 429 | ||
534 | requeue: | 430 | requeue: |
@@ -548,7 +444,6 @@ static int snd_usb_caiaq_input_open(struct input_dev *idev) | |||
548 | switch (dev->chip.usb_id) { | 444 | switch (dev->chip.usb_id) { |
549 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 445 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
550 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | 446 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): |
551 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | ||
552 | if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0) | 447 | if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0) |
553 | return -EIO; | 448 | return -EIO; |
554 | break; | 449 | break; |
@@ -567,7 +462,6 @@ static void snd_usb_caiaq_input_close(struct input_dev *idev) | |||
567 | switch (dev->chip.usb_id) { | 462 | switch (dev->chip.usb_id) { |
568 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 463 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
569 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | 464 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): |
570 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | ||
571 | usb_kill_urb(dev->ep4_in_urb); | 465 | usb_kill_urb(dev->ep4_in_urb); |
572 | break; | 466 | break; |
573 | } | 467 | } |
@@ -758,50 +652,6 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
758 | 652 | ||
759 | break; | 653 | break; |
760 | 654 | ||
761 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | ||
762 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
763 | input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) | | ||
764 | BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) | | ||
765 | BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) | | ||
766 | BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) | | ||
767 | BIT_MASK(ABS_RX) | BIT_MASK(ABS_RY) | | ||
768 | BIT_MASK(ABS_RZ); | ||
769 | |||
770 | BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_maschine)); | ||
771 | memcpy(dev->keycode, keycode_maschine, sizeof(keycode_maschine)); | ||
772 | input->keycodemax = ARRAY_SIZE(keycode_maschine); | ||
773 | |||
774 | for (i = 0; i < MASCHINE_PADS; i++) { | ||
775 | input->absbit[0] |= MASCHINE_PAD(i); | ||
776 | input_set_abs_params(input, MASCHINE_PAD(i), 0, 0xfff, 5, 10); | ||
777 | } | ||
778 | |||
779 | input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10); | ||
780 | input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10); | ||
781 | input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10); | ||
782 | input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10); | ||
783 | input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10); | ||
784 | input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10); | ||
785 | input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10); | ||
786 | input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10); | ||
787 | input_set_abs_params(input, ABS_RX, 0, 999, 0, 10); | ||
788 | input_set_abs_params(input, ABS_RY, 0, 999, 0, 10); | ||
789 | input_set_abs_params(input, ABS_RZ, 0, 999, 0, 10); | ||
790 | |||
791 | dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
792 | if (!dev->ep4_in_urb) { | ||
793 | ret = -ENOMEM; | ||
794 | goto exit_free_idev; | ||
795 | } | ||
796 | |||
797 | usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev, | ||
798 | usb_rcvbulkpipe(usb_dev, 0x4), | ||
799 | dev->ep4_in_buf, EP4_BUFSIZE, | ||
800 | snd_usb_caiaq_ep4_reply_dispatch, dev); | ||
801 | |||
802 | snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); | ||
803 | break; | ||
804 | |||
805 | default: | 655 | default: |
806 | /* no input methods supported on this device */ | 656 | /* no input methods supported on this device */ |
807 | goto exit_free_idev; | 657 | goto exit_free_idev; |
@@ -814,17 +664,15 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
814 | for (i = 0; i < input->keycodemax; i++) | 664 | for (i = 0; i < input->keycodemax; i++) |
815 | __set_bit(dev->keycode[i], input->keybit); | 665 | __set_bit(dev->keycode[i], input->keybit); |
816 | 666 | ||
817 | dev->input_dev = input; | ||
818 | |||
819 | ret = input_register_device(input); | 667 | ret = input_register_device(input); |
820 | if (ret < 0) | 668 | if (ret < 0) |
821 | goto exit_free_idev; | 669 | goto exit_free_idev; |
822 | 670 | ||
671 | dev->input_dev = input; | ||
823 | return 0; | 672 | return 0; |
824 | 673 | ||
825 | exit_free_idev: | 674 | exit_free_idev: |
826 | input_free_device(input); | 675 | input_free_device(input); |
827 | dev->input_dev = NULL; | ||
828 | return ret; | 676 | return ret; |
829 | } | 677 | } |
830 | 678 | ||
@@ -840,3 +688,4 @@ void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev) | |||
840 | input_unregister_device(dev->input_dev); | 688 | input_unregister_device(dev->input_dev); |
841 | dev->input_dev = NULL; | 689 | dev->input_dev = NULL; |
842 | } | 690 | } |
691 | |||
diff --git a/sound/usb/card.c b/sound/usb/card.c index ccf95cfe186..d8f2bf40145 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
@@ -25,6 +25,9 @@ | |||
25 | * | 25 | * |
26 | * NOTES: | 26 | * NOTES: |
27 | * | 27 | * |
28 | * - async unlink should be used for avoiding the sleep inside lock. | ||
29 | * 2.4.22 usb-uhci seems buggy for async unlinking and results in | ||
30 | * oops. in such a cse, pass async_unlink=0 option. | ||
28 | * - the linked URBs would be preferred but not used so far because of | 31 | * - the linked URBs would be preferred but not used so far because of |
29 | * the instability of unlinking. | 32 | * the instability of unlinking. |
30 | * - type II is not supported properly. there is no device which supports | 33 | * - type II is not supported properly. there is no device which supports |
@@ -44,7 +47,6 @@ | |||
44 | #include <linux/mutex.h> | 47 | #include <linux/mutex.h> |
45 | #include <linux/usb/audio.h> | 48 | #include <linux/usb/audio.h> |
46 | #include <linux/usb/audio-v2.h> | 49 | #include <linux/usb/audio-v2.h> |
47 | #include <linux/module.h> | ||
48 | 50 | ||
49 | #include <sound/control.h> | 51 | #include <sound/control.h> |
50 | #include <sound/core.h> | 52 | #include <sound/core.h> |
@@ -63,9 +65,9 @@ | |||
63 | #include "helper.h" | 65 | #include "helper.h" |
64 | #include "debug.h" | 66 | #include "debug.h" |
65 | #include "pcm.h" | 67 | #include "pcm.h" |
68 | #include "urb.h" | ||
66 | #include "format.h" | 69 | #include "format.h" |
67 | #include "power.h" | 70 | #include "power.h" |
68 | #include "stream.h" | ||
69 | 71 | ||
70 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); | 72 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); |
71 | MODULE_DESCRIPTION("USB Audio"); | 73 | MODULE_DESCRIPTION("USB Audio"); |
@@ -75,13 +77,14 @@ MODULE_SUPPORTED_DEVICE("{{Generic,USB Audio}}"); | |||
75 | 77 | ||
76 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | 78 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ |
77 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 79 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
78 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ | 80 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */ |
79 | /* Vendor/product IDs for this card */ | 81 | /* Vendor/product IDs for this card */ |
80 | static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; | 82 | static int vid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; |
81 | static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; | 83 | static int pid[SNDRV_CARDS] = { [0 ... (SNDRV_CARDS-1)] = -1 }; |
82 | static int nrpacks = 8; /* max. number of packets per urb */ | 84 | static int nrpacks = 8; /* max. number of packets per urb */ |
85 | static int async_unlink = 1; | ||
83 | static int device_setup[SNDRV_CARDS]; /* device parameter for this card */ | 86 | static int device_setup[SNDRV_CARDS]; /* device parameter for this card */ |
84 | static bool ignore_ctl_error; | 87 | static int ignore_ctl_error; |
85 | 88 | ||
86 | module_param_array(index, int, NULL, 0444); | 89 | module_param_array(index, int, NULL, 0444); |
87 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); | 90 | MODULE_PARM_DESC(index, "Index value for the USB audio adapter."); |
@@ -95,6 +98,8 @@ module_param_array(pid, int, NULL, 0444); | |||
95 | MODULE_PARM_DESC(pid, "Product ID for the USB audio device."); | 98 | MODULE_PARM_DESC(pid, "Product ID for the USB audio device."); |
96 | module_param(nrpacks, int, 0644); | 99 | module_param(nrpacks, int, 0644); |
97 | MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB."); | 100 | MODULE_PARM_DESC(nrpacks, "Max. number of packets per URB."); |
101 | module_param(async_unlink, bool, 0444); | ||
102 | MODULE_PARM_DESC(async_unlink, "Use async unlink mode."); | ||
98 | module_param_array(device_setup, int, NULL, 0444); | 103 | module_param_array(device_setup, int, NULL, 0444); |
99 | MODULE_PARM_DESC(device_setup, "Specific device setup (if needed)."); | 104 | MODULE_PARM_DESC(device_setup, "Specific device setup (if needed)."); |
100 | module_param(ignore_ctl_error, bool, 0444); | 105 | module_param(ignore_ctl_error, bool, 0444); |
@@ -125,9 +130,8 @@ static void snd_usb_stream_disconnect(struct list_head *head) | |||
125 | subs = &as->substream[idx]; | 130 | subs = &as->substream[idx]; |
126 | if (!subs->num_formats) | 131 | if (!subs->num_formats) |
127 | continue; | 132 | continue; |
133 | snd_usb_release_substream_urbs(subs, 1); | ||
128 | subs->interface = -1; | 134 | subs->interface = -1; |
129 | subs->data_endpoint = NULL; | ||
130 | subs->sync_endpoint = NULL; | ||
131 | } | 135 | } |
132 | } | 136 | } |
133 | 137 | ||
@@ -181,7 +185,7 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int | |||
181 | return -EINVAL; | 185 | return -EINVAL; |
182 | } | 186 | } |
183 | 187 | ||
184 | if (! snd_usb_parse_audio_interface(chip, interface)) { | 188 | if (! snd_usb_parse_audio_endpoints(chip, interface)) { |
185 | usb_set_interface(dev, interface, 0); /* reset the current interface */ | 189 | usb_set_interface(dev, interface, 0); /* reset the current interface */ |
186 | usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); | 190 | usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); |
187 | return -EINVAL; | 191 | return -EINVAL; |
@@ -271,7 +275,6 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif) | |||
271 | 275 | ||
272 | static int snd_usb_audio_free(struct snd_usb_audio *chip) | 276 | static int snd_usb_audio_free(struct snd_usb_audio *chip) |
273 | { | 277 | { |
274 | mutex_destroy(&chip->mutex); | ||
275 | kfree(chip); | 278 | kfree(chip); |
276 | return 0; | 279 | return 0; |
277 | } | 280 | } |
@@ -332,19 +335,18 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx, | |||
332 | return -ENOMEM; | 335 | return -ENOMEM; |
333 | } | 336 | } |
334 | 337 | ||
335 | mutex_init(&chip->mutex); | 338 | mutex_init(&chip->shutdown_mutex); |
336 | init_rwsem(&chip->shutdown_rwsem); | ||
337 | chip->index = idx; | 339 | chip->index = idx; |
338 | chip->dev = dev; | 340 | chip->dev = dev; |
339 | chip->card = card; | 341 | chip->card = card; |
340 | chip->setup = device_setup[idx]; | 342 | chip->setup = device_setup[idx]; |
341 | chip->nrpacks = nrpacks; | 343 | chip->nrpacks = nrpacks; |
344 | chip->async_unlink = async_unlink; | ||
342 | chip->probing = 1; | 345 | chip->probing = 1; |
343 | 346 | ||
344 | chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), | 347 | chip->usb_id = USB_ID(le16_to_cpu(dev->descriptor.idVendor), |
345 | le16_to_cpu(dev->descriptor.idProduct)); | 348 | le16_to_cpu(dev->descriptor.idProduct)); |
346 | INIT_LIST_HEAD(&chip->pcm_list); | 349 | INIT_LIST_HEAD(&chip->pcm_list); |
347 | INIT_LIST_HEAD(&chip->ep_list); | ||
348 | INIT_LIST_HEAD(&chip->midi_list); | 350 | INIT_LIST_HEAD(&chip->midi_list); |
349 | INIT_LIST_HEAD(&chip->mixer_list); | 351 | INIT_LIST_HEAD(&chip->mixer_list); |
350 | 352 | ||
@@ -546,17 +548,15 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, | |||
546 | struct snd_usb_audio *chip) | 548 | struct snd_usb_audio *chip) |
547 | { | 549 | { |
548 | struct snd_card *card; | 550 | struct snd_card *card; |
549 | struct list_head *p, *n; | 551 | struct list_head *p; |
550 | 552 | ||
551 | if (chip == (void *)-1L) | 553 | if (chip == (void *)-1L) |
552 | return; | 554 | return; |
553 | 555 | ||
554 | card = chip->card; | 556 | card = chip->card; |
555 | down_write(&chip->shutdown_rwsem); | ||
556 | chip->shutdown = 1; | ||
557 | up_write(&chip->shutdown_rwsem); | ||
558 | |||
559 | mutex_lock(®ister_mutex); | 557 | mutex_lock(®ister_mutex); |
558 | mutex_lock(&chip->shutdown_mutex); | ||
559 | chip->shutdown = 1; | ||
560 | chip->num_interfaces--; | 560 | chip->num_interfaces--; |
561 | if (chip->num_interfaces <= 0) { | 561 | if (chip->num_interfaces <= 0) { |
562 | snd_card_disconnect(card); | 562 | snd_card_disconnect(card); |
@@ -564,10 +564,6 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, | |||
564 | list_for_each(p, &chip->pcm_list) { | 564 | list_for_each(p, &chip->pcm_list) { |
565 | snd_usb_stream_disconnect(p); | 565 | snd_usb_stream_disconnect(p); |
566 | } | 566 | } |
567 | /* release the endpoint resources */ | ||
568 | list_for_each_safe(p, n, &chip->ep_list) { | ||
569 | snd_usb_endpoint_free(p); | ||
570 | } | ||
571 | /* release the midi resources */ | 567 | /* release the midi resources */ |
572 | list_for_each(p, &chip->midi_list) { | 568 | list_for_each(p, &chip->midi_list) { |
573 | snd_usbmidi_disconnect(p); | 569 | snd_usbmidi_disconnect(p); |
@@ -577,9 +573,11 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, | |||
577 | snd_usb_mixer_disconnect(p); | 573 | snd_usb_mixer_disconnect(p); |
578 | } | 574 | } |
579 | usb_chip[chip->index] = NULL; | 575 | usb_chip[chip->index] = NULL; |
576 | mutex_unlock(&chip->shutdown_mutex); | ||
580 | mutex_unlock(®ister_mutex); | 577 | mutex_unlock(®ister_mutex); |
581 | snd_card_free_when_closed(card); | 578 | snd_card_free_when_closed(card); |
582 | } else { | 579 | } else { |
580 | mutex_unlock(&chip->shutdown_mutex); | ||
583 | mutex_unlock(®ister_mutex); | 581 | mutex_unlock(®ister_mutex); |
584 | } | 582 | } |
585 | } | 583 | } |
@@ -611,20 +609,16 @@ int snd_usb_autoresume(struct snd_usb_audio *chip) | |||
611 | { | 609 | { |
612 | int err = -ENODEV; | 610 | int err = -ENODEV; |
613 | 611 | ||
614 | down_read(&chip->shutdown_rwsem); | ||
615 | if (!chip->shutdown && !chip->probing) | 612 | if (!chip->shutdown && !chip->probing) |
616 | err = usb_autopm_get_interface(chip->pm_intf); | 613 | err = usb_autopm_get_interface(chip->pm_intf); |
617 | up_read(&chip->shutdown_rwsem); | ||
618 | 614 | ||
619 | return err; | 615 | return err; |
620 | } | 616 | } |
621 | 617 | ||
622 | void snd_usb_autosuspend(struct snd_usb_audio *chip) | 618 | void snd_usb_autosuspend(struct snd_usb_audio *chip) |
623 | { | 619 | { |
624 | down_read(&chip->shutdown_rwsem); | ||
625 | if (!chip->shutdown && !chip->probing) | 620 | if (!chip->shutdown && !chip->probing) |
626 | usb_autopm_put_interface(chip->pm_intf); | 621 | usb_autopm_put_interface(chip->pm_intf); |
627 | up_read(&chip->shutdown_rwsem); | ||
628 | } | 622 | } |
629 | 623 | ||
630 | static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) | 624 | static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) |
@@ -637,14 +631,12 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) | |||
637 | if (chip == (void *)-1L) | 631 | if (chip == (void *)-1L) |
638 | return 0; | 632 | return 0; |
639 | 633 | ||
640 | if (!PMSG_IS_AUTO(message)) { | 634 | if (!(message.event & PM_EVENT_AUTO)) { |
641 | snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot); | 635 | snd_power_change_state(chip->card, SNDRV_CTL_POWER_D3hot); |
642 | if (!chip->num_suspended_intf++) { | 636 | if (!chip->num_suspended_intf++) { |
643 | list_for_each(p, &chip->pcm_list) { | 637 | list_for_each(p, &chip->pcm_list) { |
644 | as = list_entry(p, struct snd_usb_stream, list); | 638 | as = list_entry(p, struct snd_usb_stream, list); |
645 | snd_pcm_suspend_all(as->pcm); | 639 | snd_pcm_suspend_all(as->pcm); |
646 | as->substream[0].need_setup_ep = | ||
647 | as->substream[1].need_setup_ep = true; | ||
648 | } | 640 | } |
649 | } | 641 | } |
650 | } else { | 642 | } else { |
diff --git a/sound/usb/card.h b/sound/usb/card.h index 8a751b4887e..ae4251d5abf 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
@@ -1,7 +1,6 @@ | |||
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 | ||
5 | #define MAX_PACKS 20 | 4 | #define MAX_PACKS 20 |
6 | #define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */ | 5 | #define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */ |
7 | #define MAX_URBS 8 | 6 | #define MAX_URBS 8 |
@@ -27,77 +26,23 @@ struct audioformat { | |||
27 | unsigned int nr_rates; /* number of rate table entries */ | 26 | unsigned int nr_rates; /* number of rate table entries */ |
28 | unsigned int *rate_table; /* rate table */ | 27 | unsigned int *rate_table; /* rate table */ |
29 | unsigned char clock; /* associated clock */ | 28 | unsigned char clock; /* associated clock */ |
30 | struct snd_pcm_chmap_elem *chmap; /* (optional) channel map */ | ||
31 | }; | 29 | }; |
32 | 30 | ||
33 | struct snd_usb_substream; | 31 | struct snd_usb_substream; |
34 | struct snd_usb_endpoint; | ||
35 | 32 | ||
36 | struct snd_urb_ctx { | 33 | struct snd_urb_ctx { |
37 | struct urb *urb; | 34 | struct urb *urb; |
38 | unsigned int buffer_size; /* size of data buffer, if data URB */ | 35 | unsigned int buffer_size; /* size of data buffer, if data URB */ |
39 | struct snd_usb_substream *subs; | 36 | struct snd_usb_substream *subs; |
40 | struct snd_usb_endpoint *ep; | ||
41 | int index; /* index for urb array */ | 37 | int index; /* index for urb array */ |
42 | int packets; /* number of packets per urb */ | 38 | int packets; /* number of packets per urb */ |
43 | int packet_size[MAX_PACKS_HS]; /* size of packets for next submission */ | ||
44 | struct list_head ready_list; | ||
45 | }; | 39 | }; |
46 | 40 | ||
47 | struct snd_usb_endpoint { | 41 | struct snd_urb_ops { |
48 | struct snd_usb_audio *chip; | 42 | int (*prepare)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u); |
49 | 43 | int (*retire)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u); | |
50 | int use_count; | 44 | int (*prepare_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u); |
51 | int ep_num; /* the referenced endpoint number */ | 45 | int (*retire_sync)(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime, struct urb *u); |
52 | int type; /* SND_USB_ENDPOINT_TYPE_* */ | ||
53 | unsigned long flags; | ||
54 | |||
55 | void (*prepare_data_urb) (struct snd_usb_substream *subs, | ||
56 | struct urb *urb); | ||
57 | void (*retire_data_urb) (struct snd_usb_substream *subs, | ||
58 | struct urb *urb); | ||
59 | |||
60 | struct snd_usb_substream *data_subs; | ||
61 | struct snd_usb_endpoint *sync_master; | ||
62 | struct snd_usb_endpoint *sync_slave; | ||
63 | |||
64 | struct snd_urb_ctx urb[MAX_URBS]; | ||
65 | |||
66 | struct snd_usb_packet_info { | ||
67 | uint32_t packet_size[MAX_PACKS_HS]; | ||
68 | int packets; | ||
69 | } next_packet[MAX_URBS]; | ||
70 | int next_packet_read_pos, next_packet_write_pos; | ||
71 | struct list_head ready_playback_urbs; | ||
72 | |||
73 | unsigned int nurbs; /* # urbs */ | ||
74 | unsigned long active_mask; /* bitmask of active urbs */ | ||
75 | unsigned long unlink_mask; /* bitmask of unlinked urbs */ | ||
76 | char *syncbuf; /* sync buffer for all sync URBs */ | ||
77 | dma_addr_t sync_dma; /* DMA address of syncbuf */ | ||
78 | |||
79 | unsigned int pipe; /* the data i/o pipe */ | ||
80 | unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */ | ||
81 | unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */ | ||
82 | int freqshift; /* how much to shift the feedback value to get Q16.16 */ | ||
83 | unsigned int freqmax; /* maximum sampling rate, used for buffer management */ | ||
84 | unsigned int phase; /* phase accumulator */ | ||
85 | unsigned int maxpacksize; /* max packet size in bytes */ | ||
86 | unsigned int maxframesize; /* max packet size in frames */ | ||
87 | unsigned int curpacksize; /* current packet size in bytes (for capture) */ | ||
88 | unsigned int curframesize; /* current packet size in frames (for capture) */ | ||
89 | unsigned int syncmaxsize; /* sync endpoint packet size */ | ||
90 | unsigned int fill_max:1; /* fill max packet size always */ | ||
91 | unsigned int datainterval; /* log_2 of data packet interval */ | ||
92 | unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ | ||
93 | unsigned char silence_value; | ||
94 | unsigned int stride; | ||
95 | int iface, alt_idx; | ||
96 | int skip_packets; /* quirks for devices to ignore the first n packets | ||
97 | in a stream */ | ||
98 | |||
99 | spinlock_t lock; | ||
100 | struct list_head list; | ||
101 | }; | 46 | }; |
102 | 47 | ||
103 | struct snd_usb_substream { | 48 | struct snd_usb_substream { |
@@ -108,12 +53,24 @@ struct snd_usb_substream { | |||
108 | int interface; /* current interface */ | 53 | int interface; /* current interface */ |
109 | int endpoint; /* assigned endpoint */ | 54 | int endpoint; /* assigned endpoint */ |
110 | struct audioformat *cur_audiofmt; /* current audioformat pointer (for hw_params callback) */ | 55 | struct audioformat *cur_audiofmt; /* current audioformat pointer (for hw_params callback) */ |
111 | snd_pcm_format_t pcm_format; /* current audio format (for hw_params callback) */ | ||
112 | unsigned int channels; /* current number of channels (for hw_params callback) */ | ||
113 | unsigned int channels_max; /* max channels in the all audiofmts */ | ||
114 | unsigned int cur_rate; /* current rate (for hw_params callback) */ | 56 | unsigned int cur_rate; /* current rate (for hw_params callback) */ |
115 | unsigned int period_bytes; /* current period bytes (for hw_params callback) */ | 57 | unsigned int period_bytes; /* current period bytes (for hw_params callback) */ |
116 | unsigned int altset_idx; /* USB data format: index of alternate setting */ | 58 | unsigned int altset_idx; /* USB data format: index of alternate setting */ |
59 | unsigned int datapipe; /* the data i/o pipe */ | ||
60 | unsigned int syncpipe; /* 1 - async out or adaptive in */ | ||
61 | unsigned int datainterval; /* log_2 of data packet interval */ | ||
62 | unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ | ||
63 | unsigned int freqn; /* nominal sampling rate in fs/fps in Q16.16 format */ | ||
64 | unsigned int freqm; /* momentary sampling rate in fs/fps in Q16.16 format */ | ||
65 | int freqshift; /* how much to shift the feedback value to get Q16.16 */ | ||
66 | unsigned int freqmax; /* maximum sampling rate, used for buffer management */ | ||
67 | unsigned int phase; /* phase accumulator */ | ||
68 | unsigned int maxpacksize; /* max packet size in bytes */ | ||
69 | unsigned int maxframesize; /* max packet size in frames */ | ||
70 | unsigned int curpacksize; /* current packet size in bytes (for capture) */ | ||
71 | unsigned int curframesize; /* current packet size in frames (for capture) */ | ||
72 | unsigned int syncmaxsize; /* sync endpoint packet size */ | ||
73 | unsigned int fill_max: 1; /* fill max packet size always */ | ||
117 | unsigned int txfr_quirk:1; /* allow sub-frame alignment */ | 74 | unsigned int txfr_quirk:1; /* allow sub-frame alignment */ |
118 | unsigned int fmt_type; /* USB audio format type (1-3) */ | 75 | unsigned int fmt_type; /* USB audio format type (1-3) */ |
119 | 76 | ||
@@ -121,14 +78,14 @@ struct snd_usb_substream { | |||
121 | 78 | ||
122 | unsigned int hwptr_done; /* processed byte position in the buffer */ | 79 | unsigned int hwptr_done; /* processed byte position in the buffer */ |
123 | unsigned int transfer_done; /* processed frames since last period update */ | 80 | unsigned int transfer_done; /* processed frames since last period update */ |
81 | unsigned long active_mask; /* bitmask of active urbs */ | ||
82 | unsigned long unlink_mask; /* bitmask of unlinked urbs */ | ||
124 | 83 | ||
125 | /* data and sync endpoints for this stream */ | 84 | unsigned int nurbs; /* # urbs */ |
126 | unsigned int ep_num; /* the endpoint number */ | 85 | struct snd_urb_ctx dataurb[MAX_URBS]; /* data urb table */ |
127 | struct snd_usb_endpoint *data_endpoint; | 86 | struct snd_urb_ctx syncurb[SYNC_URBS]; /* sync urb table */ |
128 | struct snd_usb_endpoint *sync_endpoint; | 87 | char *syncbuf; /* sync buffer for all sync URBs */ |
129 | unsigned long flags; | 88 | dma_addr_t sync_dma; /* DMA address of syncbuf */ |
130 | bool need_setup_ep; /* (re)configure EP at prepare? */ | ||
131 | unsigned int speed; /* USB_SPEED_XXX */ | ||
132 | 89 | ||
133 | u64 formats; /* format bitmasks (all or'ed) */ | 90 | u64 formats; /* format bitmasks (all or'ed) */ |
134 | unsigned int num_formats; /* number of supported audio formats (list) */ | 91 | unsigned int num_formats; /* number of supported audio formats (list) */ |
@@ -136,8 +93,7 @@ struct snd_usb_substream { | |||
136 | struct snd_pcm_hw_constraint_list rate_list; /* limited rates */ | 93 | struct snd_pcm_hw_constraint_list rate_list; /* limited rates */ |
137 | spinlock_t lock; | 94 | spinlock_t lock; |
138 | 95 | ||
139 | int last_frame_number; /* stored frame number */ | 96 | struct snd_urb_ops ops; /* callbacks (must be filled at init) */ |
140 | int last_delay; /* stored delay */ | ||
141 | }; | 97 | }; |
142 | 98 | ||
143 | struct snd_usb_stream { | 99 | struct snd_usb_stream { |
diff --git a/sound/usb/clock.c b/sound/usb/clock.c index 5e634a2eb28..075195e8661 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c | |||
@@ -91,7 +91,7 @@ static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_i | |||
91 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | 91 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, |
92 | UAC2_CX_CLOCK_SELECTOR << 8, | 92 | UAC2_CX_CLOCK_SELECTOR << 8, |
93 | snd_usb_ctrl_intf(chip) | (selector_id << 8), | 93 | snd_usb_ctrl_intf(chip) | (selector_id << 8), |
94 | &buf, sizeof(buf)); | 94 | &buf, sizeof(buf), 1000); |
95 | 95 | ||
96 | if (ret < 0) | 96 | if (ret < 0) |
97 | return ret; | 97 | return ret; |
@@ -111,15 +111,14 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id) | |||
111 | return 0; | 111 | return 0; |
112 | 112 | ||
113 | /* If a clock source can't tell us whether it's valid, we assume it is */ | 113 | /* If a clock source can't tell us whether it's valid, we assume it is */ |
114 | if (!uac2_control_is_readable(cs_desc->bmControls, | 114 | if (!uac2_control_is_readable(cs_desc->bmControls, UAC2_CS_CONTROL_CLOCK_VALID)) |
115 | UAC2_CS_CONTROL_CLOCK_VALID - 1)) | ||
116 | return 1; | 115 | return 1; |
117 | 116 | ||
118 | err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, | 117 | err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, |
119 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | 118 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
120 | UAC2_CS_CONTROL_CLOCK_VALID << 8, | 119 | UAC2_CS_CONTROL_CLOCK_VALID << 8, |
121 | snd_usb_ctrl_intf(chip) | (source_id << 8), | 120 | snd_usb_ctrl_intf(chip) | (source_id << 8), |
122 | &data, sizeof(data)); | 121 | &data, sizeof(data), 1000); |
123 | 122 | ||
124 | if (err < 0) { | 123 | if (err < 0) { |
125 | snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n", | 124 | snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n", |
@@ -223,7 +222,7 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, | |||
223 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, | 222 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, |
224 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, | 223 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, |
225 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, | 224 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, |
226 | data, sizeof(data))) < 0) { | 225 | data, sizeof(data), 1000)) < 0) { |
227 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n", | 226 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n", |
228 | dev->devnum, iface, fmt->altsetting, rate, ep); | 227 | dev->devnum, iface, fmt->altsetting, rate, ep); |
229 | return err; | 228 | return err; |
@@ -232,7 +231,7 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, | |||
232 | if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR, | 231 | if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR, |
233 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN, | 232 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN, |
234 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, | 233 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, |
235 | data, sizeof(data))) < 0) { | 234 | data, sizeof(data), 1000)) < 0) { |
236 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n", | 235 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n", |
237 | dev->devnum, iface, fmt->altsetting, ep); | 236 | dev->devnum, iface, fmt->altsetting, ep); |
238 | return 0; /* some devices don't support reading */ | 237 | return 0; /* some devices don't support reading */ |
@@ -274,7 +273,7 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | |||
274 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | 273 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, |
275 | UAC2_CS_CONTROL_SAM_FREQ << 8, | 274 | UAC2_CS_CONTROL_SAM_FREQ << 8, |
276 | snd_usb_ctrl_intf(chip) | (clock << 8), | 275 | snd_usb_ctrl_intf(chip) | (clock << 8), |
277 | data, sizeof(data))) < 0) { | 276 | data, sizeof(data), 1000)) < 0) { |
278 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n", | 277 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n", |
279 | dev->devnum, iface, fmt->altsetting, rate); | 278 | dev->devnum, iface, fmt->altsetting, rate); |
280 | return err; | 279 | return err; |
@@ -284,7 +283,7 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | |||
284 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | 283 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
285 | UAC2_CS_CONTROL_SAM_FREQ << 8, | 284 | UAC2_CS_CONTROL_SAM_FREQ << 8, |
286 | snd_usb_ctrl_intf(chip) | (clock << 8), | 285 | snd_usb_ctrl_intf(chip) | (clock << 8), |
287 | data, sizeof(data))) < 0) { | 286 | data, sizeof(data), 1000)) < 0) { |
288 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", | 287 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", |
289 | dev->devnum, iface, fmt->altsetting); | 288 | dev->devnum, iface, fmt->altsetting); |
290 | return err; | 289 | return err; |
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 21049b882ee..7d46e482375 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -15,1097 +15,436 @@ | |||
15 | * | 15 | * |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/gfp.h> | ||
19 | #include <linux/init.h> | 18 | #include <linux/init.h> |
20 | #include <linux/ratelimit.h> | 19 | #include <linux/slab.h> |
21 | #include <linux/usb.h> | 20 | #include <linux/usb.h> |
22 | #include <linux/usb/audio.h> | 21 | #include <linux/usb/audio.h> |
23 | #include <linux/slab.h> | 22 | #include <linux/usb/audio-v2.h> |
24 | 23 | ||
25 | #include <sound/core.h> | 24 | #include <sound/core.h> |
26 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
27 | #include <sound/pcm_params.h> | ||
28 | 26 | ||
29 | #include "usbaudio.h" | 27 | #include "usbaudio.h" |
30 | #include "helper.h" | ||
31 | #include "card.h" | 28 | #include "card.h" |
29 | #include "proc.h" | ||
30 | #include "quirks.h" | ||
32 | #include "endpoint.h" | 31 | #include "endpoint.h" |
32 | #include "urb.h" | ||
33 | #include "pcm.h" | 33 | #include "pcm.h" |
34 | #include "quirks.h" | 34 | #include "helper.h" |
35 | 35 | #include "format.h" | |
36 | #define EP_FLAG_ACTIVATED 0 | 36 | #include "clock.h" |
37 | #define EP_FLAG_RUNNING 1 | ||
38 | #define EP_FLAG_STOPPING 2 | ||
39 | |||
40 | /* | ||
41 | * snd_usb_endpoint is a model that abstracts everything related to an | ||
42 | * USB endpoint and its streaming. | ||
43 | * | ||
44 | * There are functions to activate and deactivate the streaming URBs and | ||
45 | * optional callbacks to let the pcm logic handle the actual content of the | ||
46 | * packets for playback and record. Thus, the bus streaming and the audio | ||
47 | * handlers are fully decoupled. | ||
48 | * | ||
49 | * There are two different types of endpoints in audio applications. | ||
50 | * | ||
51 | * SND_USB_ENDPOINT_TYPE_DATA handles full audio data payload for both | ||
52 | * inbound and outbound traffic. | ||
53 | * | ||
54 | * SND_USB_ENDPOINT_TYPE_SYNC endpoints are for inbound traffic only and | ||
55 | * expect the payload to carry Q10.14 / Q16.16 formatted sync information | ||
56 | * (3 or 4 bytes). | ||
57 | * | ||
58 | * Each endpoint has to be configured prior to being used by calling | ||
59 | * snd_usb_endpoint_set_params(). | ||
60 | * | ||
61 | * The model incorporates a reference counting, so that multiple users | ||
62 | * can call snd_usb_endpoint_start() and snd_usb_endpoint_stop(), and | ||
63 | * only the first user will effectively start the URBs, and only the last | ||
64 | * one to stop it will tear the URBs down again. | ||
65 | */ | ||
66 | |||
67 | /* | ||
68 | * convert a sampling rate into our full speed format (fs/1000 in Q16.16) | ||
69 | * this will overflow at approx 524 kHz | ||
70 | */ | ||
71 | static inline unsigned get_usb_full_speed_rate(unsigned int rate) | ||
72 | { | ||
73 | return ((rate << 13) + 62) / 125; | ||
74 | } | ||
75 | |||
76 | /* | ||
77 | * convert a sampling rate into USB high speed format (fs/8000 in Q16.16) | ||
78 | * this will overflow at approx 4 MHz | ||
79 | */ | ||
80 | static inline unsigned get_usb_high_speed_rate(unsigned int rate) | ||
81 | { | ||
82 | return ((rate << 10) + 62) / 125; | ||
83 | } | ||
84 | 37 | ||
85 | /* | 38 | /* |
86 | * release a urb data | 39 | * free a substream |
87 | */ | 40 | */ |
88 | static void release_urb_ctx(struct snd_urb_ctx *u) | 41 | static void free_substream(struct snd_usb_substream *subs) |
89 | { | ||
90 | if (u->buffer_size) | ||
91 | usb_free_coherent(u->ep->chip->dev, u->buffer_size, | ||
92 | u->urb->transfer_buffer, | ||
93 | u->urb->transfer_dma); | ||
94 | usb_free_urb(u->urb); | ||
95 | u->urb = NULL; | ||
96 | } | ||
97 | |||
98 | static const char *usb_error_string(int err) | ||
99 | { | 42 | { |
100 | switch (err) { | 43 | struct list_head *p, *n; |
101 | case -ENODEV: | 44 | |
102 | return "no device"; | 45 | if (!subs->num_formats) |
103 | case -ENOENT: | 46 | return; /* not initialized */ |
104 | return "endpoint not enabled"; | 47 | list_for_each_safe(p, n, &subs->fmt_list) { |
105 | case -EPIPE: | 48 | struct audioformat *fp = list_entry(p, struct audioformat, list); |
106 | return "endpoint stalled"; | 49 | kfree(fp->rate_table); |
107 | case -ENOSPC: | 50 | kfree(fp); |
108 | return "not enough bandwidth"; | ||
109 | case -ESHUTDOWN: | ||
110 | return "device disabled"; | ||
111 | case -EHOSTUNREACH: | ||
112 | return "device suspended"; | ||
113 | case -EINVAL: | ||
114 | case -EAGAIN: | ||
115 | case -EFBIG: | ||
116 | case -EMSGSIZE: | ||
117 | return "internal error"; | ||
118 | default: | ||
119 | return "unknown error"; | ||
120 | } | 51 | } |
52 | kfree(subs->rate_list.list); | ||
121 | } | 53 | } |
122 | 54 | ||
123 | /** | ||
124 | * snd_usb_endpoint_implicit_feedback_sink: Report endpoint usage type | ||
125 | * | ||
126 | * @ep: The snd_usb_endpoint | ||
127 | * | ||
128 | * Determine whether an endpoint is driven by an implicit feedback | ||
129 | * data endpoint source. | ||
130 | */ | ||
131 | int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep) | ||
132 | { | ||
133 | return ep->sync_master && | ||
134 | ep->sync_master->type == SND_USB_ENDPOINT_TYPE_DATA && | ||
135 | ep->type == SND_USB_ENDPOINT_TYPE_DATA && | ||
136 | usb_pipeout(ep->pipe); | ||
137 | } | ||
138 | 55 | ||
139 | /* | 56 | /* |
140 | * For streaming based on information derived from sync endpoints, | 57 | * free a usb stream instance |
141 | * prepare_outbound_urb_sizes() will call next_packet_size() to | ||
142 | * determine the number of samples to be sent in the next packet. | ||
143 | * | ||
144 | * For implicit feedback, next_packet_size() is unused. | ||
145 | */ | 58 | */ |
146 | int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep) | 59 | static void snd_usb_audio_stream_free(struct snd_usb_stream *stream) |
147 | { | 60 | { |
148 | unsigned long flags; | 61 | free_substream(&stream->substream[0]); |
149 | int ret; | 62 | free_substream(&stream->substream[1]); |
150 | 63 | list_del(&stream->list); | |
151 | if (ep->fill_max) | 64 | kfree(stream); |
152 | return ep->maxframesize; | ||
153 | |||
154 | spin_lock_irqsave(&ep->lock, flags); | ||
155 | ep->phase = (ep->phase & 0xffff) | ||
156 | + (ep->freqm << ep->datainterval); | ||
157 | ret = min(ep->phase >> 16, ep->maxframesize); | ||
158 | spin_unlock_irqrestore(&ep->lock, flags); | ||
159 | |||
160 | return ret; | ||
161 | } | 65 | } |
162 | 66 | ||
163 | static void retire_outbound_urb(struct snd_usb_endpoint *ep, | 67 | static void snd_usb_audio_pcm_free(struct snd_pcm *pcm) |
164 | struct snd_urb_ctx *urb_ctx) | ||
165 | { | 68 | { |
166 | if (ep->retire_data_urb) | 69 | struct snd_usb_stream *stream = pcm->private_data; |
167 | ep->retire_data_urb(ep->data_subs, urb_ctx->urb); | 70 | if (stream) { |
168 | } | 71 | stream->pcm = NULL; |
169 | 72 | snd_usb_audio_stream_free(stream); | |
170 | static void retire_inbound_urb(struct snd_usb_endpoint *ep, | ||
171 | struct snd_urb_ctx *urb_ctx) | ||
172 | { | ||
173 | struct urb *urb = urb_ctx->urb; | ||
174 | |||
175 | if (unlikely(ep->skip_packets > 0)) { | ||
176 | ep->skip_packets--; | ||
177 | return; | ||
178 | } | 73 | } |
179 | |||
180 | if (ep->sync_slave) | ||
181 | snd_usb_handle_sync_urb(ep->sync_slave, ep, urb); | ||
182 | |||
183 | if (ep->retire_data_urb) | ||
184 | ep->retire_data_urb(ep->data_subs, urb); | ||
185 | } | 74 | } |
186 | 75 | ||
187 | /* | ||
188 | * Prepare a PLAYBACK urb for submission to the bus. | ||
189 | */ | ||
190 | static void prepare_outbound_urb(struct snd_usb_endpoint *ep, | ||
191 | struct snd_urb_ctx *ctx) | ||
192 | { | ||
193 | int i; | ||
194 | struct urb *urb = ctx->urb; | ||
195 | unsigned char *cp = urb->transfer_buffer; | ||
196 | |||
197 | urb->dev = ep->chip->dev; /* we need to set this at each time */ | ||
198 | |||
199 | switch (ep->type) { | ||
200 | case SND_USB_ENDPOINT_TYPE_DATA: | ||
201 | if (ep->prepare_data_urb) { | ||
202 | ep->prepare_data_urb(ep->data_subs, urb); | ||
203 | } else { | ||
204 | /* no data provider, so send silence */ | ||
205 | unsigned int offs = 0; | ||
206 | for (i = 0; i < ctx->packets; ++i) { | ||
207 | int counts; | ||
208 | |||
209 | if (ctx->packet_size[i]) | ||
210 | counts = ctx->packet_size[i]; | ||
211 | else | ||
212 | counts = snd_usb_endpoint_next_packet_size(ep); | ||
213 | |||
214 | urb->iso_frame_desc[i].offset = offs * ep->stride; | ||
215 | urb->iso_frame_desc[i].length = counts * ep->stride; | ||
216 | offs += counts; | ||
217 | } | ||
218 | |||
219 | urb->number_of_packets = ctx->packets; | ||
220 | urb->transfer_buffer_length = offs * ep->stride; | ||
221 | memset(urb->transfer_buffer, ep->silence_value, | ||
222 | offs * ep->stride); | ||
223 | } | ||
224 | break; | ||
225 | |||
226 | case SND_USB_ENDPOINT_TYPE_SYNC: | ||
227 | if (snd_usb_get_speed(ep->chip->dev) >= USB_SPEED_HIGH) { | ||
228 | /* | ||
229 | * fill the length and offset of each urb descriptor. | ||
230 | * the fixed 12.13 frequency is passed as 16.16 through the pipe. | ||
231 | */ | ||
232 | urb->iso_frame_desc[0].length = 4; | ||
233 | urb->iso_frame_desc[0].offset = 0; | ||
234 | cp[0] = ep->freqn; | ||
235 | cp[1] = ep->freqn >> 8; | ||
236 | cp[2] = ep->freqn >> 16; | ||
237 | cp[3] = ep->freqn >> 24; | ||
238 | } else { | ||
239 | /* | ||
240 | * fill the length and offset of each urb descriptor. | ||
241 | * the fixed 10.14 frequency is passed through the pipe. | ||
242 | */ | ||
243 | urb->iso_frame_desc[0].length = 3; | ||
244 | urb->iso_frame_desc[0].offset = 0; | ||
245 | cp[0] = ep->freqn >> 2; | ||
246 | cp[1] = ep->freqn >> 10; | ||
247 | cp[2] = ep->freqn >> 18; | ||
248 | } | ||
249 | |||
250 | break; | ||
251 | } | ||
252 | } | ||
253 | 76 | ||
254 | /* | 77 | /* |
255 | * Prepare a CAPTURE or SYNC urb for submission to the bus. | 78 | * add this endpoint to the chip instance. |
79 | * if a stream with the same endpoint already exists, append to it. | ||
80 | * if not, create a new pcm stream. | ||
256 | */ | 81 | */ |
257 | static inline void prepare_inbound_urb(struct snd_usb_endpoint *ep, | 82 | int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct audioformat *fp) |
258 | struct snd_urb_ctx *urb_ctx) | ||
259 | { | 83 | { |
260 | int i, offs; | 84 | struct list_head *p; |
261 | struct urb *urb = urb_ctx->urb; | 85 | struct snd_usb_stream *as; |
262 | 86 | struct snd_usb_substream *subs; | |
263 | urb->dev = ep->chip->dev; /* we need to set this at each time */ | 87 | struct snd_pcm *pcm; |
88 | int err; | ||
264 | 89 | ||
265 | switch (ep->type) { | 90 | list_for_each(p, &chip->pcm_list) { |
266 | case SND_USB_ENDPOINT_TYPE_DATA: | 91 | as = list_entry(p, struct snd_usb_stream, list); |
267 | offs = 0; | 92 | if (as->fmt_type != fp->fmt_type) |
268 | for (i = 0; i < urb_ctx->packets; i++) { | 93 | continue; |
269 | urb->iso_frame_desc[i].offset = offs; | 94 | subs = &as->substream[stream]; |
270 | urb->iso_frame_desc[i].length = ep->curpacksize; | 95 | if (!subs->endpoint) |
271 | offs += ep->curpacksize; | 96 | continue; |
97 | if (subs->endpoint == fp->endpoint) { | ||
98 | list_add_tail(&fp->list, &subs->fmt_list); | ||
99 | subs->num_formats++; | ||
100 | subs->formats |= fp->formats; | ||
101 | return 0; | ||
272 | } | 102 | } |
273 | |||
274 | urb->transfer_buffer_length = offs; | ||
275 | urb->number_of_packets = urb_ctx->packets; | ||
276 | break; | ||
277 | |||
278 | case SND_USB_ENDPOINT_TYPE_SYNC: | ||
279 | urb->iso_frame_desc[0].length = min(4u, ep->syncmaxsize); | ||
280 | urb->iso_frame_desc[0].offset = 0; | ||
281 | break; | ||
282 | } | 103 | } |
283 | } | 104 | /* look for an empty stream */ |
284 | 105 | list_for_each(p, &chip->pcm_list) { | |
285 | /* | 106 | as = list_entry(p, struct snd_usb_stream, list); |
286 | * Send output urbs that have been prepared previously. URBs are dequeued | 107 | if (as->fmt_type != fp->fmt_type) |
287 | * from ep->ready_playback_urbs and in case there there aren't any available | 108 | continue; |
288 | * or there are no packets that have been prepared, this function does | 109 | subs = &as->substream[stream]; |
289 | * nothing. | 110 | if (subs->endpoint) |
290 | * | 111 | continue; |
291 | * The reason why the functionality of sending and preparing URBs is separated | 112 | err = snd_pcm_new_stream(as->pcm, stream, 1); |
292 | * is that host controllers don't guarantee the order in which they return | ||
293 | * inbound and outbound packets to their submitters. | ||
294 | * | ||
295 | * This function is only used for implicit feedback endpoints. For endpoints | ||
296 | * driven by dedicated sync endpoints, URBs are immediately re-submitted | ||
297 | * from their completion handler. | ||
298 | */ | ||
299 | static void queue_pending_output_urbs(struct snd_usb_endpoint *ep) | ||
300 | { | ||
301 | while (test_bit(EP_FLAG_RUNNING, &ep->flags)) { | ||
302 | |||
303 | unsigned long flags; | ||
304 | struct snd_usb_packet_info *uninitialized_var(packet); | ||
305 | struct snd_urb_ctx *ctx = NULL; | ||
306 | struct urb *urb; | ||
307 | int err, i; | ||
308 | |||
309 | spin_lock_irqsave(&ep->lock, flags); | ||
310 | if (ep->next_packet_read_pos != ep->next_packet_write_pos) { | ||
311 | packet = ep->next_packet + ep->next_packet_read_pos; | ||
312 | ep->next_packet_read_pos++; | ||
313 | ep->next_packet_read_pos %= MAX_URBS; | ||
314 | |||
315 | /* take URB out of FIFO */ | ||
316 | if (!list_empty(&ep->ready_playback_urbs)) | ||
317 | ctx = list_first_entry(&ep->ready_playback_urbs, | ||
318 | struct snd_urb_ctx, ready_list); | ||
319 | } | ||
320 | spin_unlock_irqrestore(&ep->lock, flags); | ||
321 | |||
322 | if (ctx == NULL) | ||
323 | return; | ||
324 | |||
325 | list_del_init(&ctx->ready_list); | ||
326 | urb = ctx->urb; | ||
327 | |||
328 | /* copy over the length information */ | ||
329 | for (i = 0; i < packet->packets; i++) | ||
330 | ctx->packet_size[i] = packet->packet_size[i]; | ||
331 | |||
332 | /* call the data handler to fill in playback data */ | ||
333 | prepare_outbound_urb(ep, ctx); | ||
334 | |||
335 | err = usb_submit_urb(ctx->urb, GFP_ATOMIC); | ||
336 | if (err < 0) | 113 | if (err < 0) |
337 | snd_printk(KERN_ERR "Unable to submit urb #%d: %d (urb %p)\n", | 114 | return err; |
338 | ctx->index, err, ctx->urb); | 115 | snd_usb_init_substream(as, stream, fp); |
339 | else | 116 | return 0; |
340 | set_bit(ctx->index, &ep->active_mask); | ||
341 | } | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | * complete callback for urbs | ||
346 | */ | ||
347 | static void snd_complete_urb(struct urb *urb) | ||
348 | { | ||
349 | struct snd_urb_ctx *ctx = urb->context; | ||
350 | struct snd_usb_endpoint *ep = ctx->ep; | ||
351 | int err; | ||
352 | |||
353 | if (unlikely(urb->status == -ENOENT || /* unlinked */ | ||
354 | urb->status == -ENODEV || /* device removed */ | ||
355 | urb->status == -ECONNRESET || /* unlinked */ | ||
356 | urb->status == -ESHUTDOWN || /* device disabled */ | ||
357 | ep->chip->shutdown)) /* device disconnected */ | ||
358 | goto exit_clear; | ||
359 | |||
360 | if (usb_pipeout(ep->pipe)) { | ||
361 | retire_outbound_urb(ep, ctx); | ||
362 | /* can be stopped during retire callback */ | ||
363 | if (unlikely(!test_bit(EP_FLAG_RUNNING, &ep->flags))) | ||
364 | goto exit_clear; | ||
365 | |||
366 | if (snd_usb_endpoint_implict_feedback_sink(ep)) { | ||
367 | unsigned long flags; | ||
368 | |||
369 | spin_lock_irqsave(&ep->lock, flags); | ||
370 | list_add_tail(&ctx->ready_list, &ep->ready_playback_urbs); | ||
371 | spin_unlock_irqrestore(&ep->lock, flags); | ||
372 | queue_pending_output_urbs(ep); | ||
373 | |||
374 | goto exit_clear; | ||
375 | } | ||
376 | |||
377 | prepare_outbound_urb(ep, ctx); | ||
378 | } else { | ||
379 | retire_inbound_urb(ep, ctx); | ||
380 | /* can be stopped during retire callback */ | ||
381 | if (unlikely(!test_bit(EP_FLAG_RUNNING, &ep->flags))) | ||
382 | goto exit_clear; | ||
383 | |||
384 | prepare_inbound_urb(ep, ctx); | ||
385 | } | 117 | } |
386 | 118 | ||
387 | err = usb_submit_urb(urb, GFP_ATOMIC); | 119 | /* create a new pcm */ |
388 | if (err == 0) | 120 | as = kzalloc(sizeof(*as), GFP_KERNEL); |
389 | return; | 121 | if (!as) |
390 | 122 | return -ENOMEM; | |
391 | snd_printk(KERN_ERR "cannot submit urb (err = %d)\n", err); | 123 | as->pcm_index = chip->pcm_devs; |
392 | //snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); | 124 | as->chip = chip; |
393 | 125 | as->fmt_type = fp->fmt_type; | |
394 | exit_clear: | 126 | err = snd_pcm_new(chip->card, "USB Audio", chip->pcm_devs, |
395 | clear_bit(ctx->index, &ep->active_mask); | 127 | stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0, |
396 | } | 128 | stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1, |
397 | 129 | &pcm); | |
398 | /** | 130 | if (err < 0) { |
399 | * snd_usb_add_endpoint: Add an endpoint to an USB audio chip | 131 | kfree(as); |
400 | * | 132 | return err; |
401 | * @chip: The chip | ||
402 | * @alts: The USB host interface | ||
403 | * @ep_num: The number of the endpoint to use | ||
404 | * @direction: SNDRV_PCM_STREAM_PLAYBACK or SNDRV_PCM_STREAM_CAPTURE | ||
405 | * @type: SND_USB_ENDPOINT_TYPE_DATA or SND_USB_ENDPOINT_TYPE_SYNC | ||
406 | * | ||
407 | * If the requested endpoint has not been added to the given chip before, | ||
408 | * a new instance is created. Otherwise, a pointer to the previoulsy | ||
409 | * created instance is returned. In case of any error, NULL is returned. | ||
410 | * | ||
411 | * New endpoints will be added to chip->ep_list and must be freed by | ||
412 | * calling snd_usb_endpoint_free(). | ||
413 | */ | ||
414 | struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, | ||
415 | struct usb_host_interface *alts, | ||
416 | int ep_num, int direction, int type) | ||
417 | { | ||
418 | struct list_head *p; | ||
419 | struct snd_usb_endpoint *ep; | ||
420 | int is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK; | ||
421 | |||
422 | mutex_lock(&chip->mutex); | ||
423 | |||
424 | list_for_each(p, &chip->ep_list) { | ||
425 | ep = list_entry(p, struct snd_usb_endpoint, list); | ||
426 | if (ep->ep_num == ep_num && | ||
427 | ep->iface == alts->desc.bInterfaceNumber && | ||
428 | ep->alt_idx == alts->desc.bAlternateSetting) { | ||
429 | snd_printdd(KERN_DEBUG "Re-using EP %x in iface %d,%d @%p\n", | ||
430 | ep_num, ep->iface, ep->alt_idx, ep); | ||
431 | goto __exit_unlock; | ||
432 | } | ||
433 | } | 133 | } |
434 | 134 | as->pcm = pcm; | |
435 | snd_printdd(KERN_DEBUG "Creating new %s %s endpoint #%x\n", | 135 | pcm->private_data = as; |
436 | is_playback ? "playback" : "capture", | 136 | pcm->private_free = snd_usb_audio_pcm_free; |
437 | type == SND_USB_ENDPOINT_TYPE_DATA ? "data" : "sync", | 137 | pcm->info_flags = 0; |
438 | ep_num); | 138 | if (chip->pcm_devs > 0) |
439 | 139 | sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs); | |
440 | ep = kzalloc(sizeof(*ep), GFP_KERNEL); | ||
441 | if (!ep) | ||
442 | goto __exit_unlock; | ||
443 | |||
444 | ep->chip = chip; | ||
445 | spin_lock_init(&ep->lock); | ||
446 | ep->type = type; | ||
447 | ep->ep_num = ep_num; | ||
448 | ep->iface = alts->desc.bInterfaceNumber; | ||
449 | ep->alt_idx = alts->desc.bAlternateSetting; | ||
450 | INIT_LIST_HEAD(&ep->ready_playback_urbs); | ||
451 | ep_num &= USB_ENDPOINT_NUMBER_MASK; | ||
452 | |||
453 | if (is_playback) | ||
454 | ep->pipe = usb_sndisocpipe(chip->dev, ep_num); | ||
455 | else | 140 | else |
456 | ep->pipe = usb_rcvisocpipe(chip->dev, ep_num); | 141 | strcpy(pcm->name, "USB Audio"); |
457 | |||
458 | if (type == SND_USB_ENDPOINT_TYPE_SYNC) { | ||
459 | if (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && | ||
460 | get_endpoint(alts, 1)->bRefresh >= 1 && | ||
461 | get_endpoint(alts, 1)->bRefresh <= 9) | ||
462 | ep->syncinterval = get_endpoint(alts, 1)->bRefresh; | ||
463 | else if (snd_usb_get_speed(chip->dev) == USB_SPEED_FULL) | ||
464 | ep->syncinterval = 1; | ||
465 | else if (get_endpoint(alts, 1)->bInterval >= 1 && | ||
466 | get_endpoint(alts, 1)->bInterval <= 16) | ||
467 | ep->syncinterval = get_endpoint(alts, 1)->bInterval - 1; | ||
468 | else | ||
469 | ep->syncinterval = 3; | ||
470 | 142 | ||
471 | ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize); | 143 | snd_usb_init_substream(as, stream, fp); |
472 | } | ||
473 | |||
474 | list_add_tail(&ep->list, &chip->ep_list); | ||
475 | 144 | ||
476 | __exit_unlock: | 145 | list_add(&as->list, &chip->pcm_list); |
477 | mutex_unlock(&chip->mutex); | 146 | chip->pcm_devs++; |
478 | 147 | ||
479 | return ep; | 148 | snd_usb_proc_pcm_format_add(as); |
480 | } | ||
481 | |||
482 | /* | ||
483 | * wait until all urbs are processed. | ||
484 | */ | ||
485 | static int wait_clear_urbs(struct snd_usb_endpoint *ep) | ||
486 | { | ||
487 | unsigned long end_time = jiffies + msecs_to_jiffies(1000); | ||
488 | int alive; | ||
489 | |||
490 | do { | ||
491 | alive = bitmap_weight(&ep->active_mask, ep->nurbs); | ||
492 | if (!alive) | ||
493 | break; | ||
494 | |||
495 | schedule_timeout_uninterruptible(1); | ||
496 | } while (time_before(jiffies, end_time)); | ||
497 | |||
498 | if (alive) | ||
499 | snd_printk(KERN_ERR "timeout: still %d active urbs on EP #%x\n", | ||
500 | alive, ep->ep_num); | ||
501 | clear_bit(EP_FLAG_STOPPING, &ep->flags); | ||
502 | 149 | ||
503 | return 0; | 150 | return 0; |
504 | } | 151 | } |
505 | 152 | ||
506 | /* sync the pending stop operation; | 153 | static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip, |
507 | * this function itself doesn't trigger the stop operation | 154 | struct usb_host_interface *alts, |
508 | */ | 155 | int protocol, int iface_no) |
509 | void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep) | ||
510 | { | ||
511 | if (ep && test_bit(EP_FLAG_STOPPING, &ep->flags)) | ||
512 | wait_clear_urbs(ep); | ||
513 | } | ||
514 | |||
515 | /* | ||
516 | * unlink active urbs. | ||
517 | */ | ||
518 | static int deactivate_urbs(struct snd_usb_endpoint *ep, bool force) | ||
519 | { | ||
520 | unsigned int i; | ||
521 | |||
522 | if (!force && ep->chip->shutdown) /* to be sure... */ | ||
523 | return -EBADFD; | ||
524 | |||
525 | clear_bit(EP_FLAG_RUNNING, &ep->flags); | ||
526 | |||
527 | INIT_LIST_HEAD(&ep->ready_playback_urbs); | ||
528 | ep->next_packet_read_pos = 0; | ||
529 | ep->next_packet_write_pos = 0; | ||
530 | |||
531 | for (i = 0; i < ep->nurbs; i++) { | ||
532 | if (test_bit(i, &ep->active_mask)) { | ||
533 | if (!test_and_set_bit(i, &ep->unlink_mask)) { | ||
534 | struct urb *u = ep->urb[i].urb; | ||
535 | usb_unlink_urb(u); | ||
536 | } | ||
537 | } | ||
538 | } | ||
539 | |||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | /* | ||
544 | * release an endpoint's urbs | ||
545 | */ | ||
546 | static void release_urbs(struct snd_usb_endpoint *ep, int force) | ||
547 | { | ||
548 | int i; | ||
549 | |||
550 | /* route incoming urbs to nirvana */ | ||
551 | ep->retire_data_urb = NULL; | ||
552 | ep->prepare_data_urb = NULL; | ||
553 | |||
554 | /* stop urbs */ | ||
555 | deactivate_urbs(ep, force); | ||
556 | wait_clear_urbs(ep); | ||
557 | |||
558 | for (i = 0; i < ep->nurbs; i++) | ||
559 | release_urb_ctx(&ep->urb[i]); | ||
560 | |||
561 | if (ep->syncbuf) | ||
562 | usb_free_coherent(ep->chip->dev, SYNC_URBS * 4, | ||
563 | ep->syncbuf, ep->sync_dma); | ||
564 | |||
565 | ep->syncbuf = NULL; | ||
566 | ep->nurbs = 0; | ||
567 | } | ||
568 | |||
569 | /* | ||
570 | * configure a data endpoint | ||
571 | */ | ||
572 | static int data_ep_set_params(struct snd_usb_endpoint *ep, | ||
573 | snd_pcm_format_t pcm_format, | ||
574 | unsigned int channels, | ||
575 | unsigned int period_bytes, | ||
576 | struct audioformat *fmt, | ||
577 | struct snd_usb_endpoint *sync_ep) | ||
578 | { | 156 | { |
579 | unsigned int maxsize, i, urb_packs, total_packs, packs_per_ms; | 157 | /* parsed with a v1 header here. that's ok as we only look at the |
580 | int is_playback = usb_pipeout(ep->pipe); | 158 | * header first which is the same for both versions */ |
581 | int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels; | 159 | struct uac_iso_endpoint_descriptor *csep; |
582 | 160 | struct usb_interface_descriptor *altsd = get_iface_desc(alts); | |
583 | ep->datainterval = fmt->datainterval; | 161 | int attributes = 0; |
584 | ep->stride = frame_bits >> 3; | 162 | |
585 | ep->silence_value = pcm_format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0; | 163 | csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT); |
586 | 164 | ||
587 | /* calculate max. frequency */ | 165 | /* Creamware Noah has this descriptor after the 2nd endpoint */ |
588 | if (ep->maxpacksize) { | 166 | if (!csep && altsd->bNumEndpoints >= 2) |
589 | /* whatever fits into a max. size packet */ | 167 | csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); |
590 | maxsize = ep->maxpacksize; | 168 | |
591 | ep->freqmax = (maxsize / (frame_bits >> 3)) | 169 | if (!csep || csep->bLength < 7 || |
592 | << (16 - ep->datainterval); | 170 | csep->bDescriptorSubtype != UAC_EP_GENERAL) { |
593 | } else { | 171 | snd_printk(KERN_WARNING "%d:%u:%d : no or invalid" |
594 | /* no max. packet size: just take 25% higher than nominal */ | 172 | " class specific endpoint descriptor\n", |
595 | ep->freqmax = ep->freqn + (ep->freqn >> 2); | 173 | chip->dev->devnum, iface_no, |
596 | maxsize = ((ep->freqmax + 0xffff) * (frame_bits >> 3)) | 174 | altsd->bAlternateSetting); |
597 | >> (16 - ep->datainterval); | 175 | return 0; |
598 | } | ||
599 | |||
600 | if (ep->fill_max) | ||
601 | ep->curpacksize = ep->maxpacksize; | ||
602 | else | ||
603 | ep->curpacksize = maxsize; | ||
604 | |||
605 | if (snd_usb_get_speed(ep->chip->dev) != USB_SPEED_FULL) | ||
606 | packs_per_ms = 8 >> ep->datainterval; | ||
607 | else | ||
608 | packs_per_ms = 1; | ||
609 | |||
610 | if (is_playback && !snd_usb_endpoint_implict_feedback_sink(ep)) { | ||
611 | urb_packs = max(ep->chip->nrpacks, 1); | ||
612 | urb_packs = min(urb_packs, (unsigned int) MAX_PACKS); | ||
613 | } else { | ||
614 | urb_packs = 1; | ||
615 | } | 176 | } |
616 | 177 | ||
617 | urb_packs *= packs_per_ms; | 178 | if (protocol == UAC_VERSION_1) { |
618 | 179 | attributes = csep->bmAttributes; | |
619 | if (sync_ep && !snd_usb_endpoint_implict_feedback_sink(ep)) | ||
620 | urb_packs = min(urb_packs, 1U << sync_ep->syncinterval); | ||
621 | |||
622 | /* decide how many packets to be used */ | ||
623 | if (is_playback && !snd_usb_endpoint_implict_feedback_sink(ep)) { | ||
624 | unsigned int minsize, maxpacks; | ||
625 | /* determine how small a packet can be */ | ||
626 | minsize = (ep->freqn >> (16 - ep->datainterval)) | ||
627 | * (frame_bits >> 3); | ||
628 | /* with sync from device, assume it can be 12% lower */ | ||
629 | if (sync_ep) | ||
630 | minsize -= minsize >> 3; | ||
631 | minsize = max(minsize, 1u); | ||
632 | total_packs = (period_bytes + minsize - 1) / minsize; | ||
633 | /* we need at least two URBs for queueing */ | ||
634 | if (total_packs < 2) { | ||
635 | total_packs = 2; | ||
636 | } else { | ||
637 | /* and we don't want too long a queue either */ | ||
638 | maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2); | ||
639 | total_packs = min(total_packs, maxpacks); | ||
640 | } | ||
641 | } else { | 180 | } else { |
642 | while (urb_packs > 1 && urb_packs * maxsize >= period_bytes) | 181 | struct uac2_iso_endpoint_descriptor *csep2 = |
643 | urb_packs >>= 1; | 182 | (struct uac2_iso_endpoint_descriptor *) csep; |
644 | total_packs = MAX_URBS * urb_packs; | ||
645 | } | ||
646 | 183 | ||
647 | ep->nurbs = (total_packs + urb_packs - 1) / urb_packs; | 184 | attributes = csep->bmAttributes & UAC_EP_CS_ATTR_FILL_MAX; |
648 | if (ep->nurbs > MAX_URBS) { | ||
649 | /* too much... */ | ||
650 | ep->nurbs = MAX_URBS; | ||
651 | total_packs = MAX_URBS * urb_packs; | ||
652 | } else if (ep->nurbs < 2) { | ||
653 | /* too little - we need at least two packets | ||
654 | * to ensure contiguous playback/capture | ||
655 | */ | ||
656 | ep->nurbs = 2; | ||
657 | } | ||
658 | |||
659 | /* allocate and initialize data urbs */ | ||
660 | for (i = 0; i < ep->nurbs; i++) { | ||
661 | struct snd_urb_ctx *u = &ep->urb[i]; | ||
662 | u->index = i; | ||
663 | u->ep = ep; | ||
664 | u->packets = (i + 1) * total_packs / ep->nurbs | ||
665 | - i * total_packs / ep->nurbs; | ||
666 | u->buffer_size = maxsize * u->packets; | ||
667 | 185 | ||
668 | if (fmt->fmt_type == UAC_FORMAT_TYPE_II) | 186 | /* emulate the endpoint attributes of a v1 device */ |
669 | u->packets++; /* for transfer delimiter */ | 187 | if (csep2->bmControls & UAC2_CONTROL_PITCH) |
670 | u->urb = usb_alloc_urb(u->packets, GFP_KERNEL); | 188 | attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL; |
671 | if (!u->urb) | ||
672 | goto out_of_memory; | ||
673 | |||
674 | u->urb->transfer_buffer = | ||
675 | usb_alloc_coherent(ep->chip->dev, u->buffer_size, | ||
676 | GFP_KERNEL, &u->urb->transfer_dma); | ||
677 | if (!u->urb->transfer_buffer) | ||
678 | goto out_of_memory; | ||
679 | u->urb->pipe = ep->pipe; | ||
680 | u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; | ||
681 | u->urb->interval = 1 << ep->datainterval; | ||
682 | u->urb->context = u; | ||
683 | u->urb->complete = snd_complete_urb; | ||
684 | INIT_LIST_HEAD(&u->ready_list); | ||
685 | } | 189 | } |
686 | 190 | ||
687 | return 0; | 191 | return attributes; |
688 | |||
689 | out_of_memory: | ||
690 | release_urbs(ep, 0); | ||
691 | return -ENOMEM; | ||
692 | } | 192 | } |
693 | 193 | ||
694 | /* | 194 | static struct uac2_input_terminal_descriptor * |
695 | * configure a sync endpoint | 195 | snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface, |
696 | */ | 196 | int terminal_id) |
697 | static int sync_ep_set_params(struct snd_usb_endpoint *ep, | ||
698 | struct audioformat *fmt) | ||
699 | { | 197 | { |
700 | int i; | 198 | struct uac2_input_terminal_descriptor *term = NULL; |
701 | |||
702 | ep->syncbuf = usb_alloc_coherent(ep->chip->dev, SYNC_URBS * 4, | ||
703 | GFP_KERNEL, &ep->sync_dma); | ||
704 | if (!ep->syncbuf) | ||
705 | return -ENOMEM; | ||
706 | 199 | ||
707 | for (i = 0; i < SYNC_URBS; i++) { | 200 | while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, |
708 | struct snd_urb_ctx *u = &ep->urb[i]; | 201 | ctrl_iface->extralen, |
709 | u->index = i; | 202 | term, UAC_INPUT_TERMINAL))) { |
710 | u->ep = ep; | 203 | if (term->bTerminalID == terminal_id) |
711 | u->packets = 1; | 204 | return term; |
712 | u->urb = usb_alloc_urb(1, GFP_KERNEL); | ||
713 | if (!u->urb) | ||
714 | goto out_of_memory; | ||
715 | u->urb->transfer_buffer = ep->syncbuf + i * 4; | ||
716 | u->urb->transfer_dma = ep->sync_dma + i * 4; | ||
717 | u->urb->transfer_buffer_length = 4; | ||
718 | u->urb->pipe = ep->pipe; | ||
719 | u->urb->transfer_flags = URB_ISO_ASAP | | ||
720 | URB_NO_TRANSFER_DMA_MAP; | ||
721 | u->urb->number_of_packets = 1; | ||
722 | u->urb->interval = 1 << ep->syncinterval; | ||
723 | u->urb->context = u; | ||
724 | u->urb->complete = snd_complete_urb; | ||
725 | } | 205 | } |
726 | 206 | ||
727 | ep->nurbs = SYNC_URBS; | 207 | return NULL; |
728 | |||
729 | return 0; | ||
730 | |||
731 | out_of_memory: | ||
732 | release_urbs(ep, 0); | ||
733 | return -ENOMEM; | ||
734 | } | 208 | } |
735 | 209 | ||
736 | /** | 210 | static struct uac2_output_terminal_descriptor * |
737 | * snd_usb_endpoint_set_params: configure an snd_usb_endpoint | 211 | snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface, |
738 | * | 212 | int terminal_id) |
739 | * @ep: the snd_usb_endpoint to configure | ||
740 | * @pcm_format: the audio fomat. | ||
741 | * @channels: the number of audio channels. | ||
742 | * @period_bytes: the number of bytes in one alsa period. | ||
743 | * @rate: the frame rate. | ||
744 | * @fmt: the USB audio format information | ||
745 | * @sync_ep: the sync endpoint to use, if any | ||
746 | * | ||
747 | * Determine the number of URBs to be used on this endpoint. | ||
748 | * An endpoint must be configured before it can be started. | ||
749 | * An endpoint that is already running can not be reconfigured. | ||
750 | */ | ||
751 | int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, | ||
752 | snd_pcm_format_t pcm_format, | ||
753 | unsigned int channels, | ||
754 | unsigned int period_bytes, | ||
755 | unsigned int rate, | ||
756 | struct audioformat *fmt, | ||
757 | struct snd_usb_endpoint *sync_ep) | ||
758 | { | 213 | { |
759 | int err; | 214 | struct uac2_output_terminal_descriptor *term = NULL; |
760 | 215 | ||
761 | if (ep->use_count != 0) { | 216 | while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, |
762 | snd_printk(KERN_WARNING "Unable to change format on ep #%x: already in use\n", | 217 | ctrl_iface->extralen, |
763 | ep->ep_num); | 218 | term, UAC_OUTPUT_TERMINAL))) { |
764 | return -EBUSY; | 219 | if (term->bTerminalID == terminal_id) |
220 | return term; | ||
765 | } | 221 | } |
766 | 222 | ||
767 | /* release old buffers, if any */ | 223 | return NULL; |
768 | release_urbs(ep, 0); | ||
769 | |||
770 | ep->datainterval = fmt->datainterval; | ||
771 | ep->maxpacksize = fmt->maxpacksize; | ||
772 | ep->fill_max = !!(fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX); | ||
773 | |||
774 | if (snd_usb_get_speed(ep->chip->dev) == USB_SPEED_FULL) | ||
775 | ep->freqn = get_usb_full_speed_rate(rate); | ||
776 | else | ||
777 | ep->freqn = get_usb_high_speed_rate(rate); | ||
778 | |||
779 | /* calculate the frequency in 16.16 format */ | ||
780 | ep->freqm = ep->freqn; | ||
781 | ep->freqshift = INT_MIN; | ||
782 | |||
783 | ep->phase = 0; | ||
784 | |||
785 | switch (ep->type) { | ||
786 | case SND_USB_ENDPOINT_TYPE_DATA: | ||
787 | err = data_ep_set_params(ep, pcm_format, channels, | ||
788 | period_bytes, fmt, sync_ep); | ||
789 | break; | ||
790 | case SND_USB_ENDPOINT_TYPE_SYNC: | ||
791 | err = sync_ep_set_params(ep, fmt); | ||
792 | break; | ||
793 | default: | ||
794 | err = -EINVAL; | ||
795 | } | ||
796 | |||
797 | snd_printdd(KERN_DEBUG "Setting params for ep #%x (type %d, %d urbs), ret=%d\n", | ||
798 | ep->ep_num, ep->type, ep->nurbs, err); | ||
799 | |||
800 | return err; | ||
801 | } | 224 | } |
802 | 225 | ||
803 | /** | 226 | int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) |
804 | * snd_usb_endpoint_start: start an snd_usb_endpoint | ||
805 | * | ||
806 | * @ep: the endpoint to start | ||
807 | * @can_sleep: flag indicating whether the operation is executed in | ||
808 | * non-atomic context | ||
809 | * | ||
810 | * A call to this function will increment the use count of the endpoint. | ||
811 | * In case it is not already running, the URBs for this endpoint will be | ||
812 | * submitted. Otherwise, this function does nothing. | ||
813 | * | ||
814 | * Must be balanced to calls of snd_usb_endpoint_stop(). | ||
815 | * | ||
816 | * Returns an error if the URB submission failed, 0 in all other cases. | ||
817 | */ | ||
818 | int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep) | ||
819 | { | 227 | { |
820 | int err; | 228 | struct usb_device *dev; |
821 | unsigned int i; | 229 | struct usb_interface *iface; |
230 | struct usb_host_interface *alts; | ||
231 | struct usb_interface_descriptor *altsd; | ||
232 | int i, altno, err, stream; | ||
233 | int format = 0, num_channels = 0; | ||
234 | struct audioformat *fp = NULL; | ||
235 | int num, protocol, clock = 0; | ||
236 | struct uac_format_type_i_continuous_descriptor *fmt; | ||
822 | 237 | ||
823 | if (ep->chip->shutdown) | 238 | dev = chip->dev; |
824 | return -EBADFD; | ||
825 | 239 | ||
826 | /* already running? */ | 240 | /* parse the interface's altsettings */ |
827 | if (++ep->use_count != 1) | 241 | iface = usb_ifnum_to_if(dev, iface_no); |
828 | return 0; | ||
829 | 242 | ||
830 | /* just to be sure */ | 243 | num = iface->num_altsetting; |
831 | deactivate_urbs(ep, false); | ||
832 | if (can_sleep) | ||
833 | wait_clear_urbs(ep); | ||
834 | |||
835 | ep->active_mask = 0; | ||
836 | ep->unlink_mask = 0; | ||
837 | ep->phase = 0; | ||
838 | |||
839 | snd_usb_endpoint_start_quirk(ep); | ||
840 | 244 | ||
841 | /* | 245 | /* |
842 | * If this endpoint has a data endpoint as implicit feedback source, | 246 | * Dallas DS4201 workaround: It presents 5 altsettings, but the last |
843 | * don't start the urbs here. Instead, mark them all as available, | 247 | * one misses syncpipe, and does not produce any sound. |
844 | * wait for the record urbs to return and queue the playback urbs | ||
845 | * from that context. | ||
846 | */ | 248 | */ |
249 | if (chip->usb_id == USB_ID(0x04fa, 0x4201)) | ||
250 | num = 4; | ||
251 | |||
252 | for (i = 0; i < num; i++) { | ||
253 | alts = &iface->altsetting[i]; | ||
254 | altsd = get_iface_desc(alts); | ||
255 | protocol = altsd->bInterfaceProtocol; | ||
256 | /* skip invalid one */ | ||
257 | if ((altsd->bInterfaceClass != USB_CLASS_AUDIO && | ||
258 | altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || | ||
259 | (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING && | ||
260 | altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) || | ||
261 | altsd->bNumEndpoints < 1 || | ||
262 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0) | ||
263 | continue; | ||
264 | /* must be isochronous */ | ||
265 | if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != | ||
266 | USB_ENDPOINT_XFER_ISOC) | ||
267 | continue; | ||
268 | /* check direction */ | ||
269 | stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ? | ||
270 | SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; | ||
271 | altno = altsd->bAlternateSetting; | ||
272 | |||
273 | if (snd_usb_apply_interface_quirk(chip, iface_no, altno)) | ||
274 | continue; | ||
275 | |||
276 | /* get audio formats */ | ||
277 | switch (protocol) { | ||
278 | default: | ||
279 | snd_printdd(KERN_WARNING "%d:%u:%d: unknown interface protocol %#02x, assuming v1\n", | ||
280 | dev->devnum, iface_no, altno, protocol); | ||
281 | protocol = UAC_VERSION_1; | ||
282 | /* fall through */ | ||
283 | |||
284 | case UAC_VERSION_1: { | ||
285 | struct uac1_as_header_descriptor *as = | ||
286 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); | ||
287 | |||
288 | if (!as) { | ||
289 | snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n", | ||
290 | dev->devnum, iface_no, altno); | ||
291 | continue; | ||
292 | } | ||
847 | 293 | ||
848 | set_bit(EP_FLAG_RUNNING, &ep->flags); | 294 | if (as->bLength < sizeof(*as)) { |
849 | 295 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n", | |
850 | if (snd_usb_endpoint_implict_feedback_sink(ep)) { | 296 | dev->devnum, iface_no, altno); |
851 | for (i = 0; i < ep->nurbs; i++) { | 297 | continue; |
852 | struct snd_urb_ctx *ctx = ep->urb + i; | 298 | } |
853 | list_add_tail(&ctx->ready_list, &ep->ready_playback_urbs); | ||
854 | } | ||
855 | |||
856 | return 0; | ||
857 | } | ||
858 | |||
859 | for (i = 0; i < ep->nurbs; i++) { | ||
860 | struct urb *urb = ep->urb[i].urb; | ||
861 | |||
862 | if (snd_BUG_ON(!urb)) | ||
863 | goto __error; | ||
864 | |||
865 | if (usb_pipeout(ep->pipe)) { | ||
866 | prepare_outbound_urb(ep, urb->context); | ||
867 | } else { | ||
868 | prepare_inbound_urb(ep, urb->context); | ||
869 | } | ||
870 | 299 | ||
871 | err = usb_submit_urb(urb, GFP_ATOMIC); | 300 | format = le16_to_cpu(as->wFormatTag); /* remember the format value */ |
872 | if (err < 0) { | 301 | break; |
873 | snd_printk(KERN_ERR "cannot submit urb %d, error %d: %s\n", | ||
874 | i, err, usb_error_string(err)); | ||
875 | goto __error; | ||
876 | } | 302 | } |
877 | set_bit(i, &ep->active_mask); | ||
878 | } | ||
879 | |||
880 | return 0; | ||
881 | 303 | ||
882 | __error: | 304 | case UAC_VERSION_2: { |
883 | clear_bit(EP_FLAG_RUNNING, &ep->flags); | 305 | struct uac2_input_terminal_descriptor *input_term; |
884 | ep->use_count--; | 306 | struct uac2_output_terminal_descriptor *output_term; |
885 | deactivate_urbs(ep, false); | 307 | struct uac2_as_header_descriptor *as = |
886 | return -EPIPE; | 308 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); |
887 | } | ||
888 | |||
889 | /** | ||
890 | * snd_usb_endpoint_stop: stop an snd_usb_endpoint | ||
891 | * | ||
892 | * @ep: the endpoint to stop (may be NULL) | ||
893 | * | ||
894 | * A call to this function will decrement the use count of the endpoint. | ||
895 | * In case the last user has requested the endpoint stop, the URBs will | ||
896 | * actually be deactivated. | ||
897 | * | ||
898 | * Must be balanced to calls of snd_usb_endpoint_start(). | ||
899 | * | ||
900 | * The caller needs to synchronize the pending stop operation via | ||
901 | * snd_usb_endpoint_sync_pending_stop(). | ||
902 | */ | ||
903 | void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep) | ||
904 | { | ||
905 | if (!ep) | ||
906 | return; | ||
907 | |||
908 | if (snd_BUG_ON(ep->use_count == 0)) | ||
909 | return; | ||
910 | |||
911 | if (--ep->use_count == 0) { | ||
912 | deactivate_urbs(ep, false); | ||
913 | ep->data_subs = NULL; | ||
914 | ep->sync_slave = NULL; | ||
915 | ep->retire_data_urb = NULL; | ||
916 | ep->prepare_data_urb = NULL; | ||
917 | set_bit(EP_FLAG_STOPPING, &ep->flags); | ||
918 | } | ||
919 | } | ||
920 | |||
921 | /** | ||
922 | * snd_usb_endpoint_deactivate: deactivate an snd_usb_endpoint | ||
923 | * | ||
924 | * @ep: the endpoint to deactivate | ||
925 | * | ||
926 | * If the endpoint is not currently in use, this functions will select the | ||
927 | * alternate interface setting 0 for the interface of this endpoint. | ||
928 | * | ||
929 | * In case of any active users, this functions does nothing. | ||
930 | * | ||
931 | * Returns an error if usb_set_interface() failed, 0 in all other | ||
932 | * cases. | ||
933 | */ | ||
934 | int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep) | ||
935 | { | ||
936 | if (!ep) | ||
937 | return -EINVAL; | ||
938 | 309 | ||
939 | deactivate_urbs(ep, true); | 310 | if (!as) { |
940 | wait_clear_urbs(ep); | 311 | snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n", |
941 | 312 | dev->devnum, iface_no, altno); | |
942 | if (ep->use_count != 0) | 313 | continue; |
943 | return 0; | 314 | } |
944 | |||
945 | clear_bit(EP_FLAG_ACTIVATED, &ep->flags); | ||
946 | |||
947 | return 0; | ||
948 | } | ||
949 | |||
950 | /** | ||
951 | * snd_usb_endpoint_free: Free the resources of an snd_usb_endpoint | ||
952 | * | ||
953 | * @ep: the list header of the endpoint to free | ||
954 | * | ||
955 | * This function does not care for the endpoint's use count but will tear | ||
956 | * down all the streaming URBs immediately and free all resources. | ||
957 | */ | ||
958 | void snd_usb_endpoint_free(struct list_head *head) | ||
959 | { | ||
960 | struct snd_usb_endpoint *ep; | ||
961 | |||
962 | ep = list_entry(head, struct snd_usb_endpoint, list); | ||
963 | release_urbs(ep, 1); | ||
964 | kfree(ep); | ||
965 | } | ||
966 | 315 | ||
967 | /** | 316 | if (as->bLength < sizeof(*as)) { |
968 | * snd_usb_handle_sync_urb: parse an USB sync packet | 317 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n", |
969 | * | 318 | dev->devnum, iface_no, altno); |
970 | * @ep: the endpoint to handle the packet | 319 | continue; |
971 | * @sender: the sending endpoint | 320 | } |
972 | * @urb: the received packet | ||
973 | * | ||
974 | * This function is called from the context of an endpoint that received | ||
975 | * the packet and is used to let another endpoint object handle the payload. | ||
976 | */ | ||
977 | void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, | ||
978 | struct snd_usb_endpoint *sender, | ||
979 | const struct urb *urb) | ||
980 | { | ||
981 | int shift; | ||
982 | unsigned int f; | ||
983 | unsigned long flags; | ||
984 | 321 | ||
985 | snd_BUG_ON(ep == sender); | 322 | num_channels = as->bNrChannels; |
323 | format = le32_to_cpu(as->bmFormats); | ||
986 | 324 | ||
987 | /* | 325 | /* lookup the terminal associated to this interface |
988 | * In case the endpoint is operating in implicit feedback mode, prepare | 326 | * to extract the clock */ |
989 | * a new outbound URB that has the same layout as the received packet | 327 | input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, |
990 | * and add it to the list of pending urbs. queue_pending_output_urbs() | 328 | as->bTerminalLink); |
991 | * will take care of them later. | 329 | if (input_term) { |
992 | */ | 330 | clock = input_term->bCSourceID; |
993 | if (snd_usb_endpoint_implict_feedback_sink(ep) && | 331 | break; |
994 | ep->use_count != 0) { | 332 | } |
995 | 333 | ||
996 | /* implicit feedback case */ | 334 | output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, |
997 | int i, bytes = 0; | 335 | as->bTerminalLink); |
998 | struct snd_urb_ctx *in_ctx; | 336 | if (output_term) { |
999 | struct snd_usb_packet_info *out_packet; | 337 | clock = output_term->bCSourceID; |
338 | break; | ||
339 | } | ||
1000 | 340 | ||
1001 | in_ctx = urb->context; | 341 | snd_printk(KERN_ERR "%d:%u:%d : bogus bTerminalLink %d\n", |
342 | dev->devnum, iface_no, altno, as->bTerminalLink); | ||
343 | continue; | ||
344 | } | ||
345 | } | ||
1002 | 346 | ||
1003 | /* Count overall packet size */ | 347 | /* get format type */ |
1004 | for (i = 0; i < in_ctx->packets; i++) | 348 | fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE); |
1005 | if (urb->iso_frame_desc[i].status == 0) | 349 | if (!fmt) { |
1006 | bytes += urb->iso_frame_desc[i].actual_length; | 350 | snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n", |
351 | dev->devnum, iface_no, altno); | ||
352 | continue; | ||
353 | } | ||
354 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || | ||
355 | ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) { | ||
356 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", | ||
357 | dev->devnum, iface_no, altno); | ||
358 | continue; | ||
359 | } | ||
1007 | 360 | ||
1008 | /* | 361 | /* |
1009 | * skip empty packets. At least M-Audio's Fast Track Ultra stops | 362 | * Blue Microphones workaround: The last altsetting is identical |
1010 | * streaming once it received a 0-byte OUT URB | 363 | * with the previous one, except for a larger packet size, but |
364 | * is actually a mislabeled two-channel setting; ignore it. | ||
1011 | */ | 365 | */ |
1012 | if (bytes == 0) | 366 | if (fmt->bNrChannels == 1 && |
1013 | return; | 367 | fmt->bSubframeSize == 2 && |
1014 | 368 | altno == 2 && num == 3 && | |
1015 | spin_lock_irqsave(&ep->lock, flags); | 369 | fp && fp->altsetting == 1 && fp->channels == 1 && |
1016 | out_packet = ep->next_packet + ep->next_packet_write_pos; | 370 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && |
371 | protocol == UAC_VERSION_1 && | ||
372 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == | ||
373 | fp->maxpacksize * 2) | ||
374 | continue; | ||
375 | |||
376 | fp = kzalloc(sizeof(*fp), GFP_KERNEL); | ||
377 | if (! fp) { | ||
378 | snd_printk(KERN_ERR "cannot malloc\n"); | ||
379 | return -ENOMEM; | ||
380 | } | ||
1017 | 381 | ||
382 | fp->iface = iface_no; | ||
383 | fp->altsetting = altno; | ||
384 | fp->altset_idx = i; | ||
385 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; | ||
386 | fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; | ||
387 | fp->datainterval = snd_usb_parse_datainterval(chip, alts); | ||
388 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); | ||
389 | /* num_channels is only set for v2 interfaces */ | ||
390 | fp->channels = num_channels; | ||
391 | if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) | ||
392 | fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) | ||
393 | * (fp->maxpacksize & 0x7ff); | ||
394 | fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no); | ||
395 | fp->clock = clock; | ||
396 | |||
397 | /* some quirks for attributes here */ | ||
398 | |||
399 | switch (chip->usb_id) { | ||
400 | case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */ | ||
401 | /* Optoplay sets the sample rate attribute although | ||
402 | * it seems not supporting it in fact. | ||
403 | */ | ||
404 | fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE; | ||
405 | break; | ||
406 | case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */ | ||
407 | case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ | ||
408 | /* doesn't set the sample rate attribute, but supports it */ | ||
409 | fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE; | ||
410 | break; | ||
411 | case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */ | ||
412 | case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */ | ||
413 | case USB_ID(0x047f, 0x0ca1): /* plantronics headset */ | ||
414 | case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is | ||
415 | an older model 77d:223) */ | ||
1018 | /* | 416 | /* |
1019 | * Iterate through the inbound packet and prepare the lengths | 417 | * plantronics headset and Griffin iMic have set adaptive-in |
1020 | * for the output packet. The OUT packet we are about to send | 418 | * although it's really not... |
1021 | * will have the same amount of payload bytes per stride as the | ||
1022 | * IN packet we just received. Since the actual size is scaled | ||
1023 | * by the stride, use the sender stride to calculate the length | ||
1024 | * in case the number of channels differ between the implicitly | ||
1025 | * fed-back endpoint and the synchronizing endpoint. | ||
1026 | */ | 419 | */ |
1027 | 420 | fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE; | |
1028 | out_packet->packets = in_ctx->packets; | 421 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) |
1029 | for (i = 0; i < in_ctx->packets; i++) { | 422 | fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE; |
1030 | if (urb->iso_frame_desc[i].status == 0) | ||
1031 | out_packet->packet_size[i] = | ||
1032 | urb->iso_frame_desc[i].actual_length / sender->stride; | ||
1033 | else | 423 | else |
1034 | out_packet->packet_size[i] = 0; | 424 | fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC; |
425 | break; | ||
1035 | } | 426 | } |
1036 | 427 | ||
1037 | ep->next_packet_write_pos++; | 428 | /* ok, let's parse further... */ |
1038 | ep->next_packet_write_pos %= MAX_URBS; | 429 | if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) { |
1039 | spin_unlock_irqrestore(&ep->lock, flags); | 430 | kfree(fp->rate_table); |
1040 | queue_pending_output_urbs(ep); | 431 | kfree(fp); |
1041 | 432 | fp = NULL; | |
1042 | return; | 433 | continue; |
1043 | } | ||
1044 | |||
1045 | /* | ||
1046 | * process after playback sync complete | ||
1047 | * | ||
1048 | * Full speed devices report feedback values in 10.14 format as samples | ||
1049 | * per frame, high speed devices in 16.16 format as samples per | ||
1050 | * microframe. | ||
1051 | * | ||
1052 | * Because the Audio Class 1 spec was written before USB 2.0, many high | ||
1053 | * speed devices use a wrong interpretation, some others use an | ||
1054 | * entirely different format. | ||
1055 | * | ||
1056 | * Therefore, we cannot predict what format any particular device uses | ||
1057 | * and must detect it automatically. | ||
1058 | */ | ||
1059 | |||
1060 | if (urb->iso_frame_desc[0].status != 0 || | ||
1061 | urb->iso_frame_desc[0].actual_length < 3) | ||
1062 | return; | ||
1063 | |||
1064 | f = le32_to_cpup(urb->transfer_buffer); | ||
1065 | if (urb->iso_frame_desc[0].actual_length == 3) | ||
1066 | f &= 0x00ffffff; | ||
1067 | else | ||
1068 | f &= 0x0fffffff; | ||
1069 | |||
1070 | if (f == 0) | ||
1071 | return; | ||
1072 | |||
1073 | if (unlikely(ep->freqshift == INT_MIN)) { | ||
1074 | /* | ||
1075 | * The first time we see a feedback value, determine its format | ||
1076 | * by shifting it left or right until it matches the nominal | ||
1077 | * frequency value. This assumes that the feedback does not | ||
1078 | * differ from the nominal value more than +50% or -25%. | ||
1079 | */ | ||
1080 | shift = 0; | ||
1081 | while (f < ep->freqn - ep->freqn / 4) { | ||
1082 | f <<= 1; | ||
1083 | shift++; | ||
1084 | } | ||
1085 | while (f > ep->freqn + ep->freqn / 2) { | ||
1086 | f >>= 1; | ||
1087 | shift--; | ||
1088 | } | 434 | } |
1089 | ep->freqshift = shift; | ||
1090 | } else if (ep->freqshift >= 0) | ||
1091 | f <<= ep->freqshift; | ||
1092 | else | ||
1093 | f >>= -ep->freqshift; | ||
1094 | 435 | ||
1095 | if (likely(f >= ep->freqn - ep->freqn / 8 && f <= ep->freqmax)) { | 436 | snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint); |
1096 | /* | 437 | err = snd_usb_add_audio_endpoint(chip, stream, fp); |
1097 | * If the frequency looks valid, set it. | 438 | if (err < 0) { |
1098 | * This value is referred to in prepare_playback_urb(). | 439 | kfree(fp->rate_table); |
1099 | */ | 440 | kfree(fp); |
1100 | spin_lock_irqsave(&ep->lock, flags); | 441 | return err; |
1101 | ep->freqm = f; | 442 | } |
1102 | spin_unlock_irqrestore(&ep->lock, flags); | 443 | /* try to set the interface... */ |
1103 | } else { | 444 | usb_set_interface(chip->dev, iface_no, altno); |
1104 | /* | 445 | snd_usb_init_pitch(chip, iface_no, alts, fp); |
1105 | * Out of range; maybe the shift value is wrong. | 446 | snd_usb_init_sample_rate(chip, iface_no, alts, fp, fp->rate_max); |
1106 | * Reset it so that we autodetect again the next time. | ||
1107 | */ | ||
1108 | ep->freqshift = INT_MIN; | ||
1109 | } | 447 | } |
448 | return 0; | ||
1110 | } | 449 | } |
1111 | 450 | ||
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h index 447902dd8a4..64dd0db023b 100644 --- a/sound/usb/endpoint.h +++ b/sound/usb/endpoint.h | |||
@@ -1,33 +1,11 @@ | |||
1 | #ifndef __USBAUDIO_ENDPOINT_H | 1 | #ifndef __USBAUDIO_ENDPOINT_H |
2 | #define __USBAUDIO_ENDPOINT_H | 2 | #define __USBAUDIO_ENDPOINT_H |
3 | 3 | ||
4 | #define SND_USB_ENDPOINT_TYPE_DATA 0 | 4 | int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, |
5 | #define SND_USB_ENDPOINT_TYPE_SYNC 1 | 5 | int iface_no); |
6 | 6 | ||
7 | struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, | 7 | int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip, |
8 | struct usb_host_interface *alts, | 8 | int stream, |
9 | int ep_num, int direction, int type); | 9 | struct audioformat *fp); |
10 | |||
11 | int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep, | ||
12 | snd_pcm_format_t pcm_format, | ||
13 | unsigned int channels, | ||
14 | unsigned int period_bytes, | ||
15 | unsigned int rate, | ||
16 | struct audioformat *fmt, | ||
17 | struct snd_usb_endpoint *sync_ep); | ||
18 | |||
19 | int snd_usb_endpoint_start(struct snd_usb_endpoint *ep, bool can_sleep); | ||
20 | void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep); | ||
21 | void snd_usb_endpoint_sync_pending_stop(struct snd_usb_endpoint *ep); | ||
22 | int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep); | ||
23 | int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep); | ||
24 | void snd_usb_endpoint_free(struct list_head *head); | ||
25 | |||
26 | int snd_usb_endpoint_implict_feedback_sink(struct snd_usb_endpoint *ep); | ||
27 | int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep); | ||
28 | |||
29 | void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, | ||
30 | struct snd_usb_endpoint *sender, | ||
31 | const struct urb *urb); | ||
32 | 10 | ||
33 | #endif /* __USBAUDIO_ENDPOINT_H */ | 11 | #endif /* __USBAUDIO_ENDPOINT_H */ |
diff --git a/sound/usb/format.c b/sound/usb/format.c index e831ee4238b..8d042dce0d1 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c | |||
@@ -155,7 +155,7 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof | |||
155 | if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) { | 155 | if (fmt[0] < offset + 1 + 3 * (nr_rates ? nr_rates : 2)) { |
156 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", | 156 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", |
157 | chip->dev->devnum, fp->iface, fp->altsetting); | 157 | chip->dev->devnum, fp->iface, fp->altsetting); |
158 | return -EINVAL; | 158 | return -1; |
159 | } | 159 | } |
160 | 160 | ||
161 | if (nr_rates) { | 161 | if (nr_rates) { |
@@ -167,7 +167,7 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof | |||
167 | fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); | 167 | fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); |
168 | if (fp->rate_table == NULL) { | 168 | if (fp->rate_table == NULL) { |
169 | snd_printk(KERN_ERR "cannot malloc\n"); | 169 | snd_printk(KERN_ERR "cannot malloc\n"); |
170 | return -ENOMEM; | 170 | return -1; |
171 | } | 171 | } |
172 | 172 | ||
173 | fp->nr_rates = 0; | 173 | fp->nr_rates = 0; |
@@ -198,7 +198,7 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof | |||
198 | } | 198 | } |
199 | if (!fp->nr_rates) { | 199 | if (!fp->nr_rates) { |
200 | hwc_debug("All rates were zero. Skipping format!\n"); | 200 | hwc_debug("All rates were zero. Skipping format!\n"); |
201 | return -EINVAL; | 201 | return -1; |
202 | } | 202 | } |
203 | } else { | 203 | } else { |
204 | /* continuous rates */ | 204 | /* continuous rates */ |
@@ -226,7 +226,7 @@ static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets, | |||
226 | int min = combine_quad(&data[2 + 12 * i]); | 226 | int min = combine_quad(&data[2 + 12 * i]); |
227 | int max = combine_quad(&data[6 + 12 * i]); | 227 | int max = combine_quad(&data[6 + 12 * i]); |
228 | int res = combine_quad(&data[10 + 12 * i]); | 228 | int res = combine_quad(&data[10 + 12 * i]); |
229 | unsigned int rate; | 229 | int rate; |
230 | 230 | ||
231 | if ((max < 0) || (min < 0) || (res < 0) || (max < min)) | 231 | if ((max < 0) || (min < 0) || (res < 0) || (max < min)) |
232 | continue; | 232 | continue; |
@@ -253,10 +253,6 @@ static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets, | |||
253 | fp->rates |= snd_pcm_rate_to_rate_bit(rate); | 253 | fp->rates |= snd_pcm_rate_to_rate_bit(rate); |
254 | 254 | ||
255 | nr_rates++; | 255 | nr_rates++; |
256 | if (nr_rates >= MAX_NR_RATES) { | ||
257 | snd_printk(KERN_ERR "invalid uac2 rates\n"); | ||
258 | break; | ||
259 | } | ||
260 | 256 | ||
261 | /* avoid endless loop */ | 257 | /* avoid endless loop */ |
262 | if (res == 0) | 258 | if (res == 0) |
@@ -290,7 +286,7 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, | |||
290 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | 286 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
291 | UAC2_CS_CONTROL_SAM_FREQ << 8, | 287 | UAC2_CS_CONTROL_SAM_FREQ << 8, |
292 | snd_usb_ctrl_intf(chip) | (clock << 8), | 288 | snd_usb_ctrl_intf(chip) | (clock << 8), |
293 | tmp, sizeof(tmp)); | 289 | tmp, sizeof(tmp), 1000); |
294 | 290 | ||
295 | if (ret < 0) { | 291 | if (ret < 0) { |
296 | snd_printk(KERN_ERR "%s(): unable to retrieve number of sample rates (clock %d)\n", | 292 | snd_printk(KERN_ERR "%s(): unable to retrieve number of sample rates (clock %d)\n", |
@@ -311,7 +307,7 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, | |||
311 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | 307 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
312 | UAC2_CS_CONTROL_SAM_FREQ << 8, | 308 | UAC2_CS_CONTROL_SAM_FREQ << 8, |
313 | snd_usb_ctrl_intf(chip) | (clock << 8), | 309 | snd_usb_ctrl_intf(chip) | (clock << 8), |
314 | data, data_size); | 310 | data, data_size, 1000); |
315 | 311 | ||
316 | if (ret < 0) { | 312 | if (ret < 0) { |
317 | snd_printk(KERN_ERR "%s(): unable to retrieve sample rate range (clock %d)\n", | 313 | snd_printk(KERN_ERR "%s(): unable to retrieve sample rate range (clock %d)\n", |
@@ -383,7 +379,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, | |||
383 | fp->formats = parse_audio_format_i_type(chip, fp, format, | 379 | fp->formats = parse_audio_format_i_type(chip, fp, format, |
384 | fmt, protocol); | 380 | fmt, protocol); |
385 | if (!fp->formats) | 381 | if (!fp->formats) |
386 | return -EINVAL; | 382 | return -1; |
387 | } | 383 | } |
388 | 384 | ||
389 | /* gather possible sample rates */ | 385 | /* gather possible sample rates */ |
@@ -409,7 +405,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip, | |||
409 | if (fp->channels < 1) { | 405 | if (fp->channels < 1) { |
410 | snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n", | 406 | snd_printk(KERN_ERR "%d:%u:%d : invalid channels %d\n", |
411 | chip->dev->devnum, fp->iface, fp->altsetting, fp->channels); | 407 | chip->dev->devnum, fp->iface, fp->altsetting, fp->channels); |
412 | return -EINVAL; | 408 | return -1; |
413 | } | 409 | } |
414 | 410 | ||
415 | return ret; | 411 | return ret; |
diff --git a/sound/usb/helper.c b/sound/usb/helper.c index c1db28f874c..f280c1903c2 100644 --- a/sound/usb/helper.c +++ b/sound/usb/helper.c | |||
@@ -21,7 +21,6 @@ | |||
21 | 21 | ||
22 | #include "usbaudio.h" | 22 | #include "usbaudio.h" |
23 | #include "helper.h" | 23 | #include "helper.h" |
24 | #include "quirks.h" | ||
25 | 24 | ||
26 | /* | 25 | /* |
27 | * combine bytes and get an integer value | 26 | * combine bytes and get an integer value |
@@ -82,7 +81,7 @@ void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype | |||
82 | */ | 81 | */ |
83 | int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request, | 82 | int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request, |
84 | __u8 requesttype, __u16 value, __u16 index, void *data, | 83 | __u8 requesttype, __u16 value, __u16 index, void *data, |
85 | __u16 size) | 84 | __u16 size, int timeout) |
86 | { | 85 | { |
87 | int err; | 86 | int err; |
88 | void *buf = NULL; | 87 | void *buf = NULL; |
@@ -93,15 +92,11 @@ int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request, | |||
93 | return -ENOMEM; | 92 | return -ENOMEM; |
94 | } | 93 | } |
95 | err = usb_control_msg(dev, pipe, request, requesttype, | 94 | err = usb_control_msg(dev, pipe, request, requesttype, |
96 | value, index, buf, size, 1000); | 95 | value, index, buf, size, timeout); |
97 | if (size > 0) { | 96 | if (size > 0) { |
98 | memcpy(data, buf, size); | 97 | memcpy(data, buf, size); |
99 | kfree(buf); | 98 | kfree(buf); |
100 | } | 99 | } |
101 | |||
102 | snd_usb_ctl_msg_quirk(dev, pipe, request, requesttype, | ||
103 | value, index, data, size); | ||
104 | |||
105 | return err; | 100 | return err; |
106 | } | 101 | } |
107 | 102 | ||
diff --git a/sound/usb/helper.h b/sound/usb/helper.h index 805c300dd00..09bd943c43b 100644 --- a/sound/usb/helper.h +++ b/sound/usb/helper.h | |||
@@ -8,7 +8,7 @@ void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsub | |||
8 | 8 | ||
9 | int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, | 9 | int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, |
10 | __u8 request, __u8 requesttype, __u16 value, __u16 index, | 10 | __u8 request, __u8 requesttype, __u16 value, __u16 index, |
11 | void *data, __u16 size); | 11 | void *data, __u16 size, int timeout); |
12 | 12 | ||
13 | unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip, | 13 | unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip, |
14 | struct usb_host_interface *alts); | 14 | struct usb_host_interface *alts); |
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index 34b9bb7fe87..f9289102886 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c | |||
@@ -47,7 +47,6 @@ | |||
47 | #include <linux/usb.h> | 47 | #include <linux/usb.h> |
48 | #include <linux/wait.h> | 48 | #include <linux/wait.h> |
49 | #include <linux/usb/audio.h> | 49 | #include <linux/usb/audio.h> |
50 | #include <linux/module.h> | ||
51 | 50 | ||
52 | #include <sound/core.h> | 51 | #include <sound/core.h> |
53 | #include <sound/control.h> | 52 | #include <sound/control.h> |
@@ -116,7 +115,6 @@ struct snd_usb_midi { | |||
116 | struct list_head list; | 115 | struct list_head list; |
117 | struct timer_list error_timer; | 116 | struct timer_list error_timer; |
118 | spinlock_t disc_lock; | 117 | spinlock_t disc_lock; |
119 | struct rw_semaphore disc_rwsem; | ||
120 | struct mutex mutex; | 118 | struct mutex mutex; |
121 | u32 usb_id; | 119 | u32 usb_id; |
122 | int next_midi_device; | 120 | int next_midi_device; |
@@ -126,10 +124,8 @@ struct snd_usb_midi { | |||
126 | struct snd_usb_midi_in_endpoint *in; | 124 | struct snd_usb_midi_in_endpoint *in; |
127 | } endpoints[MIDI_MAX_ENDPOINTS]; | 125 | } endpoints[MIDI_MAX_ENDPOINTS]; |
128 | unsigned long input_triggered; | 126 | unsigned long input_triggered; |
129 | bool autopm_reference; | 127 | unsigned int opened; |
130 | unsigned int opened[2]; | ||
131 | unsigned char disconnected; | 128 | unsigned char disconnected; |
132 | unsigned char input_running; | ||
133 | 129 | ||
134 | struct snd_kcontrol *roland_load_ctl; | 130 | struct snd_kcontrol *roland_load_ctl; |
135 | }; | 131 | }; |
@@ -820,22 +816,6 @@ static struct usb_protocol_ops snd_usbmidi_raw_ops = { | |||
820 | .output = snd_usbmidi_raw_output, | 816 | .output = snd_usbmidi_raw_output, |
821 | }; | 817 | }; |
822 | 818 | ||
823 | /* | ||
824 | * FTDI protocol: raw MIDI bytes, but input packets have two modem status bytes. | ||
825 | */ | ||
826 | |||
827 | static void snd_usbmidi_ftdi_input(struct snd_usb_midi_in_endpoint* ep, | ||
828 | uint8_t* buffer, int buffer_length) | ||
829 | { | ||
830 | if (buffer_length > 2) | ||
831 | snd_usbmidi_input_data(ep, 0, buffer + 2, buffer_length - 2); | ||
832 | } | ||
833 | |||
834 | static struct usb_protocol_ops snd_usbmidi_ftdi_ops = { | ||
835 | .input = snd_usbmidi_ftdi_input, | ||
836 | .output = snd_usbmidi_raw_output, | ||
837 | }; | ||
838 | |||
839 | static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep, | 819 | static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep, |
840 | uint8_t *buffer, int buffer_length) | 820 | uint8_t *buffer, int buffer_length) |
841 | { | 821 | { |
@@ -1035,58 +1015,29 @@ static void update_roland_altsetting(struct snd_usb_midi* umidi) | |||
1035 | snd_usbmidi_input_start(&umidi->list); | 1015 | snd_usbmidi_input_start(&umidi->list); |
1036 | } | 1016 | } |
1037 | 1017 | ||
1038 | static int substream_open(struct snd_rawmidi_substream *substream, int dir, | 1018 | static void substream_open(struct snd_rawmidi_substream *substream, int open) |
1039 | int open) | ||
1040 | { | 1019 | { |
1041 | struct snd_usb_midi* umidi = substream->rmidi->private_data; | 1020 | struct snd_usb_midi* umidi = substream->rmidi->private_data; |
1042 | struct snd_kcontrol *ctl; | 1021 | struct snd_kcontrol *ctl; |
1043 | int err; | ||
1044 | |||
1045 | down_read(&umidi->disc_rwsem); | ||
1046 | if (umidi->disconnected) { | ||
1047 | up_read(&umidi->disc_rwsem); | ||
1048 | return open ? -ENODEV : 0; | ||
1049 | } | ||
1050 | 1022 | ||
1051 | mutex_lock(&umidi->mutex); | 1023 | mutex_lock(&umidi->mutex); |
1052 | if (open) { | 1024 | if (open) { |
1053 | if (!umidi->opened[0] && !umidi->opened[1]) { | 1025 | if (umidi->opened++ == 0 && umidi->roland_load_ctl) { |
1054 | err = usb_autopm_get_interface(umidi->iface); | 1026 | ctl = umidi->roland_load_ctl; |
1055 | umidi->autopm_reference = err >= 0; | 1027 | ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; |
1056 | if (err < 0 && err != -EACCES) { | 1028 | snd_ctl_notify(umidi->card, |
1057 | mutex_unlock(&umidi->mutex); | ||
1058 | up_read(&umidi->disc_rwsem); | ||
1059 | return -EIO; | ||
1060 | } | ||
1061 | if (umidi->roland_load_ctl) { | ||
1062 | ctl = umidi->roland_load_ctl; | ||
1063 | ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
1064 | snd_ctl_notify(umidi->card, | ||
1065 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); | 1029 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); |
1066 | update_roland_altsetting(umidi); | 1030 | update_roland_altsetting(umidi); |
1067 | } | ||
1068 | } | 1031 | } |
1069 | umidi->opened[dir]++; | ||
1070 | if (umidi->opened[1]) | ||
1071 | snd_usbmidi_input_start(&umidi->list); | ||
1072 | } else { | 1032 | } else { |
1073 | umidi->opened[dir]--; | 1033 | if (--umidi->opened == 0 && umidi->roland_load_ctl) { |
1074 | if (!umidi->opened[1]) | 1034 | ctl = umidi->roland_load_ctl; |
1075 | snd_usbmidi_input_stop(&umidi->list); | 1035 | ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; |
1076 | if (!umidi->opened[0] && !umidi->opened[1]) { | 1036 | snd_ctl_notify(umidi->card, |
1077 | if (umidi->roland_load_ctl) { | ||
1078 | ctl = umidi->roland_load_ctl; | ||
1079 | ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
1080 | snd_ctl_notify(umidi->card, | ||
1081 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); | 1037 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); |
1082 | } | ||
1083 | if (umidi->autopm_reference) | ||
1084 | usb_autopm_put_interface(umidi->iface); | ||
1085 | } | 1038 | } |
1086 | } | 1039 | } |
1087 | mutex_unlock(&umidi->mutex); | 1040 | mutex_unlock(&umidi->mutex); |
1088 | up_read(&umidi->disc_rwsem); | ||
1089 | return 0; | ||
1090 | } | 1041 | } |
1091 | 1042 | ||
1092 | static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) | 1043 | static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) |
@@ -1094,6 +1045,7 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) | |||
1094 | struct snd_usb_midi* umidi = substream->rmidi->private_data; | 1045 | struct snd_usb_midi* umidi = substream->rmidi->private_data; |
1095 | struct usbmidi_out_port* port = NULL; | 1046 | struct usbmidi_out_port* port = NULL; |
1096 | int i, j; | 1047 | int i, j; |
1048 | int err; | ||
1097 | 1049 | ||
1098 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) | 1050 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) |
1099 | if (umidi->endpoints[i].out) | 1051 | if (umidi->endpoints[i].out) |
@@ -1106,15 +1058,22 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) | |||
1106 | snd_BUG(); | 1058 | snd_BUG(); |
1107 | return -ENXIO; | 1059 | return -ENXIO; |
1108 | } | 1060 | } |
1109 | 1061 | err = usb_autopm_get_interface(umidi->iface); | |
1062 | if (err < 0) | ||
1063 | return -EIO; | ||
1110 | substream->runtime->private_data = port; | 1064 | substream->runtime->private_data = port; |
1111 | port->state = STATE_UNKNOWN; | 1065 | port->state = STATE_UNKNOWN; |
1112 | return substream_open(substream, 0, 1); | 1066 | substream_open(substream, 1); |
1067 | return 0; | ||
1113 | } | 1068 | } |
1114 | 1069 | ||
1115 | static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) | 1070 | static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) |
1116 | { | 1071 | { |
1117 | return substream_open(substream, 0, 0); | 1072 | struct snd_usb_midi* umidi = substream->rmidi->private_data; |
1073 | |||
1074 | substream_open(substream, 0); | ||
1075 | usb_autopm_put_interface(umidi->iface); | ||
1076 | return 0; | ||
1118 | } | 1077 | } |
1119 | 1078 | ||
1120 | static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream, int up) | 1079 | static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream, int up) |
@@ -1167,12 +1126,14 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream) | |||
1167 | 1126 | ||
1168 | static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream) | 1127 | static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream) |
1169 | { | 1128 | { |
1170 | return substream_open(substream, 1, 1); | 1129 | substream_open(substream, 1); |
1130 | return 0; | ||
1171 | } | 1131 | } |
1172 | 1132 | ||
1173 | static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream) | 1133 | static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream) |
1174 | { | 1134 | { |
1175 | return substream_open(substream, 1, 0); | 1135 | substream_open(substream, 0); |
1136 | return 0; | ||
1176 | } | 1137 | } |
1177 | 1138 | ||
1178 | static void snd_usbmidi_input_trigger(struct snd_rawmidi_substream *substream, int up) | 1139 | static void snd_usbmidi_input_trigger(struct snd_rawmidi_substream *substream, int up) |
@@ -1421,12 +1382,9 @@ void snd_usbmidi_disconnect(struct list_head* p) | |||
1421 | * a timer may submit an URB. To reliably break the cycle | 1382 | * a timer may submit an URB. To reliably break the cycle |
1422 | * a flag under lock must be used | 1383 | * a flag under lock must be used |
1423 | */ | 1384 | */ |
1424 | down_write(&umidi->disc_rwsem); | ||
1425 | spin_lock_irq(&umidi->disc_lock); | 1385 | spin_lock_irq(&umidi->disc_lock); |
1426 | umidi->disconnected = 1; | 1386 | umidi->disconnected = 1; |
1427 | spin_unlock_irq(&umidi->disc_lock); | 1387 | spin_unlock_irq(&umidi->disc_lock); |
1428 | up_write(&umidi->disc_rwsem); | ||
1429 | |||
1430 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { | 1388 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { |
1431 | struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i]; | 1389 | struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i]; |
1432 | if (ep->out) | 1390 | if (ep->out) |
@@ -2081,15 +2039,12 @@ void snd_usbmidi_input_stop(struct list_head* p) | |||
2081 | unsigned int i, j; | 2039 | unsigned int i, j; |
2082 | 2040 | ||
2083 | umidi = list_entry(p, struct snd_usb_midi, list); | 2041 | umidi = list_entry(p, struct snd_usb_midi, list); |
2084 | if (!umidi->input_running) | ||
2085 | return; | ||
2086 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { | 2042 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { |
2087 | struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i]; | 2043 | struct snd_usb_midi_endpoint* ep = &umidi->endpoints[i]; |
2088 | if (ep->in) | 2044 | if (ep->in) |
2089 | for (j = 0; j < INPUT_URBS; ++j) | 2045 | for (j = 0; j < INPUT_URBS; ++j) |
2090 | usb_kill_urb(ep->in->urbs[j]); | 2046 | usb_kill_urb(ep->in->urbs[j]); |
2091 | } | 2047 | } |
2092 | umidi->input_running = 0; | ||
2093 | } | 2048 | } |
2094 | 2049 | ||
2095 | static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep) | 2050 | static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep) |
@@ -2114,11 +2069,8 @@ void snd_usbmidi_input_start(struct list_head* p) | |||
2114 | int i; | 2069 | int i; |
2115 | 2070 | ||
2116 | umidi = list_entry(p, struct snd_usb_midi, list); | 2071 | umidi = list_entry(p, struct snd_usb_midi, list); |
2117 | if (umidi->input_running || !umidi->opened[1]) | ||
2118 | return; | ||
2119 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) | 2072 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) |
2120 | snd_usbmidi_input_start_ep(umidi->endpoints[i].in); | 2073 | snd_usbmidi_input_start_ep(umidi->endpoints[i].in); |
2121 | umidi->input_running = 1; | ||
2122 | } | 2074 | } |
2123 | 2075 | ||
2124 | /* | 2076 | /* |
@@ -2144,7 +2096,6 @@ int snd_usbmidi_create(struct snd_card *card, | |||
2144 | umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; | 2096 | umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; |
2145 | init_timer(&umidi->error_timer); | 2097 | init_timer(&umidi->error_timer); |
2146 | spin_lock_init(&umidi->disc_lock); | 2098 | spin_lock_init(&umidi->disc_lock); |
2147 | init_rwsem(&umidi->disc_rwsem); | ||
2148 | mutex_init(&umidi->mutex); | 2099 | mutex_init(&umidi->mutex); |
2149 | umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor), | 2100 | umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor), |
2150 | le16_to_cpu(umidi->dev->descriptor.idProduct)); | 2101 | le16_to_cpu(umidi->dev->descriptor.idProduct)); |
@@ -2212,17 +2163,6 @@ int snd_usbmidi_create(struct snd_card *card, | |||
2212 | /* endpoint 1 is input-only */ | 2163 | /* endpoint 1 is input-only */ |
2213 | endpoints[1].out_cables = 0; | 2164 | endpoints[1].out_cables = 0; |
2214 | break; | 2165 | break; |
2215 | case QUIRK_MIDI_FTDI: | ||
2216 | umidi->usb_protocol_ops = &snd_usbmidi_ftdi_ops; | ||
2217 | |||
2218 | /* set baud rate to 31250 (48 MHz / 16 / 96) */ | ||
2219 | err = usb_control_msg(umidi->dev, usb_sndctrlpipe(umidi->dev, 0), | ||
2220 | 3, 0x40, 0x60, 0, NULL, 0, 1000); | ||
2221 | if (err < 0) | ||
2222 | break; | ||
2223 | |||
2224 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | ||
2225 | break; | ||
2226 | default: | 2166 | default: |
2227 | snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); | 2167 | snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); |
2228 | err = -ENXIO; | 2168 | err = -ENXIO; |
@@ -2257,6 +2197,9 @@ int snd_usbmidi_create(struct snd_card *card, | |||
2257 | } | 2197 | } |
2258 | 2198 | ||
2259 | list_add_tail(&umidi->list, midi_list); | 2199 | list_add_tail(&umidi->list, midi_list); |
2200 | |||
2201 | for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) | ||
2202 | snd_usbmidi_input_start_ep(umidi->endpoints[i].in); | ||
2260 | return 0; | 2203 | return 0; |
2261 | } | 2204 | } |
2262 | 2205 | ||
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c index 8b81cb54026..c0609c21030 100644 --- a/sound/usb/misc/ua101.c +++ b/sound/usb/misc/ua101.c | |||
@@ -52,7 +52,7 @@ MODULE_SUPPORTED_DEVICE("{{Edirol,UA-101},{Edirol,UA-1000}}"); | |||
52 | 52 | ||
53 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | 53 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; |
54 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | 54 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; |
55 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | 55 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; |
56 | static unsigned int queue_length = 21; | 56 | static unsigned int queue_length = 21; |
57 | 57 | ||
58 | module_param_array(index, int, NULL, 0444); | 58 | module_param_array(index, int, NULL, 0444); |
@@ -1387,4 +1387,16 @@ static struct usb_driver ua101_driver = { | |||
1387 | #endif | 1387 | #endif |
1388 | }; | 1388 | }; |
1389 | 1389 | ||
1390 | module_usb_driver(ua101_driver); | 1390 | static int __init alsa_card_ua101_init(void) |
1391 | { | ||
1392 | return usb_register(&ua101_driver); | ||
1393 | } | ||
1394 | |||
1395 | static void __exit alsa_card_ua101_exit(void) | ||
1396 | { | ||
1397 | usb_deregister(&ua101_driver); | ||
1398 | mutex_destroy(&devices_mutex); | ||
1399 | } | ||
1400 | |||
1401 | module_init(alsa_card_ua101_init); | ||
1402 | module_exit(alsa_card_ua101_exit); | ||
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index ed4d89c8b52..0de7cbd99ea 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -287,32 +287,25 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v | |||
287 | unsigned char buf[2]; | 287 | unsigned char buf[2]; |
288 | int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; | 288 | int val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; |
289 | int timeout = 10; | 289 | int timeout = 10; |
290 | int idx = 0, err; | 290 | int err; |
291 | 291 | ||
292 | err = snd_usb_autoresume(cval->mixer->chip); | 292 | err = snd_usb_autoresume(cval->mixer->chip); |
293 | if (err < 0) | 293 | if (err < 0) |
294 | return -EIO; | 294 | return -EIO; |
295 | down_read(&chip->shutdown_rwsem); | ||
296 | while (timeout-- > 0) { | 295 | while (timeout-- > 0) { |
297 | if (chip->shutdown) | ||
298 | break; | ||
299 | idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); | ||
300 | if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, | 296 | if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, |
301 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | 297 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, |
302 | validx, idx, buf, val_len) >= val_len) { | 298 | validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), |
299 | buf, val_len, 100) >= val_len) { | ||
303 | *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); | 300 | *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); |
304 | err = 0; | 301 | snd_usb_autosuspend(cval->mixer->chip); |
305 | goto out; | 302 | return 0; |
306 | } | 303 | } |
307 | } | 304 | } |
308 | snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", | ||
309 | request, validx, idx, cval->val_type); | ||
310 | err = -EINVAL; | ||
311 | |||
312 | out: | ||
313 | up_read(&chip->shutdown_rwsem); | ||
314 | snd_usb_autosuspend(cval->mixer->chip); | 305 | snd_usb_autosuspend(cval->mixer->chip); |
315 | return err; | 306 | snd_printdd(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", |
307 | request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); | ||
308 | return -EINVAL; | ||
316 | } | 309 | } |
317 | 310 | ||
318 | static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) | 311 | static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) |
@@ -320,7 +313,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v | |||
320 | struct snd_usb_audio *chip = cval->mixer->chip; | 313 | struct snd_usb_audio *chip = cval->mixer->chip; |
321 | unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */ | 314 | unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */ |
322 | unsigned char *val; | 315 | unsigned char *val; |
323 | int idx = 0, ret, size; | 316 | int ret, size; |
324 | __u8 bRequest; | 317 | __u8 bRequest; |
325 | 318 | ||
326 | if (request == UAC_GET_CUR) { | 319 | if (request == UAC_GET_CUR) { |
@@ -337,22 +330,16 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v | |||
337 | if (ret) | 330 | if (ret) |
338 | goto error; | 331 | goto error; |
339 | 332 | ||
340 | down_read(&chip->shutdown_rwsem); | 333 | ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, |
341 | if (chip->shutdown) | ||
342 | ret = -ENODEV; | ||
343 | else { | ||
344 | idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); | ||
345 | ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, | ||
346 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | 334 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, |
347 | validx, idx, buf, size); | 335 | validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), |
348 | } | 336 | buf, size, 1000); |
349 | up_read(&chip->shutdown_rwsem); | ||
350 | snd_usb_autosuspend(chip); | 337 | snd_usb_autosuspend(chip); |
351 | 338 | ||
352 | if (ret < 0) { | 339 | if (ret < 0) { |
353 | error: | 340 | error: |
354 | snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", | 341 | snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", |
355 | request, validx, idx, cval->val_type); | 342 | request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type); |
356 | return ret; | 343 | return ret; |
357 | } | 344 | } |
358 | 345 | ||
@@ -382,8 +369,6 @@ error: | |||
382 | 369 | ||
383 | static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) | 370 | static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) |
384 | { | 371 | { |
385 | validx += cval->idx_off; | ||
386 | |||
387 | return (cval->mixer->protocol == UAC_VERSION_1) ? | 372 | return (cval->mixer->protocol == UAC_VERSION_1) ? |
388 | get_ctl_value_v1(cval, request, validx, value_ret) : | 373 | get_ctl_value_v1(cval, request, validx, value_ret) : |
389 | get_ctl_value_v2(cval, request, validx, value_ret); | 374 | get_ctl_value_v2(cval, request, validx, value_ret); |
@@ -432,9 +417,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, | |||
432 | { | 417 | { |
433 | struct snd_usb_audio *chip = cval->mixer->chip; | 418 | struct snd_usb_audio *chip = cval->mixer->chip; |
434 | unsigned char buf[2]; | 419 | unsigned char buf[2]; |
435 | int idx = 0, val_len, err, timeout = 10; | 420 | int val_len, err, timeout = 10; |
436 | |||
437 | validx += cval->idx_off; | ||
438 | 421 | ||
439 | if (cval->mixer->protocol == UAC_VERSION_1) { | 422 | if (cval->mixer->protocol == UAC_VERSION_1) { |
440 | val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; | 423 | val_len = cval->val_type >= USB_MIXER_S16 ? 2 : 1; |
@@ -457,27 +440,19 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, | |||
457 | err = snd_usb_autoresume(chip); | 440 | err = snd_usb_autoresume(chip); |
458 | if (err < 0) | 441 | if (err < 0) |
459 | return -EIO; | 442 | return -EIO; |
460 | down_read(&chip->shutdown_rwsem); | 443 | while (timeout-- > 0) |
461 | while (timeout-- > 0) { | ||
462 | if (chip->shutdown) | ||
463 | break; | ||
464 | idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); | ||
465 | if (snd_usb_ctl_msg(chip->dev, | 444 | if (snd_usb_ctl_msg(chip->dev, |
466 | usb_sndctrlpipe(chip->dev, 0), request, | 445 | usb_sndctrlpipe(chip->dev, 0), request, |
467 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, | 446 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, |
468 | validx, idx, buf, val_len) >= 0) { | 447 | validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), |
469 | err = 0; | 448 | buf, val_len, 100) >= 0) { |
470 | goto out; | 449 | snd_usb_autosuspend(chip); |
450 | return 0; | ||
471 | } | 451 | } |
472 | } | ||
473 | snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", | ||
474 | request, validx, idx, cval->val_type, buf[0], buf[1]); | ||
475 | err = -EINVAL; | ||
476 | |||
477 | out: | ||
478 | up_read(&chip->shutdown_rwsem); | ||
479 | snd_usb_autosuspend(chip); | 452 | snd_usb_autosuspend(chip); |
480 | return err; | 453 | snd_printdd(KERN_ERR "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", |
454 | request, validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), cval->val_type, buf[0], buf[1]); | ||
455 | return -EINVAL; | ||
481 | } | 456 | } |
482 | 457 | ||
483 | static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value) | 458 | static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value) |
@@ -511,7 +486,7 @@ static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, | |||
511 | /* | 486 | /* |
512 | * TLV callback for mixer volume controls | 487 | * TLV callback for mixer volume controls |
513 | */ | 488 | */ |
514 | int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, | 489 | static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, |
515 | unsigned int size, unsigned int __user *_tlv) | 490 | unsigned int size, unsigned int __user *_tlv) |
516 | { | 491 | { |
517 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | 492 | struct usb_mixer_elem_info *cval = kcontrol->private_data; |
@@ -723,19 +698,8 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ | |||
723 | return 0; | 698 | return 0; |
724 | } | 699 | } |
725 | case UAC1_PROCESSING_UNIT: | 700 | case UAC1_PROCESSING_UNIT: |
726 | case UAC1_EXTENSION_UNIT: | 701 | case UAC1_EXTENSION_UNIT: { |
727 | /* UAC2_PROCESSING_UNIT_V2 */ | ||
728 | /* UAC2_EFFECT_UNIT */ { | ||
729 | struct uac_processing_unit_descriptor *d = p1; | 702 | struct uac_processing_unit_descriptor *d = p1; |
730 | |||
731 | if (state->mixer->protocol == UAC_VERSION_2 && | ||
732 | hdr[2] == UAC2_EFFECT_UNIT) { | ||
733 | /* UAC2/UAC1 unit IDs overlap here in an | ||
734 | * uncompatible way. Ignore this unit for now. | ||
735 | */ | ||
736 | return 0; | ||
737 | } | ||
738 | |||
739 | if (d->bNrInPins) { | 703 | if (d->bNrInPins) { |
740 | id = d->baSourceID[0]; | 704 | id = d->baSourceID[0]; |
741 | break; /* continue to parse */ | 705 | break; /* continue to parse */ |
@@ -806,53 +770,6 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, | |||
806 | struct snd_kcontrol *kctl) | 770 | struct snd_kcontrol *kctl) |
807 | { | 771 | { |
808 | switch (cval->mixer->chip->usb_id) { | 772 | switch (cval->mixer->chip->usb_id) { |
809 | case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */ | ||
810 | if (strcmp(kctl->id.name, "Effect Duration") == 0) { | ||
811 | cval->min = 0x0000; | ||
812 | cval->max = 0xffff; | ||
813 | cval->res = 0x00e6; | ||
814 | break; | ||
815 | } | ||
816 | if (strcmp(kctl->id.name, "Effect Volume") == 0 || | ||
817 | strcmp(kctl->id.name, "Effect Feedback Volume") == 0) { | ||
818 | cval->min = 0x00; | ||
819 | cval->max = 0xff; | ||
820 | break; | ||
821 | } | ||
822 | if (strstr(kctl->id.name, "Effect Return") != NULL) { | ||
823 | cval->min = 0xb706; | ||
824 | cval->max = 0xff7b; | ||
825 | cval->res = 0x0073; | ||
826 | break; | ||
827 | } | ||
828 | if ((strstr(kctl->id.name, "Playback Volume") != NULL) || | ||
829 | (strstr(kctl->id.name, "Effect Send") != NULL)) { | ||
830 | cval->min = 0xb5fb; /* -73 dB = 0xb6ff */ | ||
831 | cval->max = 0xfcfe; | ||
832 | cval->res = 0x0073; | ||
833 | } | ||
834 | break; | ||
835 | |||
836 | case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */ | ||
837 | case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */ | ||
838 | if (strcmp(kctl->id.name, "Effect Duration") == 0) { | ||
839 | snd_printk(KERN_INFO | ||
840 | "usb-audio: set quirk for FTU Effect Duration\n"); | ||
841 | cval->min = 0x0000; | ||
842 | cval->max = 0x7f00; | ||
843 | cval->res = 0x0100; | ||
844 | break; | ||
845 | } | ||
846 | if (strcmp(kctl->id.name, "Effect Volume") == 0 || | ||
847 | strcmp(kctl->id.name, "Effect Feedback Volume") == 0) { | ||
848 | snd_printk(KERN_INFO | ||
849 | "usb-audio: set quirks for FTU Effect Feedback/Volume\n"); | ||
850 | cval->min = 0x00; | ||
851 | cval->max = 0x7f; | ||
852 | break; | ||
853 | } | ||
854 | break; | ||
855 | |||
856 | case USB_ID(0x0471, 0x0101): | 773 | case USB_ID(0x0471, 0x0101): |
857 | case USB_ID(0x0471, 0x0104): | 774 | case USB_ID(0x0471, 0x0104): |
858 | case USB_ID(0x0471, 0x0105): | 775 | case USB_ID(0x0471, 0x0105): |
@@ -882,7 +799,6 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, | |||
882 | 799 | ||
883 | case USB_ID(0x046d, 0x0808): | 800 | case USB_ID(0x046d, 0x0808): |
884 | case USB_ID(0x046d, 0x0809): | 801 | case USB_ID(0x046d, 0x0809): |
885 | case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ | ||
886 | case USB_ID(0x046d, 0x0991): | 802 | case USB_ID(0x046d, 0x0991): |
887 | /* Most audio usb devices lie about volume resolution. | 803 | /* Most audio usb devices lie about volume resolution. |
888 | * Most Logitech webcams have res = 384. | 804 | * Most Logitech webcams have res = 384. |
@@ -1022,7 +938,7 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
1022 | if (!cval->initialized) { | 938 | if (!cval->initialized) { |
1023 | get_min_max_with_quirks(cval, 0, kcontrol); | 939 | get_min_max_with_quirks(cval, 0, kcontrol); |
1024 | if (cval->initialized && cval->dBmin >= cval->dBmax) { | 940 | if (cval->initialized && cval->dBmin >= cval->dBmax) { |
1025 | kcontrol->vd[0].access &= | 941 | kcontrol->vd[0].access &= |
1026 | ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | | 942 | ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | |
1027 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK); | 943 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK); |
1028 | snd_ctl_notify(cval->mixer->chip->card, | 944 | snd_ctl_notify(cval->mixer->chip->card, |
@@ -1136,32 +1052,6 @@ static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str) | |||
1136 | return strlcat(kctl->id.name, str, sizeof(kctl->id.name)); | 1052 | return strlcat(kctl->id.name, str, sizeof(kctl->id.name)); |
1137 | } | 1053 | } |
1138 | 1054 | ||
1139 | /* A lot of headsets/headphones have a "Speaker" mixer. Make sure we | ||
1140 | rename it to "Headphone". We determine if something is a headphone | ||
1141 | similar to how udev determines form factor. */ | ||
1142 | static void check_no_speaker_on_headset(struct snd_kcontrol *kctl, | ||
1143 | struct snd_card *card) | ||
1144 | { | ||
1145 | const char *names_to_check[] = { | ||
1146 | "Headset", "headset", "Headphone", "headphone", NULL}; | ||
1147 | const char **s; | ||
1148 | bool found = 0; | ||
1149 | |||
1150 | if (strcmp("Speaker", kctl->id.name)) | ||
1151 | return; | ||
1152 | |||
1153 | for (s = names_to_check; *s; s++) | ||
1154 | if (strstr(card->shortname, *s)) { | ||
1155 | found = 1; | ||
1156 | break; | ||
1157 | } | ||
1158 | |||
1159 | if (!found) | ||
1160 | return; | ||
1161 | |||
1162 | strlcpy(kctl->id.name, "Headphone", sizeof(kctl->id.name)); | ||
1163 | } | ||
1164 | |||
1165 | static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | 1055 | static void build_feature_ctl(struct mixer_build *state, void *raw_desc, |
1166 | unsigned int ctl_mask, int control, | 1056 | unsigned int ctl_mask, int control, |
1167 | struct usb_audio_term *iterm, int unitid, | 1057 | struct usb_audio_term *iterm, int unitid, |
@@ -1230,6 +1120,9 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1230 | len = snd_usb_copy_string_desc(state, nameid, | 1120 | len = snd_usb_copy_string_desc(state, nameid, |
1231 | kctl->id.name, sizeof(kctl->id.name)); | 1121 | kctl->id.name, sizeof(kctl->id.name)); |
1232 | 1122 | ||
1123 | /* get min/max values */ | ||
1124 | get_min_max_with_quirks(cval, 0, kctl); | ||
1125 | |||
1233 | switch (control) { | 1126 | switch (control) { |
1234 | case UAC_FU_MUTE: | 1127 | case UAC_FU_MUTE: |
1235 | case UAC_FU_VOLUME: | 1128 | case UAC_FU_VOLUME: |
@@ -1248,10 +1141,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1248 | len = snprintf(kctl->id.name, sizeof(kctl->id.name), | 1141 | len = snprintf(kctl->id.name, sizeof(kctl->id.name), |
1249 | "Feature %d", unitid); | 1142 | "Feature %d", unitid); |
1250 | } | 1143 | } |
1251 | |||
1252 | if (!mapped_name) | ||
1253 | check_no_speaker_on_headset(kctl, state->mixer->chip->card); | ||
1254 | |||
1255 | /* determine the stream direction: | 1144 | /* determine the stream direction: |
1256 | * if the connected output is USB stream, then it's likely a | 1145 | * if the connected output is USB stream, then it's likely a |
1257 | * capture stream. otherwise it should be playback (hopefully :) | 1146 | * capture stream. otherwise it should be playback (hopefully :) |
@@ -1265,7 +1154,17 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1265 | } | 1154 | } |
1266 | append_ctl_name(kctl, control == UAC_FU_MUTE ? | 1155 | append_ctl_name(kctl, control == UAC_FU_MUTE ? |
1267 | " Switch" : " Volume"); | 1156 | " Switch" : " Volume"); |
1157 | if (control == UAC_FU_VOLUME) { | ||
1158 | check_mapped_dB(map, cval); | ||
1159 | if (cval->dBmin < cval->dBmax || !cval->initialized) { | ||
1160 | kctl->tlv.c = mixer_vol_tlv; | ||
1161 | kctl->vd[0].access |= | ||
1162 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | | ||
1163 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; | ||
1164 | } | ||
1165 | } | ||
1268 | break; | 1166 | break; |
1167 | |||
1269 | default: | 1168 | default: |
1270 | if (! len) | 1169 | if (! len) |
1271 | strlcpy(kctl->id.name, audio_feature_info[control-1].name, | 1170 | strlcpy(kctl->id.name, audio_feature_info[control-1].name, |
@@ -1273,19 +1172,6 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1273 | break; | 1172 | break; |
1274 | } | 1173 | } |
1275 | 1174 | ||
1276 | /* get min/max values */ | ||
1277 | get_min_max_with_quirks(cval, 0, kctl); | ||
1278 | |||
1279 | if (control == UAC_FU_VOLUME) { | ||
1280 | check_mapped_dB(map, cval); | ||
1281 | if (cval->dBmin < cval->dBmax || !cval->initialized) { | ||
1282 | kctl->tlv.c = snd_usb_mixer_vol_tlv; | ||
1283 | kctl->vd[0].access |= | ||
1284 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | | ||
1285 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; | ||
1286 | } | ||
1287 | } | ||
1288 | |||
1289 | range = (cval->max - cval->min) / cval->res; | 1175 | range = (cval->max - cval->min) / cval->res; |
1290 | /* Are there devices with volume range more than 255? I use a bit more | 1176 | /* Are there devices with volume range more than 255? I use a bit more |
1291 | * to be sure. 384 is a resolution magic number found on Logitech | 1177 | * to be sure. 384 is a resolution magic number found on Logitech |
@@ -1360,13 +1246,6 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void | |||
1360 | /* disable non-functional volume control */ | 1246 | /* disable non-functional volume control */ |
1361 | master_bits &= ~UAC_CONTROL_BIT(UAC_FU_VOLUME); | 1247 | master_bits &= ~UAC_CONTROL_BIT(UAC_FU_VOLUME); |
1362 | break; | 1248 | break; |
1363 | case USB_ID(0x1130, 0xf211): | ||
1364 | snd_printk(KERN_INFO | ||
1365 | "usbmixer: volume control quirk for Tenx TP6911 Audio Headset\n"); | ||
1366 | /* disable non-functional volume control */ | ||
1367 | channels = 0; | ||
1368 | break; | ||
1369 | |||
1370 | } | 1249 | } |
1371 | if (channels > 0) | 1250 | if (channels > 0) |
1372 | first_ch_bits = snd_usb_combine_bytes(bmaControls + csize, csize); | 1251 | first_ch_bits = snd_usb_combine_bytes(bmaControls + csize, csize); |
@@ -1389,7 +1268,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void | |||
1389 | build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0); | 1268 | build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0); |
1390 | } | 1269 | } |
1391 | } else { /* UAC_VERSION_2 */ | 1270 | } else { /* UAC_VERSION_2 */ |
1392 | for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) { | 1271 | for (i = 0; i < 30/2; i++) { |
1393 | unsigned int ch_bits = 0; | 1272 | unsigned int ch_bits = 0; |
1394 | unsigned int ch_read_only = 0; | 1273 | unsigned int ch_read_only = 0; |
1395 | 1274 | ||
@@ -1508,7 +1387,7 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *r | |||
1508 | for (pin = 0; pin < input_pins; pin++) { | 1387 | for (pin = 0; pin < input_pins; pin++) { |
1509 | err = parse_audio_unit(state, desc->baSourceID[pin]); | 1388 | err = parse_audio_unit(state, desc->baSourceID[pin]); |
1510 | if (err < 0) | 1389 | if (err < 0) |
1511 | continue; | 1390 | return err; |
1512 | err = check_input_term(state, desc->baSourceID[pin], &iterm); | 1391 | err = check_input_term(state, desc->baSourceID[pin], &iterm); |
1513 | if (err < 0) | 1392 | if (err < 0) |
1514 | return err; | 1393 | return err; |
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h index aab80df201b..81b2d8a32fb 100644 --- a/sound/usb/mixer.h +++ b/sound/usb/mixer.h | |||
@@ -43,7 +43,6 @@ struct usb_mixer_elem_info { | |||
43 | unsigned int id; | 43 | unsigned int id; |
44 | unsigned int control; /* CS or ICN (high byte) */ | 44 | unsigned int control; /* CS or ICN (high byte) */ |
45 | unsigned int cmask; /* channel mask bitmap: 0 = master */ | 45 | unsigned int cmask; /* channel mask bitmap: 0 = master */ |
46 | unsigned int idx_off; /* Control index offset */ | ||
47 | unsigned int ch_readonly; | 46 | unsigned int ch_readonly; |
48 | unsigned int master_readonly; | 47 | unsigned int master_readonly; |
49 | int channels; | 48 | int channels; |
@@ -69,7 +68,4 @@ int snd_usb_mixer_activate(struct usb_mixer_interface *mixer); | |||
69 | int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer, | 68 | int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer, |
70 | struct snd_kcontrol *kctl); | 69 | struct snd_kcontrol *kctl); |
71 | 70 | ||
72 | int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, | ||
73 | unsigned int size, unsigned int __user *_tlv); | ||
74 | |||
75 | #endif /* __USBMIXER_H */ | 71 | #endif /* __USBMIXER_H */ |
diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index e71fe55cebe..f1324c42383 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c | |||
@@ -288,15 +288,6 @@ static struct usbmix_name_map scratch_live_map[] = { | |||
288 | { 0 } /* terminator */ | 288 | { 0 } /* terminator */ |
289 | }; | 289 | }; |
290 | 290 | ||
291 | static struct usbmix_name_map ebox44_map[] = { | ||
292 | { 4, NULL }, /* FU */ | ||
293 | { 6, NULL }, /* MU */ | ||
294 | { 7, NULL }, /* FU */ | ||
295 | { 10, NULL }, /* FU */ | ||
296 | { 11, NULL }, /* MU */ | ||
297 | { 0 } | ||
298 | }; | ||
299 | |||
300 | /* "Gamesurround Muse Pocket LT" looks same like "Sound Blaster MP3+" | 291 | /* "Gamesurround Muse Pocket LT" looks same like "Sound Blaster MP3+" |
301 | * most importand difference is SU[8], it should be set to "Capture Source" | 292 | * most importand difference is SU[8], it should be set to "Capture Source" |
302 | * to make alsamixer and PA working properly. | 293 | * to make alsamixer and PA working properly. |
@@ -341,14 +332,6 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { | |||
341 | .map = audigy2nx_map, | 332 | .map = audigy2nx_map, |
342 | .selector_map = audigy2nx_selectors, | 333 | .selector_map = audigy2nx_selectors, |
343 | }, | 334 | }, |
344 | { /* Logitech, Inc. QuickCam Pro for Notebooks */ | ||
345 | .id = USB_ID(0x046d, 0x0991), | ||
346 | .ignore_ctl_error = 1, | ||
347 | }, | ||
348 | { /* Logitech, Inc. QuickCam E 3500 */ | ||
349 | .id = USB_ID(0x046d, 0x09a4), | ||
350 | .ignore_ctl_error = 1, | ||
351 | }, | ||
352 | { | 335 | { |
353 | /* Hercules DJ Console (Windows Edition) */ | 336 | /* Hercules DJ Console (Windows Edition) */ |
354 | .id = USB_ID(0x06f8, 0xb000), | 337 | .id = USB_ID(0x06f8, 0xb000), |
@@ -388,10 +371,6 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { | |||
388 | .map = scratch_live_map, | 371 | .map = scratch_live_map, |
389 | .ignore_ctl_error = 1, | 372 | .ignore_ctl_error = 1, |
390 | }, | 373 | }, |
391 | { | ||
392 | .id = USB_ID(0x200c, 0x1018), | ||
393 | .map = ebox44_map, | ||
394 | }, | ||
395 | { 0 } /* terminator */ | 374 | { 0 } /* terminator */ |
396 | }; | 375 | }; |
397 | 376 | ||
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 15520de1df5..3d0f4873112 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c | |||
@@ -42,117 +42,6 @@ | |||
42 | 42 | ||
43 | extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; | 43 | extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; |
44 | 44 | ||
45 | struct std_mono_table { | ||
46 | unsigned int unitid, control, cmask; | ||
47 | int val_type; | ||
48 | const char *name; | ||
49 | snd_kcontrol_tlv_rw_t *tlv_callback; | ||
50 | }; | ||
51 | |||
52 | /* private_free callback */ | ||
53 | static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | ||
54 | { | ||
55 | kfree(kctl->private_data); | ||
56 | kctl->private_data = NULL; | ||
57 | } | ||
58 | |||
59 | /* This function allows for the creation of standard UAC controls. | ||
60 | * See the quirks for M-Audio FTUs or Ebox-44. | ||
61 | * If you don't want to set a TLV callback pass NULL. | ||
62 | * | ||
63 | * Since there doesn't seem to be a devices that needs a multichannel | ||
64 | * version, we keep it mono for simplicity. | ||
65 | */ | ||
66 | static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer, | ||
67 | unsigned int unitid, | ||
68 | unsigned int control, | ||
69 | unsigned int cmask, | ||
70 | int val_type, | ||
71 | unsigned int idx_off, | ||
72 | const char *name, | ||
73 | snd_kcontrol_tlv_rw_t *tlv_callback) | ||
74 | { | ||
75 | int err; | ||
76 | struct usb_mixer_elem_info *cval; | ||
77 | struct snd_kcontrol *kctl; | ||
78 | |||
79 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | ||
80 | if (!cval) | ||
81 | return -ENOMEM; | ||
82 | |||
83 | cval->id = unitid; | ||
84 | cval->mixer = mixer; | ||
85 | cval->val_type = val_type; | ||
86 | cval->channels = 1; | ||
87 | cval->control = control; | ||
88 | cval->cmask = cmask; | ||
89 | cval->idx_off = idx_off; | ||
90 | |||
91 | /* get_min_max() is called only for integer volumes later, | ||
92 | * so provide a short-cut for booleans */ | ||
93 | cval->min = 0; | ||
94 | cval->max = 1; | ||
95 | cval->res = 0; | ||
96 | cval->dBmin = 0; | ||
97 | cval->dBmax = 0; | ||
98 | |||
99 | /* Create control */ | ||
100 | kctl = snd_ctl_new1(snd_usb_feature_unit_ctl, cval); | ||
101 | if (!kctl) { | ||
102 | kfree(cval); | ||
103 | return -ENOMEM; | ||
104 | } | ||
105 | |||
106 | /* Set name */ | ||
107 | snprintf(kctl->id.name, sizeof(kctl->id.name), name); | ||
108 | kctl->private_free = usb_mixer_elem_free; | ||
109 | |||
110 | /* set TLV */ | ||
111 | if (tlv_callback) { | ||
112 | kctl->tlv.c = tlv_callback; | ||
113 | kctl->vd[0].access |= | ||
114 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | | ||
115 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; | ||
116 | } | ||
117 | /* Add control to mixer */ | ||
118 | err = snd_usb_mixer_add_control(mixer, kctl); | ||
119 | if (err < 0) | ||
120 | return err; | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer, | ||
126 | unsigned int unitid, | ||
127 | unsigned int control, | ||
128 | unsigned int cmask, | ||
129 | int val_type, | ||
130 | const char *name, | ||
131 | snd_kcontrol_tlv_rw_t *tlv_callback) | ||
132 | { | ||
133 | return snd_create_std_mono_ctl_offset(mixer, unitid, control, cmask, | ||
134 | val_type, 0 /* Offset */, name, tlv_callback); | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * Create a set of standard UAC controls from a table | ||
139 | */ | ||
140 | static int snd_create_std_mono_table(struct usb_mixer_interface *mixer, | ||
141 | struct std_mono_table *t) | ||
142 | { | ||
143 | int err; | ||
144 | |||
145 | while (t->name != NULL) { | ||
146 | err = snd_create_std_mono_ctl(mixer, t->unitid, t->control, | ||
147 | t->cmask, t->val_type, t->name, t->tlv_callback); | ||
148 | if (err < 0) | ||
149 | return err; | ||
150 | t++; | ||
151 | } | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | /* | 45 | /* |
157 | * Sound Blaster remote control configuration | 46 | * Sound Blaster remote control configuration |
158 | * | 47 | * |
@@ -297,29 +186,22 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
297 | if (value > 1) | 186 | if (value > 1) |
298 | return -EINVAL; | 187 | return -EINVAL; |
299 | changed = value != mixer->audigy2nx_leds[index]; | 188 | changed = value != mixer->audigy2nx_leds[index]; |
300 | down_read(&mixer->chip->shutdown_rwsem); | ||
301 | if (mixer->chip->shutdown) { | ||
302 | err = -ENODEV; | ||
303 | goto out; | ||
304 | } | ||
305 | if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) | 189 | if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) |
306 | err = snd_usb_ctl_msg(mixer->chip->dev, | 190 | err = snd_usb_ctl_msg(mixer->chip->dev, |
307 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, | 191 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, |
308 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 192 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
309 | !value, 0, NULL, 0); | 193 | !value, 0, NULL, 0, 100); |
310 | /* USB X-Fi S51 Pro */ | 194 | /* USB X-Fi S51 Pro */ |
311 | if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) | 195 | if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) |
312 | err = snd_usb_ctl_msg(mixer->chip->dev, | 196 | err = snd_usb_ctl_msg(mixer->chip->dev, |
313 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, | 197 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, |
314 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 198 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
315 | !value, 0, NULL, 0); | 199 | !value, 0, NULL, 0, 100); |
316 | else | 200 | else |
317 | err = snd_usb_ctl_msg(mixer->chip->dev, | 201 | err = snd_usb_ctl_msg(mixer->chip->dev, |
318 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, | 202 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, |
319 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 203 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
320 | value, index + 2, NULL, 0); | 204 | value, index + 2, NULL, 0, 100); |
321 | out: | ||
322 | up_read(&mixer->chip->shutdown_rwsem); | ||
323 | if (err < 0) | 205 | if (err < 0) |
324 | return err; | 206 | return err; |
325 | mixer->audigy2nx_leds[index] = value; | 207 | mixer->audigy2nx_leds[index] = value; |
@@ -413,16 +295,11 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry, | |||
413 | 295 | ||
414 | for (i = 0; jacks[i].name; ++i) { | 296 | for (i = 0; jacks[i].name; ++i) { |
415 | snd_iprintf(buffer, "%s: ", jacks[i].name); | 297 | snd_iprintf(buffer, "%s: ", jacks[i].name); |
416 | down_read(&mixer->chip->shutdown_rwsem); | 298 | err = snd_usb_ctl_msg(mixer->chip->dev, |
417 | if (mixer->chip->shutdown) | ||
418 | err = 0; | ||
419 | else | ||
420 | err = snd_usb_ctl_msg(mixer->chip->dev, | ||
421 | usb_rcvctrlpipe(mixer->chip->dev, 0), | 299 | usb_rcvctrlpipe(mixer->chip->dev, 0), |
422 | UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS | | 300 | UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS | |
423 | USB_RECIP_INTERFACE, 0, | 301 | USB_RECIP_INTERFACE, 0, |
424 | jacks[i].unitid << 8, buf, 3); | 302 | jacks[i].unitid << 8, buf, 3, 100); |
425 | up_read(&mixer->chip->shutdown_rwsem); | ||
426 | if (err == 3 && (buf[0] == 3 || buf[0] == 6)) | 303 | if (err == 3 && (buf[0] == 3 || buf[0] == 6)) |
427 | snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]); | 304 | snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]); |
428 | else | 305 | else |
@@ -430,8 +307,6 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry, | |||
430 | } | 307 | } |
431 | } | 308 | } |
432 | 309 | ||
433 | /* ASUS Xonar U1 / U3 controls */ | ||
434 | |||
435 | static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol, | 310 | static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol, |
436 | struct snd_ctl_elem_value *ucontrol) | 311 | struct snd_ctl_elem_value *ucontrol) |
437 | { | 312 | { |
@@ -454,15 +329,10 @@ static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol, | |||
454 | else | 329 | else |
455 | new_status = old_status & ~0x02; | 330 | new_status = old_status & ~0x02; |
456 | changed = new_status != old_status; | 331 | changed = new_status != old_status; |
457 | down_read(&mixer->chip->shutdown_rwsem); | 332 | err = snd_usb_ctl_msg(mixer->chip->dev, |
458 | if (mixer->chip->shutdown) | ||
459 | err = -ENODEV; | ||
460 | else | ||
461 | err = snd_usb_ctl_msg(mixer->chip->dev, | ||
462 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x08, | 333 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x08, |
463 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 334 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
464 | 50, 0, &new_status, 1); | 335 | 50, 0, &new_status, 1, 100); |
465 | up_read(&mixer->chip->shutdown_rwsem); | ||
466 | if (err < 0) | 336 | if (err < 0) |
467 | return err; | 337 | return err; |
468 | mixer->xonar_u1_status = new_status; | 338 | mixer->xonar_u1_status = new_status; |
@@ -501,17 +371,11 @@ static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol, | |||
501 | u8 bRequest = (kcontrol->private_value >> 16) & 0xff; | 371 | u8 bRequest = (kcontrol->private_value >> 16) & 0xff; |
502 | u16 wIndex = kcontrol->private_value & 0xffff; | 372 | u16 wIndex = kcontrol->private_value & 0xffff; |
503 | u8 tmp; | 373 | u8 tmp; |
504 | int ret; | ||
505 | 374 | ||
506 | down_read(&mixer->chip->shutdown_rwsem); | 375 | int ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest, |
507 | if (mixer->chip->shutdown) | ||
508 | ret = -ENODEV; | ||
509 | else | ||
510 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest, | ||
511 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, | 376 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, |
512 | 0, cpu_to_le16(wIndex), | 377 | 0, cpu_to_le16(wIndex), |
513 | &tmp, sizeof(tmp), 1000); | 378 | &tmp, sizeof(tmp), 1000); |
514 | up_read(&mixer->chip->shutdown_rwsem); | ||
515 | 379 | ||
516 | if (ret < 0) { | 380 | if (ret < 0) { |
517 | snd_printk(KERN_ERR | 381 | snd_printk(KERN_ERR |
@@ -532,17 +396,11 @@ static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol, | |||
532 | u8 bRequest = (kcontrol->private_value >> 16) & 0xff; | 396 | u8 bRequest = (kcontrol->private_value >> 16) & 0xff; |
533 | u16 wIndex = kcontrol->private_value & 0xffff; | 397 | u16 wIndex = kcontrol->private_value & 0xffff; |
534 | u16 wValue = ucontrol->value.integer.value[0]; | 398 | u16 wValue = ucontrol->value.integer.value[0]; |
535 | int ret; | ||
536 | 399 | ||
537 | down_read(&mixer->chip->shutdown_rwsem); | 400 | int ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, |
538 | if (mixer->chip->shutdown) | ||
539 | ret = -ENODEV; | ||
540 | else | ||
541 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest, | ||
542 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, | 401 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, |
543 | cpu_to_le16(wValue), cpu_to_le16(wIndex), | 402 | cpu_to_le16(wValue), cpu_to_le16(wIndex), |
544 | NULL, 0, 1000); | 403 | NULL, 0, 1000); |
545 | up_read(&mixer->chip->shutdown_rwsem); | ||
546 | 404 | ||
547 | if (ret < 0) { | 405 | if (ret < 0) { |
548 | snd_printk(KERN_ERR | 406 | snd_printk(KERN_ERR |
@@ -637,240 +495,60 @@ static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer, | |||
637 | } | 495 | } |
638 | 496 | ||
639 | /* M-Audio FastTrack Ultra quirks */ | 497 | /* M-Audio FastTrack Ultra quirks */ |
640 | /* FTU Effect switch (also used by C400) */ | ||
641 | struct snd_ftu_eff_switch_priv_val { | ||
642 | struct usb_mixer_interface *mixer; | ||
643 | int cached_value; | ||
644 | int is_cached; | ||
645 | int bUnitID; | ||
646 | int validx; | ||
647 | }; | ||
648 | |||
649 | static int snd_ftu_eff_switch_info(struct snd_kcontrol *kcontrol, | ||
650 | struct snd_ctl_elem_info *uinfo) | ||
651 | { | ||
652 | static const char *texts[8] = {"Room 1", | ||
653 | "Room 2", | ||
654 | "Room 3", | ||
655 | "Hall 1", | ||
656 | "Hall 2", | ||
657 | "Plate", | ||
658 | "Delay", | ||
659 | "Echo" | ||
660 | }; | ||
661 | |||
662 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
663 | uinfo->count = 1; | ||
664 | uinfo->value.enumerated.items = 8; | ||
665 | if (uinfo->value.enumerated.item > 7) | ||
666 | uinfo->value.enumerated.item = 7; | ||
667 | strcpy(uinfo->value.enumerated.name, | ||
668 | texts[uinfo->value.enumerated.item]); | ||
669 | |||
670 | return 0; | ||
671 | } | ||
672 | |||
673 | static int snd_ftu_eff_switch_get(struct snd_kcontrol *kctl, | ||
674 | struct snd_ctl_elem_value *ucontrol) | ||
675 | { | ||
676 | struct snd_usb_audio *chip; | ||
677 | struct usb_mixer_interface *mixer; | ||
678 | struct snd_ftu_eff_switch_priv_val *pval; | ||
679 | int err; | ||
680 | unsigned char value[2]; | ||
681 | int id, validx; | ||
682 | 498 | ||
683 | const int val_len = 2; | 499 | /* private_free callback */ |
684 | 500 | static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | |
685 | value[0] = 0x00; | ||
686 | value[1] = 0x00; | ||
687 | |||
688 | pval = (struct snd_ftu_eff_switch_priv_val *) | ||
689 | kctl->private_value; | ||
690 | |||
691 | if (pval->is_cached) { | ||
692 | ucontrol->value.enumerated.item[0] = pval->cached_value; | ||
693 | return 0; | ||
694 | } | ||
695 | |||
696 | mixer = (struct usb_mixer_interface *) pval->mixer; | ||
697 | if (snd_BUG_ON(!mixer)) | ||
698 | return -EINVAL; | ||
699 | |||
700 | chip = (struct snd_usb_audio *) mixer->chip; | ||
701 | if (snd_BUG_ON(!chip)) | ||
702 | return -EINVAL; | ||
703 | |||
704 | id = pval->bUnitID; | ||
705 | validx = pval->validx; | ||
706 | |||
707 | down_read(&mixer->chip->shutdown_rwsem); | ||
708 | if (mixer->chip->shutdown) | ||
709 | err = -ENODEV; | ||
710 | else | ||
711 | err = snd_usb_ctl_msg(chip->dev, | ||
712 | usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, | ||
713 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
714 | validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), | ||
715 | value, val_len); | ||
716 | up_read(&mixer->chip->shutdown_rwsem); | ||
717 | if (err < 0) | ||
718 | return err; | ||
719 | |||
720 | ucontrol->value.enumerated.item[0] = value[0]; | ||
721 | pval->cached_value = value[0]; | ||
722 | pval->is_cached = 1; | ||
723 | |||
724 | return 0; | ||
725 | } | ||
726 | |||
727 | static int snd_ftu_eff_switch_put(struct snd_kcontrol *kctl, | ||
728 | struct snd_ctl_elem_value *ucontrol) | ||
729 | { | 501 | { |
730 | struct snd_usb_audio *chip; | 502 | kfree(kctl->private_data); |
731 | struct snd_ftu_eff_switch_priv_val *pval; | 503 | kctl->private_data = NULL; |
732 | |||
733 | struct usb_mixer_interface *mixer; | ||
734 | int changed, cur_val, err, new_val; | ||
735 | unsigned char value[2]; | ||
736 | int id, validx; | ||
737 | |||
738 | const int val_len = 2; | ||
739 | |||
740 | changed = 0; | ||
741 | |||
742 | pval = (struct snd_ftu_eff_switch_priv_val *) | ||
743 | kctl->private_value; | ||
744 | cur_val = pval->cached_value; | ||
745 | new_val = ucontrol->value.enumerated.item[0]; | ||
746 | |||
747 | mixer = (struct usb_mixer_interface *) pval->mixer; | ||
748 | if (snd_BUG_ON(!mixer)) | ||
749 | return -EINVAL; | ||
750 | |||
751 | chip = (struct snd_usb_audio *) mixer->chip; | ||
752 | if (snd_BUG_ON(!chip)) | ||
753 | return -EINVAL; | ||
754 | |||
755 | id = pval->bUnitID; | ||
756 | validx = pval->validx; | ||
757 | |||
758 | if (!pval->is_cached) { | ||
759 | /* Read current value */ | ||
760 | down_read(&mixer->chip->shutdown_rwsem); | ||
761 | if (mixer->chip->shutdown) | ||
762 | err = -ENODEV; | ||
763 | else | ||
764 | err = snd_usb_ctl_msg(chip->dev, | ||
765 | usb_rcvctrlpipe(chip->dev, 0), UAC_GET_CUR, | ||
766 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | ||
767 | validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), | ||
768 | value, val_len); | ||
769 | up_read(&mixer->chip->shutdown_rwsem); | ||
770 | if (err < 0) | ||
771 | return err; | ||
772 | |||
773 | cur_val = value[0]; | ||
774 | pval->cached_value = cur_val; | ||
775 | pval->is_cached = 1; | ||
776 | } | ||
777 | /* update value if needed */ | ||
778 | if (cur_val != new_val) { | ||
779 | value[0] = new_val; | ||
780 | value[1] = 0; | ||
781 | down_read(&mixer->chip->shutdown_rwsem); | ||
782 | if (mixer->chip->shutdown) | ||
783 | err = -ENODEV; | ||
784 | else | ||
785 | err = snd_usb_ctl_msg(chip->dev, | ||
786 | usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR, | ||
787 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, | ||
788 | validx << 8, snd_usb_ctrl_intf(chip) | (id << 8), | ||
789 | value, val_len); | ||
790 | up_read(&mixer->chip->shutdown_rwsem); | ||
791 | if (err < 0) | ||
792 | return err; | ||
793 | |||
794 | pval->cached_value = new_val; | ||
795 | pval->is_cached = 1; | ||
796 | changed = 1; | ||
797 | } | ||
798 | |||
799 | return changed; | ||
800 | } | 504 | } |
801 | 505 | ||
802 | static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer, | 506 | static int snd_maudio_ftu_create_ctl(struct usb_mixer_interface *mixer, |
803 | int validx, int bUnitID) | 507 | int in, int out, const char *name) |
804 | { | 508 | { |
805 | static struct snd_kcontrol_new template = { | 509 | struct usb_mixer_elem_info *cval; |
806 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
807 | .name = "Effect Program Switch", | ||
808 | .index = 0, | ||
809 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
810 | .info = snd_ftu_eff_switch_info, | ||
811 | .get = snd_ftu_eff_switch_get, | ||
812 | .put = snd_ftu_eff_switch_put | ||
813 | }; | ||
814 | |||
815 | int err; | ||
816 | struct snd_kcontrol *kctl; | 510 | struct snd_kcontrol *kctl; |
817 | struct snd_ftu_eff_switch_priv_val *pval; | ||
818 | 511 | ||
819 | pval = kzalloc(sizeof(*pval), GFP_KERNEL); | 512 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
820 | if (!pval) | 513 | if (!cval) |
821 | return -ENOMEM; | 514 | return -ENOMEM; |
822 | 515 | ||
823 | pval->cached_value = 0; | 516 | cval->id = 5; |
824 | pval->is_cached = 0; | 517 | cval->mixer = mixer; |
825 | pval->mixer = mixer; | 518 | cval->val_type = USB_MIXER_S16; |
826 | pval->bUnitID = bUnitID; | 519 | cval->channels = 1; |
827 | pval->validx = validx; | 520 | cval->control = out + 1; |
521 | cval->cmask = 1 << in; | ||
828 | 522 | ||
829 | template.private_value = (unsigned long) pval; | 523 | kctl = snd_ctl_new1(snd_usb_feature_unit_ctl, cval); |
830 | kctl = snd_ctl_new1(&template, mixer->chip); | ||
831 | if (!kctl) { | 524 | if (!kctl) { |
832 | kfree(pval); | 525 | kfree(cval); |
833 | return -ENOMEM; | 526 | return -ENOMEM; |
834 | } | 527 | } |
835 | 528 | ||
836 | err = snd_ctl_add(mixer->chip->card, kctl); | 529 | snprintf(kctl->id.name, sizeof(kctl->id.name), name); |
837 | if (err < 0) | 530 | kctl->private_free = usb_mixer_elem_free; |
838 | return err; | 531 | return snd_usb_mixer_add_control(mixer, kctl); |
839 | |||
840 | return 0; | ||
841 | } | 532 | } |
842 | 533 | ||
843 | /* Create volume controls for FTU devices*/ | 534 | static int snd_maudio_ftu_create_mixer(struct usb_mixer_interface *mixer) |
844 | static int snd_ftu_create_volume_ctls(struct usb_mixer_interface *mixer) | ||
845 | { | 535 | { |
846 | char name[64]; | 536 | char name[64]; |
847 | unsigned int control, cmask; | ||
848 | int in, out, err; | 537 | int in, out, err; |
849 | 538 | ||
850 | const unsigned int id = 5; | ||
851 | const int val_type = USB_MIXER_S16; | ||
852 | |||
853 | for (out = 0; out < 8; out++) { | 539 | for (out = 0; out < 8; out++) { |
854 | control = out + 1; | ||
855 | for (in = 0; in < 8; in++) { | 540 | for (in = 0; in < 8; in++) { |
856 | cmask = 1 << in; | ||
857 | snprintf(name, sizeof(name), | 541 | snprintf(name, sizeof(name), |
858 | "AIn%d - Out%d Capture Volume", | 542 | "AIn%d - Out%d Capture Volume", in + 1, out + 1); |
859 | in + 1, out + 1); | 543 | err = snd_maudio_ftu_create_ctl(mixer, in, out, name); |
860 | err = snd_create_std_mono_ctl(mixer, id, control, | ||
861 | cmask, val_type, name, | ||
862 | &snd_usb_mixer_vol_tlv); | ||
863 | if (err < 0) | 544 | if (err < 0) |
864 | return err; | 545 | return err; |
865 | } | 546 | } |
547 | |||
866 | for (in = 8; in < 16; in++) { | 548 | for (in = 8; in < 16; in++) { |
867 | cmask = 1 << in; | ||
868 | snprintf(name, sizeof(name), | 549 | snprintf(name, sizeof(name), |
869 | "DIn%d - Out%d Playback Volume", | 550 | "DIn%d - Out%d Playback Volume", in - 7, out + 1); |
870 | in - 7, out + 1); | 551 | err = snd_maudio_ftu_create_ctl(mixer, in, out, name); |
871 | err = snd_create_std_mono_ctl(mixer, id, control, | ||
872 | cmask, val_type, name, | ||
873 | &snd_usb_mixer_vol_tlv); | ||
874 | if (err < 0) | 552 | if (err < 0) |
875 | return err; | 553 | return err; |
876 | } | 554 | } |
@@ -879,137 +557,6 @@ static int snd_ftu_create_volume_ctls(struct usb_mixer_interface *mixer) | |||
879 | return 0; | 557 | return 0; |
880 | } | 558 | } |
881 | 559 | ||
882 | /* This control needs a volume quirk, see mixer.c */ | ||
883 | static int snd_ftu_create_effect_volume_ctl(struct usb_mixer_interface *mixer) | ||
884 | { | ||
885 | static const char name[] = "Effect Volume"; | ||
886 | const unsigned int id = 6; | ||
887 | const int val_type = USB_MIXER_U8; | ||
888 | const unsigned int control = 2; | ||
889 | const unsigned int cmask = 0; | ||
890 | |||
891 | return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type, | ||
892 | name, snd_usb_mixer_vol_tlv); | ||
893 | } | ||
894 | |||
895 | /* This control needs a volume quirk, see mixer.c */ | ||
896 | static int snd_ftu_create_effect_duration_ctl(struct usb_mixer_interface *mixer) | ||
897 | { | ||
898 | static const char name[] = "Effect Duration"; | ||
899 | const unsigned int id = 6; | ||
900 | const int val_type = USB_MIXER_S16; | ||
901 | const unsigned int control = 3; | ||
902 | const unsigned int cmask = 0; | ||
903 | |||
904 | return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type, | ||
905 | name, snd_usb_mixer_vol_tlv); | ||
906 | } | ||
907 | |||
908 | /* This control needs a volume quirk, see mixer.c */ | ||
909 | static int snd_ftu_create_effect_feedback_ctl(struct usb_mixer_interface *mixer) | ||
910 | { | ||
911 | static const char name[] = "Effect Feedback Volume"; | ||
912 | const unsigned int id = 6; | ||
913 | const int val_type = USB_MIXER_U8; | ||
914 | const unsigned int control = 4; | ||
915 | const unsigned int cmask = 0; | ||
916 | |||
917 | return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type, | ||
918 | name, NULL); | ||
919 | } | ||
920 | |||
921 | static int snd_ftu_create_effect_return_ctls(struct usb_mixer_interface *mixer) | ||
922 | { | ||
923 | unsigned int cmask; | ||
924 | int err, ch; | ||
925 | char name[48]; | ||
926 | |||
927 | const unsigned int id = 7; | ||
928 | const int val_type = USB_MIXER_S16; | ||
929 | const unsigned int control = 7; | ||
930 | |||
931 | for (ch = 0; ch < 4; ++ch) { | ||
932 | cmask = 1 << ch; | ||
933 | snprintf(name, sizeof(name), | ||
934 | "Effect Return %d Volume", ch + 1); | ||
935 | err = snd_create_std_mono_ctl(mixer, id, control, | ||
936 | cmask, val_type, name, | ||
937 | snd_usb_mixer_vol_tlv); | ||
938 | if (err < 0) | ||
939 | return err; | ||
940 | } | ||
941 | |||
942 | return 0; | ||
943 | } | ||
944 | |||
945 | static int snd_ftu_create_effect_send_ctls(struct usb_mixer_interface *mixer) | ||
946 | { | ||
947 | unsigned int cmask; | ||
948 | int err, ch; | ||
949 | char name[48]; | ||
950 | |||
951 | const unsigned int id = 5; | ||
952 | const int val_type = USB_MIXER_S16; | ||
953 | const unsigned int control = 9; | ||
954 | |||
955 | for (ch = 0; ch < 8; ++ch) { | ||
956 | cmask = 1 << ch; | ||
957 | snprintf(name, sizeof(name), | ||
958 | "Effect Send AIn%d Volume", ch + 1); | ||
959 | err = snd_create_std_mono_ctl(mixer, id, control, cmask, | ||
960 | val_type, name, | ||
961 | snd_usb_mixer_vol_tlv); | ||
962 | if (err < 0) | ||
963 | return err; | ||
964 | } | ||
965 | for (ch = 8; ch < 16; ++ch) { | ||
966 | cmask = 1 << ch; | ||
967 | snprintf(name, sizeof(name), | ||
968 | "Effect Send DIn%d Volume", ch - 7); | ||
969 | err = snd_create_std_mono_ctl(mixer, id, control, cmask, | ||
970 | val_type, name, | ||
971 | snd_usb_mixer_vol_tlv); | ||
972 | if (err < 0) | ||
973 | return err; | ||
974 | } | ||
975 | return 0; | ||
976 | } | ||
977 | |||
978 | static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer) | ||
979 | { | ||
980 | int err; | ||
981 | |||
982 | err = snd_ftu_create_volume_ctls(mixer); | ||
983 | if (err < 0) | ||
984 | return err; | ||
985 | |||
986 | err = snd_ftu_create_effect_switch(mixer, 1, 6); | ||
987 | if (err < 0) | ||
988 | return err; | ||
989 | |||
990 | err = snd_ftu_create_effect_volume_ctl(mixer); | ||
991 | if (err < 0) | ||
992 | return err; | ||
993 | |||
994 | err = snd_ftu_create_effect_duration_ctl(mixer); | ||
995 | if (err < 0) | ||
996 | return err; | ||
997 | |||
998 | err = snd_ftu_create_effect_feedback_ctl(mixer); | ||
999 | if (err < 0) | ||
1000 | return err; | ||
1001 | |||
1002 | err = snd_ftu_create_effect_return_ctls(mixer); | ||
1003 | if (err < 0) | ||
1004 | return err; | ||
1005 | |||
1006 | err = snd_ftu_create_effect_send_ctls(mixer); | ||
1007 | if (err < 0) | ||
1008 | return err; | ||
1009 | |||
1010 | return 0; | ||
1011 | } | ||
1012 | |||
1013 | void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, | 560 | void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, |
1014 | unsigned char samplerate_id) | 561 | unsigned char samplerate_id) |
1015 | { | 562 | { |
@@ -1029,253 +576,6 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, | |||
1029 | } | 576 | } |
1030 | } | 577 | } |
1031 | 578 | ||
1032 | /* M-Audio Fast Track C400 */ | ||
1033 | /* C400 volume controls, this control needs a volume quirk, see mixer.c */ | ||
1034 | static int snd_c400_create_vol_ctls(struct usb_mixer_interface *mixer) | ||
1035 | { | ||
1036 | char name[64]; | ||
1037 | unsigned int cmask, offset; | ||
1038 | int out, chan, err; | ||
1039 | |||
1040 | const unsigned int id = 0x40; | ||
1041 | const int val_type = USB_MIXER_S16; | ||
1042 | const int control = 1; | ||
1043 | |||
1044 | for (chan = 0; chan < 10; chan++) { | ||
1045 | for (out = 0; out < 6; out++) { | ||
1046 | if (chan < 6) { | ||
1047 | snprintf(name, sizeof(name), | ||
1048 | "PCM%d-Out%d Playback Volume", | ||
1049 | chan + 1, out + 1); | ||
1050 | } else { | ||
1051 | snprintf(name, sizeof(name), | ||
1052 | "In%d-Out%d Playback Volume", | ||
1053 | chan - 5, out + 1); | ||
1054 | } | ||
1055 | |||
1056 | cmask = (out == 0) ? 0 : 1 << (out - 1); | ||
1057 | offset = chan * 6; | ||
1058 | err = snd_create_std_mono_ctl_offset(mixer, id, control, | ||
1059 | cmask, val_type, offset, name, | ||
1060 | &snd_usb_mixer_vol_tlv); | ||
1061 | if (err < 0) | ||
1062 | return err; | ||
1063 | } | ||
1064 | } | ||
1065 | |||
1066 | return 0; | ||
1067 | } | ||
1068 | |||
1069 | /* This control needs a volume quirk, see mixer.c */ | ||
1070 | static int snd_c400_create_effect_volume_ctl(struct usb_mixer_interface *mixer) | ||
1071 | { | ||
1072 | static const char name[] = "Effect Volume"; | ||
1073 | const unsigned int id = 0x43; | ||
1074 | const int val_type = USB_MIXER_U8; | ||
1075 | const unsigned int control = 3; | ||
1076 | const unsigned int cmask = 0; | ||
1077 | |||
1078 | return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type, | ||
1079 | name, snd_usb_mixer_vol_tlv); | ||
1080 | } | ||
1081 | |||
1082 | /* This control needs a volume quirk, see mixer.c */ | ||
1083 | static int snd_c400_create_effect_duration_ctl(struct usb_mixer_interface *mixer) | ||
1084 | { | ||
1085 | static const char name[] = "Effect Duration"; | ||
1086 | const unsigned int id = 0x43; | ||
1087 | const int val_type = USB_MIXER_S16; | ||
1088 | const unsigned int control = 4; | ||
1089 | const unsigned int cmask = 0; | ||
1090 | |||
1091 | return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type, | ||
1092 | name, snd_usb_mixer_vol_tlv); | ||
1093 | } | ||
1094 | |||
1095 | /* This control needs a volume quirk, see mixer.c */ | ||
1096 | static int snd_c400_create_effect_feedback_ctl(struct usb_mixer_interface *mixer) | ||
1097 | { | ||
1098 | static const char name[] = "Effect Feedback Volume"; | ||
1099 | const unsigned int id = 0x43; | ||
1100 | const int val_type = USB_MIXER_U8; | ||
1101 | const unsigned int control = 5; | ||
1102 | const unsigned int cmask = 0; | ||
1103 | |||
1104 | return snd_create_std_mono_ctl(mixer, id, control, cmask, val_type, | ||
1105 | name, NULL); | ||
1106 | } | ||
1107 | |||
1108 | static int snd_c400_create_effect_vol_ctls(struct usb_mixer_interface *mixer) | ||
1109 | { | ||
1110 | char name[64]; | ||
1111 | unsigned int cmask; | ||
1112 | int chan, err; | ||
1113 | |||
1114 | const unsigned int id = 0x42; | ||
1115 | const int val_type = USB_MIXER_S16; | ||
1116 | const int control = 1; | ||
1117 | |||
1118 | for (chan = 0; chan < 10; chan++) { | ||
1119 | if (chan < 6) { | ||
1120 | snprintf(name, sizeof(name), | ||
1121 | "Effect Send DOut%d", | ||
1122 | chan + 1); | ||
1123 | } else { | ||
1124 | snprintf(name, sizeof(name), | ||
1125 | "Effect Send AIn%d", | ||
1126 | chan - 5); | ||
1127 | } | ||
1128 | |||
1129 | cmask = (chan == 0) ? 0 : 1 << (chan - 1); | ||
1130 | err = snd_create_std_mono_ctl(mixer, id, control, | ||
1131 | cmask, val_type, name, | ||
1132 | &snd_usb_mixer_vol_tlv); | ||
1133 | if (err < 0) | ||
1134 | return err; | ||
1135 | } | ||
1136 | |||
1137 | return 0; | ||
1138 | } | ||
1139 | |||
1140 | static int snd_c400_create_effect_ret_vol_ctls(struct usb_mixer_interface *mixer) | ||
1141 | { | ||
1142 | char name[64]; | ||
1143 | unsigned int cmask; | ||
1144 | int chan, err; | ||
1145 | |||
1146 | const unsigned int id = 0x40; | ||
1147 | const int val_type = USB_MIXER_S16; | ||
1148 | const int control = 1; | ||
1149 | const int chan_id[6] = { 0, 7, 2, 9, 4, 0xb }; | ||
1150 | const unsigned int offset = 0x3c; | ||
1151 | /* { 0x3c, 0x43, 0x3e, 0x45, 0x40, 0x47 } */ | ||
1152 | |||
1153 | for (chan = 0; chan < 6; chan++) { | ||
1154 | snprintf(name, sizeof(name), | ||
1155 | "Effect Return %d", | ||
1156 | chan + 1); | ||
1157 | |||
1158 | cmask = (chan_id[chan] == 0) ? 0 : 1 << (chan_id[chan] - 1); | ||
1159 | err = snd_create_std_mono_ctl_offset(mixer, id, control, | ||
1160 | cmask, val_type, offset, name, | ||
1161 | &snd_usb_mixer_vol_tlv); | ||
1162 | if (err < 0) | ||
1163 | return err; | ||
1164 | } | ||
1165 | |||
1166 | return 0; | ||
1167 | } | ||
1168 | |||
1169 | static int snd_c400_create_mixer(struct usb_mixer_interface *mixer) | ||
1170 | { | ||
1171 | int err; | ||
1172 | |||
1173 | err = snd_c400_create_vol_ctls(mixer); | ||
1174 | if (err < 0) | ||
1175 | return err; | ||
1176 | |||
1177 | err = snd_c400_create_effect_vol_ctls(mixer); | ||
1178 | if (err < 0) | ||
1179 | return err; | ||
1180 | |||
1181 | err = snd_c400_create_effect_ret_vol_ctls(mixer); | ||
1182 | if (err < 0) | ||
1183 | return err; | ||
1184 | |||
1185 | err = snd_ftu_create_effect_switch(mixer, 2, 0x43); | ||
1186 | if (err < 0) | ||
1187 | return err; | ||
1188 | |||
1189 | err = snd_c400_create_effect_volume_ctl(mixer); | ||
1190 | if (err < 0) | ||
1191 | return err; | ||
1192 | |||
1193 | err = snd_c400_create_effect_duration_ctl(mixer); | ||
1194 | if (err < 0) | ||
1195 | return err; | ||
1196 | |||
1197 | err = snd_c400_create_effect_feedback_ctl(mixer); | ||
1198 | if (err < 0) | ||
1199 | return err; | ||
1200 | |||
1201 | return 0; | ||
1202 | } | ||
1203 | |||
1204 | /* | ||
1205 | * The mixer units for Ebox-44 are corrupt, and even where they | ||
1206 | * are valid they presents mono controls as L and R channels of | ||
1207 | * stereo. So we provide a good mixer here. | ||
1208 | */ | ||
1209 | static struct std_mono_table ebox44_table[] = { | ||
1210 | { | ||
1211 | .unitid = 4, | ||
1212 | .control = 1, | ||
1213 | .cmask = 0x0, | ||
1214 | .val_type = USB_MIXER_INV_BOOLEAN, | ||
1215 | .name = "Headphone Playback Switch" | ||
1216 | }, | ||
1217 | { | ||
1218 | .unitid = 4, | ||
1219 | .control = 2, | ||
1220 | .cmask = 0x1, | ||
1221 | .val_type = USB_MIXER_S16, | ||
1222 | .name = "Headphone A Mix Playback Volume" | ||
1223 | }, | ||
1224 | { | ||
1225 | .unitid = 4, | ||
1226 | .control = 2, | ||
1227 | .cmask = 0x2, | ||
1228 | .val_type = USB_MIXER_S16, | ||
1229 | .name = "Headphone B Mix Playback Volume" | ||
1230 | }, | ||
1231 | |||
1232 | { | ||
1233 | .unitid = 7, | ||
1234 | .control = 1, | ||
1235 | .cmask = 0x0, | ||
1236 | .val_type = USB_MIXER_INV_BOOLEAN, | ||
1237 | .name = "Output Playback Switch" | ||
1238 | }, | ||
1239 | { | ||
1240 | .unitid = 7, | ||
1241 | .control = 2, | ||
1242 | .cmask = 0x1, | ||
1243 | .val_type = USB_MIXER_S16, | ||
1244 | .name = "Output A Playback Volume" | ||
1245 | }, | ||
1246 | { | ||
1247 | .unitid = 7, | ||
1248 | .control = 2, | ||
1249 | .cmask = 0x2, | ||
1250 | .val_type = USB_MIXER_S16, | ||
1251 | .name = "Output B Playback Volume" | ||
1252 | }, | ||
1253 | |||
1254 | { | ||
1255 | .unitid = 10, | ||
1256 | .control = 1, | ||
1257 | .cmask = 0x0, | ||
1258 | .val_type = USB_MIXER_INV_BOOLEAN, | ||
1259 | .name = "Input Capture Switch" | ||
1260 | }, | ||
1261 | { | ||
1262 | .unitid = 10, | ||
1263 | .control = 2, | ||
1264 | .cmask = 0x1, | ||
1265 | .val_type = USB_MIXER_S16, | ||
1266 | .name = "Input A Capture Volume" | ||
1267 | }, | ||
1268 | { | ||
1269 | .unitid = 10, | ||
1270 | .control = 2, | ||
1271 | .cmask = 0x2, | ||
1272 | .val_type = USB_MIXER_S16, | ||
1273 | .name = "Input B Capture Volume" | ||
1274 | }, | ||
1275 | |||
1276 | {} | ||
1277 | }; | ||
1278 | |||
1279 | int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | 579 | int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) |
1280 | { | 580 | { |
1281 | int err = 0; | 581 | int err = 0; |
@@ -1298,18 +598,13 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | |||
1298 | snd_audigy2nx_proc_read); | 598 | snd_audigy2nx_proc_read); |
1299 | break; | 599 | break; |
1300 | 600 | ||
1301 | case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */ | ||
1302 | err = snd_c400_create_mixer(mixer); | ||
1303 | break; | ||
1304 | |||
1305 | case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */ | 601 | case USB_ID(0x0763, 0x2080): /* M-Audio Fast Track Ultra */ |
1306 | case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */ | 602 | case USB_ID(0x0763, 0x2081): /* M-Audio Fast Track Ultra 8R */ |
1307 | err = snd_ftu_create_mixer(mixer); | 603 | err = snd_maudio_ftu_create_mixer(mixer); |
1308 | break; | 604 | break; |
1309 | 605 | ||
1310 | case USB_ID(0x0b05, 0x1739): /* ASUS Xonar U1 */ | 606 | case USB_ID(0x0b05, 0x1739): |
1311 | case USB_ID(0x0b05, 0x1743): /* ASUS Xonar U1 (2) */ | 607 | case USB_ID(0x0b05, 0x1743): |
1312 | case USB_ID(0x0b05, 0x17a0): /* ASUS Xonar U3 */ | ||
1313 | err = snd_xonar_u1_controls_create(mixer); | 608 | err = snd_xonar_u1_controls_create(mixer); |
1314 | break; | 609 | break; |
1315 | 610 | ||
@@ -1324,11 +619,6 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | |||
1324 | snd_nativeinstruments_ta10_mixers, | 619 | snd_nativeinstruments_ta10_mixers, |
1325 | ARRAY_SIZE(snd_nativeinstruments_ta10_mixers)); | 620 | ARRAY_SIZE(snd_nativeinstruments_ta10_mixers)); |
1326 | break; | 621 | break; |
1327 | |||
1328 | case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */ | ||
1329 | /* detection is disabled in mixer_maps.c */ | ||
1330 | err = snd_create_std_mono_table(mixer, ebox44_table); | ||
1331 | break; | ||
1332 | } | 622 | } |
1333 | 623 | ||
1334 | return err; | 624 | return err; |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index d82e378d37c..b8dcbf407bb 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -16,7 +16,6 @@ | |||
16 | 16 | ||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/ratelimit.h> | ||
20 | #include <linux/usb.h> | 19 | #include <linux/usb.h> |
21 | #include <linux/usb/audio.h> | 20 | #include <linux/usb/audio.h> |
22 | #include <linux/usb/audio-v2.h> | 21 | #include <linux/usb/audio-v2.h> |
@@ -29,42 +28,12 @@ | |||
29 | #include "card.h" | 28 | #include "card.h" |
30 | #include "quirks.h" | 29 | #include "quirks.h" |
31 | #include "debug.h" | 30 | #include "debug.h" |
32 | #include "endpoint.h" | 31 | #include "urb.h" |
33 | #include "helper.h" | 32 | #include "helper.h" |
34 | #include "pcm.h" | 33 | #include "pcm.h" |
35 | #include "clock.h" | 34 | #include "clock.h" |
36 | #include "power.h" | 35 | #include "power.h" |
37 | 36 | ||
38 | #define SUBSTREAM_FLAG_DATA_EP_STARTED 0 | ||
39 | #define SUBSTREAM_FLAG_SYNC_EP_STARTED 1 | ||
40 | |||
41 | /* return the estimated delay based on USB frame counters */ | ||
42 | snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs, | ||
43 | unsigned int rate) | ||
44 | { | ||
45 | int current_frame_number; | ||
46 | int frame_diff; | ||
47 | int est_delay; | ||
48 | |||
49 | if (!subs->last_delay) | ||
50 | return 0; /* short path */ | ||
51 | |||
52 | current_frame_number = usb_get_current_frame_number(subs->dev); | ||
53 | /* | ||
54 | * HCD implementations use different widths, use lower 8 bits. | ||
55 | * The delay will be managed up to 256ms, which is more than | ||
56 | * enough | ||
57 | */ | ||
58 | frame_diff = (current_frame_number - subs->last_frame_number) & 0xff; | ||
59 | |||
60 | /* Approximation based on number of samples per USB frame (ms), | ||
61 | some truncation for 44.1 but the estimate is good enough */ | ||
62 | est_delay = subs->last_delay - (frame_diff * rate / 1000); | ||
63 | if (est_delay < 0) | ||
64 | est_delay = 0; | ||
65 | return est_delay; | ||
66 | } | ||
67 | |||
68 | /* | 37 | /* |
69 | * return the current pcm pointer. just based on the hwptr_done value. | 38 | * return the current pcm pointer. just based on the hwptr_done value. |
70 | */ | 39 | */ |
@@ -74,13 +43,8 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream | |||
74 | unsigned int hwptr_done; | 43 | unsigned int hwptr_done; |
75 | 44 | ||
76 | subs = (struct snd_usb_substream *)substream->runtime->private_data; | 45 | subs = (struct snd_usb_substream *)substream->runtime->private_data; |
77 | if (subs->stream->chip->shutdown) | ||
78 | return SNDRV_PCM_POS_XRUN; | ||
79 | spin_lock(&subs->lock); | 46 | spin_lock(&subs->lock); |
80 | hwptr_done = subs->hwptr_done; | 47 | hwptr_done = subs->hwptr_done; |
81 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
82 | substream->runtime->delay = snd_usb_pcm_delay(subs, | ||
83 | substream->runtime->rate); | ||
84 | spin_unlock(&subs->lock); | 48 | spin_unlock(&subs->lock); |
85 | return hwptr_done / (substream->runtime->frame_bits >> 3); | 49 | return hwptr_done / (substream->runtime->frame_bits >> 3); |
86 | } | 50 | } |
@@ -88,7 +52,8 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream | |||
88 | /* | 52 | /* |
89 | * find a matching audio format | 53 | * find a matching audio format |
90 | */ | 54 | */ |
91 | static struct audioformat *find_format(struct snd_usb_substream *subs) | 55 | static struct audioformat *find_format(struct snd_usb_substream *subs, unsigned int format, |
56 | unsigned int rate, unsigned int channels) | ||
92 | { | 57 | { |
93 | struct list_head *p; | 58 | struct list_head *p; |
94 | struct audioformat *found = NULL; | 59 | struct audioformat *found = NULL; |
@@ -97,17 +62,16 @@ static struct audioformat *find_format(struct snd_usb_substream *subs) | |||
97 | list_for_each(p, &subs->fmt_list) { | 62 | list_for_each(p, &subs->fmt_list) { |
98 | struct audioformat *fp; | 63 | struct audioformat *fp; |
99 | fp = list_entry(p, struct audioformat, list); | 64 | fp = list_entry(p, struct audioformat, list); |
100 | if (!(fp->formats & (1uLL << subs->pcm_format))) | 65 | if (!(fp->formats & (1uLL << format))) |
101 | continue; | 66 | continue; |
102 | if (fp->channels != subs->channels) | 67 | if (fp->channels != channels) |
103 | continue; | 68 | continue; |
104 | if (subs->cur_rate < fp->rate_min || | 69 | if (rate < fp->rate_min || rate > fp->rate_max) |
105 | subs->cur_rate > fp->rate_max) | ||
106 | continue; | 70 | continue; |
107 | if (! (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)) { | 71 | if (! (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)) { |
108 | unsigned int i; | 72 | unsigned int i; |
109 | for (i = 0; i < fp->nr_rates; i++) | 73 | for (i = 0; i < fp->nr_rates; i++) |
110 | if (fp->rate_table[i] == subs->cur_rate) | 74 | if (fp->rate_table[i] == rate) |
111 | break; | 75 | break; |
112 | if (i >= fp->nr_rates) | 76 | if (i >= fp->nr_rates) |
113 | continue; | 77 | continue; |
@@ -162,7 +126,7 @@ static int init_pitch_v1(struct snd_usb_audio *chip, int iface, | |||
162 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, | 126 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, |
163 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, | 127 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, |
164 | UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, | 128 | UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, |
165 | data, sizeof(data))) < 0) { | 129 | data, sizeof(data), 1000)) < 0) { |
166 | snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n", | 130 | snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n", |
167 | dev->devnum, iface, ep); | 131 | dev->devnum, iface, ep); |
168 | return err; | 132 | return err; |
@@ -177,13 +141,16 @@ static int init_pitch_v2(struct snd_usb_audio *chip, int iface, | |||
177 | { | 141 | { |
178 | struct usb_device *dev = chip->dev; | 142 | struct usb_device *dev = chip->dev; |
179 | unsigned char data[1]; | 143 | unsigned char data[1]; |
144 | unsigned int ep; | ||
180 | int err; | 145 | int err; |
181 | 146 | ||
147 | ep = get_endpoint(alts, 0)->bEndpointAddress; | ||
148 | |||
182 | data[0] = 1; | 149 | data[0] = 1; |
183 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, | 150 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, |
184 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, | 151 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, |
185 | UAC2_EP_CS_PITCH << 8, 0, | 152 | UAC2_EP_CS_PITCH << 8, 0, |
186 | data, sizeof(data))) < 0) { | 153 | data, sizeof(data), 1000)) < 0) { |
187 | snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH (v2)\n", | 154 | snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH (v2)\n", |
188 | dev->devnum, iface, fmt->altsetting); | 155 | dev->devnum, iface, fmt->altsetting); |
189 | return err; | 156 | return err; |
@@ -215,88 +182,6 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, | |||
215 | } | 182 | } |
216 | } | 183 | } |
217 | 184 | ||
218 | static int start_endpoints(struct snd_usb_substream *subs, bool can_sleep) | ||
219 | { | ||
220 | int err; | ||
221 | |||
222 | if (!subs->data_endpoint) | ||
223 | return -EINVAL; | ||
224 | |||
225 | if (!test_and_set_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags)) { | ||
226 | struct snd_usb_endpoint *ep = subs->data_endpoint; | ||
227 | |||
228 | snd_printdd(KERN_DEBUG "Starting data EP @%p\n", ep); | ||
229 | |||
230 | ep->data_subs = subs; | ||
231 | err = snd_usb_endpoint_start(ep, can_sleep); | ||
232 | if (err < 0) { | ||
233 | clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags); | ||
234 | return err; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | if (subs->sync_endpoint && | ||
239 | !test_and_set_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags)) { | ||
240 | struct snd_usb_endpoint *ep = subs->sync_endpoint; | ||
241 | |||
242 | if (subs->data_endpoint->iface != subs->sync_endpoint->iface || | ||
243 | subs->data_endpoint->alt_idx != subs->sync_endpoint->alt_idx) { | ||
244 | err = usb_set_interface(subs->dev, | ||
245 | subs->sync_endpoint->iface, | ||
246 | subs->sync_endpoint->alt_idx); | ||
247 | if (err < 0) { | ||
248 | snd_printk(KERN_ERR | ||
249 | "%d:%d:%d: cannot set interface (%d)\n", | ||
250 | subs->dev->devnum, | ||
251 | subs->sync_endpoint->iface, | ||
252 | subs->sync_endpoint->alt_idx, err); | ||
253 | return -EIO; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | snd_printdd(KERN_DEBUG "Starting sync EP @%p\n", ep); | ||
258 | |||
259 | ep->sync_slave = subs->data_endpoint; | ||
260 | err = snd_usb_endpoint_start(ep, can_sleep); | ||
261 | if (err < 0) { | ||
262 | clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags); | ||
263 | return err; | ||
264 | } | ||
265 | } | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static void stop_endpoints(struct snd_usb_substream *subs, bool wait) | ||
271 | { | ||
272 | if (test_and_clear_bit(SUBSTREAM_FLAG_SYNC_EP_STARTED, &subs->flags)) | ||
273 | snd_usb_endpoint_stop(subs->sync_endpoint); | ||
274 | |||
275 | if (test_and_clear_bit(SUBSTREAM_FLAG_DATA_EP_STARTED, &subs->flags)) | ||
276 | snd_usb_endpoint_stop(subs->data_endpoint); | ||
277 | |||
278 | if (wait) { | ||
279 | snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint); | ||
280 | snd_usb_endpoint_sync_pending_stop(subs->data_endpoint); | ||
281 | } | ||
282 | } | ||
283 | |||
284 | static int deactivate_endpoints(struct snd_usb_substream *subs) | ||
285 | { | ||
286 | int reta, retb; | ||
287 | |||
288 | reta = snd_usb_endpoint_deactivate(subs->sync_endpoint); | ||
289 | retb = snd_usb_endpoint_deactivate(subs->data_endpoint); | ||
290 | |||
291 | if (reta < 0) | ||
292 | return reta; | ||
293 | |||
294 | if (retb < 0) | ||
295 | return retb; | ||
296 | |||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | /* | 185 | /* |
301 | * find a matching format and set up the interface | 186 | * find a matching format and set up the interface |
302 | */ | 187 | */ |
@@ -308,7 +193,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) | |||
308 | struct usb_interface *iface; | 193 | struct usb_interface *iface; |
309 | unsigned int ep, attr; | 194 | unsigned int ep, attr; |
310 | int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; | 195 | int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; |
311 | int err, implicit_fb = 0; | 196 | int err; |
312 | 197 | ||
313 | iface = usb_ifnum_to_if(dev, fmt->iface); | 198 | iface = usb_ifnum_to_if(dev, fmt->iface); |
314 | if (WARN_ON(!iface)) | 199 | if (WARN_ON(!iface)) |
@@ -323,10 +208,9 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) | |||
323 | 208 | ||
324 | /* close the old interface */ | 209 | /* close the old interface */ |
325 | if (subs->interface >= 0 && subs->interface != fmt->iface) { | 210 | if (subs->interface >= 0 && subs->interface != fmt->iface) { |
326 | err = usb_set_interface(subs->dev, subs->interface, 0); | 211 | if (usb_set_interface(subs->dev, subs->interface, 0) < 0) { |
327 | if (err < 0) { | 212 | snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed\n", |
328 | snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed (%d)\n", | 213 | dev->devnum, fmt->iface, fmt->altsetting); |
329 | dev->devnum, fmt->iface, fmt->altsetting, err); | ||
330 | return -EIO; | 214 | return -EIO; |
331 | } | 215 | } |
332 | subs->interface = -1; | 216 | subs->interface = -1; |
@@ -334,25 +218,28 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) | |||
334 | } | 218 | } |
335 | 219 | ||
336 | /* set interface */ | 220 | /* set interface */ |
337 | if (subs->interface != fmt->iface || | 221 | if (subs->interface != fmt->iface || subs->altset_idx != fmt->altset_idx) { |
338 | subs->altset_idx != fmt->altset_idx) { | 222 | if (usb_set_interface(dev, fmt->iface, fmt->altsetting) < 0) { |
339 | err = usb_set_interface(dev, fmt->iface, fmt->altsetting); | 223 | snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed\n", |
340 | if (err < 0) { | 224 | dev->devnum, fmt->iface, fmt->altsetting); |
341 | snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed (%d)\n", | ||
342 | dev->devnum, fmt->iface, fmt->altsetting, err); | ||
343 | return -EIO; | 225 | return -EIO; |
344 | } | 226 | } |
345 | snd_printdd(KERN_INFO "setting usb interface %d:%d\n", | 227 | snd_printdd(KERN_INFO "setting usb interface %d:%d\n", fmt->iface, fmt->altsetting); |
346 | fmt->iface, fmt->altsetting); | ||
347 | subs->interface = fmt->iface; | 228 | subs->interface = fmt->iface; |
348 | subs->altset_idx = fmt->altset_idx; | 229 | subs->altset_idx = fmt->altset_idx; |
349 | } | 230 | } |
350 | 231 | ||
351 | subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip, | 232 | /* create a data pipe */ |
352 | alts, fmt->endpoint, subs->direction, | 233 | ep = fmt->endpoint & USB_ENDPOINT_NUMBER_MASK; |
353 | SND_USB_ENDPOINT_TYPE_DATA); | 234 | if (is_playback) |
354 | if (!subs->data_endpoint) | 235 | subs->datapipe = usb_sndisocpipe(dev, ep); |
355 | return -EINVAL; | 236 | else |
237 | subs->datapipe = usb_rcvisocpipe(dev, ep); | ||
238 | subs->datainterval = fmt->datainterval; | ||
239 | subs->syncpipe = subs->syncinterval = 0; | ||
240 | subs->maxpacksize = fmt->maxpacksize; | ||
241 | subs->syncmaxsize = 0; | ||
242 | subs->fill_max = 0; | ||
356 | 243 | ||
357 | /* we need a sync pipe in async OUT or adaptive IN mode */ | 244 | /* we need a sync pipe in async OUT or adaptive IN mode */ |
358 | /* check the number of EP, since some devices have broken | 245 | /* check the number of EP, since some devices have broken |
@@ -360,81 +247,52 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) | |||
360 | * assume it as adaptive-out or sync-in. | 247 | * assume it as adaptive-out or sync-in. |
361 | */ | 248 | */ |
362 | attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE; | 249 | attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE; |
363 | |||
364 | switch (subs->stream->chip->usb_id) { | ||
365 | case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */ | ||
366 | if (is_playback) { | ||
367 | implicit_fb = 1; | ||
368 | ep = 0x81; | ||
369 | iface = usb_ifnum_to_if(dev, 3); | ||
370 | |||
371 | if (!iface || iface->num_altsetting == 0) | ||
372 | return -EINVAL; | ||
373 | |||
374 | alts = &iface->altsetting[1]; | ||
375 | goto add_sync_ep; | ||
376 | } | ||
377 | break; | ||
378 | case USB_ID(0x0763, 0x2080): /* M-Audio FastTrack Ultra */ | ||
379 | case USB_ID(0x0763, 0x2081): | ||
380 | if (is_playback) { | ||
381 | implicit_fb = 1; | ||
382 | ep = 0x81; | ||
383 | iface = usb_ifnum_to_if(dev, 2); | ||
384 | |||
385 | if (!iface || iface->num_altsetting == 0) | ||
386 | return -EINVAL; | ||
387 | |||
388 | alts = &iface->altsetting[1]; | ||
389 | goto add_sync_ep; | ||
390 | } | ||
391 | } | ||
392 | |||
393 | if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) || | 250 | if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) || |
394 | (!is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) && | 251 | (! is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) && |
395 | altsd->bNumEndpoints >= 2) { | 252 | altsd->bNumEndpoints >= 2) { |
396 | /* check sync-pipe endpoint */ | 253 | /* check sync-pipe endpoint */ |
397 | /* ... and check descriptor size before accessing bSynchAddress | 254 | /* ... and check descriptor size before accessing bSynchAddress |
398 | because there is a version of the SB Audigy 2 NX firmware lacking | 255 | because there is a version of the SB Audigy 2 NX firmware lacking |
399 | the audio fields in the endpoint descriptors */ | 256 | the audio fields in the endpoint descriptors */ |
400 | if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC || | 257 | if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 0x01 || |
401 | (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && | 258 | (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && |
402 | get_endpoint(alts, 1)->bSynchAddress != 0 && | 259 | get_endpoint(alts, 1)->bSynchAddress != 0)) { |
403 | !implicit_fb)) { | 260 | snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n", |
404 | snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. bmAttributes %02x, bLength %d, bSynchAddress %02x\n", | 261 | dev->devnum, fmt->iface, fmt->altsetting); |
405 | dev->devnum, fmt->iface, fmt->altsetting, | ||
406 | get_endpoint(alts, 1)->bmAttributes, | ||
407 | get_endpoint(alts, 1)->bLength, | ||
408 | get_endpoint(alts, 1)->bSynchAddress); | ||
409 | return -EINVAL; | 262 | return -EINVAL; |
410 | } | 263 | } |
411 | ep = get_endpoint(alts, 1)->bEndpointAddress; | 264 | ep = get_endpoint(alts, 1)->bEndpointAddress; |
412 | if (!implicit_fb && | 265 | if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && |
413 | get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && | ||
414 | (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) || | 266 | (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) || |
415 | (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) { | 267 | (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) { |
416 | snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. is_playback %d, ep %02x, bSynchAddress %02x\n", | 268 | snd_printk(KERN_ERR "%d:%d:%d : invalid synch pipe\n", |
417 | dev->devnum, fmt->iface, fmt->altsetting, | 269 | dev->devnum, fmt->iface, fmt->altsetting); |
418 | is_playback, ep, get_endpoint(alts, 0)->bSynchAddress); | ||
419 | return -EINVAL; | 270 | return -EINVAL; |
420 | } | 271 | } |
421 | 272 | ep &= USB_ENDPOINT_NUMBER_MASK; | |
422 | implicit_fb = (get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_USAGE_MASK) | 273 | if (is_playback) |
423 | == USB_ENDPOINT_USAGE_IMPLICIT_FB; | 274 | subs->syncpipe = usb_rcvisocpipe(dev, ep); |
424 | 275 | else | |
425 | add_sync_ep: | 276 | subs->syncpipe = usb_sndisocpipe(dev, ep); |
426 | subs->sync_endpoint = snd_usb_add_endpoint(subs->stream->chip, | 277 | if (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && |
427 | alts, ep, !subs->direction, | 278 | get_endpoint(alts, 1)->bRefresh >= 1 && |
428 | implicit_fb ? | 279 | get_endpoint(alts, 1)->bRefresh <= 9) |
429 | SND_USB_ENDPOINT_TYPE_DATA : | 280 | subs->syncinterval = get_endpoint(alts, 1)->bRefresh; |
430 | SND_USB_ENDPOINT_TYPE_SYNC); | 281 | else if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) |
431 | if (!subs->sync_endpoint) | 282 | subs->syncinterval = 1; |
432 | return -EINVAL; | 283 | else if (get_endpoint(alts, 1)->bInterval >= 1 && |
433 | 284 | get_endpoint(alts, 1)->bInterval <= 16) | |
434 | subs->data_endpoint->sync_master = subs->sync_endpoint; | 285 | subs->syncinterval = get_endpoint(alts, 1)->bInterval - 1; |
286 | else | ||
287 | subs->syncinterval = 3; | ||
288 | subs->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize); | ||
435 | } | 289 | } |
436 | 290 | ||
437 | if ((err = snd_usb_init_pitch(subs->stream->chip, fmt->iface, alts, fmt)) < 0) | 291 | /* always fill max packet size */ |
292 | if (fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX) | ||
293 | subs->fill_max = 1; | ||
294 | |||
295 | if ((err = snd_usb_init_pitch(subs->stream->chip, subs->interface, alts, fmt)) < 0) | ||
438 | return err; | 296 | return err; |
439 | 297 | ||
440 | subs->cur_audiofmt = fmt; | 298 | subs->cur_audiofmt = fmt; |
@@ -454,140 +312,6 @@ add_sync_ep: | |||
454 | } | 312 | } |
455 | 313 | ||
456 | /* | 314 | /* |
457 | * Return the score of matching two audioformats. | ||
458 | * Veto the audioformat if: | ||
459 | * - It has no channels for some reason. | ||
460 | * - Requested PCM format is not supported. | ||
461 | * - Requested sample rate is not supported. | ||
462 | */ | ||
463 | static int match_endpoint_audioformats(struct audioformat *fp, | ||
464 | struct audioformat *match, int rate, | ||
465 | snd_pcm_format_t pcm_format) | ||
466 | { | ||
467 | int i; | ||
468 | int score = 0; | ||
469 | |||
470 | if (fp->channels < 1) { | ||
471 | snd_printdd("%s: (fmt @%p) no channels\n", __func__, fp); | ||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | if (!(fp->formats & (1ULL << pcm_format))) { | ||
476 | snd_printdd("%s: (fmt @%p) no match for format %d\n", __func__, | ||
477 | fp, pcm_format); | ||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | for (i = 0; i < fp->nr_rates; i++) { | ||
482 | if (fp->rate_table[i] == rate) { | ||
483 | score++; | ||
484 | break; | ||
485 | } | ||
486 | } | ||
487 | if (!score) { | ||
488 | snd_printdd("%s: (fmt @%p) no match for rate %d\n", __func__, | ||
489 | fp, rate); | ||
490 | return 0; | ||
491 | } | ||
492 | |||
493 | if (fp->channels == match->channels) | ||
494 | score++; | ||
495 | |||
496 | snd_printdd("%s: (fmt @%p) score %d\n", __func__, fp, score); | ||
497 | |||
498 | return score; | ||
499 | } | ||
500 | |||
501 | /* | ||
502 | * Configure the sync ep using the rate and pcm format of the data ep. | ||
503 | */ | ||
504 | static int configure_sync_endpoint(struct snd_usb_substream *subs) | ||
505 | { | ||
506 | int ret; | ||
507 | struct audioformat *fp; | ||
508 | struct audioformat *sync_fp = NULL; | ||
509 | int cur_score = 0; | ||
510 | int sync_period_bytes = subs->period_bytes; | ||
511 | struct snd_usb_substream *sync_subs = | ||
512 | &subs->stream->substream[subs->direction ^ 1]; | ||
513 | |||
514 | if (subs->sync_endpoint->type != SND_USB_ENDPOINT_TYPE_DATA || | ||
515 | !subs->stream) | ||
516 | return snd_usb_endpoint_set_params(subs->sync_endpoint, | ||
517 | subs->pcm_format, | ||
518 | subs->channels, | ||
519 | subs->period_bytes, | ||
520 | subs->cur_rate, | ||
521 | subs->cur_audiofmt, | ||
522 | NULL); | ||
523 | |||
524 | /* Try to find the best matching audioformat. */ | ||
525 | list_for_each_entry(fp, &sync_subs->fmt_list, list) { | ||
526 | int score = match_endpoint_audioformats(fp, subs->cur_audiofmt, | ||
527 | subs->cur_rate, subs->pcm_format); | ||
528 | |||
529 | if (score > cur_score) { | ||
530 | sync_fp = fp; | ||
531 | cur_score = score; | ||
532 | } | ||
533 | } | ||
534 | |||
535 | if (unlikely(sync_fp == NULL)) { | ||
536 | snd_printk(KERN_ERR "%s: no valid audioformat for sync ep %x found\n", | ||
537 | __func__, sync_subs->ep_num); | ||
538 | return -EINVAL; | ||
539 | } | ||
540 | |||
541 | /* | ||
542 | * Recalculate the period bytes if channel number differ between | ||
543 | * data and sync ep audioformat. | ||
544 | */ | ||
545 | if (sync_fp->channels != subs->channels) { | ||
546 | sync_period_bytes = (subs->period_bytes / subs->channels) * | ||
547 | sync_fp->channels; | ||
548 | snd_printdd("%s: adjusted sync ep period bytes (%d -> %d)\n", | ||
549 | __func__, subs->period_bytes, sync_period_bytes); | ||
550 | } | ||
551 | |||
552 | ret = snd_usb_endpoint_set_params(subs->sync_endpoint, | ||
553 | subs->pcm_format, | ||
554 | sync_fp->channels, | ||
555 | sync_period_bytes, | ||
556 | subs->cur_rate, | ||
557 | sync_fp, | ||
558 | NULL); | ||
559 | |||
560 | return ret; | ||
561 | } | ||
562 | |||
563 | /* | ||
564 | * configure endpoint params | ||
565 | * | ||
566 | * called during initial setup and upon resume | ||
567 | */ | ||
568 | static int configure_endpoint(struct snd_usb_substream *subs) | ||
569 | { | ||
570 | int ret; | ||
571 | |||
572 | /* format changed */ | ||
573 | stop_endpoints(subs, true); | ||
574 | ret = snd_usb_endpoint_set_params(subs->data_endpoint, | ||
575 | subs->pcm_format, | ||
576 | subs->channels, | ||
577 | subs->period_bytes, | ||
578 | subs->cur_rate, | ||
579 | subs->cur_audiofmt, | ||
580 | subs->sync_endpoint); | ||
581 | if (ret < 0) | ||
582 | return ret; | ||
583 | |||
584 | if (subs->sync_endpoint) | ||
585 | ret = configure_sync_endpoint(subs); | ||
586 | |||
587 | return ret; | ||
588 | } | ||
589 | |||
590 | /* | ||
591 | * hw_params callback | 315 | * hw_params callback |
592 | * | 316 | * |
593 | * allocate a buffer and set the given audio format. | 317 | * allocate a buffer and set the given audio format. |
@@ -602,39 +326,54 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, | |||
602 | { | 326 | { |
603 | struct snd_usb_substream *subs = substream->runtime->private_data; | 327 | struct snd_usb_substream *subs = substream->runtime->private_data; |
604 | struct audioformat *fmt; | 328 | struct audioformat *fmt; |
605 | int ret; | 329 | unsigned int channels, rate, format; |
330 | int ret, changed; | ||
606 | 331 | ||
607 | ret = snd_pcm_lib_alloc_vmalloc_buffer(substream, | 332 | ret = snd_pcm_lib_alloc_vmalloc_buffer(substream, |
608 | params_buffer_bytes(hw_params)); | 333 | params_buffer_bytes(hw_params)); |
609 | if (ret < 0) | 334 | if (ret < 0) |
610 | return ret; | 335 | return ret; |
611 | 336 | ||
612 | subs->pcm_format = params_format(hw_params); | 337 | format = params_format(hw_params); |
613 | subs->period_bytes = params_period_bytes(hw_params); | 338 | rate = params_rate(hw_params); |
614 | subs->channels = params_channels(hw_params); | 339 | channels = params_channels(hw_params); |
615 | subs->cur_rate = params_rate(hw_params); | 340 | fmt = find_format(subs, format, rate, channels); |
616 | |||
617 | fmt = find_format(subs); | ||
618 | if (!fmt) { | 341 | if (!fmt) { |
619 | snd_printd(KERN_DEBUG "cannot set format: format = %#x, rate = %d, channels = %d\n", | 342 | snd_printd(KERN_DEBUG "cannot set format: format = %#x, rate = %d, channels = %d\n", |
620 | subs->pcm_format, subs->cur_rate, subs->channels); | 343 | format, rate, channels); |
621 | return -EINVAL; | 344 | return -EINVAL; |
622 | } | 345 | } |
623 | 346 | ||
624 | down_read(&subs->stream->chip->shutdown_rwsem); | 347 | changed = subs->cur_audiofmt != fmt || |
625 | if (subs->stream->chip->shutdown) | 348 | subs->period_bytes != params_period_bytes(hw_params) || |
626 | ret = -ENODEV; | 349 | subs->cur_rate != rate; |
627 | else | 350 | if ((ret = set_format(subs, fmt)) < 0) |
628 | ret = set_format(subs, fmt); | ||
629 | up_read(&subs->stream->chip->shutdown_rwsem); | ||
630 | if (ret < 0) | ||
631 | return ret; | 351 | return ret; |
632 | 352 | ||
633 | subs->interface = fmt->iface; | 353 | if (subs->cur_rate != rate) { |
634 | subs->altset_idx = fmt->altset_idx; | 354 | struct usb_host_interface *alts; |
635 | subs->need_setup_ep = true; | 355 | struct usb_interface *iface; |
356 | iface = usb_ifnum_to_if(subs->dev, fmt->iface); | ||
357 | alts = &iface->altsetting[fmt->altset_idx]; | ||
358 | ret = snd_usb_init_sample_rate(subs->stream->chip, subs->interface, alts, fmt, rate); | ||
359 | if (ret < 0) | ||
360 | return ret; | ||
361 | subs->cur_rate = rate; | ||
362 | } | ||
636 | 363 | ||
637 | return 0; | 364 | if (changed) { |
365 | mutex_lock(&subs->stream->chip->shutdown_mutex); | ||
366 | /* format changed */ | ||
367 | snd_usb_release_substream_urbs(subs, 0); | ||
368 | /* influenced: period_bytes, channels, rate, format, */ | ||
369 | ret = snd_usb_init_substream_urbs(subs, params_period_bytes(hw_params), | ||
370 | params_rate(hw_params), | ||
371 | snd_pcm_format_physical_width(params_format(hw_params)) * | ||
372 | params_channels(hw_params)); | ||
373 | mutex_unlock(&subs->stream->chip->shutdown_mutex); | ||
374 | } | ||
375 | |||
376 | return ret; | ||
638 | } | 377 | } |
639 | 378 | ||
640 | /* | 379 | /* |
@@ -649,12 +388,9 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) | |||
649 | subs->cur_audiofmt = NULL; | 388 | subs->cur_audiofmt = NULL; |
650 | subs->cur_rate = 0; | 389 | subs->cur_rate = 0; |
651 | subs->period_bytes = 0; | 390 | subs->period_bytes = 0; |
652 | down_read(&subs->stream->chip->shutdown_rwsem); | 391 | mutex_lock(&subs->stream->chip->shutdown_mutex); |
653 | if (!subs->stream->chip->shutdown) { | 392 | snd_usb_release_substream_urbs(subs, 0); |
654 | stop_endpoints(subs, true); | 393 | mutex_unlock(&subs->stream->chip->shutdown_mutex); |
655 | deactivate_endpoints(subs); | ||
656 | } | ||
657 | up_read(&subs->stream->chip->shutdown_rwsem); | ||
658 | return snd_pcm_lib_free_vmalloc_buffer(substream); | 394 | return snd_pcm_lib_free_vmalloc_buffer(substream); |
659 | } | 395 | } |
660 | 396 | ||
@@ -667,70 +403,23 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) | |||
667 | { | 403 | { |
668 | struct snd_pcm_runtime *runtime = substream->runtime; | 404 | struct snd_pcm_runtime *runtime = substream->runtime; |
669 | struct snd_usb_substream *subs = runtime->private_data; | 405 | struct snd_usb_substream *subs = runtime->private_data; |
670 | struct usb_host_interface *alts; | ||
671 | struct usb_interface *iface; | ||
672 | int ret; | ||
673 | 406 | ||
674 | if (! subs->cur_audiofmt) { | 407 | if (! subs->cur_audiofmt) { |
675 | snd_printk(KERN_ERR "usbaudio: no format is specified!\n"); | 408 | snd_printk(KERN_ERR "usbaudio: no format is specified!\n"); |
676 | return -ENXIO; | 409 | return -ENXIO; |
677 | } | 410 | } |
678 | 411 | ||
679 | down_read(&subs->stream->chip->shutdown_rwsem); | ||
680 | if (subs->stream->chip->shutdown) { | ||
681 | ret = -ENODEV; | ||
682 | goto unlock; | ||
683 | } | ||
684 | if (snd_BUG_ON(!subs->data_endpoint)) { | ||
685 | ret = -EIO; | ||
686 | goto unlock; | ||
687 | } | ||
688 | |||
689 | snd_usb_endpoint_sync_pending_stop(subs->sync_endpoint); | ||
690 | snd_usb_endpoint_sync_pending_stop(subs->data_endpoint); | ||
691 | |||
692 | ret = set_format(subs, subs->cur_audiofmt); | ||
693 | if (ret < 0) | ||
694 | goto unlock; | ||
695 | |||
696 | iface = usb_ifnum_to_if(subs->dev, subs->cur_audiofmt->iface); | ||
697 | alts = &iface->altsetting[subs->cur_audiofmt->altset_idx]; | ||
698 | ret = snd_usb_init_sample_rate(subs->stream->chip, | ||
699 | subs->cur_audiofmt->iface, | ||
700 | alts, | ||
701 | subs->cur_audiofmt, | ||
702 | subs->cur_rate); | ||
703 | if (ret < 0) | ||
704 | goto unlock; | ||
705 | |||
706 | if (subs->need_setup_ep) { | ||
707 | ret = configure_endpoint(subs); | ||
708 | if (ret < 0) | ||
709 | goto unlock; | ||
710 | subs->need_setup_ep = false; | ||
711 | } | ||
712 | |||
713 | /* some unit conversions in runtime */ | 412 | /* some unit conversions in runtime */ |
714 | subs->data_endpoint->maxframesize = | 413 | subs->maxframesize = bytes_to_frames(runtime, subs->maxpacksize); |
715 | bytes_to_frames(runtime, subs->data_endpoint->maxpacksize); | 414 | subs->curframesize = bytes_to_frames(runtime, subs->curpacksize); |
716 | subs->data_endpoint->curframesize = | ||
717 | bytes_to_frames(runtime, subs->data_endpoint->curpacksize); | ||
718 | 415 | ||
719 | /* reset the pointer */ | 416 | /* reset the pointer */ |
720 | subs->hwptr_done = 0; | 417 | subs->hwptr_done = 0; |
721 | subs->transfer_done = 0; | 418 | subs->transfer_done = 0; |
722 | subs->last_delay = 0; | 419 | subs->phase = 0; |
723 | subs->last_frame_number = 0; | ||
724 | runtime->delay = 0; | 420 | runtime->delay = 0; |
725 | 421 | ||
726 | /* for playback, submit the URBs now; otherwise, the first hwptr_done | 422 | return snd_usb_substream_prepare(subs, runtime); |
727 | * updates for all URBs would happen at the same time when starting */ | ||
728 | if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) | ||
729 | ret = start_endpoints(subs, true); | ||
730 | |||
731 | unlock: | ||
732 | up_read(&subs->stream->chip->shutdown_rwsem); | ||
733 | return ret; | ||
734 | } | 423 | } |
735 | 424 | ||
736 | static struct snd_pcm_hardware snd_usb_hardware = | 425 | static struct snd_pcm_hardware snd_usb_hardware = |
@@ -783,7 +472,7 @@ static int hw_check_valid_format(struct snd_usb_substream *subs, | |||
783 | return 0; | 472 | return 0; |
784 | } | 473 | } |
785 | /* check whether the period time is >= the data packet interval */ | 474 | /* check whether the period time is >= the data packet interval */ |
786 | if (subs->speed != USB_SPEED_FULL) { | 475 | if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) { |
787 | ptime = 125 * (1 << fp->datainterval); | 476 | ptime = 125 * (1 << fp->datainterval); |
788 | if (ptime > pt->max || (ptime == pt->max && pt->openmax)) { | 477 | if (ptime > pt->max || (ptime == pt->max && pt->openmax)) { |
789 | hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max); | 478 | hwc_debug(" > check: ptime %u > max %u\n", ptime, pt->max); |
@@ -978,13 +667,9 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, | |||
978 | struct snd_usb_substream *subs) | 667 | struct snd_usb_substream *subs) |
979 | { | 668 | { |
980 | struct audioformat *fp; | 669 | struct audioformat *fp; |
981 | int *rate_list; | ||
982 | int count = 0, needs_knot = 0; | 670 | int count = 0, needs_knot = 0; |
983 | int err; | 671 | int err; |
984 | 672 | ||
985 | kfree(subs->rate_list.list); | ||
986 | subs->rate_list.list = NULL; | ||
987 | |||
988 | list_for_each_entry(fp, &subs->fmt_list, list) { | 673 | list_for_each_entry(fp, &subs->fmt_list, list) { |
989 | if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) | 674 | if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) |
990 | return 0; | 675 | return 0; |
@@ -995,8 +680,7 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, | |||
995 | if (!needs_knot) | 680 | if (!needs_knot) |
996 | return 0; | 681 | return 0; |
997 | 682 | ||
998 | subs->rate_list.list = rate_list = | 683 | subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL); |
999 | kmalloc(sizeof(int) * count, GFP_KERNEL); | ||
1000 | if (!subs->rate_list.list) | 684 | if (!subs->rate_list.list) |
1001 | return -ENOMEM; | 685 | return -ENOMEM; |
1002 | subs->rate_list.count = count; | 686 | subs->rate_list.count = count; |
@@ -1005,7 +689,7 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, | |||
1005 | list_for_each_entry(fp, &subs->fmt_list, list) { | 689 | list_for_each_entry(fp, &subs->fmt_list, list) { |
1006 | int i; | 690 | int i; |
1007 | for (i = 0; i < fp->nr_rates; i++) | 691 | for (i = 0; i < fp->nr_rates; i++) |
1008 | rate_list[count++] = fp->rate_table[i]; | 692 | subs->rate_list.list[count++] = fp->rate_table[i]; |
1009 | } | 693 | } |
1010 | err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 694 | err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
1011 | &subs->rate_list); | 695 | &subs->rate_list); |
@@ -1061,7 +745,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre | |||
1061 | return err; | 745 | return err; |
1062 | 746 | ||
1063 | param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; | 747 | param_period_time_if_needed = SNDRV_PCM_HW_PARAM_PERIOD_TIME; |
1064 | if (subs->speed == USB_SPEED_FULL) | 748 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) |
1065 | /* full speed devices have fixed data packet interval */ | 749 | /* full speed devices have fixed data packet interval */ |
1066 | ptmin = 1000; | 750 | ptmin = 1000; |
1067 | if (ptmin == 1000) | 751 | if (ptmin == 1000) |
@@ -1131,220 +815,15 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) | |||
1131 | struct snd_usb_stream *as = snd_pcm_substream_chip(substream); | 815 | struct snd_usb_stream *as = snd_pcm_substream_chip(substream); |
1132 | struct snd_usb_substream *subs = &as->substream[direction]; | 816 | struct snd_usb_substream *subs = &as->substream[direction]; |
1133 | 817 | ||
1134 | stop_endpoints(subs, true); | ||
1135 | |||
1136 | if (!as->chip->shutdown && subs->interface >= 0) { | 818 | if (!as->chip->shutdown && subs->interface >= 0) { |
1137 | usb_set_interface(subs->dev, subs->interface, 0); | 819 | usb_set_interface(subs->dev, subs->interface, 0); |
1138 | subs->interface = -1; | 820 | subs->interface = -1; |
1139 | } | 821 | } |
1140 | |||
1141 | subs->pcm_substream = NULL; | 822 | subs->pcm_substream = NULL; |
1142 | snd_usb_autosuspend(subs->stream->chip); | 823 | snd_usb_autosuspend(subs->stream->chip); |
1143 | |||
1144 | return 0; | 824 | return 0; |
1145 | } | 825 | } |
1146 | 826 | ||
1147 | /* Since a URB can handle only a single linear buffer, we must use double | ||
1148 | * buffering when the data to be transferred overflows the buffer boundary. | ||
1149 | * To avoid inconsistencies when updating hwptr_done, we use double buffering | ||
1150 | * for all URBs. | ||
1151 | */ | ||
1152 | static void retire_capture_urb(struct snd_usb_substream *subs, | ||
1153 | struct urb *urb) | ||
1154 | { | ||
1155 | struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; | ||
1156 | unsigned int stride, frames, bytes, oldptr; | ||
1157 | int i, period_elapsed = 0; | ||
1158 | unsigned long flags; | ||
1159 | unsigned char *cp; | ||
1160 | |||
1161 | stride = runtime->frame_bits >> 3; | ||
1162 | |||
1163 | for (i = 0; i < urb->number_of_packets; i++) { | ||
1164 | cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset; | ||
1165 | if (urb->iso_frame_desc[i].status && printk_ratelimit()) { | ||
1166 | snd_printdd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status); | ||
1167 | // continue; | ||
1168 | } | ||
1169 | bytes = urb->iso_frame_desc[i].actual_length; | ||
1170 | frames = bytes / stride; | ||
1171 | if (!subs->txfr_quirk) | ||
1172 | bytes = frames * stride; | ||
1173 | if (bytes % (runtime->sample_bits >> 3) != 0) { | ||
1174 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
1175 | int oldbytes = bytes; | ||
1176 | #endif | ||
1177 | bytes = frames * stride; | ||
1178 | snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n", | ||
1179 | oldbytes, bytes); | ||
1180 | } | ||
1181 | /* update the current pointer */ | ||
1182 | spin_lock_irqsave(&subs->lock, flags); | ||
1183 | oldptr = subs->hwptr_done; | ||
1184 | subs->hwptr_done += bytes; | ||
1185 | if (subs->hwptr_done >= runtime->buffer_size * stride) | ||
1186 | subs->hwptr_done -= runtime->buffer_size * stride; | ||
1187 | frames = (bytes + (oldptr % stride)) / stride; | ||
1188 | subs->transfer_done += frames; | ||
1189 | if (subs->transfer_done >= runtime->period_size) { | ||
1190 | subs->transfer_done -= runtime->period_size; | ||
1191 | period_elapsed = 1; | ||
1192 | } | ||
1193 | spin_unlock_irqrestore(&subs->lock, flags); | ||
1194 | /* copy a data chunk */ | ||
1195 | if (oldptr + bytes > runtime->buffer_size * stride) { | ||
1196 | unsigned int bytes1 = | ||
1197 | runtime->buffer_size * stride - oldptr; | ||
1198 | memcpy(runtime->dma_area + oldptr, cp, bytes1); | ||
1199 | memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1); | ||
1200 | } else { | ||
1201 | memcpy(runtime->dma_area + oldptr, cp, bytes); | ||
1202 | } | ||
1203 | } | ||
1204 | |||
1205 | if (period_elapsed) | ||
1206 | snd_pcm_period_elapsed(subs->pcm_substream); | ||
1207 | } | ||
1208 | |||
1209 | static void prepare_playback_urb(struct snd_usb_substream *subs, | ||
1210 | struct urb *urb) | ||
1211 | { | ||
1212 | struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; | ||
1213 | struct snd_usb_endpoint *ep = subs->data_endpoint; | ||
1214 | struct snd_urb_ctx *ctx = urb->context; | ||
1215 | unsigned int counts, frames, bytes; | ||
1216 | int i, stride, period_elapsed = 0; | ||
1217 | unsigned long flags; | ||
1218 | |||
1219 | stride = runtime->frame_bits >> 3; | ||
1220 | |||
1221 | frames = 0; | ||
1222 | urb->number_of_packets = 0; | ||
1223 | spin_lock_irqsave(&subs->lock, flags); | ||
1224 | for (i = 0; i < ctx->packets; i++) { | ||
1225 | if (ctx->packet_size[i]) | ||
1226 | counts = ctx->packet_size[i]; | ||
1227 | else | ||
1228 | counts = snd_usb_endpoint_next_packet_size(ep); | ||
1229 | |||
1230 | /* set up descriptor */ | ||
1231 | urb->iso_frame_desc[i].offset = frames * stride; | ||
1232 | urb->iso_frame_desc[i].length = counts * stride; | ||
1233 | frames += counts; | ||
1234 | urb->number_of_packets++; | ||
1235 | subs->transfer_done += counts; | ||
1236 | if (subs->transfer_done >= runtime->period_size) { | ||
1237 | subs->transfer_done -= runtime->period_size; | ||
1238 | period_elapsed = 1; | ||
1239 | if (subs->fmt_type == UAC_FORMAT_TYPE_II) { | ||
1240 | if (subs->transfer_done > 0) { | ||
1241 | /* FIXME: fill-max mode is not | ||
1242 | * supported yet */ | ||
1243 | frames -= subs->transfer_done; | ||
1244 | counts -= subs->transfer_done; | ||
1245 | urb->iso_frame_desc[i].length = | ||
1246 | counts * stride; | ||
1247 | subs->transfer_done = 0; | ||
1248 | } | ||
1249 | i++; | ||
1250 | if (i < ctx->packets) { | ||
1251 | /* add a transfer delimiter */ | ||
1252 | urb->iso_frame_desc[i].offset = | ||
1253 | frames * stride; | ||
1254 | urb->iso_frame_desc[i].length = 0; | ||
1255 | urb->number_of_packets++; | ||
1256 | } | ||
1257 | break; | ||
1258 | } | ||
1259 | } | ||
1260 | if (period_elapsed && | ||
1261 | !snd_usb_endpoint_implict_feedback_sink(subs->data_endpoint)) /* finish at the period boundary */ | ||
1262 | break; | ||
1263 | } | ||
1264 | bytes = frames * stride; | ||
1265 | if (subs->hwptr_done + bytes > runtime->buffer_size * stride) { | ||
1266 | /* err, the transferred area goes over buffer boundary. */ | ||
1267 | unsigned int bytes1 = | ||
1268 | runtime->buffer_size * stride - subs->hwptr_done; | ||
1269 | memcpy(urb->transfer_buffer, | ||
1270 | runtime->dma_area + subs->hwptr_done, bytes1); | ||
1271 | memcpy(urb->transfer_buffer + bytes1, | ||
1272 | runtime->dma_area, bytes - bytes1); | ||
1273 | } else { | ||
1274 | memcpy(urb->transfer_buffer, | ||
1275 | runtime->dma_area + subs->hwptr_done, bytes); | ||
1276 | } | ||
1277 | subs->hwptr_done += bytes; | ||
1278 | if (subs->hwptr_done >= runtime->buffer_size * stride) | ||
1279 | subs->hwptr_done -= runtime->buffer_size * stride; | ||
1280 | |||
1281 | /* update delay with exact number of samples queued */ | ||
1282 | runtime->delay = subs->last_delay; | ||
1283 | runtime->delay += frames; | ||
1284 | subs->last_delay = runtime->delay; | ||
1285 | |||
1286 | /* realign last_frame_number */ | ||
1287 | subs->last_frame_number = usb_get_current_frame_number(subs->dev); | ||
1288 | subs->last_frame_number &= 0xFF; /* keep 8 LSBs */ | ||
1289 | |||
1290 | spin_unlock_irqrestore(&subs->lock, flags); | ||
1291 | urb->transfer_buffer_length = bytes; | ||
1292 | if (period_elapsed) | ||
1293 | snd_pcm_period_elapsed(subs->pcm_substream); | ||
1294 | } | ||
1295 | |||
1296 | /* | ||
1297 | * process after playback data complete | ||
1298 | * - decrease the delay count again | ||
1299 | */ | ||
1300 | static void retire_playback_urb(struct snd_usb_substream *subs, | ||
1301 | struct urb *urb) | ||
1302 | { | ||
1303 | unsigned long flags; | ||
1304 | struct snd_pcm_runtime *runtime = subs->pcm_substream->runtime; | ||
1305 | int stride = runtime->frame_bits >> 3; | ||
1306 | int processed = urb->transfer_buffer_length / stride; | ||
1307 | int est_delay; | ||
1308 | |||
1309 | /* ignore the delay accounting when procssed=0 is given, i.e. | ||
1310 | * silent payloads are procssed before handling the actual data | ||
1311 | */ | ||
1312 | if (!processed) | ||
1313 | return; | ||
1314 | |||
1315 | spin_lock_irqsave(&subs->lock, flags); | ||
1316 | if (!subs->last_delay) | ||
1317 | goto out; /* short path */ | ||
1318 | |||
1319 | est_delay = snd_usb_pcm_delay(subs, runtime->rate); | ||
1320 | /* update delay with exact number of samples played */ | ||
1321 | if (processed > subs->last_delay) | ||
1322 | subs->last_delay = 0; | ||
1323 | else | ||
1324 | subs->last_delay -= processed; | ||
1325 | runtime->delay = subs->last_delay; | ||
1326 | |||
1327 | /* | ||
1328 | * Report when delay estimate is off by more than 2ms. | ||
1329 | * The error should be lower than 2ms since the estimate relies | ||
1330 | * on two reads of a counter updated every ms. | ||
1331 | */ | ||
1332 | if (abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2) | ||
1333 | snd_printk(KERN_DEBUG "delay: estimated %d, actual %d\n", | ||
1334 | est_delay, subs->last_delay); | ||
1335 | |||
1336 | if (!subs->running) { | ||
1337 | /* update last_frame_number for delay counting here since | ||
1338 | * prepare_playback_urb won't be called during pause | ||
1339 | */ | ||
1340 | subs->last_frame_number = | ||
1341 | usb_get_current_frame_number(subs->dev) & 0xff; | ||
1342 | } | ||
1343 | |||
1344 | out: | ||
1345 | spin_unlock_irqrestore(&subs->lock, flags); | ||
1346 | } | ||
1347 | |||
1348 | static int snd_usb_playback_open(struct snd_pcm_substream *substream) | 827 | static int snd_usb_playback_open(struct snd_pcm_substream *substream) |
1349 | { | 828 | { |
1350 | return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK); | 829 | return snd_usb_pcm_open(substream, SNDRV_PCM_STREAM_PLAYBACK); |
@@ -1365,65 +844,6 @@ static int snd_usb_capture_close(struct snd_pcm_substream *substream) | |||
1365 | return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_CAPTURE); | 844 | return snd_usb_pcm_close(substream, SNDRV_PCM_STREAM_CAPTURE); |
1366 | } | 845 | } |
1367 | 846 | ||
1368 | static int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, | ||
1369 | int cmd) | ||
1370 | { | ||
1371 | struct snd_usb_substream *subs = substream->runtime->private_data; | ||
1372 | |||
1373 | switch (cmd) { | ||
1374 | case SNDRV_PCM_TRIGGER_START: | ||
1375 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
1376 | subs->data_endpoint->prepare_data_urb = prepare_playback_urb; | ||
1377 | subs->data_endpoint->retire_data_urb = retire_playback_urb; | ||
1378 | subs->running = 1; | ||
1379 | return 0; | ||
1380 | case SNDRV_PCM_TRIGGER_STOP: | ||
1381 | stop_endpoints(subs, false); | ||
1382 | subs->running = 0; | ||
1383 | return 0; | ||
1384 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
1385 | subs->data_endpoint->prepare_data_urb = NULL; | ||
1386 | /* keep retire_data_urb for delay calculation */ | ||
1387 | subs->data_endpoint->retire_data_urb = retire_playback_urb; | ||
1388 | subs->running = 0; | ||
1389 | return 0; | ||
1390 | } | ||
1391 | |||
1392 | return -EINVAL; | ||
1393 | } | ||
1394 | |||
1395 | static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, | ||
1396 | int cmd) | ||
1397 | { | ||
1398 | int err; | ||
1399 | struct snd_usb_substream *subs = substream->runtime->private_data; | ||
1400 | |||
1401 | switch (cmd) { | ||
1402 | case SNDRV_PCM_TRIGGER_START: | ||
1403 | err = start_endpoints(subs, false); | ||
1404 | if (err < 0) | ||
1405 | return err; | ||
1406 | |||
1407 | subs->data_endpoint->retire_data_urb = retire_capture_urb; | ||
1408 | subs->running = 1; | ||
1409 | return 0; | ||
1410 | case SNDRV_PCM_TRIGGER_STOP: | ||
1411 | stop_endpoints(subs, false); | ||
1412 | subs->running = 0; | ||
1413 | return 0; | ||
1414 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
1415 | subs->data_endpoint->retire_data_urb = NULL; | ||
1416 | subs->running = 0; | ||
1417 | return 0; | ||
1418 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
1419 | subs->data_endpoint->retire_data_urb = retire_capture_urb; | ||
1420 | subs->running = 1; | ||
1421 | return 0; | ||
1422 | } | ||
1423 | |||
1424 | return -EINVAL; | ||
1425 | } | ||
1426 | |||
1427 | static struct snd_pcm_ops snd_usb_playback_ops = { | 847 | static struct snd_pcm_ops snd_usb_playback_ops = { |
1428 | .open = snd_usb_playback_open, | 848 | .open = snd_usb_playback_open, |
1429 | .close = snd_usb_playback_close, | 849 | .close = snd_usb_playback_close, |
diff --git a/sound/usb/pcm.h b/sound/usb/pcm.h index df7a003682a..ed3e283f618 100644 --- a/sound/usb/pcm.h +++ b/sound/usb/pcm.h | |||
@@ -1,9 +1,6 @@ | |||
1 | #ifndef __USBAUDIO_PCM_H | 1 | #ifndef __USBAUDIO_PCM_H |
2 | #define __USBAUDIO_PCM_H | 2 | #define __USBAUDIO_PCM_H |
3 | 3 | ||
4 | snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs, | ||
5 | unsigned int rate); | ||
6 | |||
7 | void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream); | 4 | void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream); |
8 | 5 | ||
9 | int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, | 6 | int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, |
diff --git a/sound/usb/proc.c b/sound/usb/proc.c index d218f763501..961c9a25068 100644 --- a/sound/usb/proc.c +++ b/sound/usb/proc.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include "usbaudio.h" | 25 | #include "usbaudio.h" |
26 | #include "helper.h" | 26 | #include "helper.h" |
27 | #include "card.h" | 27 | #include "card.h" |
28 | #include "endpoint.h" | ||
29 | #include "proc.h" | 28 | #include "proc.h" |
30 | 29 | ||
31 | /* convert our full speed USB rate into sampling rate in Hz */ | 30 | /* convert our full speed USB rate into sampling rate in Hz */ |
@@ -108,7 +107,7 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s | |||
108 | } | 107 | } |
109 | snd_iprintf(buffer, "\n"); | 108 | snd_iprintf(buffer, "\n"); |
110 | } | 109 | } |
111 | if (subs->speed != USB_SPEED_FULL) | 110 | if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) |
112 | snd_iprintf(buffer, " Data packet interval: %d us\n", | 111 | snd_iprintf(buffer, " Data packet interval: %d us\n", |
113 | 125 * (1 << fp->datainterval)); | 112 | 125 * (1 << fp->datainterval)); |
114 | // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize); | 113 | // snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize); |
@@ -116,33 +115,28 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s | |||
116 | } | 115 | } |
117 | } | 116 | } |
118 | 117 | ||
119 | static void proc_dump_ep_status(struct snd_usb_substream *subs, | ||
120 | struct snd_usb_endpoint *ep, | ||
121 | struct snd_info_buffer *buffer) | ||
122 | { | ||
123 | if (!ep) | ||
124 | return; | ||
125 | snd_iprintf(buffer, " Packet Size = %d\n", ep->curpacksize); | ||
126 | snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n", | ||
127 | subs->speed == USB_SPEED_FULL | ||
128 | ? get_full_speed_hz(ep->freqm) | ||
129 | : get_high_speed_hz(ep->freqm), | ||
130 | ep->freqm >> 16, ep->freqm & 0xffff); | ||
131 | if (ep->freqshift != INT_MIN) { | ||
132 | int res = 16 - ep->freqshift; | ||
133 | snd_iprintf(buffer, " Feedback Format = %d.%d\n", | ||
134 | (ep->syncmaxsize > 3 ? 32 : 24) - res, res); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | static void proc_dump_substream_status(struct snd_usb_substream *subs, struct snd_info_buffer *buffer) | 118 | static void proc_dump_substream_status(struct snd_usb_substream *subs, struct snd_info_buffer *buffer) |
139 | { | 119 | { |
140 | if (subs->running) { | 120 | if (subs->running) { |
121 | unsigned int i; | ||
141 | snd_iprintf(buffer, " Status: Running\n"); | 122 | snd_iprintf(buffer, " Status: Running\n"); |
142 | snd_iprintf(buffer, " Interface = %d\n", subs->interface); | 123 | snd_iprintf(buffer, " Interface = %d\n", subs->interface); |
143 | snd_iprintf(buffer, " Altset = %d\n", subs->altset_idx); | 124 | snd_iprintf(buffer, " Altset = %d\n", subs->altset_idx); |
144 | proc_dump_ep_status(subs, subs->data_endpoint, buffer); | 125 | snd_iprintf(buffer, " URBs = %d [ ", subs->nurbs); |
145 | proc_dump_ep_status(subs, subs->sync_endpoint, buffer); | 126 | for (i = 0; i < subs->nurbs; i++) |
127 | snd_iprintf(buffer, "%d ", subs->dataurb[i].packets); | ||
128 | snd_iprintf(buffer, "]\n"); | ||
129 | snd_iprintf(buffer, " Packet Size = %d\n", subs->curpacksize); | ||
130 | snd_iprintf(buffer, " Momentary freq = %u Hz (%#x.%04x)\n", | ||
131 | snd_usb_get_speed(subs->dev) == USB_SPEED_FULL | ||
132 | ? get_full_speed_hz(subs->freqm) | ||
133 | : get_high_speed_hz(subs->freqm), | ||
134 | subs->freqm >> 16, subs->freqm & 0xffff); | ||
135 | if (subs->freqshift != INT_MIN) | ||
136 | snd_iprintf(buffer, " Feedback Format = %d.%d\n", | ||
137 | (subs->syncmaxsize > 3 ? 32 : 24) | ||
138 | - (16 - subs->freqshift), | ||
139 | 16 - subs->freqshift); | ||
146 | } else { | 140 | } else { |
147 | snd_iprintf(buffer, " Status: Stop\n"); | 141 | snd_iprintf(buffer, " Status: Stop\n"); |
148 | } | 142 | } |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 78e845ec65d..a42e3ef3832 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -39,39 +39,6 @@ | |||
39 | .idProduct = prod, \ | 39 | .idProduct = prod, \ |
40 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC | 40 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC |
41 | 41 | ||
42 | /* FTDI devices */ | ||
43 | { | ||
44 | USB_DEVICE(0x0403, 0xb8d8), | ||
45 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
46 | /* .vendor_name = "STARR LABS", */ | ||
47 | /* .product_name = "Starr Labs MIDI USB device", */ | ||
48 | .ifnum = 0, | ||
49 | .type = QUIRK_MIDI_FTDI | ||
50 | } | ||
51 | }, | ||
52 | |||
53 | { | ||
54 | /* Creative BT-D1 */ | ||
55 | USB_DEVICE(0x041e, 0x0005), | ||
56 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
57 | .ifnum = 1, | ||
58 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
59 | .data = &(const struct audioformat) { | ||
60 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
61 | .channels = 2, | ||
62 | .iface = 1, | ||
63 | .altsetting = 1, | ||
64 | .altset_idx = 1, | ||
65 | .endpoint = 0x03, | ||
66 | .ep_attr = USB_ENDPOINT_XFER_ISOC, | ||
67 | .attributes = 0, | ||
68 | .rates = SNDRV_PCM_RATE_CONTINUOUS, | ||
69 | .rate_min = 48000, | ||
70 | .rate_max = 48000, | ||
71 | } | ||
72 | } | ||
73 | }, | ||
74 | |||
75 | /* Creative/Toshiba Multimedia Center SB-0500 */ | 42 | /* Creative/Toshiba Multimedia Center SB-0500 */ |
76 | { | 43 | { |
77 | USB_DEVICE(0x041e, 0x3048), | 44 | USB_DEVICE(0x041e, 0x3048), |
@@ -121,42 +88,6 @@ | |||
121 | }, | 88 | }, |
122 | 89 | ||
123 | /* | 90 | /* |
124 | * HP Wireless Audio | ||
125 | * When not ignored, causes instability issues for some users, forcing them to | ||
126 | * blacklist the entire module. | ||
127 | */ | ||
128 | { | ||
129 | USB_DEVICE(0x0424, 0xb832), | ||
130 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
131 | .vendor_name = "Standard Microsystems Corp.", | ||
132 | .product_name = "HP Wireless Audio", | ||
133 | .ifnum = QUIRK_ANY_INTERFACE, | ||
134 | .type = QUIRK_COMPOSITE, | ||
135 | .data = (const struct snd_usb_audio_quirk[]) { | ||
136 | /* Mixer */ | ||
137 | { | ||
138 | .ifnum = 0, | ||
139 | .type = QUIRK_IGNORE_INTERFACE, | ||
140 | }, | ||
141 | /* Playback */ | ||
142 | { | ||
143 | .ifnum = 1, | ||
144 | .type = QUIRK_IGNORE_INTERFACE, | ||
145 | }, | ||
146 | /* Capture */ | ||
147 | { | ||
148 | .ifnum = 2, | ||
149 | .type = QUIRK_IGNORE_INTERFACE, | ||
150 | }, | ||
151 | /* HID Device, .ifnum = 3 */ | ||
152 | { | ||
153 | .ifnum = -1, | ||
154 | } | ||
155 | } | ||
156 | } | ||
157 | }, | ||
158 | |||
159 | /* | ||
160 | * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface | 91 | * Logitech QuickCam: bDeviceClass is vendor-specific, so generic interface |
161 | * class matches do not take effect without an explicit ID match. | 92 | * class matches do not take effect without an explicit ID match. |
162 | */ | 93 | */ |
@@ -327,32 +258,6 @@ YAMAHA_DEVICE(0x105a, NULL), | |||
327 | YAMAHA_DEVICE(0x105b, NULL), | 258 | YAMAHA_DEVICE(0x105b, NULL), |
328 | YAMAHA_DEVICE(0x105c, NULL), | 259 | YAMAHA_DEVICE(0x105c, NULL), |
329 | YAMAHA_DEVICE(0x105d, NULL), | 260 | YAMAHA_DEVICE(0x105d, NULL), |
330 | { | ||
331 | USB_DEVICE(0x0499, 0x1503), | ||
332 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
333 | /* .vendor_name = "Yamaha", */ | ||
334 | /* .product_name = "MOX6/MOX8", */ | ||
335 | .ifnum = QUIRK_ANY_INTERFACE, | ||
336 | .type = QUIRK_COMPOSITE, | ||
337 | .data = (const struct snd_usb_audio_quirk[]) { | ||
338 | { | ||
339 | .ifnum = 1, | ||
340 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
341 | }, | ||
342 | { | ||
343 | .ifnum = 2, | ||
344 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
345 | }, | ||
346 | { | ||
347 | .ifnum = 3, | ||
348 | .type = QUIRK_MIDI_YAMAHA | ||
349 | }, | ||
350 | { | ||
351 | .ifnum = -1 | ||
352 | } | ||
353 | } | ||
354 | } | ||
355 | }, | ||
356 | YAMAHA_DEVICE(0x2000, "DGP-7"), | 261 | YAMAHA_DEVICE(0x2000, "DGP-7"), |
357 | YAMAHA_DEVICE(0x2001, "DGP-5"), | 262 | YAMAHA_DEVICE(0x2001, "DGP-5"), |
358 | YAMAHA_DEVICE(0x2002, NULL), | 263 | YAMAHA_DEVICE(0x2002, NULL), |
@@ -1515,40 +1420,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1515 | } | 1420 | } |
1516 | }, | 1421 | }, |
1517 | { | 1422 | { |
1518 | /* Advanced mode of the Roland VG-99, with MIDI and 24-bit PCM at 44.1 | ||
1519 | * kHz. In standard mode, the device has ID 0582:00b3, and offers | ||
1520 | * 16-bit PCM at 44.1 kHz with no MIDI. | ||
1521 | */ | ||
1522 | USB_DEVICE(0x0582, 0x00b2), | ||
1523 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1524 | .vendor_name = "Roland", | ||
1525 | .product_name = "VG-99", | ||
1526 | .ifnum = QUIRK_ANY_INTERFACE, | ||
1527 | .type = QUIRK_COMPOSITE, | ||
1528 | .data = (const struct snd_usb_audio_quirk[]) { | ||
1529 | { | ||
1530 | .ifnum = 0, | ||
1531 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1532 | }, | ||
1533 | { | ||
1534 | .ifnum = 1, | ||
1535 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1536 | }, | ||
1537 | { | ||
1538 | .ifnum = 2, | ||
1539 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1540 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
1541 | .out_cables = 0x0003, | ||
1542 | .in_cables = 0x0003 | ||
1543 | } | ||
1544 | }, | ||
1545 | { | ||
1546 | .ifnum = -1 | ||
1547 | } | ||
1548 | } | ||
1549 | } | ||
1550 | }, | ||
1551 | { | ||
1552 | /* Roland SonicCell */ | 1423 | /* Roland SonicCell */ |
1553 | USB_DEVICE(0x0582, 0x00c2), | 1424 | USB_DEVICE(0x0582, 0x00c2), |
1554 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 1425 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
@@ -1710,14 +1581,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1710 | } | 1581 | } |
1711 | }, | 1582 | }, |
1712 | { | 1583 | { |
1713 | /* Edirol UM-3G */ | ||
1714 | USB_DEVICE_VENDOR_SPEC(0x0582, 0x0108), | ||
1715 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1716 | .ifnum = 0, | ||
1717 | .type = QUIRK_MIDI_STANDARD_INTERFACE | ||
1718 | } | ||
1719 | }, | ||
1720 | { | ||
1721 | /* Boss JS-8 Jam Station */ | 1584 | /* Boss JS-8 Jam Station */ |
1722 | USB_DEVICE(0x0582, 0x0109), | 1585 | USB_DEVICE(0x0582, 0x0109), |
1723 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 1586 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
@@ -1759,37 +1622,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1759 | } | 1622 | } |
1760 | }, | 1623 | }, |
1761 | { | 1624 | { |
1762 | /* Roland GAIA SH-01 */ | ||
1763 | USB_DEVICE(0x0582, 0x0111), | ||
1764 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
1765 | .vendor_name = "Roland", | ||
1766 | .product_name = "GAIA", | ||
1767 | .ifnum = QUIRK_ANY_INTERFACE, | ||
1768 | .type = QUIRK_COMPOSITE, | ||
1769 | .data = (const struct snd_usb_audio_quirk[]) { | ||
1770 | { | ||
1771 | .ifnum = 0, | ||
1772 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1773 | }, | ||
1774 | { | ||
1775 | .ifnum = 1, | ||
1776 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1777 | }, | ||
1778 | { | ||
1779 | .ifnum = 2, | ||
1780 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1781 | .data = &(const struct snd_usb_midi_endpoint_info) { | ||
1782 | .out_cables = 0x0003, | ||
1783 | .in_cables = 0x0003 | ||
1784 | } | ||
1785 | }, | ||
1786 | { | ||
1787 | .ifnum = -1 | ||
1788 | } | ||
1789 | } | ||
1790 | } | ||
1791 | }, | ||
1792 | { | ||
1793 | USB_DEVICE(0x0582, 0x0113), | 1625 | USB_DEVICE(0x0582, 0x0113), |
1794 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 1626 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
1795 | /* .vendor_name = "BOSS", */ | 1627 | /* .vendor_name = "BOSS", */ |
@@ -1846,20 +1678,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1846 | } | 1678 | } |
1847 | }, | 1679 | }, |
1848 | { | 1680 | { |
1849 | /* Added support for Roland UM-ONE which differs from UM-1 */ | ||
1850 | USB_DEVICE(0x0582, 0x012a), | ||
1851 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1852 | /* .vendor_name = "ROLAND", */ | ||
1853 | /* .product_name = "UM-ONE", */ | ||
1854 | .ifnum = 0, | ||
1855 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1856 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
1857 | .out_cables = 0x0001, | ||
1858 | .in_cables = 0x0003 | ||
1859 | } | ||
1860 | } | ||
1861 | }, | ||
1862 | { | ||
1863 | USB_DEVICE(0x0582, 0x011e), | 1681 | USB_DEVICE(0x0582, 0x011e), |
1864 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 1682 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
1865 | /* .vendor_name = "BOSS", */ | 1683 | /* .vendor_name = "BOSS", */ |
@@ -1923,36 +1741,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1923 | } | 1741 | } |
1924 | } | 1742 | } |
1925 | }, | 1743 | }, |
1926 | { | ||
1927 | USB_DEVICE(0x0582, 0x014d), | ||
1928 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1929 | /* .vendor_name = "BOSS", */ | ||
1930 | /* .product_name = "GT-100", */ | ||
1931 | .ifnum = QUIRK_ANY_INTERFACE, | ||
1932 | .type = QUIRK_COMPOSITE, | ||
1933 | .data = (const struct snd_usb_audio_quirk[]) { | ||
1934 | { | ||
1935 | .ifnum = 1, | ||
1936 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1937 | }, | ||
1938 | { | ||
1939 | .ifnum = 2, | ||
1940 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1941 | }, | ||
1942 | { | ||
1943 | .ifnum = 3, | ||
1944 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1945 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
1946 | .out_cables = 0x0001, | ||
1947 | .in_cables = 0x0001 | ||
1948 | } | ||
1949 | }, | ||
1950 | { | ||
1951 | .ifnum = -1 | ||
1952 | } | ||
1953 | } | ||
1954 | } | ||
1955 | }, | ||
1956 | 1744 | ||
1957 | /* Guillemot devices */ | 1745 | /* Guillemot devices */ |
1958 | { | 1746 | { |
@@ -2255,77 +2043,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2255 | } | 2043 | } |
2256 | }, | 2044 | }, |
2257 | { | 2045 | { |
2258 | USB_DEVICE_VENDOR_SPEC(0x0763, 0x2030), | ||
2259 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
2260 | /* .vendor_name = "M-Audio", */ | ||
2261 | /* .product_name = "Fast Track C400", */ | ||
2262 | .ifnum = QUIRK_ANY_INTERFACE, | ||
2263 | .type = QUIRK_COMPOSITE, | ||
2264 | .data = &(const struct snd_usb_audio_quirk[]) { | ||
2265 | { | ||
2266 | .ifnum = 1, | ||
2267 | .type = QUIRK_AUDIO_STANDARD_MIXER, | ||
2268 | }, | ||
2269 | /* Playback */ | ||
2270 | { | ||
2271 | .ifnum = 2, | ||
2272 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
2273 | .data = &(const struct audioformat) { | ||
2274 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, | ||
2275 | .channels = 6, | ||
2276 | .iface = 2, | ||
2277 | .altsetting = 1, | ||
2278 | .altset_idx = 1, | ||
2279 | .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, | ||
2280 | .endpoint = 0x01, | ||
2281 | .ep_attr = 0x09, | ||
2282 | .rates = SNDRV_PCM_RATE_44100 | | ||
2283 | SNDRV_PCM_RATE_48000 | | ||
2284 | SNDRV_PCM_RATE_88200 | | ||
2285 | SNDRV_PCM_RATE_96000, | ||
2286 | .rate_min = 44100, | ||
2287 | .rate_max = 96000, | ||
2288 | .nr_rates = 4, | ||
2289 | .rate_table = (unsigned int[]) { | ||
2290 | 44100, 48000, 88200, 96000 | ||
2291 | }, | ||
2292 | .clock = 0x81, | ||
2293 | } | ||
2294 | }, | ||
2295 | /* Capture */ | ||
2296 | { | ||
2297 | .ifnum = 3, | ||
2298 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
2299 | .data = &(const struct audioformat) { | ||
2300 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, | ||
2301 | .channels = 4, | ||
2302 | .iface = 3, | ||
2303 | .altsetting = 1, | ||
2304 | .altset_idx = 1, | ||
2305 | .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, | ||
2306 | .endpoint = 0x81, | ||
2307 | .ep_attr = 0x05, | ||
2308 | .rates = SNDRV_PCM_RATE_44100 | | ||
2309 | SNDRV_PCM_RATE_48000 | | ||
2310 | SNDRV_PCM_RATE_88200 | | ||
2311 | SNDRV_PCM_RATE_96000, | ||
2312 | .rate_min = 44100, | ||
2313 | .rate_max = 96000, | ||
2314 | .nr_rates = 4, | ||
2315 | .rate_table = (unsigned int[]) { | ||
2316 | 44100, 48000, 88200, 96000 | ||
2317 | }, | ||
2318 | .clock = 0x81, | ||
2319 | } | ||
2320 | }, | ||
2321 | /* MIDI */ | ||
2322 | { | ||
2323 | .ifnum = -1 /* Interface = 4 */ | ||
2324 | } | ||
2325 | } | ||
2326 | } | ||
2327 | }, | ||
2328 | { | ||
2329 | USB_DEVICE_VENDOR_SPEC(0x0763, 0x2080), | 2046 | USB_DEVICE_VENDOR_SPEC(0x0763, 0x2080), |
2330 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 2047 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
2331 | /* .vendor_name = "M-Audio", */ | 2048 | /* .vendor_name = "M-Audio", */ |
@@ -2563,16 +2280,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2563 | } | 2280 | } |
2564 | }, | 2281 | }, |
2565 | 2282 | ||
2566 | { | ||
2567 | USB_DEVICE_VENDOR_SPEC(0x0944, 0x0201), | ||
2568 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
2569 | .vendor_name = "KORG, Inc.", | ||
2570 | /* .product_name = "ToneLab ST", */ | ||
2571 | .ifnum = 3, | ||
2572 | .type = QUIRK_MIDI_STANDARD_INTERFACE, | ||
2573 | } | ||
2574 | }, | ||
2575 | |||
2576 | /* AKAI devices */ | 2283 | /* AKAI devices */ |
2577 | { | 2284 | { |
2578 | USB_DEVICE(0x09e8, 0x0062), | 2285 | USB_DEVICE(0x09e8, 0x0062), |
@@ -2944,285 +2651,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2944 | } | 2651 | } |
2945 | }, | 2652 | }, |
2946 | 2653 | ||
2947 | /* DIGIDESIGN MBOX 2 */ | ||
2948 | { | ||
2949 | USB_DEVICE(0x0dba, 0x3000), | ||
2950 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
2951 | .vendor_name = "Digidesign", | ||
2952 | .product_name = "Mbox 2", | ||
2953 | .ifnum = QUIRK_ANY_INTERFACE, | ||
2954 | .type = QUIRK_COMPOSITE, | ||
2955 | .data = (const struct snd_usb_audio_quirk[]) { | ||
2956 | { | ||
2957 | .ifnum = 0, | ||
2958 | .type = QUIRK_IGNORE_INTERFACE | ||
2959 | }, | ||
2960 | { | ||
2961 | .ifnum = 1, | ||
2962 | .type = QUIRK_IGNORE_INTERFACE | ||
2963 | }, | ||
2964 | { | ||
2965 | .ifnum = 2, | ||
2966 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
2967 | .data = &(const struct audioformat) { | ||
2968 | .formats = SNDRV_PCM_FMTBIT_S24_3BE, | ||
2969 | .channels = 2, | ||
2970 | .iface = 2, | ||
2971 | .altsetting = 2, | ||
2972 | .altset_idx = 1, | ||
2973 | .attributes = 0x00, | ||
2974 | .endpoint = 0x03, | ||
2975 | .ep_attr = USB_ENDPOINT_SYNC_ASYNC, | ||
2976 | .maxpacksize = 0x128, | ||
2977 | .rates = SNDRV_PCM_RATE_48000, | ||
2978 | .rate_min = 48000, | ||
2979 | .rate_max = 48000, | ||
2980 | .nr_rates = 1, | ||
2981 | .rate_table = (unsigned int[]) { | ||
2982 | 48000 | ||
2983 | } | ||
2984 | } | ||
2985 | }, | ||
2986 | { | ||
2987 | .ifnum = 3, | ||
2988 | .type = QUIRK_IGNORE_INTERFACE | ||
2989 | }, | ||
2990 | { | ||
2991 | .ifnum = 4, | ||
2992 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
2993 | .data = &(const struct audioformat) { | ||
2994 | .formats = SNDRV_PCM_FMTBIT_S24_3BE, | ||
2995 | .channels = 2, | ||
2996 | .iface = 4, | ||
2997 | .altsetting = 2, | ||
2998 | .altset_idx = 1, | ||
2999 | .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, | ||
3000 | .endpoint = 0x85, | ||
3001 | .ep_attr = USB_ENDPOINT_SYNC_SYNC, | ||
3002 | .maxpacksize = 0x128, | ||
3003 | .rates = SNDRV_PCM_RATE_48000, | ||
3004 | .rate_min = 48000, | ||
3005 | .rate_max = 48000, | ||
3006 | .nr_rates = 1, | ||
3007 | .rate_table = (unsigned int[]) { | ||
3008 | 48000 | ||
3009 | } | ||
3010 | } | ||
3011 | }, | ||
3012 | { | ||
3013 | .ifnum = 5, | ||
3014 | .type = QUIRK_IGNORE_INTERFACE | ||
3015 | }, | ||
3016 | { | ||
3017 | .ifnum = 6, | ||
3018 | .type = QUIRK_MIDI_MIDIMAN, | ||
3019 | .data = &(const struct snd_usb_midi_endpoint_info) { | ||
3020 | .out_ep = 0x02, | ||
3021 | .out_cables = 0x0001, | ||
3022 | .in_ep = 0x81, | ||
3023 | .in_interval = 0x01, | ||
3024 | .in_cables = 0x0001 | ||
3025 | } | ||
3026 | }, | ||
3027 | { | ||
3028 | .ifnum = -1 | ||
3029 | } | ||
3030 | } | ||
3031 | } | ||
3032 | }, | ||
3033 | { | ||
3034 | /* Tascam US122 MKII - playback-only support */ | ||
3035 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | ||
3036 | .idVendor = 0x0644, | ||
3037 | .idProduct = 0x8021, | ||
3038 | .bInterfaceClass = USB_CLASS_AUDIO, | ||
3039 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
3040 | .vendor_name = "TASCAM", | ||
3041 | .product_name = "US122 MKII", | ||
3042 | .ifnum = QUIRK_ANY_INTERFACE, | ||
3043 | .type = QUIRK_COMPOSITE, | ||
3044 | .data = (const struct snd_usb_audio_quirk[]) { | ||
3045 | { | ||
3046 | .ifnum = 0, | ||
3047 | .type = QUIRK_IGNORE_INTERFACE | ||
3048 | }, | ||
3049 | { | ||
3050 | .ifnum = 1, | ||
3051 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
3052 | .data = &(const struct audioformat) { | ||
3053 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, | ||
3054 | .channels = 2, | ||
3055 | .iface = 1, | ||
3056 | .altsetting = 1, | ||
3057 | .altset_idx = 1, | ||
3058 | .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, | ||
3059 | .endpoint = 0x02, | ||
3060 | .ep_attr = USB_ENDPOINT_XFER_ISOC, | ||
3061 | .rates = SNDRV_PCM_RATE_44100 | | ||
3062 | SNDRV_PCM_RATE_48000 | | ||
3063 | SNDRV_PCM_RATE_88200 | | ||
3064 | SNDRV_PCM_RATE_96000, | ||
3065 | .rate_min = 44100, | ||
3066 | .rate_max = 96000, | ||
3067 | .nr_rates = 4, | ||
3068 | .rate_table = (unsigned int[]) { | ||
3069 | 44100, 48000, 88200, 96000 | ||
3070 | } | ||
3071 | } | ||
3072 | }, | ||
3073 | { | ||
3074 | .ifnum = -1 | ||
3075 | } | ||
3076 | } | ||
3077 | } | ||
3078 | }, | ||
3079 | |||
3080 | /* Microsoft XboxLive Headset/Xbox Communicator */ | ||
3081 | { | ||
3082 | USB_DEVICE(0x045e, 0x0283), | ||
3083 | .bInterfaceClass = USB_CLASS_PER_INTERFACE, | ||
3084 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
3085 | .vendor_name = "Microsoft", | ||
3086 | .product_name = "XboxLive Headset/Xbox Communicator", | ||
3087 | .ifnum = QUIRK_ANY_INTERFACE, | ||
3088 | .type = QUIRK_COMPOSITE, | ||
3089 | .data = &(const struct snd_usb_audio_quirk[]) { | ||
3090 | { | ||
3091 | /* playback */ | ||
3092 | .ifnum = 0, | ||
3093 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
3094 | .data = &(const struct audioformat) { | ||
3095 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
3096 | .channels = 1, | ||
3097 | .iface = 0, | ||
3098 | .altsetting = 0, | ||
3099 | .altset_idx = 0, | ||
3100 | .attributes = 0, | ||
3101 | .endpoint = 0x04, | ||
3102 | .ep_attr = 0x05, | ||
3103 | .rates = SNDRV_PCM_RATE_CONTINUOUS, | ||
3104 | .rate_min = 22050, | ||
3105 | .rate_max = 22050 | ||
3106 | } | ||
3107 | }, | ||
3108 | { | ||
3109 | /* capture */ | ||
3110 | .ifnum = 1, | ||
3111 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
3112 | .data = &(const struct audioformat) { | ||
3113 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
3114 | .channels = 1, | ||
3115 | .iface = 1, | ||
3116 | .altsetting = 0, | ||
3117 | .altset_idx = 0, | ||
3118 | .attributes = 0, | ||
3119 | .endpoint = 0x85, | ||
3120 | .ep_attr = 0x05, | ||
3121 | .rates = SNDRV_PCM_RATE_CONTINUOUS, | ||
3122 | .rate_min = 16000, | ||
3123 | .rate_max = 16000 | ||
3124 | } | ||
3125 | }, | ||
3126 | { | ||
3127 | .ifnum = -1 | ||
3128 | } | ||
3129 | } | ||
3130 | } | ||
3131 | }, | ||
3132 | |||
3133 | /* Reloop Play */ | ||
3134 | { | ||
3135 | USB_DEVICE(0x200c, 0x100b), | ||
3136 | .bInterfaceClass = USB_CLASS_PER_INTERFACE, | ||
3137 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
3138 | .ifnum = QUIRK_ANY_INTERFACE, | ||
3139 | .type = QUIRK_COMPOSITE, | ||
3140 | .data = &(const struct snd_usb_audio_quirk[]) { | ||
3141 | { | ||
3142 | .ifnum = 0, | ||
3143 | .type = QUIRK_AUDIO_STANDARD_MIXER, | ||
3144 | }, | ||
3145 | { | ||
3146 | .ifnum = 1, | ||
3147 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
3148 | .data = &(const struct audioformat) { | ||
3149 | .formats = SNDRV_PCM_FMTBIT_S24_3LE, | ||
3150 | .channels = 4, | ||
3151 | .iface = 1, | ||
3152 | .altsetting = 1, | ||
3153 | .altset_idx = 1, | ||
3154 | .attributes = UAC_EP_CS_ATTR_SAMPLE_RATE, | ||
3155 | .endpoint = 0x01, | ||
3156 | .ep_attr = USB_ENDPOINT_SYNC_ADAPTIVE, | ||
3157 | .rates = SNDRV_PCM_RATE_44100 | | ||
3158 | SNDRV_PCM_RATE_48000, | ||
3159 | .rate_min = 44100, | ||
3160 | .rate_max = 48000, | ||
3161 | .nr_rates = 2, | ||
3162 | .rate_table = (unsigned int[]) { | ||
3163 | 44100, 48000 | ||
3164 | } | ||
3165 | } | ||
3166 | }, | ||
3167 | { | ||
3168 | .ifnum = -1 | ||
3169 | } | ||
3170 | } | ||
3171 | } | ||
3172 | }, | ||
3173 | |||
3174 | { | ||
3175 | /* | ||
3176 | * Focusrite Scarlett 18i6 | ||
3177 | * | ||
3178 | * Avoid mixer creation, which otherwise fails because some of | ||
3179 | * the interface descriptor subtypes for interface 0 are | ||
3180 | * unknown. That should be fixed or worked-around but this at | ||
3181 | * least allows the device to be used successfully with a DAW | ||
3182 | * and an external mixer. See comments below about other | ||
3183 | * ignored interfaces. | ||
3184 | */ | ||
3185 | USB_DEVICE(0x1235, 0x8004), | ||
3186 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
3187 | .vendor_name = "Focusrite", | ||
3188 | .product_name = "Scarlett 18i6", | ||
3189 | .ifnum = QUIRK_ANY_INTERFACE, | ||
3190 | .type = QUIRK_COMPOSITE, | ||
3191 | .data = & (const struct snd_usb_audio_quirk[]) { | ||
3192 | { | ||
3193 | /* InterfaceSubClass 1 (Control Device) */ | ||
3194 | .ifnum = 0, | ||
3195 | .type = QUIRK_IGNORE_INTERFACE | ||
3196 | }, | ||
3197 | { | ||
3198 | .ifnum = 1, | ||
3199 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
3200 | }, | ||
3201 | { | ||
3202 | .ifnum = 2, | ||
3203 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
3204 | }, | ||
3205 | { | ||
3206 | /* InterfaceSubClass 1 (Control Device) */ | ||
3207 | .ifnum = 3, | ||
3208 | .type = QUIRK_IGNORE_INTERFACE | ||
3209 | }, | ||
3210 | { | ||
3211 | .ifnum = 4, | ||
3212 | .type = QUIRK_MIDI_STANDARD_INTERFACE | ||
3213 | }, | ||
3214 | { | ||
3215 | /* InterfaceSubClass 1 (Device Firmware Update) */ | ||
3216 | .ifnum = 5, | ||
3217 | .type = QUIRK_IGNORE_INTERFACE | ||
3218 | }, | ||
3219 | { | ||
3220 | .ifnum = -1 | ||
3221 | } | ||
3222 | } | ||
3223 | } | ||
3224 | }, | ||
3225 | |||
3226 | { | 2654 | { |
3227 | /* | 2655 | /* |
3228 | * Some USB MIDI devices don't have an audio control interface, | 2656 | * Some USB MIDI devices don't have an audio control interface, |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index acc12f004c2..81e07d84258 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include "endpoint.h" | 34 | #include "endpoint.h" |
35 | #include "pcm.h" | 35 | #include "pcm.h" |
36 | #include "clock.h" | 36 | #include "clock.h" |
37 | #include "stream.h" | ||
38 | 37 | ||
39 | /* | 38 | /* |
40 | * handle the quirks for the contained interfaces | 39 | * handle the quirks for the contained interfaces |
@@ -107,7 +106,7 @@ static int create_standard_audio_quirk(struct snd_usb_audio *chip, | |||
107 | 106 | ||
108 | alts = &iface->altsetting[0]; | 107 | alts = &iface->altsetting[0]; |
109 | altsd = get_iface_desc(alts); | 108 | altsd = get_iface_desc(alts); |
110 | err = snd_usb_parse_audio_interface(chip, altsd->bInterfaceNumber); | 109 | err = snd_usb_parse_audio_endpoints(chip, altsd->bInterfaceNumber); |
111 | if (err < 0) { | 110 | if (err < 0) { |
112 | snd_printk(KERN_ERR "cannot setup if %d: error %d\n", | 111 | snd_printk(KERN_ERR "cannot setup if %d: error %d\n", |
113 | altsd->bInterfaceNumber, err); | 112 | altsd->bInterfaceNumber, err); |
@@ -132,27 +131,23 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, | |||
132 | unsigned *rate_table = NULL; | 131 | unsigned *rate_table = NULL; |
133 | 132 | ||
134 | fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL); | 133 | fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL); |
135 | if (!fp) { | 134 | if (! fp) { |
136 | snd_printk(KERN_ERR "cannot memdup\n"); | 135 | snd_printk(KERN_ERR "cannot memdup\n"); |
137 | return -ENOMEM; | 136 | return -ENOMEM; |
138 | } | 137 | } |
139 | if (fp->nr_rates > MAX_NR_RATES) { | ||
140 | kfree(fp); | ||
141 | return -EINVAL; | ||
142 | } | ||
143 | if (fp->nr_rates > 0) { | 138 | if (fp->nr_rates > 0) { |
144 | rate_table = kmemdup(fp->rate_table, | 139 | rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL); |
145 | sizeof(int) * fp->nr_rates, GFP_KERNEL); | ||
146 | if (!rate_table) { | 140 | if (!rate_table) { |
147 | kfree(fp); | 141 | kfree(fp); |
148 | return -ENOMEM; | 142 | return -ENOMEM; |
149 | } | 143 | } |
144 | memcpy(rate_table, fp->rate_table, sizeof(int) * fp->nr_rates); | ||
150 | fp->rate_table = rate_table; | 145 | fp->rate_table = rate_table; |
151 | } | 146 | } |
152 | 147 | ||
153 | stream = (fp->endpoint & USB_DIR_IN) | 148 | stream = (fp->endpoint & USB_DIR_IN) |
154 | ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; | 149 | ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; |
155 | err = snd_usb_add_audio_stream(chip, stream, fp); | 150 | err = snd_usb_add_audio_endpoint(chip, stream, fp); |
156 | if (err < 0) { | 151 | if (err < 0) { |
157 | kfree(fp); | 152 | kfree(fp); |
158 | kfree(rate_table); | 153 | kfree(rate_table); |
@@ -228,9 +223,10 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, | |||
228 | if (altsd->bNumEndpoints != 1) | 223 | if (altsd->bNumEndpoints != 1) |
229 | return -ENXIO; | 224 | return -ENXIO; |
230 | 225 | ||
231 | fp = kmemdup(&ua_format, sizeof(*fp), GFP_KERNEL); | 226 | fp = kmalloc(sizeof(*fp), GFP_KERNEL); |
232 | if (!fp) | 227 | if (!fp) |
233 | return -ENOMEM; | 228 | return -ENOMEM; |
229 | memcpy(fp, &ua_format, sizeof(*fp)); | ||
234 | 230 | ||
235 | fp->iface = altsd->bInterfaceNumber; | 231 | fp->iface = altsd->bInterfaceNumber; |
236 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; | 232 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; |
@@ -258,7 +254,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, | |||
258 | 254 | ||
259 | stream = (fp->endpoint & USB_DIR_IN) | 255 | stream = (fp->endpoint & USB_DIR_IN) |
260 | ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; | 256 | ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; |
261 | err = snd_usb_add_audio_stream(chip, stream, fp); | 257 | err = snd_usb_add_audio_endpoint(chip, stream, fp); |
262 | if (err < 0) { | 258 | if (err < 0) { |
263 | kfree(fp); | 259 | kfree(fp); |
264 | return err; | 260 | return err; |
@@ -310,7 +306,6 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, | |||
310 | [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, | 306 | [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, |
311 | [QUIRK_MIDI_CME] = create_any_midi_quirk, | 307 | [QUIRK_MIDI_CME] = create_any_midi_quirk, |
312 | [QUIRK_MIDI_AKAI] = create_any_midi_quirk, | 308 | [QUIRK_MIDI_AKAI] = create_any_midi_quirk, |
313 | [QUIRK_MIDI_FTDI] = create_any_midi_quirk, | ||
314 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, | 309 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, |
315 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, | 310 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, |
316 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, | 311 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, |
@@ -343,7 +338,7 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac | |||
343 | snd_printdd("sending Extigy boot sequence...\n"); | 338 | snd_printdd("sending Extigy boot sequence...\n"); |
344 | /* Send message to force it to reconnect with full interface. */ | 339 | /* Send message to force it to reconnect with full interface. */ |
345 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0), | 340 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0), |
346 | 0x10, 0x43, 0x0001, 0x000a, NULL, 0); | 341 | 0x10, 0x43, 0x0001, 0x000a, NULL, 0, 1000); |
347 | if (err < 0) snd_printdd("error sending boot message: %d\n", err); | 342 | if (err < 0) snd_printdd("error sending boot message: %d\n", err); |
348 | err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, | 343 | err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, |
349 | &dev->descriptor, sizeof(dev->descriptor)); | 344 | &dev->descriptor, sizeof(dev->descriptor)); |
@@ -364,11 +359,11 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) | |||
364 | 359 | ||
365 | snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a, | 360 | snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a, |
366 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 361 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
367 | 0, 0, &buf, 1); | 362 | 0, 0, &buf, 1, 1000); |
368 | if (buf == 0) { | 363 | if (buf == 0) { |
369 | snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29, | 364 | snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29, |
370 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 365 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
371 | 1, 2000, NULL, 0); | 366 | 1, 2000, NULL, 0, 1000); |
372 | return -ENODEV; | 367 | return -ENODEV; |
373 | } | 368 | } |
374 | return 0; | 369 | return 0; |
@@ -411,7 +406,7 @@ static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 valu | |||
411 | buf[3] = reg; | 406 | buf[3] = reg; |
412 | return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION, | 407 | return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION, |
413 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT, | 408 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT, |
414 | 0, 0, &buf, 4); | 409 | 0, 0, &buf, 4, 1000); |
415 | } | 410 | } |
416 | 411 | ||
417 | static int snd_usb_cm106_boot_quirk(struct usb_device *dev) | 412 | static int snd_usb_cm106_boot_quirk(struct usb_device *dev) |
@@ -497,92 +492,6 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev) | |||
497 | return -EAGAIN; | 492 | return -EAGAIN; |
498 | } | 493 | } |
499 | 494 | ||
500 | static void mbox2_setup_48_24_magic(struct usb_device *dev) | ||
501 | { | ||
502 | u8 srate[3]; | ||
503 | u8 temp[12]; | ||
504 | |||
505 | /* Choose 48000Hz permanently */ | ||
506 | srate[0] = 0x80; | ||
507 | srate[1] = 0xbb; | ||
508 | srate[2] = 0x00; | ||
509 | |||
510 | /* Send the magic! */ | ||
511 | snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
512 | 0x01, 0x22, 0x0100, 0x0085, &temp, 0x0003); | ||
513 | snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), | ||
514 | 0x81, 0xa2, 0x0100, 0x0085, &srate, 0x0003); | ||
515 | snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), | ||
516 | 0x81, 0xa2, 0x0100, 0x0086, &srate, 0x0003); | ||
517 | snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), | ||
518 | 0x81, 0xa2, 0x0100, 0x0003, &srate, 0x0003); | ||
519 | return; | ||
520 | } | ||
521 | |||
522 | /* Digidesign Mbox 2 needs to load firmware onboard | ||
523 | * and driver must wait a few seconds for initialisation. | ||
524 | */ | ||
525 | |||
526 | #define MBOX2_FIRMWARE_SIZE 646 | ||
527 | #define MBOX2_BOOT_LOADING 0x01 /* Hard coded into the device */ | ||
528 | #define MBOX2_BOOT_READY 0x02 /* Hard coded into the device */ | ||
529 | |||
530 | static int snd_usb_mbox2_boot_quirk(struct usb_device *dev) | ||
531 | { | ||
532 | struct usb_host_config *config = dev->actconfig; | ||
533 | int err; | ||
534 | u8 bootresponse[12]; | ||
535 | int fwsize; | ||
536 | int count; | ||
537 | |||
538 | fwsize = le16_to_cpu(get_cfg_desc(config)->wTotalLength); | ||
539 | |||
540 | if (fwsize != MBOX2_FIRMWARE_SIZE) { | ||
541 | snd_printk(KERN_ERR "usb-audio: Invalid firmware size=%d.\n", fwsize); | ||
542 | return -ENODEV; | ||
543 | } | ||
544 | |||
545 | snd_printd("usb-audio: Sending Digidesign Mbox 2 boot sequence...\n"); | ||
546 | |||
547 | count = 0; | ||
548 | bootresponse[0] = MBOX2_BOOT_LOADING; | ||
549 | while ((bootresponse[0] == MBOX2_BOOT_LOADING) && (count < 10)) { | ||
550 | msleep(500); /* 0.5 second delay */ | ||
551 | snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
552 | /* Control magic - load onboard firmware */ | ||
553 | 0x85, 0xc0, 0x0001, 0x0000, &bootresponse, 0x0012); | ||
554 | if (bootresponse[0] == MBOX2_BOOT_READY) | ||
555 | break; | ||
556 | snd_printd("usb-audio: device not ready, resending boot sequence...\n"); | ||
557 | count++; | ||
558 | } | ||
559 | |||
560 | if (bootresponse[0] != MBOX2_BOOT_READY) { | ||
561 | snd_printk(KERN_ERR "usb-audio: Unknown bootresponse=%d, or timed out, ignoring device.\n", bootresponse[0]); | ||
562 | return -ENODEV; | ||
563 | } | ||
564 | |||
565 | snd_printdd("usb-audio: device initialised!\n"); | ||
566 | |||
567 | err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, | ||
568 | &dev->descriptor, sizeof(dev->descriptor)); | ||
569 | config = dev->actconfig; | ||
570 | if (err < 0) | ||
571 | snd_printd("error usb_get_descriptor: %d\n", err); | ||
572 | |||
573 | err = usb_reset_configuration(dev); | ||
574 | if (err < 0) | ||
575 | snd_printd("error usb_reset_configuration: %d\n", err); | ||
576 | snd_printdd("mbox2_boot: new boot length = %d\n", | ||
577 | le16_to_cpu(get_cfg_desc(config)->wTotalLength)); | ||
578 | |||
579 | mbox2_setup_48_24_magic(dev); | ||
580 | |||
581 | snd_printk(KERN_INFO "usb-audio: Digidesign Mbox 2: 24bit 48kHz"); | ||
582 | |||
583 | return 0; /* Successful boot */ | ||
584 | } | ||
585 | |||
586 | /* | 495 | /* |
587 | * Setup quirks | 496 | * Setup quirks |
588 | */ | 497 | */ |
@@ -659,6 +568,7 @@ static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip, | |||
659 | return 0; /* keep this altsetting */ | 568 | return 0; /* keep this altsetting */ |
660 | } | 569 | } |
661 | 570 | ||
571 | |||
662 | static int fasttrackpro_skip_setting_quirk(struct snd_usb_audio *chip, | 572 | static int fasttrackpro_skip_setting_quirk(struct snd_usb_audio *chip, |
663 | int iface, int altno) | 573 | int iface, int altno) |
664 | { | 574 | { |
@@ -740,10 +650,6 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev, | |||
740 | case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */ | 650 | case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */ |
741 | return snd_usb_cm6206_boot_quirk(dev); | 651 | return snd_usb_cm6206_boot_quirk(dev); |
742 | 652 | ||
743 | case USB_ID(0x0dba, 0x3000): | ||
744 | /* Digidesign Mbox 2 */ | ||
745 | return snd_usb_mbox2_boot_quirk(dev); | ||
746 | |||
747 | case USB_ID(0x133e, 0x0815): | 653 | case USB_ID(0x133e, 0x0815): |
748 | /* Access Music VirusTI Desktop */ | 654 | /* Access Music VirusTI Desktop */ |
749 | return snd_usb_accessmusic_boot_quirk(dev); | 655 | return snd_usb_accessmusic_boot_quirk(dev); |
@@ -764,7 +670,7 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev, | |||
764 | */ | 670 | */ |
765 | int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp) | 671 | int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp) |
766 | { | 672 | { |
767 | /* it depends on altsetting whether the device is big-endian or not */ | 673 | /* it depends on altsetting wether the device is big-endian or not */ |
768 | switch (chip->usb_id) { | 674 | switch (chip->usb_id) { |
769 | case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */ | 675 | case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */ |
770 | if (fp->altsetting == 2 || fp->altsetting == 3 || | 676 | if (fp->altsetting == 2 || fp->altsetting == 3 || |
@@ -850,27 +756,3 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs, | |||
850 | } | 756 | } |
851 | } | 757 | } |
852 | 758 | ||
853 | void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep) | ||
854 | { | ||
855 | /* | ||
856 | * "Playback Design" products send bogus feedback data at the start | ||
857 | * of the stream. Ignore them. | ||
858 | */ | ||
859 | if ((le16_to_cpu(ep->chip->dev->descriptor.idVendor) == 0x23ba) && | ||
860 | ep->type == SND_USB_ENDPOINT_TYPE_SYNC) | ||
861 | ep->skip_packets = 4; | ||
862 | } | ||
863 | |||
864 | void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, | ||
865 | __u8 request, __u8 requesttype, __u16 value, | ||
866 | __u16 index, void *data, __u16 size) | ||
867 | { | ||
868 | /* | ||
869 | * "Playback Design" products need a 20ms delay after each | ||
870 | * class compliant request | ||
871 | */ | ||
872 | if ((le16_to_cpu(dev->descriptor.idVendor) == 0x23ba) && | ||
873 | (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) | ||
874 | mdelay(20); | ||
875 | } | ||
876 | |||
diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h index 0ca9e91067a..03e5e94098c 100644 --- a/sound/usb/quirks.h +++ b/sound/usb/quirks.h | |||
@@ -1,10 +1,6 @@ | |||
1 | #ifndef __USBAUDIO_QUIRKS_H | 1 | #ifndef __USBAUDIO_QUIRKS_H |
2 | #define __USBAUDIO_QUIRKS_H | 2 | #define __USBAUDIO_QUIRKS_H |
3 | 3 | ||
4 | struct audioformat; | ||
5 | struct snd_usb_endpoint; | ||
6 | struct snd_usb_substream; | ||
7 | |||
8 | int snd_usb_create_quirk(struct snd_usb_audio *chip, | 4 | int snd_usb_create_quirk(struct snd_usb_audio *chip, |
9 | struct usb_interface *iface, | 5 | struct usb_interface *iface, |
10 | struct usb_driver *driver, | 6 | struct usb_driver *driver, |
@@ -24,10 +20,4 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs, | |||
24 | int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, | 20 | int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, |
25 | struct audioformat *fp); | 21 | struct audioformat *fp); |
26 | 22 | ||
27 | void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep); | ||
28 | |||
29 | void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, | ||
30 | __u8 request, __u8 requesttype, __u16 value, | ||
31 | __u16 index, void *data, __u16 size); | ||
32 | |||
33 | #endif /* __USBAUDIO_QUIRKS_H */ | 23 | #endif /* __USBAUDIO_QUIRKS_H */ |
diff --git a/sound/usb/stream.c b/sound/usb/stream.c deleted file mode 100644 index ad181d538bd..00000000000 --- a/sound/usb/stream.c +++ /dev/null | |||
@@ -1,697 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License as published by | ||
4 | * the Free Software Foundation; either version 2 of the License, or | ||
5 | * (at your option) any later version. | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, | ||
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | * GNU General Public License for more details. | ||
11 | * | ||
12 | * You should have received a copy of the GNU General Public License | ||
13 | * along with this program; if not, write to the Free Software | ||
14 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
15 | */ | ||
16 | |||
17 | |||
18 | #include <linux/init.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/usb.h> | ||
21 | #include <linux/usb/audio.h> | ||
22 | #include <linux/usb/audio-v2.h> | ||
23 | |||
24 | #include <sound/core.h> | ||
25 | #include <sound/pcm.h> | ||
26 | #include <sound/control.h> | ||
27 | #include <sound/tlv.h> | ||
28 | |||
29 | #include "usbaudio.h" | ||
30 | #include "card.h" | ||
31 | #include "proc.h" | ||
32 | #include "quirks.h" | ||
33 | #include "endpoint.h" | ||
34 | #include "pcm.h" | ||
35 | #include "helper.h" | ||
36 | #include "format.h" | ||
37 | #include "clock.h" | ||
38 | #include "stream.h" | ||
39 | |||
40 | /* | ||
41 | * free a substream | ||
42 | */ | ||
43 | static void free_substream(struct snd_usb_substream *subs) | ||
44 | { | ||
45 | struct list_head *p, *n; | ||
46 | |||
47 | if (!subs->num_formats) | ||
48 | return; /* not initialized */ | ||
49 | list_for_each_safe(p, n, &subs->fmt_list) { | ||
50 | struct audioformat *fp = list_entry(p, struct audioformat, list); | ||
51 | kfree(fp->rate_table); | ||
52 | kfree(fp->chmap); | ||
53 | kfree(fp); | ||
54 | } | ||
55 | kfree(subs->rate_list.list); | ||
56 | } | ||
57 | |||
58 | |||
59 | /* | ||
60 | * free a usb stream instance | ||
61 | */ | ||
62 | static void snd_usb_audio_stream_free(struct snd_usb_stream *stream) | ||
63 | { | ||
64 | free_substream(&stream->substream[0]); | ||
65 | free_substream(&stream->substream[1]); | ||
66 | list_del(&stream->list); | ||
67 | kfree(stream); | ||
68 | } | ||
69 | |||
70 | static void snd_usb_audio_pcm_free(struct snd_pcm *pcm) | ||
71 | { | ||
72 | struct snd_usb_stream *stream = pcm->private_data; | ||
73 | if (stream) { | ||
74 | stream->pcm = NULL; | ||
75 | snd_usb_audio_stream_free(stream); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | /* | ||
80 | * initialize the substream instance. | ||
81 | */ | ||
82 | |||
83 | static void snd_usb_init_substream(struct snd_usb_stream *as, | ||
84 | int stream, | ||
85 | struct audioformat *fp) | ||
86 | { | ||
87 | struct snd_usb_substream *subs = &as->substream[stream]; | ||
88 | |||
89 | INIT_LIST_HEAD(&subs->fmt_list); | ||
90 | spin_lock_init(&subs->lock); | ||
91 | |||
92 | subs->stream = as; | ||
93 | subs->direction = stream; | ||
94 | subs->dev = as->chip->dev; | ||
95 | subs->txfr_quirk = as->chip->txfr_quirk; | ||
96 | subs->speed = snd_usb_get_speed(subs->dev); | ||
97 | |||
98 | snd_usb_set_pcm_ops(as->pcm, stream); | ||
99 | |||
100 | list_add_tail(&fp->list, &subs->fmt_list); | ||
101 | subs->formats |= fp->formats; | ||
102 | subs->num_formats++; | ||
103 | subs->fmt_type = fp->fmt_type; | ||
104 | subs->ep_num = fp->endpoint; | ||
105 | if (fp->channels > subs->channels_max) | ||
106 | subs->channels_max = fp->channels; | ||
107 | } | ||
108 | |||
109 | /* kctl callbacks for usb-audio channel maps */ | ||
110 | static int usb_chmap_ctl_info(struct snd_kcontrol *kcontrol, | ||
111 | struct snd_ctl_elem_info *uinfo) | ||
112 | { | ||
113 | struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); | ||
114 | struct snd_usb_substream *subs = info->private_data; | ||
115 | |||
116 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
117 | uinfo->count = subs->channels_max; | ||
118 | uinfo->value.integer.min = 0; | ||
119 | uinfo->value.integer.max = SNDRV_CHMAP_LAST; | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | /* check whether a duplicated entry exists in the audiofmt list */ | ||
124 | static bool have_dup_chmap(struct snd_usb_substream *subs, | ||
125 | struct audioformat *fp) | ||
126 | { | ||
127 | struct list_head *p; | ||
128 | |||
129 | for (p = fp->list.prev; p != &subs->fmt_list; p = p->prev) { | ||
130 | struct audioformat *prev; | ||
131 | prev = list_entry(p, struct audioformat, list); | ||
132 | if (prev->chmap && | ||
133 | !memcmp(prev->chmap, fp->chmap, sizeof(*fp->chmap))) | ||
134 | return true; | ||
135 | } | ||
136 | return false; | ||
137 | } | ||
138 | |||
139 | static int usb_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag, | ||
140 | unsigned int size, unsigned int __user *tlv) | ||
141 | { | ||
142 | struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); | ||
143 | struct snd_usb_substream *subs = info->private_data; | ||
144 | struct audioformat *fp; | ||
145 | unsigned int __user *dst; | ||
146 | int count = 0; | ||
147 | |||
148 | if (size < 8) | ||
149 | return -ENOMEM; | ||
150 | if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv)) | ||
151 | return -EFAULT; | ||
152 | size -= 8; | ||
153 | dst = tlv + 2; | ||
154 | list_for_each_entry(fp, &subs->fmt_list, list) { | ||
155 | int i, ch_bytes; | ||
156 | |||
157 | if (!fp->chmap) | ||
158 | continue; | ||
159 | if (have_dup_chmap(subs, fp)) | ||
160 | continue; | ||
161 | /* copy the entry */ | ||
162 | ch_bytes = fp->chmap->channels * 4; | ||
163 | if (size < 8 + ch_bytes) | ||
164 | return -ENOMEM; | ||
165 | if (put_user(SNDRV_CTL_TLVT_CHMAP_FIXED, dst) || | ||
166 | put_user(ch_bytes, dst + 1)) | ||
167 | return -EFAULT; | ||
168 | dst += 2; | ||
169 | for (i = 0; i < fp->chmap->channels; i++, dst++) { | ||
170 | if (put_user(fp->chmap->map[i], dst)) | ||
171 | return -EFAULT; | ||
172 | } | ||
173 | |||
174 | count += 8 + ch_bytes; | ||
175 | size -= 8 + ch_bytes; | ||
176 | } | ||
177 | if (put_user(count, tlv + 1)) | ||
178 | return -EFAULT; | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int usb_chmap_ctl_get(struct snd_kcontrol *kcontrol, | ||
183 | struct snd_ctl_elem_value *ucontrol) | ||
184 | { | ||
185 | struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); | ||
186 | struct snd_usb_substream *subs = info->private_data; | ||
187 | struct snd_pcm_chmap_elem *chmap = NULL; | ||
188 | int i; | ||
189 | |||
190 | memset(ucontrol->value.integer.value, 0, | ||
191 | sizeof(ucontrol->value.integer.value)); | ||
192 | if (subs->cur_audiofmt) | ||
193 | chmap = subs->cur_audiofmt->chmap; | ||
194 | if (chmap) { | ||
195 | for (i = 0; i < chmap->channels; i++) | ||
196 | ucontrol->value.integer.value[i] = chmap->map[i]; | ||
197 | } | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | /* create a chmap kctl assigned to the given USB substream */ | ||
202 | static int add_chmap(struct snd_pcm *pcm, int stream, | ||
203 | struct snd_usb_substream *subs) | ||
204 | { | ||
205 | struct audioformat *fp; | ||
206 | struct snd_pcm_chmap *chmap; | ||
207 | struct snd_kcontrol *kctl; | ||
208 | int err; | ||
209 | |||
210 | list_for_each_entry(fp, &subs->fmt_list, list) | ||
211 | if (fp->chmap) | ||
212 | goto ok; | ||
213 | /* no chmap is found */ | ||
214 | return 0; | ||
215 | |||
216 | ok: | ||
217 | err = snd_pcm_add_chmap_ctls(pcm, stream, NULL, 0, 0, &chmap); | ||
218 | if (err < 0) | ||
219 | return err; | ||
220 | |||
221 | /* override handlers */ | ||
222 | chmap->private_data = subs; | ||
223 | kctl = chmap->kctl; | ||
224 | kctl->info = usb_chmap_ctl_info; | ||
225 | kctl->get = usb_chmap_ctl_get; | ||
226 | kctl->tlv.c = usb_chmap_ctl_tlv; | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | /* convert from USB ChannelConfig bits to ALSA chmap element */ | ||
232 | static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits, | ||
233 | int protocol) | ||
234 | { | ||
235 | static unsigned int uac1_maps[] = { | ||
236 | SNDRV_CHMAP_FL, /* left front */ | ||
237 | SNDRV_CHMAP_FR, /* right front */ | ||
238 | SNDRV_CHMAP_FC, /* center front */ | ||
239 | SNDRV_CHMAP_LFE, /* LFE */ | ||
240 | SNDRV_CHMAP_SL, /* left surround */ | ||
241 | SNDRV_CHMAP_SR, /* right surround */ | ||
242 | SNDRV_CHMAP_FLC, /* left of center */ | ||
243 | SNDRV_CHMAP_FRC, /* right of center */ | ||
244 | SNDRV_CHMAP_RC, /* surround */ | ||
245 | SNDRV_CHMAP_SL, /* side left */ | ||
246 | SNDRV_CHMAP_SR, /* side right */ | ||
247 | SNDRV_CHMAP_TC, /* top */ | ||
248 | 0 /* terminator */ | ||
249 | }; | ||
250 | static unsigned int uac2_maps[] = { | ||
251 | SNDRV_CHMAP_FL, /* front left */ | ||
252 | SNDRV_CHMAP_FR, /* front right */ | ||
253 | SNDRV_CHMAP_FC, /* front center */ | ||
254 | SNDRV_CHMAP_LFE, /* LFE */ | ||
255 | SNDRV_CHMAP_RL, /* back left */ | ||
256 | SNDRV_CHMAP_RR, /* back right */ | ||
257 | SNDRV_CHMAP_FLC, /* front left of center */ | ||
258 | SNDRV_CHMAP_FRC, /* front right of center */ | ||
259 | SNDRV_CHMAP_RC, /* back center */ | ||
260 | SNDRV_CHMAP_SL, /* side left */ | ||
261 | SNDRV_CHMAP_SR, /* side right */ | ||
262 | SNDRV_CHMAP_TC, /* top center */ | ||
263 | SNDRV_CHMAP_TFL, /* top front left */ | ||
264 | SNDRV_CHMAP_TFC, /* top front center */ | ||
265 | SNDRV_CHMAP_TFR, /* top front right */ | ||
266 | SNDRV_CHMAP_TRL, /* top back left */ | ||
267 | SNDRV_CHMAP_TRC, /* top back center */ | ||
268 | SNDRV_CHMAP_TRR, /* top back right */ | ||
269 | SNDRV_CHMAP_TFLC, /* top front left of center */ | ||
270 | SNDRV_CHMAP_TFRC, /* top front right of center */ | ||
271 | SNDRV_CHMAP_LLFE, /* left LFE */ | ||
272 | SNDRV_CHMAP_RLFE, /* right LFE */ | ||
273 | SNDRV_CHMAP_TSL, /* top side left */ | ||
274 | SNDRV_CHMAP_TSR, /* top side right */ | ||
275 | SNDRV_CHMAP_BC, /* bottom center */ | ||
276 | SNDRV_CHMAP_BLC, /* bottom left center */ | ||
277 | SNDRV_CHMAP_BRC, /* bottom right center */ | ||
278 | 0 /* terminator */ | ||
279 | }; | ||
280 | struct snd_pcm_chmap_elem *chmap; | ||
281 | const unsigned int *maps; | ||
282 | int c; | ||
283 | |||
284 | if (!bits) | ||
285 | return NULL; | ||
286 | if (channels > ARRAY_SIZE(chmap->map)) | ||
287 | return NULL; | ||
288 | |||
289 | chmap = kzalloc(sizeof(*chmap), GFP_KERNEL); | ||
290 | if (!chmap) | ||
291 | return NULL; | ||
292 | |||
293 | maps = protocol == UAC_VERSION_2 ? uac2_maps : uac1_maps; | ||
294 | chmap->channels = channels; | ||
295 | c = 0; | ||
296 | for (; bits && *maps; maps++, bits >>= 1) { | ||
297 | if (bits & 1) | ||
298 | chmap->map[c++] = *maps; | ||
299 | } | ||
300 | |||
301 | for (; c < channels; c++) | ||
302 | chmap->map[c] = SNDRV_CHMAP_UNKNOWN; | ||
303 | |||
304 | return chmap; | ||
305 | } | ||
306 | |||
307 | /* | ||
308 | * add this endpoint to the chip instance. | ||
309 | * if a stream with the same endpoint already exists, append to it. | ||
310 | * if not, create a new pcm stream. | ||
311 | */ | ||
312 | int snd_usb_add_audio_stream(struct snd_usb_audio *chip, | ||
313 | int stream, | ||
314 | struct audioformat *fp) | ||
315 | { | ||
316 | struct list_head *p; | ||
317 | struct snd_usb_stream *as; | ||
318 | struct snd_usb_substream *subs; | ||
319 | struct snd_pcm *pcm; | ||
320 | int err; | ||
321 | |||
322 | list_for_each(p, &chip->pcm_list) { | ||
323 | as = list_entry(p, struct snd_usb_stream, list); | ||
324 | if (as->fmt_type != fp->fmt_type) | ||
325 | continue; | ||
326 | subs = &as->substream[stream]; | ||
327 | if (subs->ep_num == fp->endpoint) { | ||
328 | list_add_tail(&fp->list, &subs->fmt_list); | ||
329 | subs->num_formats++; | ||
330 | subs->formats |= fp->formats; | ||
331 | return 0; | ||
332 | } | ||
333 | } | ||
334 | /* look for an empty stream */ | ||
335 | list_for_each(p, &chip->pcm_list) { | ||
336 | as = list_entry(p, struct snd_usb_stream, list); | ||
337 | if (as->fmt_type != fp->fmt_type) | ||
338 | continue; | ||
339 | subs = &as->substream[stream]; | ||
340 | if (subs->ep_num) | ||
341 | continue; | ||
342 | err = snd_pcm_new_stream(as->pcm, stream, 1); | ||
343 | if (err < 0) | ||
344 | return err; | ||
345 | snd_usb_init_substream(as, stream, fp); | ||
346 | return add_chmap(as->pcm, stream, subs); | ||
347 | } | ||
348 | |||
349 | /* create a new pcm */ | ||
350 | as = kzalloc(sizeof(*as), GFP_KERNEL); | ||
351 | if (!as) | ||
352 | return -ENOMEM; | ||
353 | as->pcm_index = chip->pcm_devs; | ||
354 | as->chip = chip; | ||
355 | as->fmt_type = fp->fmt_type; | ||
356 | err = snd_pcm_new(chip->card, "USB Audio", chip->pcm_devs, | ||
357 | stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0, | ||
358 | stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1, | ||
359 | &pcm); | ||
360 | if (err < 0) { | ||
361 | kfree(as); | ||
362 | return err; | ||
363 | } | ||
364 | as->pcm = pcm; | ||
365 | pcm->private_data = as; | ||
366 | pcm->private_free = snd_usb_audio_pcm_free; | ||
367 | pcm->info_flags = 0; | ||
368 | if (chip->pcm_devs > 0) | ||
369 | sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs); | ||
370 | else | ||
371 | strcpy(pcm->name, "USB Audio"); | ||
372 | |||
373 | snd_usb_init_substream(as, stream, fp); | ||
374 | |||
375 | list_add(&as->list, &chip->pcm_list); | ||
376 | chip->pcm_devs++; | ||
377 | |||
378 | snd_usb_proc_pcm_format_add(as); | ||
379 | |||
380 | return add_chmap(pcm, stream, &as->substream[stream]); | ||
381 | } | ||
382 | |||
383 | static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip, | ||
384 | struct usb_host_interface *alts, | ||
385 | int protocol, int iface_no) | ||
386 | { | ||
387 | /* parsed with a v1 header here. that's ok as we only look at the | ||
388 | * header first which is the same for both versions */ | ||
389 | struct uac_iso_endpoint_descriptor *csep; | ||
390 | struct usb_interface_descriptor *altsd = get_iface_desc(alts); | ||
391 | int attributes = 0; | ||
392 | |||
393 | csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT); | ||
394 | |||
395 | /* Creamware Noah has this descriptor after the 2nd endpoint */ | ||
396 | if (!csep && altsd->bNumEndpoints >= 2) | ||
397 | csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); | ||
398 | |||
399 | if (!csep || csep->bLength < 7 || | ||
400 | csep->bDescriptorSubtype != UAC_EP_GENERAL) { | ||
401 | snd_printk(KERN_WARNING "%d:%u:%d : no or invalid" | ||
402 | " class specific endpoint descriptor\n", | ||
403 | chip->dev->devnum, iface_no, | ||
404 | altsd->bAlternateSetting); | ||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | if (protocol == UAC_VERSION_1) { | ||
409 | attributes = csep->bmAttributes; | ||
410 | } else { | ||
411 | struct uac2_iso_endpoint_descriptor *csep2 = | ||
412 | (struct uac2_iso_endpoint_descriptor *) csep; | ||
413 | |||
414 | attributes = csep->bmAttributes & UAC_EP_CS_ATTR_FILL_MAX; | ||
415 | |||
416 | /* emulate the endpoint attributes of a v1 device */ | ||
417 | if (csep2->bmControls & UAC2_CONTROL_PITCH) | ||
418 | attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL; | ||
419 | } | ||
420 | |||
421 | return attributes; | ||
422 | } | ||
423 | |||
424 | /* find an input terminal descriptor (either UAC1 or UAC2) with the given | ||
425 | * terminal id | ||
426 | */ | ||
427 | static void * | ||
428 | snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface, | ||
429 | int terminal_id) | ||
430 | { | ||
431 | struct uac2_input_terminal_descriptor *term = NULL; | ||
432 | |||
433 | while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, | ||
434 | ctrl_iface->extralen, | ||
435 | term, UAC_INPUT_TERMINAL))) { | ||
436 | if (term->bTerminalID == terminal_id) | ||
437 | return term; | ||
438 | } | ||
439 | |||
440 | return NULL; | ||
441 | } | ||
442 | |||
443 | static struct uac2_output_terminal_descriptor * | ||
444 | snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface, | ||
445 | int terminal_id) | ||
446 | { | ||
447 | struct uac2_output_terminal_descriptor *term = NULL; | ||
448 | |||
449 | while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, | ||
450 | ctrl_iface->extralen, | ||
451 | term, UAC_OUTPUT_TERMINAL))) { | ||
452 | if (term->bTerminalID == terminal_id) | ||
453 | return term; | ||
454 | } | ||
455 | |||
456 | return NULL; | ||
457 | } | ||
458 | |||
459 | int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) | ||
460 | { | ||
461 | struct usb_device *dev; | ||
462 | struct usb_interface *iface; | ||
463 | struct usb_host_interface *alts; | ||
464 | struct usb_interface_descriptor *altsd; | ||
465 | int i, altno, err, stream; | ||
466 | int format = 0, num_channels = 0; | ||
467 | struct audioformat *fp = NULL; | ||
468 | int num, protocol, clock = 0; | ||
469 | struct uac_format_type_i_continuous_descriptor *fmt; | ||
470 | unsigned int chconfig; | ||
471 | |||
472 | dev = chip->dev; | ||
473 | |||
474 | /* parse the interface's altsettings */ | ||
475 | iface = usb_ifnum_to_if(dev, iface_no); | ||
476 | |||
477 | num = iface->num_altsetting; | ||
478 | |||
479 | /* | ||
480 | * Dallas DS4201 workaround: It presents 5 altsettings, but the last | ||
481 | * one misses syncpipe, and does not produce any sound. | ||
482 | */ | ||
483 | if (chip->usb_id == USB_ID(0x04fa, 0x4201)) | ||
484 | num = 4; | ||
485 | |||
486 | for (i = 0; i < num; i++) { | ||
487 | alts = &iface->altsetting[i]; | ||
488 | altsd = get_iface_desc(alts); | ||
489 | protocol = altsd->bInterfaceProtocol; | ||
490 | /* skip invalid one */ | ||
491 | if ((altsd->bInterfaceClass != USB_CLASS_AUDIO && | ||
492 | altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || | ||
493 | (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING && | ||
494 | altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) || | ||
495 | altsd->bNumEndpoints < 1 || | ||
496 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0) | ||
497 | continue; | ||
498 | /* must be isochronous */ | ||
499 | if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != | ||
500 | USB_ENDPOINT_XFER_ISOC) | ||
501 | continue; | ||
502 | /* check direction */ | ||
503 | stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ? | ||
504 | SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; | ||
505 | altno = altsd->bAlternateSetting; | ||
506 | |||
507 | if (snd_usb_apply_interface_quirk(chip, iface_no, altno)) | ||
508 | continue; | ||
509 | |||
510 | chconfig = 0; | ||
511 | /* get audio formats */ | ||
512 | switch (protocol) { | ||
513 | default: | ||
514 | snd_printdd(KERN_WARNING "%d:%u:%d: unknown interface protocol %#02x, assuming v1\n", | ||
515 | dev->devnum, iface_no, altno, protocol); | ||
516 | protocol = UAC_VERSION_1; | ||
517 | /* fall through */ | ||
518 | |||
519 | case UAC_VERSION_1: { | ||
520 | struct uac1_as_header_descriptor *as = | ||
521 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); | ||
522 | struct uac_input_terminal_descriptor *iterm; | ||
523 | |||
524 | if (!as) { | ||
525 | snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n", | ||
526 | dev->devnum, iface_no, altno); | ||
527 | continue; | ||
528 | } | ||
529 | |||
530 | if (as->bLength < sizeof(*as)) { | ||
531 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n", | ||
532 | dev->devnum, iface_no, altno); | ||
533 | continue; | ||
534 | } | ||
535 | |||
536 | format = le16_to_cpu(as->wFormatTag); /* remember the format value */ | ||
537 | |||
538 | iterm = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, | ||
539 | as->bTerminalLink); | ||
540 | if (iterm) { | ||
541 | num_channels = iterm->bNrChannels; | ||
542 | chconfig = le16_to_cpu(iterm->wChannelConfig); | ||
543 | } | ||
544 | |||
545 | break; | ||
546 | } | ||
547 | |||
548 | case UAC_VERSION_2: { | ||
549 | struct uac2_input_terminal_descriptor *input_term; | ||
550 | struct uac2_output_terminal_descriptor *output_term; | ||
551 | struct uac2_as_header_descriptor *as = | ||
552 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); | ||
553 | |||
554 | if (!as) { | ||
555 | snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n", | ||
556 | dev->devnum, iface_no, altno); | ||
557 | continue; | ||
558 | } | ||
559 | |||
560 | if (as->bLength < sizeof(*as)) { | ||
561 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n", | ||
562 | dev->devnum, iface_no, altno); | ||
563 | continue; | ||
564 | } | ||
565 | |||
566 | num_channels = as->bNrChannels; | ||
567 | format = le32_to_cpu(as->bmFormats); | ||
568 | |||
569 | /* lookup the terminal associated to this interface | ||
570 | * to extract the clock */ | ||
571 | input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, | ||
572 | as->bTerminalLink); | ||
573 | if (input_term) { | ||
574 | clock = input_term->bCSourceID; | ||
575 | chconfig = le32_to_cpu(input_term->bmChannelConfig); | ||
576 | break; | ||
577 | } | ||
578 | |||
579 | output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, | ||
580 | as->bTerminalLink); | ||
581 | if (output_term) { | ||
582 | clock = output_term->bCSourceID; | ||
583 | break; | ||
584 | } | ||
585 | |||
586 | snd_printk(KERN_ERR "%d:%u:%d : bogus bTerminalLink %d\n", | ||
587 | dev->devnum, iface_no, altno, as->bTerminalLink); | ||
588 | continue; | ||
589 | } | ||
590 | } | ||
591 | |||
592 | /* get format type */ | ||
593 | fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE); | ||
594 | if (!fmt) { | ||
595 | snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n", | ||
596 | dev->devnum, iface_no, altno); | ||
597 | continue; | ||
598 | } | ||
599 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || | ||
600 | ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) { | ||
601 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", | ||
602 | dev->devnum, iface_no, altno); | ||
603 | continue; | ||
604 | } | ||
605 | |||
606 | /* | ||
607 | * Blue Microphones workaround: The last altsetting is identical | ||
608 | * with the previous one, except for a larger packet size, but | ||
609 | * is actually a mislabeled two-channel setting; ignore it. | ||
610 | */ | ||
611 | if (fmt->bNrChannels == 1 && | ||
612 | fmt->bSubframeSize == 2 && | ||
613 | altno == 2 && num == 3 && | ||
614 | fp && fp->altsetting == 1 && fp->channels == 1 && | ||
615 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && | ||
616 | protocol == UAC_VERSION_1 && | ||
617 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == | ||
618 | fp->maxpacksize * 2) | ||
619 | continue; | ||
620 | |||
621 | fp = kzalloc(sizeof(*fp), GFP_KERNEL); | ||
622 | if (! fp) { | ||
623 | snd_printk(KERN_ERR "cannot malloc\n"); | ||
624 | return -ENOMEM; | ||
625 | } | ||
626 | |||
627 | fp->iface = iface_no; | ||
628 | fp->altsetting = altno; | ||
629 | fp->altset_idx = i; | ||
630 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; | ||
631 | fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; | ||
632 | fp->datainterval = snd_usb_parse_datainterval(chip, alts); | ||
633 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); | ||
634 | fp->channels = num_channels; | ||
635 | if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) | ||
636 | fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) | ||
637 | * (fp->maxpacksize & 0x7ff); | ||
638 | fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no); | ||
639 | fp->clock = clock; | ||
640 | fp->chmap = convert_chmap(num_channels, chconfig, protocol); | ||
641 | |||
642 | /* some quirks for attributes here */ | ||
643 | |||
644 | switch (chip->usb_id) { | ||
645 | case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */ | ||
646 | /* Optoplay sets the sample rate attribute although | ||
647 | * it seems not supporting it in fact. | ||
648 | */ | ||
649 | fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE; | ||
650 | break; | ||
651 | case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */ | ||
652 | case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ | ||
653 | /* doesn't set the sample rate attribute, but supports it */ | ||
654 | fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE; | ||
655 | break; | ||
656 | case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */ | ||
657 | case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */ | ||
658 | case USB_ID(0x047f, 0x0ca1): /* plantronics headset */ | ||
659 | case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is | ||
660 | an older model 77d:223) */ | ||
661 | /* | ||
662 | * plantronics headset and Griffin iMic have set adaptive-in | ||
663 | * although it's really not... | ||
664 | */ | ||
665 | fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE; | ||
666 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
667 | fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE; | ||
668 | else | ||
669 | fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC; | ||
670 | break; | ||
671 | } | ||
672 | |||
673 | /* ok, let's parse further... */ | ||
674 | if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) { | ||
675 | kfree(fp->rate_table); | ||
676 | kfree(fp->chmap); | ||
677 | kfree(fp); | ||
678 | fp = NULL; | ||
679 | continue; | ||
680 | } | ||
681 | |||
682 | snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint); | ||
683 | err = snd_usb_add_audio_stream(chip, stream, fp); | ||
684 | if (err < 0) { | ||
685 | kfree(fp->rate_table); | ||
686 | kfree(fp->chmap); | ||
687 | kfree(fp); | ||
688 | return err; | ||
689 | } | ||
690 | /* try to set the interface... */ | ||
691 | usb_set_interface(chip->dev, iface_no, altno); | ||
692 | snd_usb_init_pitch(chip, iface_no, alts, fp); | ||
693 | snd_usb_init_sample_rate(chip, iface_no, alts, fp, fp->rate_max); | ||
694 | } | ||
695 | return 0; | ||
696 | } | ||
697 | |||
diff --git a/sound/usb/stream.h b/sound/usb/stream.h deleted file mode 100644 index c97f679fc84..00000000000 --- a/sound/usb/stream.h +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | #ifndef __USBAUDIO_STREAM_H | ||
2 | #define __USBAUDIO_STREAM_H | ||
3 | |||
4 | int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, | ||
5 | int iface_no); | ||
6 | |||
7 | int snd_usb_add_audio_stream(struct snd_usb_audio *chip, | ||
8 | int stream, | ||
9 | struct audioformat *fp); | ||
10 | |||
11 | #endif /* __USBAUDIO_STREAM_H */ | ||
12 | |||
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 1ac3fd9cc5a..1e79986b577 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
@@ -36,8 +36,7 @@ struct snd_usb_audio { | |||
36 | struct snd_card *card; | 36 | struct snd_card *card; |
37 | struct usb_interface *pm_intf; | 37 | struct usb_interface *pm_intf; |
38 | u32 usb_id; | 38 | u32 usb_id; |
39 | struct mutex mutex; | 39 | struct mutex shutdown_mutex; |
40 | struct rw_semaphore shutdown_rwsem; | ||
41 | unsigned int shutdown:1; | 40 | unsigned int shutdown:1; |
42 | unsigned int probing:1; | 41 | unsigned int probing:1; |
43 | unsigned int autosuspended:1; | 42 | unsigned int autosuspended:1; |
@@ -47,7 +46,6 @@ struct snd_usb_audio { | |||
47 | int num_suspended_intf; | 46 | int num_suspended_intf; |
48 | 47 | ||
49 | struct list_head pcm_list; /* list of pcm streams */ | 48 | struct list_head pcm_list; /* list of pcm streams */ |
50 | struct list_head ep_list; /* list of audio-related endpoints */ | ||
51 | int pcm_devs; | 49 | int pcm_devs; |
52 | 50 | ||
53 | struct list_head midi_list; /* list of midi interfaces */ | 51 | struct list_head midi_list; /* list of midi interfaces */ |
@@ -56,6 +54,7 @@ struct snd_usb_audio { | |||
56 | 54 | ||
57 | int setup; /* from the 'device_setup' module param */ | 55 | int setup; /* from the 'device_setup' module param */ |
58 | int nrpacks; /* from the 'nrpacks' module param */ | 56 | int nrpacks; /* from the 'nrpacks' module param */ |
57 | int async_unlink; /* from the 'async_unlink' module param */ | ||
59 | 58 | ||
60 | struct usb_host_interface *ctrl_intf; /* the audio control interface */ | 59 | struct usb_host_interface *ctrl_intf; /* the audio control interface */ |
61 | }; | 60 | }; |
@@ -81,7 +80,6 @@ enum quirk_type { | |||
81 | QUIRK_MIDI_CME, | 80 | QUIRK_MIDI_CME, |
82 | QUIRK_MIDI_AKAI, | 81 | QUIRK_MIDI_AKAI, |
83 | QUIRK_MIDI_US122L, | 82 | QUIRK_MIDI_US122L, |
84 | QUIRK_MIDI_FTDI, | ||
85 | QUIRK_AUDIO_STANDARD_INTERFACE, | 83 | QUIRK_AUDIO_STANDARD_INTERFACE, |
86 | QUIRK_AUDIO_FIXED_ENDPOINT, | 84 | QUIRK_AUDIO_FIXED_ENDPOINT, |
87 | QUIRK_AUDIO_EDIROL_UAXX, | 85 | QUIRK_AUDIO_EDIROL_UAXX, |
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c index d0323a693ba..084e6fc8d5b 100644 --- a/sound/usb/usx2y/us122l.c +++ b/sound/usb/usx2y/us122l.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/usb.h> | 20 | #include <linux/usb.h> |
21 | #include <linux/usb/audio.h> | 21 | #include <linux/usb/audio.h> |
22 | #include <linux/module.h> | ||
23 | #include <sound/core.h> | 22 | #include <sound/core.h> |
24 | #include <sound/hwdep.h> | 23 | #include <sound/hwdep.h> |
25 | #include <sound/pcm.h> | 24 | #include <sound/pcm.h> |
@@ -37,7 +36,7 @@ MODULE_LICENSE("GPL"); | |||
37 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ | 36 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ |
38 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ | 37 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ |
39 | /* Enable this card */ | 38 | /* Enable this card */ |
40 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | 39 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; |
41 | 40 | ||
42 | module_param_array(index, int, NULL, 0444); | 41 | module_param_array(index, int, NULL, 0444); |
43 | MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS"."); | 42 | MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS"."); |
@@ -262,7 +261,7 @@ static int usb_stream_hwdep_mmap(struct snd_hwdep *hw, | |||
262 | } | 261 | } |
263 | 262 | ||
264 | area->vm_ops = &usb_stream_hwdep_vm_ops; | 263 | area->vm_ops = &usb_stream_hwdep_vm_ops; |
265 | area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; | 264 | area->vm_flags |= VM_RESERVED; |
266 | area->vm_private_data = us122l; | 265 | area->vm_private_data = us122l; |
267 | atomic_inc(&us122l->mmap_count); | 266 | atomic_inc(&us122l->mmap_count); |
268 | out: | 267 | out: |
@@ -772,4 +771,16 @@ static struct usb_driver snd_us122l_usb_driver = { | |||
772 | .supports_autosuspend = 1 | 771 | .supports_autosuspend = 1 |
773 | }; | 772 | }; |
774 | 773 | ||
775 | module_usb_driver(snd_us122l_usb_driver); | 774 | |
775 | static int __init snd_us122l_module_init(void) | ||
776 | { | ||
777 | return usb_register(&snd_us122l_usb_driver); | ||
778 | } | ||
779 | |||
780 | static void __exit snd_us122l_module_exit(void) | ||
781 | { | ||
782 | usb_deregister(&snd_us122l_usb_driver); | ||
783 | } | ||
784 | |||
785 | module_init(snd_us122l_module_init) | ||
786 | module_exit(snd_us122l_module_exit) | ||
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c index 0b34dbc8f30..04aafb43a13 100644 --- a/sound/usb/usx2y/usX2Yhwdep.c +++ b/sound/usb/usx2y/usX2Yhwdep.c | |||
@@ -82,7 +82,7 @@ static int snd_us428ctls_mmap(struct snd_hwdep * hw, struct file *filp, struct v | |||
82 | us428->us428ctls_sharedmem->CtlSnapShotLast = -2; | 82 | us428->us428ctls_sharedmem->CtlSnapShotLast = -2; |
83 | } | 83 | } |
84 | area->vm_ops = &us428ctls_vm_ops; | 84 | area->vm_ops = &us428ctls_vm_ops; |
85 | area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; | 85 | area->vm_flags |= VM_RESERVED | VM_DONTEXPAND; |
86 | area->vm_private_data = hw->private_data; | 86 | area->vm_private_data = hw->private_data; |
87 | return 0; | 87 | return 0; |
88 | } | 88 | } |
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c index 9af7c1f1741..cbd37f2c76d 100644 --- a/sound/usb/usx2y/usbusx2y.c +++ b/sound/usb/usx2y/usbusx2y.c | |||
@@ -154,7 +154,7 @@ MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007 | |||
154 | 154 | ||
155 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ | 155 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ |
156 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ | 156 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ |
157 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ | 157 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ |
158 | 158 | ||
159 | module_param_array(index, int, NULL, 0444); | 159 | module_param_array(index, int, NULL, 0444); |
160 | MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS"."); | 160 | MODULE_PARM_DESC(index, "Index value for "NAME_ALLCAPS"."); |
@@ -459,4 +459,15 @@ static void usX2Y_usb_disconnect(struct usb_device *device, void* ptr) | |||
459 | } | 459 | } |
460 | } | 460 | } |
461 | 461 | ||
462 | module_usb_driver(snd_usX2Y_usb_driver); | 462 | static int __init snd_usX2Y_module_init(void) |
463 | { | ||
464 | return usb_register(&snd_usX2Y_usb_driver); | ||
465 | } | ||
466 | |||
467 | static void __exit snd_usX2Y_module_exit(void) | ||
468 | { | ||
469 | usb_deregister(&snd_usX2Y_usb_driver); | ||
470 | } | ||
471 | |||
472 | module_init(snd_usX2Y_module_init) | ||
473 | module_exit(snd_usX2Y_module_exit) | ||
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index 520ef96d7c7..5d37d1ccf81 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/usb.h> | 36 | #include <linux/usb.h> |
37 | #include <linux/moduleparam.h> | ||
38 | #include <sound/core.h> | 37 | #include <sound/core.h> |
39 | #include <sound/info.h> | 38 | #include <sound/info.h> |
40 | #include <sound/pcm.h> | 39 | #include <sound/pcm.h> |
@@ -80,7 +79,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; | 79 | cp = (unsigned char*)urb->transfer_buffer + urb->iso_frame_desc[i].offset; |
81 | if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */ | 80 | if (urb->iso_frame_desc[i].status) { /* active? hmm, skip this */ |
82 | snd_printk(KERN_ERR "active frame status %i. " | 81 | snd_printk(KERN_ERR "active frame status %i. " |
83 | "Most probably some hardware problem.\n", | 82 | "Most propably some hardware problem.\n", |
84 | urb->iso_frame_desc[i].status); | 83 | urb->iso_frame_desc[i].status); |
85 | return urb->iso_frame_desc[i].status; | 84 | return urb->iso_frame_desc[i].status; |
86 | } | 85 | } |
@@ -300,7 +299,7 @@ static void usX2Y_error_sequence(struct usX2Ydev *usX2Y, | |||
300 | { | 299 | { |
301 | snd_printk(KERN_ERR | 300 | snd_printk(KERN_ERR |
302 | "Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n" | 301 | "Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n" |
303 | "Most probably some urb of usb-frame %i is still missing.\n" | 302 | "Most propably some urb of usb-frame %i is still missing.\n" |
304 | "Cause could be too long delays in usb-hcd interrupt handling.\n", | 303 | "Cause could be too long delays in usb-hcd interrupt handling.\n", |
305 | usb_get_current_frame_number(usX2Y->dev), | 304 | usb_get_current_frame_number(usX2Y->dev), |
306 | subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", | 305 | subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", |
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c index cc56007791e..a51340f6f2d 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 "active frame status %i. Most probably some hardware problem.\n", urb->iso_frame_desc[i].status); | 77 | snd_printk(KERN_ERR "activ frame status %i. Most propably 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; |
@@ -723,7 +723,7 @@ static int snd_usX2Y_hwdep_pcm_mmap(struct snd_hwdep * hw, struct file *filp, st | |||
723 | return -ENODEV; | 723 | return -ENODEV; |
724 | } | 724 | } |
725 | area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops; | 725 | area->vm_ops = &snd_usX2Y_hwdep_pcm_vm_ops; |
726 | area->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; | 726 | area->vm_flags |= VM_RESERVED | VM_DONTEXPAND; |
727 | area->vm_private_data = hw->private_data; | 727 | area->vm_private_data = hw->private_data; |
728 | return 0; | 728 | return 0; |
729 | } | 729 | } |