1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Linux driver for TerraTec DMX 6Fire USB 4 * 5 * Mixer control 6 * 7 * Author: Torsten Schenk <torsten.schenk@zoho.com> 8 * Created: Jan 01, 2011 9 * Copyright: (C) Torsten Schenk 10 * 11 * Thanks to: 12 * - Holger Ruckdeschel: he found out how to control individual channel 13 * volumes and introduced mute switch 14 */ 15 16 #include <linux/interrupt.h> 17 #include <sound/control.h> 18 #include <sound/tlv.h> 19 20 #include "control.h" 21 #include "comm.h" 22 #include "chip.h" 23 24 static const char * const opt_coax_texts[2] = { "Optical", "Coax" }; 25 static const char * const line_phono_texts[2] = { "Line", "Phono" }; 26 27 /* 28 * data that needs to be sent to device. sets up card internal stuff. 29 * values dumped from windows driver and filtered by trial'n'error. 30 */ 31 static const struct { 32 u8 type; 33 u8 reg; 34 u8 value; 35 } 36 init_data[] = { 37 { 0x22, 0x00, 0x00 }, { 0x20, 0x00, 0x08 }, { 0x22, 0x01, 0x01 }, 38 { 0x20, 0x01, 0x08 }, { 0x22, 0x02, 0x00 }, { 0x20, 0x02, 0x08 }, 39 { 0x22, 0x03, 0x00 }, { 0x20, 0x03, 0x08 }, { 0x22, 0x04, 0x00 }, 40 { 0x20, 0x04, 0x08 }, { 0x22, 0x05, 0x01 }, { 0x20, 0x05, 0x08 }, 41 { 0x22, 0x04, 0x01 }, { 0x12, 0x04, 0x00 }, { 0x12, 0x05, 0x00 }, 42 { 0x12, 0x0d, 0x38 }, { 0x12, 0x21, 0x82 }, { 0x12, 0x22, 0x80 }, 43 { 0x12, 0x23, 0x00 }, { 0x12, 0x06, 0x02 }, { 0x12, 0x03, 0x00 }, 44 { 0x12, 0x02, 0x00 }, { 0x22, 0x03, 0x01 }, 45 { 0 } /* TERMINATING ENTRY */ 46 }; 47 48 static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 }; 49 /* values to write to soundcard register for all samplerates */ 50 static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}; 51 static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00}; 52 53 static DECLARE_TLV_DB_MINMAX(tlv_output, -9000, 0); 54 static DECLARE_TLV_DB_MINMAX(tlv_input, -1500, 1500); 55 56 enum { 57 DIGITAL_THRU_ONLY_SAMPLERATE = 3 58 }; 59 60 static void usb6fire_control_output_vol_update(struct control_runtime *rt) 61 { 62 struct comm_runtime *comm_rt = rt->chip->comm; 63 int i; 64 65 if (comm_rt) 66 for (i = 0; i < 6; i++) 67 if (!(rt->ovol_updated & (1 << i))) { 68 comm_rt->write8(comm_rt, 0x12, 0x0f + i, 69 180 - rt->output_vol[i]); 70 rt->ovol_updated |= 1 << i; 71 } 72 } 73 74 static void usb6fire_control_output_mute_update(struct control_runtime *rt) 75 { 76 struct comm_runtime *comm_rt = rt->chip->comm; 77 78 if (comm_rt) 79 comm_rt->write8(comm_rt, 0x12, 0x0e, ~rt->output_mute); 80 } 81 82 static void usb6fire_control_input_vol_update(struct control_runtime *rt) 83 { 84 struct comm_runtime *comm_rt = rt->chip->comm; 85 int i; 86 87 if (comm_rt) 88 for (i = 0; i < 2; i++) 89 if (!(rt->ivol_updated & (1 << i))) { 90 comm_rt->write8(comm_rt, 0x12, 0x1c + i, 91 rt->input_vol[i] & 0x3f); 92 rt->ivol_updated |= 1 << i; 93 } 94 } 95 96 static void usb6fire_control_line_phono_update(struct control_runtime *rt) 97 { 98 struct comm_runtime *comm_rt = rt->chip->comm; 99 if (comm_rt) { 100 comm_rt->write8(comm_rt, 0x22, 0x02, rt->line_phono_switch); 101 comm_rt->write8(comm_rt, 0x21, 0x02, rt->line_phono_switch); 102 } 103 } 104 105 static void usb6fire_control_opt_coax_update(struct control_runtime *rt) 106 { 107 struct comm_runtime *comm_rt = rt->chip->comm; 108 if (comm_rt) { 109 comm_rt->write8(comm_rt, 0x22, 0x00, rt->opt_coax_switch); 110 comm_rt->write8(comm_rt, 0x21, 0x00, rt->opt_coax_switch); 111 } 112 } 113 114 static int usb6fire_control_set_rate(struct control_runtime *rt, int rate) 115 { 116 int ret; 117 struct usb_device *device = rt->chip->dev; 118 struct comm_runtime *comm_rt = rt->chip->comm; 119 120 if (rate < 0 || rate >= CONTROL_N_RATES) 121 return -EINVAL; 122 123 ret = usb_set_interface(device, 1, rates_altsetting[rate]); 124 if (ret < 0) 125 return ret; 126 127 /* set soundcard clock */ 128 ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rate], 129 rates_6fire_vh[rate]); 130 if (ret < 0) 131 return ret; 132 133 return 0; 134 } 135 136 static int usb6fire_control_set_channels( 137 struct control_runtime *rt, int n_analog_out, 138 int n_analog_in, bool spdif_out, bool spdif_in) 139 { 140 int ret; 141 struct comm_runtime *comm_rt = rt->chip->comm; 142 143 /* enable analog inputs and outputs 144 * (one bit per stereo-channel) */ 145 ret = comm_rt->write16(comm_rt, 0x02, 0x02, 146 (1 << (n_analog_out / 2)) - 1, 147 (1 << (n_analog_in / 2)) - 1); 148 if (ret < 0) 149 return ret; 150 151 /* disable digital inputs and outputs */ 152 /* TODO: use spdif_x to enable/disable digital channels */ 153 ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00); 154 if (ret < 0) 155 return ret; 156 157 return 0; 158 } 159 160 static int usb6fire_control_streaming_update(struct control_runtime *rt) 161 { 162 struct comm_runtime *comm_rt = rt->chip->comm; 163 164 if (comm_rt) { 165 if (!rt->usb_streaming && rt->digital_thru_switch) 166 usb6fire_control_set_rate(rt, 167 DIGITAL_THRU_ONLY_SAMPLERATE); 168 return comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 169 (rt->usb_streaming ? 0x01 : 0x00) | 170 (rt->digital_thru_switch ? 0x08 : 0x00)); 171 } 172 return -EINVAL; 173 } 174 175 static int usb6fire_control_output_vol_info(struct snd_kcontrol *kcontrol, 176 struct snd_ctl_elem_info *uinfo) 177 { 178 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 179 uinfo->count = 2; 180 uinfo->value.integer.min = 0; 181 uinfo->value.integer.max = 180; 182 return 0; 183 } 184 185 static int usb6fire_control_output_vol_put(struct snd_kcontrol *kcontrol, 186 struct snd_ctl_elem_value *ucontrol) 187 { 188 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 189 unsigned int ch = kcontrol->private_value; 190 int changed = 0; 191 192 if (ch > 4) { 193 dev_err(&rt->chip->dev->dev, 194 "Invalid channel in volume control."); 195 return -EINVAL; 196 } 197 198 if (rt->output_vol[ch] != ucontrol->value.integer.value[0]) { 199 rt->output_vol[ch] = ucontrol->value.integer.value[0]; 200 rt->ovol_updated &= ~(1 << ch); 201 changed = 1; 202 } 203 if (rt->output_vol[ch + 1] != ucontrol->value.integer.value[1]) { 204 rt->output_vol[ch + 1] = ucontrol->value.integer.value[1]; 205 rt->ovol_updated &= ~(2 << ch); 206 changed = 1; 207 } 208 209 if (changed) 210 usb6fire_control_output_vol_update(rt); 211 212 return changed; 213 } 214 215 static int usb6fire_control_output_vol_get(struct snd_kcontrol *kcontrol, 216 struct snd_ctl_elem_value *ucontrol) 217 { 218 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 219 unsigned int ch = kcontrol->private_value; 220 221 if (ch > 4) { 222 dev_err(&rt->chip->dev->dev, 223 "Invalid channel in volume control."); 224 return -EINVAL; 225 } 226 227 ucontrol->value.integer.value[0] = rt->output_vol[ch]; 228 ucontrol->value.integer.value[1] = rt->output_vol[ch + 1]; 229 return 0; 230 } 231 232 static int usb6fire_control_output_mute_put(struct snd_kcontrol *kcontrol, 233 struct snd_ctl_elem_value *ucontrol) 234 { 235 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 236 unsigned int ch = kcontrol->private_value; 237 u8 old = rt->output_mute; 238 u8 value = 0; 239 240 if (ch > 4) { 241 dev_err(&rt->chip->dev->dev, 242 "Invalid channel in volume control."); 243 return -EINVAL; 244 } 245 246 rt->output_mute &= ~(3 << ch); 247 if (ucontrol->value.integer.value[0]) 248 value |= 1; 249 if (ucontrol->value.integer.value[1]) 250 value |= 2; 251 rt->output_mute |= value << ch; 252 253 if (rt->output_mute != old) 254 usb6fire_control_output_mute_update(rt); 255 256 return rt->output_mute != old; 257 } 258 259 static int usb6fire_control_output_mute_get(struct snd_kcontrol *kcontrol, 260 struct snd_ctl_elem_value *ucontrol) 261 { 262 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 263 unsigned int ch = kcontrol->private_value; 264 u8 value = rt->output_mute >> ch; 265 266 if (ch > 4) { 267 dev_err(&rt->chip->dev->dev, 268 "Invalid channel in volume control."); 269 return -EINVAL; 270 } 271 272 ucontrol->value.integer.value[0] = 1 & value; 273 value >>= 1; 274 ucontrol->value.integer.value[1] = 1 & value; 275 276 return 0; 277 } 278 279 static int usb6fire_control_input_vol_info(struct snd_kcontrol *kcontrol, 280 struct snd_ctl_elem_info *uinfo) 281 { 282 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 283 uinfo->count = 2; 284 uinfo->value.integer.min = 0; 285 uinfo->value.integer.max = 30; 286 return 0; 287 } 288 289 static int usb6fire_control_input_vol_put(struct snd_kcontrol *kcontrol, 290 struct snd_ctl_elem_value *ucontrol) 291 { 292 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 293 int vol0 = ucontrol->value.integer.value[0] - 15; 294 int vol1 = ucontrol->value.integer.value[1] - 15; 295 int changed = 0; 296 297 if (rt->input_vol[0] != vol0) { 298 rt->input_vol[0] = vol0; 299 rt->ivol_updated &= ~(1 << 0); 300 changed = 1; 301 } 302 if (rt->input_vol[1] != vol1) { 303 rt->input_vol[1] = vol1; 304 rt->ivol_updated &= ~(1 << 1); 305 changed = 1; 306 } 307 308 if (changed) 309 usb6fire_control_input_vol_update(rt); 310 311 return changed; 312 } 313 314 static int usb6fire_control_input_vol_get(struct snd_kcontrol *kcontrol, 315 struct snd_ctl_elem_value *ucontrol) 316 { 317 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 318 319 ucontrol->value.integer.value[0] = rt->input_vol[0] + 15; 320 ucontrol->value.integer.value[1] = rt->input_vol[1] + 15; 321 322 return 0; 323 } 324 325 static int usb6fire_control_line_phono_info(struct snd_kcontrol *kcontrol, 326 struct snd_ctl_elem_info *uinfo) 327 { 328 return snd_ctl_enum_info(uinfo, 1, 2, line_phono_texts); 329 } 330 331 static int usb6fire_control_line_phono_put(struct snd_kcontrol *kcontrol, 332 struct snd_ctl_elem_value *ucontrol) 333 { 334 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 335 int changed = 0; 336 if (rt->line_phono_switch != ucontrol->value.integer.value[0]) { 337 rt->line_phono_switch = ucontrol->value.integer.value[0]; 338 usb6fire_control_line_phono_update(rt); 339 changed = 1; 340 } 341 return changed; 342 } 343 344 static int usb6fire_control_line_phono_get(struct snd_kcontrol *kcontrol, 345 struct snd_ctl_elem_value *ucontrol) 346 { 347 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 348 ucontrol->value.integer.value[0] = rt->line_phono_switch; 349 return 0; 350 } 351 352 static int usb6fire_control_opt_coax_info(struct snd_kcontrol *kcontrol, 353 struct snd_ctl_elem_info *uinfo) 354 { 355 return snd_ctl_enum_info(uinfo, 1, 2, opt_coax_texts); 356 } 357 358 static int usb6fire_control_opt_coax_put(struct snd_kcontrol *kcontrol, 359 struct snd_ctl_elem_value *ucontrol) 360 { 361 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 362 int changed = 0; 363 364 if (rt->opt_coax_switch != ucontrol->value.enumerated.item[0]) { 365 rt->opt_coax_switch = ucontrol->value.enumerated.item[0]; 366 usb6fire_control_opt_coax_update(rt); 367 changed = 1; 368 } 369 return changed; 370 } 371 372 static int usb6fire_control_opt_coax_get(struct snd_kcontrol *kcontrol, 373 struct snd_ctl_elem_value *ucontrol) 374 { 375 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 376 ucontrol->value.enumerated.item[0] = rt->opt_coax_switch; 377 return 0; 378 } 379 380 static int usb6fire_control_digital_thru_put(struct snd_kcontrol *kcontrol, 381 struct snd_ctl_elem_value *ucontrol) 382 { 383 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 384 int changed = 0; 385 386 if (rt->digital_thru_switch != ucontrol->value.integer.value[0]) { 387 rt->digital_thru_switch = ucontrol->value.integer.value[0]; 388 usb6fire_control_streaming_update(rt); 389 changed = 1; 390 } 391 return changed; 392 } 393 394 static int usb6fire_control_digital_thru_get(struct snd_kcontrol *kcontrol, 395 struct snd_ctl_elem_value *ucontrol) 396 { 397 struct control_runtime *rt = snd_kcontrol_chip(kcontrol); 398 ucontrol->value.integer.value[0] = rt->digital_thru_switch; 399 return 0; 400 } 401 402 static const struct snd_kcontrol_new vol_elements[] = { 403 { 404 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 405 .name = "Analog Playback Volume", 406 .index = 0, 407 .private_value = 0, 408 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 409 SNDRV_CTL_ELEM_ACCESS_TLV_READ, 410 .info = usb6fire_control_output_vol_info, 411 .get = usb6fire_control_output_vol_get, 412 .put = usb6fire_control_output_vol_put, 413 .tlv = { .p = tlv_output } 414 }, 415 { 416 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 417 .name = "Analog Playback Volume", 418 .index = 1, 419 .private_value = 2, 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 = 2, 431 .private_value = 4, 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 }; 441 442 static const struct snd_kcontrol_new mute_elements[] = { 443 { 444 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 445 .name = "Analog Playback Switch", 446 .index = 0, 447 .private_value = 0, 448 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 449 .info = snd_ctl_boolean_stereo_info, 450 .get = usb6fire_control_output_mute_get, 451 .put = usb6fire_control_output_mute_put, 452 }, 453 { 454 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 455 .name = "Analog Playback Switch", 456 .index = 1, 457 .private_value = 2, 458 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 459 .info = snd_ctl_boolean_stereo_info, 460 .get = usb6fire_control_output_mute_get, 461 .put = usb6fire_control_output_mute_put, 462 }, 463 { 464 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 465 .name = "Analog Playback Switch", 466 .index = 2, 467 .private_value = 4, 468 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 469 .info = snd_ctl_boolean_stereo_info, 470 .get = usb6fire_control_output_mute_get, 471 .put = usb6fire_control_output_mute_put, 472 }, 473 {} 474 }; 475 476 static const struct snd_kcontrol_new elements[] = { 477 { 478 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 479 .name = "Line/Phono Capture Route", 480 .index = 0, 481 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 482 .info = usb6fire_control_line_phono_info, 483 .get = usb6fire_control_line_phono_get, 484 .put = usb6fire_control_line_phono_put 485 }, 486 { 487 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 488 .name = "Opt/Coax Capture Route", 489 .index = 0, 490 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 491 .info = usb6fire_control_opt_coax_info, 492 .get = usb6fire_control_opt_coax_get, 493 .put = usb6fire_control_opt_coax_put 494 }, 495 { 496 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 497 .name = "Digital Thru Playback Route", 498 .index = 0, 499 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 500 .info = snd_ctl_boolean_mono_info, 501 .get = usb6fire_control_digital_thru_get, 502 .put = usb6fire_control_digital_thru_put 503 }, 504 { 505 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 506 .name = "Analog Capture Volume", 507 .index = 0, 508 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 509 SNDRV_CTL_ELEM_ACCESS_TLV_READ, 510 .info = usb6fire_control_input_vol_info, 511 .get = usb6fire_control_input_vol_get, 512 .put = usb6fire_control_input_vol_put, 513 .tlv = { .p = tlv_input } 514 }, 515 {} 516 }; 517 518 static int usb6fire_control_add_virtual( 519 struct control_runtime *rt, 520 struct snd_card *card, 521 char *name, 522 const struct snd_kcontrol_new *elems) 523 { 524 int ret; 525 int i; 526 struct snd_kcontrol *vmaster = 527 snd_ctl_make_virtual_master(name, tlv_output); 528 struct snd_kcontrol *control; 529 530 if (!vmaster) 531 return -ENOMEM; 532 ret = snd_ctl_add(card, vmaster); 533 if (ret < 0) 534 return ret; 535 536 i = 0; 537 while (elems[i].name) { 538 control = snd_ctl_new1(&elems[i], rt); 539 if (!control) 540 return -ENOMEM; 541 ret = snd_ctl_add(card, control); 542 if (ret < 0) 543 return ret; 544 ret = snd_ctl_add_follower(vmaster, control); 545 if (ret < 0) 546 return ret; 547 i++; 548 } 549 return 0; 550 } 551 552 int usb6fire_control_init(struct sfire_chip *chip) 553 { 554 int i; 555 int ret; 556 struct control_runtime *rt = kzalloc_obj(struct control_runtime); 557 struct comm_runtime *comm_rt = chip->comm; 558 559 if (!rt) 560 return -ENOMEM; 561 562 rt->chip = chip; 563 rt->update_streaming = usb6fire_control_streaming_update; 564 rt->set_rate = usb6fire_control_set_rate; 565 rt->set_channels = usb6fire_control_set_channels; 566 567 i = 0; 568 while (init_data[i].type) { 569 comm_rt->write8(comm_rt, init_data[i].type, init_data[i].reg, 570 init_data[i].value); 571 i++; 572 } 573 574 usb6fire_control_opt_coax_update(rt); 575 usb6fire_control_line_phono_update(rt); 576 usb6fire_control_output_vol_update(rt); 577 usb6fire_control_output_mute_update(rt); 578 usb6fire_control_input_vol_update(rt); 579 usb6fire_control_streaming_update(rt); 580 581 ret = usb6fire_control_add_virtual(rt, chip->card, 582 "Master Playback Volume", vol_elements); 583 if (ret) { 584 dev_err(&chip->dev->dev, "cannot add control.\n"); 585 kfree(rt); 586 return ret; 587 } 588 ret = usb6fire_control_add_virtual(rt, chip->card, 589 "Master Playback Switch", mute_elements); 590 if (ret) { 591 dev_err(&chip->dev->dev, "cannot add control.\n"); 592 kfree(rt); 593 return ret; 594 } 595 596 i = 0; 597 while (elements[i].name) { 598 ret = snd_ctl_add(chip->card, snd_ctl_new1(&elements[i], rt)); 599 if (ret < 0) { 600 kfree(rt); 601 dev_err(&chip->dev->dev, "cannot add control.\n"); 602 return ret; 603 } 604 i++; 605 } 606 607 chip->control = rt; 608 return 0; 609 } 610 611 void usb6fire_control_abort(struct sfire_chip *chip) 612 {} 613 614 void usb6fire_control_destroy(struct sfire_chip *chip) 615 { 616 kfree(chip->control); 617 chip->control = NULL; 618 } 619