summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/usb/mixer_us16x08.c92
-rw-r--r--sound/usb/mixer_us16x08.h1
2 files changed, 39 insertions, 54 deletions
diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c
index 73a0b9afdd70..f7289541fbce 100644
--- a/sound/usb/mixer_us16x08.c
+++ b/sound/usb/mixer_us16x08.c
@@ -1053,11 +1053,22 @@ static struct snd_us16x08_meter_store *snd_us16x08_create_meter_store(void)
1053 1053
1054} 1054}
1055 1055
1056/* release elem->private_free as well; called only once for each *_store */
1057static void elem_private_free(struct snd_kcontrol *kctl)
1058{
1059 struct usb_mixer_elem_info *elem = kctl->private_data;
1060
1061 if (elem)
1062 kfree(elem->private_data);
1063 kfree(elem);
1064 kctl->private_data = NULL;
1065}
1066
1056static int add_new_ctl(struct usb_mixer_interface *mixer, 1067static int add_new_ctl(struct usb_mixer_interface *mixer,
1057 const struct snd_kcontrol_new *ncontrol, 1068 const struct snd_kcontrol_new *ncontrol,
1058 int index, int val_type, int channels, 1069 int index, int val_type, int channels,
1059 const char *name, const void *opt, 1070 const char *name, const void *opt,
1060 void (*freeer)(struct snd_kcontrol *kctl), 1071 bool do_private_free,
1061 struct usb_mixer_elem_info **elem_ret) 1072 struct usb_mixer_elem_info **elem_ret)
1062{ 1073{
1063 struct snd_kcontrol *kctl; 1074 struct snd_kcontrol *kctl;
@@ -1085,7 +1096,10 @@ static int add_new_ctl(struct usb_mixer_interface *mixer,
1085 return -ENOMEM; 1096 return -ENOMEM;
1086 } 1097 }
1087 1098
1088 kctl->private_free = freeer; 1099 if (do_private_free)
1100 kctl->private_free = elem_private_free;
1101 else
1102 kctl->private_free = snd_usb_mixer_elem_free;
1089 1103
1090 strlcpy(kctl->id.name, name, sizeof(kctl->id.name)); 1104 strlcpy(kctl->id.name, name, sizeof(kctl->id.name));
1091 1105
@@ -1109,7 +1123,6 @@ static struct snd_us16x08_control_params eq_controls[] = {
1109 .type = USB_MIXER_BOOLEAN, 1123 .type = USB_MIXER_BOOLEAN,
1110 .num_channels = 16, 1124 .num_channels = 16,
1111 .name = "EQ Switch", 1125 .name = "EQ Switch",
1112 .freeer = snd_usb_mixer_elem_free
1113 }, 1126 },
1114 { /* EQ low gain */ 1127 { /* EQ low gain */
1115 .kcontrol_new = &snd_us16x08_eq_gain_ctl, 1128 .kcontrol_new = &snd_us16x08_eq_gain_ctl,
@@ -1117,7 +1130,6 @@ static struct snd_us16x08_control_params eq_controls[] = {
1117 .type = USB_MIXER_U8, 1130 .type = USB_MIXER_U8,
1118 .num_channels = 16, 1131 .num_channels = 16,
1119 .name = "EQ Low Volume", 1132 .name = "EQ Low Volume",
1120 .freeer = snd_usb_mixer_elem_free
1121 }, 1133 },
1122 { /* EQ low freq */ 1134 { /* EQ low freq */
1123 .kcontrol_new = &snd_us16x08_eq_low_freq_ctl, 1135 .kcontrol_new = &snd_us16x08_eq_low_freq_ctl,
@@ -1125,7 +1137,6 @@ static struct snd_us16x08_control_params eq_controls[] = {
1125 .type = USB_MIXER_U8, 1137 .type = USB_MIXER_U8,
1126 .num_channels = 16, 1138 .num_channels = 16,
1127 .name = "EQ Low Frequence", 1139 .name = "EQ Low Frequence",
1128 .freeer = NULL
1129 }, 1140 },
1130 { /* EQ mid low gain */ 1141 { /* EQ mid low gain */
1131 .kcontrol_new = &snd_us16x08_eq_gain_ctl, 1142 .kcontrol_new = &snd_us16x08_eq_gain_ctl,
@@ -1133,7 +1144,6 @@ static struct snd_us16x08_control_params eq_controls[] = {
1133 .type = USB_MIXER_U8, 1144 .type = USB_MIXER_U8,
1134 .num_channels = 16, 1145 .num_channels = 16,
1135 .name = "EQ MidLow Volume", 1146 .name = "EQ MidLow Volume",
1136 .freeer = snd_usb_mixer_elem_free
1137 }, 1147 },
1138 { /* EQ mid low freq */ 1148 { /* EQ mid low freq */
1139 .kcontrol_new = &snd_us16x08_eq_mid_freq_ctl, 1149 .kcontrol_new = &snd_us16x08_eq_mid_freq_ctl,
@@ -1141,7 +1151,6 @@ static struct snd_us16x08_control_params eq_controls[] = {
1141 .type = USB_MIXER_U8, 1151 .type = USB_MIXER_U8,
1142 .num_channels = 16, 1152 .num_channels = 16,
1143 .name = "EQ MidLow Frequence", 1153 .name = "EQ MidLow Frequence",
1144 .freeer = NULL
1145 }, 1154 },
1146 { /* EQ mid low Q */ 1155 { /* EQ mid low Q */
1147 .kcontrol_new = &snd_us16x08_eq_mid_width_ctl, 1156 .kcontrol_new = &snd_us16x08_eq_mid_width_ctl,
@@ -1149,7 +1158,6 @@ static struct snd_us16x08_control_params eq_controls[] = {
1149 .type = USB_MIXER_U8, 1158 .type = USB_MIXER_U8,
1150 .num_channels = 16, 1159 .num_channels = 16,
1151 .name = "EQ MidQLow Q", 1160 .name = "EQ MidQLow Q",
1152 .freeer = NULL
1153 }, 1161 },
1154 { /* EQ mid high gain */ 1162 { /* EQ mid high gain */
1155 .kcontrol_new = &snd_us16x08_eq_gain_ctl, 1163 .kcontrol_new = &snd_us16x08_eq_gain_ctl,
@@ -1157,7 +1165,6 @@ static struct snd_us16x08_control_params eq_controls[] = {
1157 .type = USB_MIXER_U8, 1165 .type = USB_MIXER_U8,
1158 .num_channels = 16, 1166 .num_channels = 16,
1159 .name = "EQ MidHigh Volume", 1167 .name = "EQ MidHigh Volume",
1160 .freeer = snd_usb_mixer_elem_free
1161 }, 1168 },
1162 { /* EQ mid high freq */ 1169 { /* EQ mid high freq */
1163 .kcontrol_new = &snd_us16x08_eq_mid_freq_ctl, 1170 .kcontrol_new = &snd_us16x08_eq_mid_freq_ctl,
@@ -1165,7 +1172,6 @@ static struct snd_us16x08_control_params eq_controls[] = {
1165 .type = USB_MIXER_U8, 1172 .type = USB_MIXER_U8,
1166 .num_channels = 16, 1173 .num_channels = 16,
1167 .name = "EQ MidHigh Frequence", 1174 .name = "EQ MidHigh Frequence",
1168 .freeer = NULL
1169 }, 1175 },
1170 { /* EQ mid high Q */ 1176 { /* EQ mid high Q */
1171 .kcontrol_new = &snd_us16x08_eq_mid_width_ctl, 1177 .kcontrol_new = &snd_us16x08_eq_mid_width_ctl,
@@ -1173,7 +1179,6 @@ static struct snd_us16x08_control_params eq_controls[] = {
1173 .type = USB_MIXER_U8, 1179 .type = USB_MIXER_U8,
1174 .num_channels = 16, 1180 .num_channels = 16,
1175 .name = "EQ MidHigh Q", 1181 .name = "EQ MidHigh Q",
1176 .freeer = NULL
1177 }, 1182 },
1178 { /* EQ high gain */ 1183 { /* EQ high gain */
1179 .kcontrol_new = &snd_us16x08_eq_gain_ctl, 1184 .kcontrol_new = &snd_us16x08_eq_gain_ctl,
@@ -1181,7 +1186,6 @@ static struct snd_us16x08_control_params eq_controls[] = {
1181 .type = USB_MIXER_U8, 1186 .type = USB_MIXER_U8,
1182 .num_channels = 16, 1187 .num_channels = 16,
1183 .name = "EQ High Volume", 1188 .name = "EQ High Volume",
1184 .freeer = snd_usb_mixer_elem_free
1185 }, 1189 },
1186 { /* EQ low freq */ 1190 { /* EQ low freq */
1187 .kcontrol_new = &snd_us16x08_eq_high_freq_ctl, 1191 .kcontrol_new = &snd_us16x08_eq_high_freq_ctl,
@@ -1189,7 +1193,6 @@ static struct snd_us16x08_control_params eq_controls[] = {
1189 .type = USB_MIXER_U8, 1193 .type = USB_MIXER_U8,
1190 .num_channels = 16, 1194 .num_channels = 16,
1191 .name = "EQ High Frequence", 1195 .name = "EQ High Frequence",
1192 .freeer = NULL
1193 }, 1196 },
1194}; 1197};
1195 1198
@@ -1201,7 +1204,6 @@ static struct snd_us16x08_control_params comp_controls[] = {
1201 .type = USB_MIXER_BOOLEAN, 1204 .type = USB_MIXER_BOOLEAN,
1202 .num_channels = 16, 1205 .num_channels = 16,
1203 .name = "Compressor Switch", 1206 .name = "Compressor Switch",
1204 .freeer = snd_usb_mixer_elem_free
1205 }, 1207 },
1206 { /* Comp threshold */ 1208 { /* Comp threshold */
1207 .kcontrol_new = &snd_us16x08_comp_threshold_ctl, 1209 .kcontrol_new = &snd_us16x08_comp_threshold_ctl,
@@ -1209,7 +1211,6 @@ static struct snd_us16x08_control_params comp_controls[] = {
1209 .type = USB_MIXER_U8, 1211 .type = USB_MIXER_U8,
1210 .num_channels = 16, 1212 .num_channels = 16,
1211 .name = "Compressor Threshold Volume", 1213 .name = "Compressor Threshold Volume",
1212 .freeer = NULL
1213 }, 1214 },
1214 { /* Comp ratio */ 1215 { /* Comp ratio */
1215 .kcontrol_new = &snd_us16x08_comp_ratio_ctl, 1216 .kcontrol_new = &snd_us16x08_comp_ratio_ctl,
@@ -1217,7 +1218,6 @@ static struct snd_us16x08_control_params comp_controls[] = {
1217 .type = USB_MIXER_U8, 1218 .type = USB_MIXER_U8,
1218 .num_channels = 16, 1219 .num_channels = 16,
1219 .name = "Compressor Ratio", 1220 .name = "Compressor Ratio",
1220 .freeer = NULL
1221 }, 1221 },
1222 { /* Comp attack */ 1222 { /* Comp attack */
1223 .kcontrol_new = &snd_us16x08_comp_attack_ctl, 1223 .kcontrol_new = &snd_us16x08_comp_attack_ctl,
@@ -1225,7 +1225,6 @@ static struct snd_us16x08_control_params comp_controls[] = {
1225 .type = USB_MIXER_U8, 1225 .type = USB_MIXER_U8,
1226 .num_channels = 16, 1226 .num_channels = 16,
1227 .name = "Compressor Attack", 1227 .name = "Compressor Attack",
1228 .freeer = NULL
1229 }, 1228 },
1230 { /* Comp release */ 1229 { /* Comp release */
1231 .kcontrol_new = &snd_us16x08_comp_release_ctl, 1230 .kcontrol_new = &snd_us16x08_comp_release_ctl,
@@ -1233,7 +1232,6 @@ static struct snd_us16x08_control_params comp_controls[] = {
1233 .type = USB_MIXER_U8, 1232 .type = USB_MIXER_U8,
1234 .num_channels = 16, 1233 .num_channels = 16,
1235 .name = "Compressor Release", 1234 .name = "Compressor Release",
1236 .freeer = NULL
1237 }, 1235 },
1238 { /* Comp gain */ 1236 { /* Comp gain */
1239 .kcontrol_new = &snd_us16x08_comp_gain_ctl, 1237 .kcontrol_new = &snd_us16x08_comp_gain_ctl,
@@ -1241,7 +1239,6 @@ static struct snd_us16x08_control_params comp_controls[] = {
1241 .type = USB_MIXER_U8, 1239 .type = USB_MIXER_U8,
1242 .num_channels = 16, 1240 .num_channels = 16,
1243 .name = "Compressor Volume", 1241 .name = "Compressor Volume",
1244 .freeer = NULL
1245 }, 1242 },
1246}; 1243};
1247 1244
@@ -1253,7 +1250,6 @@ static struct snd_us16x08_control_params channel_controls[] = {
1253 .type = USB_MIXER_BOOLEAN, 1250 .type = USB_MIXER_BOOLEAN,
1254 .num_channels = 16, 1251 .num_channels = 16,
1255 .name = "Phase Switch", 1252 .name = "Phase Switch",
1256 .freeer = snd_usb_mixer_elem_free,
1257 .default_val = 0 1253 .default_val = 0
1258 }, 1254 },
1259 { /* Fader */ 1255 { /* Fader */
@@ -1262,7 +1258,6 @@ static struct snd_us16x08_control_params channel_controls[] = {
1262 .type = USB_MIXER_U8, 1258 .type = USB_MIXER_U8,
1263 .num_channels = 16, 1259 .num_channels = 16,
1264 .name = "Line Volume", 1260 .name = "Line Volume",
1265 .freeer = NULL,
1266 .default_val = 127 1261 .default_val = 127
1267 }, 1262 },
1268 { /* Mute */ 1263 { /* Mute */
@@ -1271,7 +1266,6 @@ static struct snd_us16x08_control_params channel_controls[] = {
1271 .type = USB_MIXER_BOOLEAN, 1266 .type = USB_MIXER_BOOLEAN,
1272 .num_channels = 16, 1267 .num_channels = 16,
1273 .name = "Mute Switch", 1268 .name = "Mute Switch",
1274 .freeer = NULL,
1275 .default_val = 0 1269 .default_val = 0
1276 }, 1270 },
1277 { /* Pan */ 1271 { /* Pan */
@@ -1280,7 +1274,6 @@ static struct snd_us16x08_control_params channel_controls[] = {
1280 .type = USB_MIXER_U16, 1274 .type = USB_MIXER_U16,
1281 .num_channels = 16, 1275 .num_channels = 16,
1282 .name = "Pan Left-Right Volume", 1276 .name = "Pan Left-Right Volume",
1283 .freeer = NULL,
1284 .default_val = 127 1277 .default_val = 127
1285 }, 1278 },
1286}; 1279};
@@ -1293,7 +1286,6 @@ static struct snd_us16x08_control_params master_controls[] = {
1293 .type = USB_MIXER_U8, 1286 .type = USB_MIXER_U8,
1294 .num_channels = 16, 1287 .num_channels = 16,
1295 .name = "Master Volume", 1288 .name = "Master Volume",
1296 .freeer = NULL,
1297 .default_val = 127 1289 .default_val = 127
1298 }, 1290 },
1299 { /* Bypass */ 1291 { /* Bypass */
@@ -1302,7 +1294,6 @@ static struct snd_us16x08_control_params master_controls[] = {
1302 .type = USB_MIXER_BOOLEAN, 1294 .type = USB_MIXER_BOOLEAN,
1303 .num_channels = 16, 1295 .num_channels = 16,
1304 .name = "DSP Bypass Switch", 1296 .name = "DSP Bypass Switch",
1305 .freeer = NULL,
1306 .default_val = 0 1297 .default_val = 0
1307 }, 1298 },
1308 { /* Buss out */ 1299 { /* Buss out */
@@ -1311,7 +1302,6 @@ static struct snd_us16x08_control_params master_controls[] = {
1311 .type = USB_MIXER_BOOLEAN, 1302 .type = USB_MIXER_BOOLEAN,
1312 .num_channels = 16, 1303 .num_channels = 16,
1313 .name = "Buss Out Switch", 1304 .name = "Buss Out Switch",
1314 .freeer = NULL,
1315 .default_val = 0 1305 .default_val = 0
1316 }, 1306 },
1317 { /* Master mute */ 1307 { /* Master mute */
@@ -1320,7 +1310,6 @@ static struct snd_us16x08_control_params master_controls[] = {
1320 .type = USB_MIXER_BOOLEAN, 1310 .type = USB_MIXER_BOOLEAN,
1321 .num_channels = 16, 1311 .num_channels = 16,
1322 .name = "Master Mute Switch", 1312 .name = "Master Mute Switch",
1323 .freeer = NULL,
1324 .default_val = 0 1313 .default_val = 0
1325 }, 1314 },
1326 1315
@@ -1338,30 +1327,10 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer)
1338 /* just check for non-MIDI interface */ 1327 /* just check for non-MIDI interface */
1339 if (mixer->hostif->desc.bInterfaceNumber == 3) { 1328 if (mixer->hostif->desc.bInterfaceNumber == 3) {
1340 1329
1341 /* create compressor mixer elements */
1342 comp_store = snd_us16x08_create_comp_store();
1343 if (comp_store == NULL)
1344 return -ENOMEM;
1345
1346 /* create eq store */
1347 eq_store = snd_us16x08_create_eq_store();
1348 if (eq_store == NULL) {
1349 kfree(comp_store);
1350 return -ENOMEM;
1351 }
1352
1353 /* create meters store */
1354 meter_store = snd_us16x08_create_meter_store();
1355 if (meter_store == NULL) {
1356 kfree(comp_store);
1357 kfree(eq_store);
1358 return -ENOMEM;
1359 }
1360
1361 /* add routing control */ 1330 /* add routing control */
1362 err = add_new_ctl(mixer, &snd_us16x08_route_ctl, 1331 err = add_new_ctl(mixer, &snd_us16x08_route_ctl,
1363 SND_US16X08_ID_ROUTE, USB_MIXER_U8, 8, "Line Out Route", 1332 SND_US16X08_ID_ROUTE, USB_MIXER_U8, 8, "Line Out Route",
1364 NULL, NULL, &elem); 1333 NULL, false, &elem);
1365 if (err < 0) { 1334 if (err < 0) {
1366 usb_audio_dbg(mixer->chip, 1335 usb_audio_dbg(mixer->chip,
1367 "Failed to create route control, err:%d\n", 1336 "Failed to create route control, err:%d\n",
@@ -1372,6 +1341,11 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer)
1372 elem->cache_val[i] = i < 2 ? i : i + 2; 1341 elem->cache_val[i] = i < 2 ? i : i + 2;
1373 elem->cached = 0xff; 1342 elem->cached = 0xff;
1374 1343
1344 /* create compressor mixer elements */
1345 comp_store = snd_us16x08_create_comp_store();
1346 if (!comp_store)
1347 return -ENOMEM;
1348
1375 /* add master controls */ 1349 /* add master controls */
1376 for (i = 0; 1350 for (i = 0;
1377 i < sizeof(master_controls) 1351 i < sizeof(master_controls)
@@ -1385,7 +1359,8 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer)
1385 master_controls[i].num_channels, 1359 master_controls[i].num_channels,
1386 master_controls[i].name, 1360 master_controls[i].name,
1387 comp_store, 1361 comp_store,
1388 master_controls[i].freeer, &elem); 1362 i == 0, /* release comp_store only once */
1363 &elem);
1389 if (err < 0) 1364 if (err < 0)
1390 return err; 1365 return err;
1391 elem->cache_val[0] = master_controls[i].default_val; 1366 elem->cache_val[0] = master_controls[i].default_val;
@@ -1405,7 +1380,7 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer)
1405 channel_controls[i].num_channels, 1380 channel_controls[i].num_channels,
1406 channel_controls[i].name, 1381 channel_controls[i].name,
1407 comp_store, 1382 comp_store,
1408 channel_controls[i].freeer, &elem); 1383 false, &elem);
1409 if (err < 0) 1384 if (err < 0)
1410 return err; 1385 return err;
1411 for (j = 0; j < SND_US16X08_MAX_CHANNELS; j++) { 1386 for (j = 0; j < SND_US16X08_MAX_CHANNELS; j++) {
@@ -1415,6 +1390,11 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer)
1415 elem->cached = 0xffff; 1390 elem->cached = 0xffff;
1416 } 1391 }
1417 1392
1393 /* create eq store */
1394 eq_store = snd_us16x08_create_eq_store();
1395 if (!eq_store)
1396 return -ENOMEM;
1397
1418 /* add EQ controls */ 1398 /* add EQ controls */
1419 for (i = 0; i < sizeof(eq_controls) / 1399 for (i = 0; i < sizeof(eq_controls) /
1420 sizeof(control_params); i++) { 1400 sizeof(control_params); i++) {
@@ -1426,7 +1406,8 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer)
1426 eq_controls[i].num_channels, 1406 eq_controls[i].num_channels,
1427 eq_controls[i].name, 1407 eq_controls[i].name,
1428 eq_store, 1408 eq_store,
1429 eq_controls[i].freeer, NULL); 1409 i == 0, /* release eq_store only once */
1410 NULL);
1430 if (err < 0) 1411 if (err < 0)
1431 return err; 1412 return err;
1432 } 1413 }
@@ -1444,18 +1425,23 @@ int snd_us16x08_controls_create(struct usb_mixer_interface *mixer)
1444 comp_controls[i].num_channels, 1425 comp_controls[i].num_channels,
1445 comp_controls[i].name, 1426 comp_controls[i].name,
1446 comp_store, 1427 comp_store,
1447 comp_controls[i].freeer, NULL); 1428 false, NULL);
1448 if (err < 0) 1429 if (err < 0)
1449 return err; 1430 return err;
1450 } 1431 }
1451 1432
1433 /* create meters store */
1434 meter_store = snd_us16x08_create_meter_store();
1435 if (!meter_store)
1436 return -ENOMEM;
1437
1452 /* meter function 'get' must access to compressor store 1438 /* meter function 'get' must access to compressor store
1453 * so place a reference here 1439 * so place a reference here
1454 */ 1440 */
1455 meter_store->comp_store = comp_store; 1441 meter_store->comp_store = comp_store;
1456 err = add_new_ctl(mixer, &snd_us16x08_meter_ctl, 1442 err = add_new_ctl(mixer, &snd_us16x08_meter_ctl,
1457 SND_US16X08_ID_METER, USB_MIXER_U16, 0, "Level Meter", 1443 SND_US16X08_ID_METER, USB_MIXER_U16, 0, "Level Meter",
1458 (void *) meter_store, snd_usb_mixer_elem_free, NULL); 1444 meter_store, true, NULL);
1459 if (err < 0) 1445 if (err < 0)
1460 return err; 1446 return err;
1461 } 1447 }
diff --git a/sound/usb/mixer_us16x08.h b/sound/usb/mixer_us16x08.h
index 64f89b5eca2d..a6312fb0f962 100644
--- a/sound/usb/mixer_us16x08.h
+++ b/sound/usb/mixer_us16x08.h
@@ -112,7 +112,6 @@ struct snd_us16x08_control_params {
112 int type; 112 int type;
113 int num_channels; 113 int num_channels;
114 const char *name; 114 const char *name;
115 void (*freeer)(struct snd_kcontrol *kctl);
116 int default_val; 115 int default_val;
117}; 116};
118 117