1 /* 2 * Auvia BeOS Driver for Via VT82xx Southbridge audio 3 * 4 * Copyright (c) 2003, Jerome Duval (jerome.duval@free.fr) 5 * 6 * Original code : BeOS Driver for Intel ICH AC'97 Link interface 7 * Copyright (c) 2002, Marcus Overhagen <marcus@overhagen.de> 8 * 9 * All rights reserved. 10 * Redistribution and use in source and binary forms, with or without modification, 11 * are permitted provided that the following conditions are met: 12 * 13 * - Redistributions of source code must retain the above copyright notice, 14 * this list of conditions and the following disclaimer. 15 * - Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 25 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 */ 31 32 #include <OS.h> 33 #include <MediaDefs.h> 34 #include "multi_audio.h" 35 #include "multi.h" 36 #include "ac97.h" 37 38 //#define DEBUG 1 39 40 #include "debug.h" 41 #include "auvia.h" 42 #include "util.h" 43 #include "io.h" 44 45 static void 46 auvia_ac97_get_mix(void *card, const void *cookie, int32 type, float *values) { 47 auvia_dev *dev = (auvia_dev*)card; 48 ac97_source_info *info = (ac97_source_info *)cookie; 49 uint16 value, mask; 50 float gain; 51 52 switch(type) { 53 case B_MIX_GAIN: 54 value = auvia_codec_read(&dev->config, info->reg); 55 //PRINT(("B_MIX_GAIN value : %u\n", value)); 56 if(info->type & B_MIX_STEREO) { 57 mask = ((1 << (info->bits + 1)) - 1) << 8; 58 gain = ((value & mask) >> 8) * info->granularity; 59 if(info->polarity == 1) 60 values[0] = info->max_gain - gain; 61 else 62 values[0] = gain - info->min_gain; 63 64 mask = ((1 << (info->bits + 1)) - 1); 65 gain = (value & mask) * info->granularity; 66 if(info->polarity == 1) 67 values[1] = info->max_gain - gain; 68 else 69 values[1] = gain - info->min_gain; 70 } else { 71 mask = ((1 << (info->bits + 1)) - 1); 72 gain = (value & mask) * info->granularity; 73 if(info->polarity == 1) 74 values[0] = info->max_gain - gain; 75 else 76 values[0] = gain - info->min_gain; 77 } 78 break; 79 case B_MIX_MUTE: 80 mask = ((1 << 1) - 1) << 15; 81 value = auvia_codec_read(&dev->config, info->reg); 82 //PRINT(("B_MIX_MUTE value : %u\n", value)); 83 value &= mask; 84 values[0] = ((value >> 15) == 1) ? 1.0 : 0.0; 85 break; 86 case B_MIX_MICBOOST: 87 mask = ((1 << 1) - 1) << 6; 88 value = auvia_codec_read(&dev->config, info->reg); 89 //PRINT(("B_MIX_MICBOOST value : %u\n", value)); 90 value &= mask; 91 values[0] = ((value >> 6) == 1) ? 1.0 : 0.0; 92 break; 93 case B_MIX_MUX: 94 mask = ((1 << 3) - 1); 95 value = auvia_codec_read(&dev->config, AC97_RECORD_SELECT); 96 value &= mask; 97 //PRINT(("B_MIX_MUX value : %u\n", value)); 98 values[0] = (float)value; 99 break; 100 } 101 } 102 103 static void 104 auvia_ac97_set_mix(void *card, const void *cookie, int32 type, float *values) { 105 auvia_dev *dev = (auvia_dev*)card; 106 ac97_source_info *info = (ac97_source_info *)cookie; 107 uint16 value, mask; 108 float gain; 109 110 switch(type) { 111 case B_MIX_GAIN: 112 value = auvia_codec_read(&dev->config, info->reg); 113 if(info->type & B_MIX_STEREO) { 114 mask = ((1 << (info->bits + 1)) - 1) << 8; 115 value &= ~mask; 116 117 if(info->polarity == 1) 118 gain = info->max_gain - values[0]; 119 else 120 gain = values[0] - info->min_gain; 121 value |= ((uint16)(gain / info->granularity) << 8) & mask; 122 123 mask = ((1 << (info->bits + 1)) - 1); 124 value &= ~mask; 125 if(info->polarity == 1) 126 gain = info->max_gain - values[1]; 127 else 128 gain = values[1] - info->min_gain; 129 value |= ((uint16)(gain / info->granularity)) & mask; 130 } else { 131 mask = ((1 << (info->bits + 1)) - 1); 132 value &= ~mask; 133 if(info->polarity == 1) 134 gain = info->max_gain - values[0]; 135 else 136 gain = values[0] - info->min_gain; 137 value |= ((uint16)(gain / info->granularity)) & mask; 138 } 139 //PRINT(("B_MIX_GAIN value : %u\n", value)); 140 auvia_codec_write(&dev->config, info->reg, value); 141 break; 142 case B_MIX_MUTE: 143 mask = ((1 << 1) - 1) << 15; 144 value = auvia_codec_read(&dev->config, info->reg); 145 value &= ~mask; 146 value |= ((values[0] == 1.0 ? 1 : 0 ) << 15 & mask); 147 if(info->reg == AC97_SURROUND_VOLUME) { 148 // there is a independent mute for each channel 149 mask = ((1 << 1) - 1) << 7; 150 value &= ~mask; 151 value |= ((values[0] == 1.0 ? 1 : 0 ) << 7 & mask); 152 } 153 //PRINT(("B_MIX_MUTE value : %u\n", value)); 154 auvia_codec_write(&dev->config, info->reg, value); 155 break; 156 case B_MIX_MICBOOST: 157 mask = ((1 << 1) - 1) << 6; 158 value = auvia_codec_read(&dev->config, info->reg); 159 value &= ~mask; 160 value |= ((values[0] == 1.0 ? 1 : 0 ) << 6 & mask); 161 //PRINT(("B_MIX_MICBOOST value : %u\n", value)); 162 auvia_codec_write(&dev->config, info->reg, value); 163 break; 164 case B_MIX_MUX: 165 mask = ((1 << 3) - 1); 166 value = ((int32)values[0]) & mask; 167 value = value | (value << 8); 168 //PRINT(("B_MIX_MUX value : %u\n", value)); 169 auvia_codec_write(&dev->config, AC97_RECORD_SELECT, value); 170 break; 171 } 172 173 } 174 175 static int32 176 auvia_create_group_control(multi_dev *multi, int32 *index, int32 parent, 177 int32 string, const char* name) { 178 int32 i = *index; 179 (*index)++; 180 multi->controls[i].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + i; 181 multi->controls[i].mix_control.parent = parent; 182 multi->controls[i].mix_control.flags = B_MULTI_MIX_GROUP; 183 multi->controls[i].mix_control.master = EMU_MULTI_CONTROL_MASTERID; 184 multi->controls[i].mix_control.string = string; 185 if(name) 186 strcpy(multi->controls[i].mix_control.name, name); 187 188 return multi->controls[i].mix_control.id; 189 } 190 191 static status_t 192 auvia_create_controls_list(multi_dev *multi) 193 { 194 uint32 i = 0, index = 0, count, id, parent, parent2, parent3; 195 auvia_dev *card = (auvia_dev*)multi->card; 196 const ac97_source_info *info; 197 198 parent = auvia_create_group_control(multi, &index, 0, 0, "Record"); 199 200 /* AC97 Record */ 201 info = &source_info[0]; 202 PRINT(("name : %s\n", info->name)); 203 204 parent2 = auvia_create_group_control(multi, &index, parent, 0, info->name); 205 206 if(info->type & B_MIX_GAIN) { 207 if(info->type & B_MIX_MUTE) { 208 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 209 multi->controls[index].mix_control.flags = B_MULTI_MIX_ENABLE; 210 multi->controls[index].mix_control.master = EMU_MULTI_CONTROL_MASTERID; 211 multi->controls[index].mix_control.parent = parent2; 212 multi->controls[index].mix_control.string = S_MUTE; 213 multi->controls[index].cookie = info; 214 multi->controls[index].type = B_MIX_MUTE; 215 multi->controls[index].get = &auvia_ac97_get_mix; 216 multi->controls[index].set = &auvia_ac97_set_mix; 217 index++; 218 } 219 220 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 221 multi->controls[index].mix_control.flags = B_MULTI_MIX_GAIN; 222 multi->controls[index].mix_control.master = EMU_MULTI_CONTROL_MASTERID; 223 multi->controls[index].mix_control.parent = parent2; 224 strcpy(multi->controls[index].mix_control.name, info->name); 225 multi->controls[index].mix_control.u.gain.min_gain = info->min_gain; 226 multi->controls[index].mix_control.u.gain.max_gain = info->max_gain; 227 multi->controls[index].mix_control.u.gain.granularity = info->granularity; 228 multi->controls[index].cookie = info; 229 multi->controls[index].type = B_MIX_GAIN; 230 multi->controls[index].get = &auvia_ac97_get_mix; 231 multi->controls[index].set = &auvia_ac97_set_mix; 232 id = multi->controls[index].mix_control.id; 233 index++; 234 235 if(info->type & B_MIX_STEREO) { 236 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 237 multi->controls[index].mix_control.flags = B_MULTI_MIX_GAIN; 238 multi->controls[index].mix_control.master = id; 239 multi->controls[index].mix_control.parent = parent2; 240 strcpy(multi->controls[index].mix_control.name, info->name); 241 multi->controls[index].mix_control.u.gain.min_gain = info->min_gain; 242 multi->controls[index].mix_control.u.gain.max_gain = info->max_gain; 243 multi->controls[index].mix_control.u.gain.granularity = info->granularity; 244 multi->controls[index].cookie = info; 245 multi->controls[index].type = B_MIX_GAIN; 246 multi->controls[index].get = &auvia_ac97_get_mix; 247 multi->controls[index].set = &auvia_ac97_set_mix; 248 index++; 249 } 250 251 if(info->type & B_MIX_RECORDMUX) { 252 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 253 multi->controls[index].mix_control.flags = B_MULTI_MIX_MUX; 254 multi->controls[index].mix_control.parent = parent2; 255 strcpy(multi->controls[index].mix_control.name, "Record Mux"); 256 multi->controls[index].cookie = info; 257 multi->controls[index].type = B_MIX_MUX; 258 multi->controls[index].get = &auvia_ac97_get_mix; 259 multi->controls[index].set = &auvia_ac97_set_mix; 260 parent3 = multi->controls[index].mix_control.id; 261 index++; 262 263 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 264 multi->controls[index].mix_control.flags = B_MULTI_MIX_MUX_VALUE; 265 multi->controls[index].mix_control.parent = parent3; 266 multi->controls[index].mix_control.string = S_MIC; 267 index++; 268 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 269 multi->controls[index].mix_control.flags = B_MULTI_MIX_MUX_VALUE; 270 multi->controls[index].mix_control.parent = parent3; 271 strcpy(multi->controls[index].mix_control.name, "CD In"); 272 index++; 273 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 274 multi->controls[index].mix_control.flags = B_MULTI_MIX_MUX_VALUE; 275 multi->controls[index].mix_control.parent = parent3; 276 strcpy(multi->controls[index].mix_control.name, "Video In"); 277 index++; 278 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 279 multi->controls[index].mix_control.flags = B_MULTI_MIX_MUX_VALUE; 280 multi->controls[index].mix_control.parent = parent3; 281 strcpy(multi->controls[index].mix_control.name, "Aux In"); 282 index++; 283 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 284 multi->controls[index].mix_control.flags = B_MULTI_MIX_MUX_VALUE; 285 multi->controls[index].mix_control.parent = parent3; 286 strcpy(multi->controls[index].mix_control.name, "Line In"); 287 index++; 288 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 289 multi->controls[index].mix_control.flags = B_MULTI_MIX_MUX_VALUE; 290 multi->controls[index].mix_control.parent = parent3; 291 multi->controls[index].mix_control.string = S_STEREO_MIX; 292 index++; 293 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 294 multi->controls[index].mix_control.flags = B_MULTI_MIX_MUX_VALUE; 295 multi->controls[index].mix_control.parent = parent3; 296 multi->controls[index].mix_control.string = S_MONO_MIX; 297 index++; 298 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 299 multi->controls[index].mix_control.flags = B_MULTI_MIX_MUX_VALUE; 300 multi->controls[index].mix_control.parent = parent3; 301 strcpy(multi->controls[index].mix_control.name, "TAD"); 302 index++; 303 } 304 } 305 306 parent = auvia_create_group_control(multi, &index, 0, 0, "AC97 Mixer"); 307 308 count = source_info_size; 309 count--; 310 311 for(i=1; i < count ; i++) { 312 info = &source_info[i]; 313 PRINT(("name : %s\n", info->name)); 314 315 parent2 = auvia_create_group_control(multi, &index, parent, 0, info->name); 316 317 if(info->type & B_MIX_GAIN) { 318 if(info->type & B_MIX_MUTE) { 319 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 320 multi->controls[index].mix_control.flags = B_MULTI_MIX_ENABLE; 321 multi->controls[index].mix_control.master = EMU_MULTI_CONTROL_MASTERID; 322 multi->controls[index].mix_control.parent = parent2; 323 multi->controls[index].mix_control.string = S_MUTE; 324 multi->controls[index].cookie = info; 325 multi->controls[index].type = B_MIX_MUTE; 326 multi->controls[index].get = &auvia_ac97_get_mix; 327 multi->controls[index].set = &auvia_ac97_set_mix; 328 index++; 329 } 330 331 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 332 multi->controls[index].mix_control.flags = B_MULTI_MIX_GAIN; 333 multi->controls[index].mix_control.master = EMU_MULTI_CONTROL_MASTERID; 334 multi->controls[index].mix_control.parent = parent2; 335 strcpy(multi->controls[index].mix_control.name, info->name); 336 multi->controls[index].mix_control.u.gain.min_gain = info->min_gain; 337 multi->controls[index].mix_control.u.gain.max_gain = info->max_gain; 338 multi->controls[index].mix_control.u.gain.granularity = info->granularity; 339 multi->controls[index].cookie = info; 340 multi->controls[index].type = B_MIX_GAIN; 341 multi->controls[index].get = &auvia_ac97_get_mix; 342 multi->controls[index].set = &auvia_ac97_set_mix; 343 id = multi->controls[index].mix_control.id; 344 index++; 345 346 if(info->type & B_MIX_STEREO) { 347 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 348 multi->controls[index].mix_control.flags = B_MULTI_MIX_GAIN; 349 multi->controls[index].mix_control.master = id; 350 multi->controls[index].mix_control.parent = parent2; 351 strcpy(multi->controls[index].mix_control.name, info->name); 352 multi->controls[index].mix_control.u.gain.min_gain = info->min_gain; 353 multi->controls[index].mix_control.u.gain.max_gain = info->max_gain; 354 multi->controls[index].mix_control.u.gain.granularity = info->granularity; 355 multi->controls[index].cookie = info; 356 multi->controls[index].type = B_MIX_GAIN; 357 multi->controls[index].get = &auvia_ac97_get_mix; 358 multi->controls[index].set = &auvia_ac97_set_mix; 359 index++; 360 } 361 } 362 } 363 364 parent = auvia_create_group_control(multi, &index, 0, S_SETUP, NULL); 365 366 /* AC97 20db Boost Mic */ 367 info = &source_info[6]; 368 369 if(info->type & B_MIX_GAIN && info->type & B_MIX_MICBOOST) { 370 multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; 371 multi->controls[index].mix_control.flags = B_MULTI_MIX_ENABLE; 372 multi->controls[index].mix_control.master = EMU_MULTI_CONTROL_MASTERID; 373 multi->controls[index].mix_control.parent = parent; 374 strcpy(multi->controls[index].mix_control.name, "Mic +20dB"); 375 multi->controls[index].cookie = info; 376 multi->controls[index].type = B_MIX_MICBOOST; 377 multi->controls[index].get = &auvia_ac97_get_mix; 378 multi->controls[index].set = &auvia_ac97_set_mix; 379 index++; 380 } 381 382 multi->control_count = index; 383 PRINT(("multi->control_count %u\n", multi->control_count)); 384 return B_OK; 385 } 386 387 static status_t 388 auvia_get_mix(auvia_dev *card, multi_mix_value_info * MMVI) 389 { 390 int32 i, id; 391 multi_mixer_control *control = NULL; 392 for(i=0; i<MMVI->item_count; i++) { 393 id = MMVI->values[i].id - EMU_MULTI_CONTROL_FIRSTID; 394 if(id < 0 || id >= card->multi.control_count) { 395 PRINT(("auvia_get_mix : invalid control id requested : %i\n", id)); 396 continue; 397 } 398 control = &card->multi.controls[id]; 399 400 if(control->mix_control.flags & B_MULTI_MIX_GAIN) { 401 if(control->get) { 402 float values[2]; 403 control->get(card, control->cookie, control->type, values); 404 if(control->mix_control.master == EMU_MULTI_CONTROL_MASTERID) 405 MMVI->values[i].u.gain = values[0]; 406 else 407 MMVI->values[i].u.gain = values[1]; 408 } 409 } 410 411 if(control->mix_control.flags & B_MULTI_MIX_ENABLE && control->get) { 412 float values[1]; 413 control->get(card, control->cookie, control->type, values); 414 MMVI->values[i].u.enable = (values[0] == 1.0); 415 } 416 417 if(control->mix_control.flags & B_MULTI_MIX_MUX && control->get) { 418 float values[1]; 419 control->get(card, control->cookie, control->type, values); 420 MMVI->values[i].u.mux = (int32)values[0]; 421 } 422 } 423 return B_OK; 424 } 425 426 static status_t 427 auvia_set_mix(auvia_dev *card, multi_mix_value_info * MMVI) 428 { 429 int32 i, id; 430 multi_mixer_control *control = NULL; 431 for(i=0; i<MMVI->item_count; i++) { 432 id = MMVI->values[i].id - EMU_MULTI_CONTROL_FIRSTID; 433 if(id < 0 || id >= card->multi.control_count) { 434 PRINT(("auvia_set_mix : invalid control id requested : %i\n", id)); 435 continue; 436 } 437 control = &card->multi.controls[id]; 438 439 if(control->mix_control.flags & B_MULTI_MIX_GAIN) { 440 multi_mixer_control *control2 = NULL; 441 if(i+1<MMVI->item_count) { 442 id = MMVI->values[i + 1].id - EMU_MULTI_CONTROL_FIRSTID; 443 if(id < 0 || id >= card->multi.control_count) { 444 PRINT(("auvia_set_mix : invalid control id requested : %i\n", id)); 445 } else { 446 control2 = &card->multi.controls[id]; 447 if(control2->mix_control.master != control->mix_control.id) 448 control2 = NULL; 449 } 450 } 451 452 if(control->set) { 453 float values[2]; 454 values[0] = 0.0; 455 values[1] = 0.0; 456 457 if(control->mix_control.master == EMU_MULTI_CONTROL_MASTERID) 458 values[0] = MMVI->values[i].u.gain; 459 else 460 values[1] = MMVI->values[i].u.gain; 461 462 if(control2 && control2->mix_control.master != EMU_MULTI_CONTROL_MASTERID) 463 values[1] = MMVI->values[i+1].u.gain; 464 465 control->set(card, control->cookie, control->type, values); 466 } 467 468 if(control2) 469 i++; 470 } 471 472 if(control->mix_control.flags & B_MULTI_MIX_ENABLE && control->set) { 473 float values[1]; 474 475 values[0] = MMVI->values[i].u.enable ? 1.0 : 0.0; 476 control->set(card, control->cookie, control->type, values); 477 } 478 479 if(control->mix_control.flags & B_MULTI_MIX_MUX && control->set) { 480 float values[1]; 481 482 values[0] = (float)MMVI->values[i].u.mux; 483 control->set(card, control->cookie, control->type, values); 484 } 485 } 486 return B_OK; 487 } 488 489 static status_t 490 auvia_list_mix_controls(auvia_dev *card, multi_mix_control_info * MMCI) 491 { 492 multi_mix_control *MMC; 493 int32 i; 494 495 MMC = MMCI->controls; 496 if(MMCI->control_count < 24) 497 return B_ERROR; 498 499 if(auvia_create_controls_list(&card->multi) < B_OK) 500 return B_ERROR; 501 for(i=0; i<card->multi.control_count; i++) { 502 MMC[i] = card->multi.controls[i].mix_control; 503 } 504 505 MMCI->control_count = card->multi.control_count; 506 return B_OK; 507 } 508 509 static status_t 510 auvia_list_mix_connections(auvia_dev *card, multi_mix_connection_info * data) 511 { 512 return B_ERROR; 513 } 514 515 static status_t 516 auvia_list_mix_channels(auvia_dev *card, multi_mix_channel_info *data) 517 { 518 return B_ERROR; 519 } 520 521 /*multi_channel_info chans[] = { 522 { 0, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 }, 523 { 1, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 }, 524 { 2, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 }, 525 { 3, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 }, 526 { 4, B_MULTI_INPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 }, 527 { 5, B_MULTI_INPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 }, 528 { 6, B_MULTI_INPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 }, 529 { 7, B_MULTI_INPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 }, 530 { 8, B_MULTI_OUTPUT_BUS, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 531 { 9, B_MULTI_OUTPUT_BUS, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 532 { 10, B_MULTI_INPUT_BUS, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 533 { 11, B_MULTI_INPUT_BUS, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 534 };*/ 535 536 /*multi_channel_info chans[] = { 537 { 0, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 }, 538 { 1, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 }, 539 { 2, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_SURROUND_BUS, 0 }, 540 { 3, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_SURROUND_BUS, 0 }, 541 { 4, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_REARLEFT | B_CHANNEL_SURROUND_BUS, 0 }, 542 { 5, B_MULTI_OUTPUT_CHANNEL, B_CHANNEL_REARRIGHT | B_CHANNEL_SURROUND_BUS, 0 }, 543 { 6, B_MULTI_INPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 }, 544 { 7, B_MULTI_INPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 }, 545 { 8, B_MULTI_INPUT_CHANNEL, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, 0 }, 546 { 9, B_MULTI_INPUT_CHANNEL, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, 0 }, 547 { 10, B_MULTI_OUTPUT_BUS, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 548 { 11, B_MULTI_OUTPUT_BUS, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 549 { 12, B_MULTI_INPUT_BUS, B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 550 { 13, B_MULTI_INPUT_BUS, B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS, B_CHANNEL_MINI_JACK_STEREO }, 551 };*/ 552 553 554 static void 555 auvia_create_channels_list(multi_dev *multi) 556 { 557 auvia_stream *stream; 558 uint32 index, i, mode, designations; 559 multi_channel_info *chans; 560 uint32 chan_designations[] = { 561 B_CHANNEL_LEFT, 562 B_CHANNEL_RIGHT, 563 B_CHANNEL_REARLEFT, 564 B_CHANNEL_REARRIGHT, 565 B_CHANNEL_CENTER, 566 B_CHANNEL_SUB 567 }; 568 569 chans = multi->chans; 570 index = 0; 571 572 for(mode=AUVIA_USE_PLAY; mode!=-1; 573 mode = (mode == AUVIA_USE_PLAY) ? AUVIA_USE_RECORD : -1) { 574 LIST_FOREACH(stream, &((auvia_dev*)multi->card)->streams, next) { 575 if ((stream->use & mode) == 0) 576 continue; 577 578 if(stream->channels == 2) 579 designations = B_CHANNEL_STEREO_BUS; 580 else 581 designations = B_CHANNEL_SURROUND_BUS; 582 583 for(i=0; i<stream->channels; i++) { 584 chans[index].channel_id = index; 585 chans[index].kind = (mode == AUVIA_USE_PLAY) ? B_MULTI_OUTPUT_CHANNEL : B_MULTI_INPUT_CHANNEL; 586 chans[index].designations = designations | chan_designations[i]; 587 chans[index].connectors = 0; 588 index++; 589 } 590 } 591 592 if(mode==AUVIA_USE_PLAY) { 593 multi->output_channel_count = index; 594 } else { 595 multi->input_channel_count = index - multi->output_channel_count; 596 } 597 } 598 599 chans[index].channel_id = index; 600 chans[index].kind = B_MULTI_OUTPUT_BUS; 601 chans[index].designations = B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS; 602 chans[index].connectors = B_CHANNEL_MINI_JACK_STEREO; 603 index++; 604 605 chans[index].channel_id = index; 606 chans[index].kind = B_MULTI_OUTPUT_BUS; 607 chans[index].designations = B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS; 608 chans[index].connectors = B_CHANNEL_MINI_JACK_STEREO; 609 index++; 610 611 multi->output_bus_channel_count = index - multi->output_channel_count 612 - multi->input_channel_count; 613 614 chans[index].channel_id = index; 615 chans[index].kind = B_MULTI_INPUT_BUS; 616 chans[index].designations = B_CHANNEL_LEFT | B_CHANNEL_STEREO_BUS; 617 chans[index].connectors = B_CHANNEL_MINI_JACK_STEREO; 618 index++; 619 620 chans[index].channel_id = index; 621 chans[index].kind = B_MULTI_INPUT_BUS; 622 chans[index].designations = B_CHANNEL_RIGHT | B_CHANNEL_STEREO_BUS; 623 chans[index].connectors = B_CHANNEL_MINI_JACK_STEREO; 624 index++; 625 626 multi->input_bus_channel_count = index - multi->output_channel_count 627 - multi->input_channel_count - multi->output_bus_channel_count; 628 629 multi->aux_bus_channel_count = 0; 630 } 631 632 633 static status_t 634 auvia_get_description(auvia_dev *card, multi_description *data) 635 { 636 uint32 size; 637 638 data->interface_version = B_CURRENT_INTERFACE_VERSION; 639 data->interface_minimum = B_CURRENT_INTERFACE_VERSION; 640 641 if(IS_686(&card->config)) 642 strncpy(data->friendly_name, FRIENDLY_NAME_686, 32); 643 else if(IS_8233(&card->config)) { 644 switch(card->info.revision) { 645 case VIATECH_8233_AC97_REV_8233_10: 646 strncpy(data->friendly_name, FRIENDLY_NAME_8233, 32); 647 break; 648 case VIATECH_8233_AC97_REV_8233C: 649 strncpy(data->friendly_name, FRIENDLY_NAME_8233C, 32); 650 break; 651 case VIATECH_8233_AC97_REV_8233: 652 strncpy(data->friendly_name, FRIENDLY_NAME_8233, 32); 653 break; 654 case VIATECH_8233_AC97_REV_8233A: 655 strncpy(data->friendly_name, FRIENDLY_NAME_8233A, 32); 656 break; 657 case VIATECH_8233_AC97_REV_8235: 658 strncpy(data->friendly_name, FRIENDLY_NAME_8235, 32); 659 break; 660 case VIATECH_8233_AC97_REV_8237: 661 strncpy(data->friendly_name, FRIENDLY_NAME_8237, 32); 662 break; 663 default: 664 strncpy(data->friendly_name, FRIENDLY_NAME); 665 } 666 } 667 strcpy(data->vendor_info, AUTHOR); 668 669 /*data->output_channel_count = 6; 670 data->input_channel_count = 4; 671 data->output_bus_channel_count = 2; 672 data->input_bus_channel_count = 2; 673 data->aux_bus_channel_count = 0;*/ 674 675 data->output_channel_count = card->multi.output_channel_count; 676 data->input_channel_count = card->multi.input_channel_count; 677 data->output_bus_channel_count = card->multi.output_bus_channel_count; 678 data->input_bus_channel_count = card->multi.input_bus_channel_count; 679 data->aux_bus_channel_count = card->multi.aux_bus_channel_count; 680 681 size = card->multi.output_channel_count + card->multi.input_channel_count 682 + card->multi.output_bus_channel_count + card->multi.input_bus_channel_count 683 + card->multi.aux_bus_channel_count; 684 685 // for each channel, starting with the first output channel, 686 // then the second, third..., followed by the first input 687 // channel, second, third, ..., followed by output bus 688 // channels and input bus channels and finally auxillary channels, 689 690 LOG(("request_channel_count = %d\n",data->request_channel_count)); 691 if (data->request_channel_count >= size) { 692 LOG(("copying data\n")); 693 memcpy(data->channels, card->multi.chans, size * sizeof(card->multi.chans[0])); 694 } 695 696 data->output_rates = B_SR_48000;// | B_SR_44100 | B_SR_CVSR; 697 data->input_rates = B_SR_48000;// | B_SR_44100 | B_SR_CVSR; 698 //data->output_rates = B_SR_44100; 699 //data->input_rates = B_SR_44100; 700 data->min_cvsr_rate = 0; 701 data->max_cvsr_rate = 48000; 702 //data->max_cvsr_rate = 44100; 703 704 data->output_formats = B_FMT_16BIT; 705 data->input_formats = B_FMT_16BIT; 706 data->lock_sources = B_MULTI_LOCK_INTERNAL; 707 data->timecode_sources = 0; 708 data->interface_flags = B_MULTI_INTERFACE_PLAYBACK | B_MULTI_INTERFACE_RECORD; 709 data->start_latency = 3000; 710 711 strcpy(data->control_panel,""); 712 713 return B_OK; 714 } 715 716 static status_t 717 auvia_get_enabled_channels(auvia_dev *card, multi_channel_enable *data) 718 { 719 B_SET_CHANNEL(data->enable_bits, 0, true); 720 B_SET_CHANNEL(data->enable_bits, 1, true); 721 B_SET_CHANNEL(data->enable_bits, 2, true); 722 B_SET_CHANNEL(data->enable_bits, 3, true); 723 data->lock_source = B_MULTI_LOCK_INTERNAL; 724 /* 725 uint32 lock_source; 726 int32 lock_data; 727 uint32 timecode_source; 728 uint32 * connectors; 729 */ 730 return B_OK; 731 } 732 733 static status_t 734 auvia_set_enabled_channels(auvia_dev *card, multi_channel_enable *data) 735 { 736 PRINT(("set_enabled_channels 0 : %s\n", B_TEST_CHANNEL(data->enable_bits, 0) ? "enabled": "disabled")); 737 PRINT(("set_enabled_channels 1 : %s\n", B_TEST_CHANNEL(data->enable_bits, 1) ? "enabled": "disabled")); 738 PRINT(("set_enabled_channels 2 : %s\n", B_TEST_CHANNEL(data->enable_bits, 2) ? "enabled": "disabled")); 739 PRINT(("set_enabled_channels 3 : %s\n", B_TEST_CHANNEL(data->enable_bits, 3) ? "enabled": "disabled")); 740 return B_OK; 741 } 742 743 static status_t 744 auvia_get_global_format(auvia_dev *card, multi_format_info *data) 745 { 746 data->output_latency = 0; 747 data->input_latency = 0; 748 data->timecode_kind = 0; 749 data->input.rate = B_SR_48000; 750 data->input.cvsr = 48000; 751 data->input.format = B_FMT_16BIT; 752 data->output.rate = B_SR_48000; 753 data->output.cvsr = 48000; 754 data->output.format = B_FMT_16BIT; 755 /*data->input.rate = B_SR_44100; 756 data->input.cvsr = 44100; 757 data->input.format = B_FMT_16BIT; 758 data->output.rate = B_SR_44100; 759 data->output.cvsr = 44100; 760 data->output.format = B_FMT_16BIT;*/ 761 return B_OK; 762 } 763 764 static status_t 765 auvia_get_buffers(auvia_dev *card, multi_buffer_list *data) 766 { 767 uint32 i, j, pchannels, rchannels; 768 769 LOG(("flags = %#x\n",data->flags)); 770 LOG(("request_playback_buffers = %#x\n",data->request_playback_buffers)); 771 LOG(("request_playback_channels = %#x\n",data->request_playback_channels)); 772 LOG(("request_playback_buffer_size = %#x\n",data->request_playback_buffer_size)); 773 LOG(("request_record_buffers = %#x\n",data->request_record_buffers)); 774 LOG(("request_record_channels = %#x\n",data->request_record_channels)); 775 LOG(("request_record_buffer_size = %#x\n",data->request_record_buffer_size)); 776 777 pchannels = card->pstream->channels; 778 rchannels = card->rstream->channels; 779 780 if (data->request_playback_buffers < BUFFER_COUNT || 781 data->request_playback_channels < (pchannels) || 782 data->request_record_buffers < BUFFER_COUNT || 783 data->request_record_channels < (rchannels)) { 784 LOG(("not enough channels/buffers\n")); 785 } 786 787 ASSERT(BUFFER_COUNT == 2); 788 789 data->flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; // XXX ??? 790 // data->flags = 0; 791 792 data->return_playback_buffers = BUFFER_COUNT; /* playback_buffers[b][] */ 793 data->return_playback_channels = pchannels; /* playback_buffers[][c] */ 794 data->return_playback_buffer_size = BUFFER_FRAMES; /* frames */ 795 796 for(i=0; i<BUFFER_COUNT; i++) 797 for(j=0; j<pchannels; j++) 798 auvia_stream_get_nth_buffer(card->pstream, j, i, 799 &data->playback_buffers[i][j].base, 800 &data->playback_buffers[i][j].stride); 801 802 data->return_record_buffers = BUFFER_COUNT; 803 data->return_record_channels = rchannels; 804 data->return_record_buffer_size = BUFFER_FRAMES; /* frames */ 805 806 for(i=0; i<BUFFER_COUNT; i++) 807 for(j=0; j<rchannels; j++) 808 auvia_stream_get_nth_buffer(card->rstream, j, i, 809 &data->record_buffers[i][j].base, 810 &data->record_buffers[i][j].stride); 811 812 return B_OK; 813 } 814 815 816 void 817 auvia_play_inth(void* inthparams) 818 { 819 auvia_stream *stream = (auvia_stream *)inthparams; 820 //int32 count; 821 822 //TRACE(("auvia_play_inth\n")); 823 824 acquire_spinlock(&slock); 825 stream->real_time = system_time(); 826 stream->frames_count += BUFFER_FRAMES; 827 stream->buffer_cycle = (stream->trigblk 828 + stream->blkmod -1) % stream->blkmod; 829 stream->update_needed = true; 830 release_spinlock(&slock); 831 832 //get_sem_count(stream->card->buffer_ready_sem, &count); 833 //if (count <= 0) 834 release_sem_etc(stream->card->buffer_ready_sem, 1, B_DO_NOT_RESCHEDULE); 835 } 836 837 void 838 auvia_record_inth(void* inthparams) 839 { 840 auvia_stream *stream = (auvia_stream *)inthparams; 841 //int32 count; 842 843 //TRACE(("auvia_record_inth\n")); 844 845 acquire_spinlock(&slock); 846 stream->real_time = system_time(); 847 stream->frames_count += BUFFER_FRAMES; 848 stream->buffer_cycle = (stream->trigblk 849 + stream->blkmod -1) % stream->blkmod; 850 stream->update_needed = true; 851 release_spinlock(&slock); 852 853 //get_sem_count(stream->card->buffer_ready_sem, &count); 854 //if (count <= 0) 855 release_sem_etc(stream->card->buffer_ready_sem, 1, B_DO_NOT_RESCHEDULE); 856 } 857 858 static status_t 859 auvia_buffer_exchange(auvia_dev *card, multi_buffer_info *data) 860 { 861 cpu_status status; 862 auvia_stream *pstream, *rstream; 863 864 data->flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; 865 866 if (!(card->pstream->state & AUVIA_STATE_STARTED)) 867 auvia_stream_start(card->pstream, auvia_play_inth, card->pstream); 868 869 if (!(card->rstream->state & AUVIA_STATE_STARTED)) 870 auvia_stream_start(card->rstream, auvia_record_inth, card->rstream); 871 872 if(acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT, 50000) 873 == B_TIMED_OUT) { 874 LOG(("buffer_exchange timeout ff\n")); 875 } 876 877 status = lock(); 878 879 LIST_FOREACH(pstream, &card->streams, next) { 880 if ((pstream->use & AUVIA_USE_PLAY) == 0 || 881 (pstream->state & AUVIA_STATE_STARTED) == 0) 882 continue; 883 if(pstream->update_needed) 884 break; 885 } 886 887 LIST_FOREACH(rstream, &card->streams, next) { 888 if ((rstream->use & AUVIA_USE_RECORD) == 0 || 889 (rstream->state & AUVIA_STATE_STARTED) == 0) 890 continue; 891 if(rstream->update_needed) 892 break; 893 } 894 895 if(!pstream) 896 pstream = card->pstream; 897 if(!rstream) 898 rstream = card->rstream; 899 900 /* do playback */ 901 data->playback_buffer_cycle = pstream->buffer_cycle; 902 data->played_real_time = pstream->real_time; 903 data->played_frames_count = pstream->frames_count; 904 data->_reserved_0 = pstream->first_channel; 905 pstream->update_needed = false; 906 907 /* do record */ 908 data->record_buffer_cycle = rstream->buffer_cycle; 909 data->recorded_frames_count = rstream->frames_count; 910 data->recorded_real_time = rstream->real_time; 911 data->_reserved_1 = rstream->first_channel; 912 rstream->update_needed = false; 913 unlock(status); 914 915 //TRACE(("buffer_exchange ended\n")); 916 return B_OK; 917 } 918 919 static status_t 920 auvia_buffer_force_stop(auvia_dev *card) 921 { 922 //auvia_voice_halt(card->pvoice); 923 return B_OK; 924 } 925 926 static status_t 927 auvia_multi_control(void *cookie, uint32 op, void *data, size_t length) 928 { 929 auvia_dev *card = (auvia_dev *)cookie; 930 931 switch (op) { 932 case B_MULTI_GET_DESCRIPTION: 933 LOG(("B_MULTI_GET_DESCRIPTION\n")); 934 return auvia_get_description(card, (multi_description *)data); 935 case B_MULTI_GET_EVENT_INFO: 936 LOG(("B_MULTI_GET_EVENT_INFO\n")); 937 return B_ERROR; 938 case B_MULTI_SET_EVENT_INFO: 939 LOG(("B_MULTI_SET_EVENT_INFO\n")); 940 return B_ERROR; 941 case B_MULTI_GET_EVENT: 942 LOG(("B_MULTI_GET_EVENT\n")); 943 return B_ERROR; 944 case B_MULTI_GET_ENABLED_CHANNELS: 945 LOG(("B_MULTI_GET_ENABLED_CHANNELS\n")); 946 return auvia_get_enabled_channels(card, (multi_channel_enable *)data); 947 case B_MULTI_SET_ENABLED_CHANNELS: 948 LOG(("B_MULTI_SET_ENABLED_CHANNELS\n")); 949 return auvia_set_enabled_channels(card, (multi_channel_enable *)data); 950 case B_MULTI_GET_GLOBAL_FORMAT: 951 LOG(("B_MULTI_GET_GLOBAL_FORMAT\n")); 952 return auvia_get_global_format(card, (multi_format_info *)data); 953 case B_MULTI_SET_GLOBAL_FORMAT: 954 LOG(("B_MULTI_SET_GLOBAL_FORMAT\n")); 955 return B_OK; /* XXX BUG! we *MUST* return B_OK, returning B_ERROR will prevent 956 * BeOS to accept the format returned in B_MULTI_GET_GLOBAL_FORMAT 957 */ 958 case B_MULTI_GET_CHANNEL_FORMATS: 959 LOG(("B_MULTI_GET_CHANNEL_FORMATS\n")); 960 return B_ERROR; 961 case B_MULTI_SET_CHANNEL_FORMATS: /* only implemented if possible */ 962 LOG(("B_MULTI_SET_CHANNEL_FORMATS\n")); 963 return B_ERROR; 964 case B_MULTI_GET_MIX: 965 LOG(("B_MULTI_GET_MIX\n")); 966 return auvia_get_mix(card, (multi_mix_value_info *)data); 967 case B_MULTI_SET_MIX: 968 LOG(("B_MULTI_SET_MIX\n")); 969 return auvia_set_mix(card, (multi_mix_value_info *)data); 970 case B_MULTI_LIST_MIX_CHANNELS: 971 LOG(("B_MULTI_LIST_MIX_CHANNELS\n")); 972 return auvia_list_mix_channels(card, (multi_mix_channel_info *)data); 973 case B_MULTI_LIST_MIX_CONTROLS: 974 LOG(("B_MULTI_LIST_MIX_CONTROLS\n")); 975 return auvia_list_mix_controls(card, (multi_mix_control_info *)data); 976 case B_MULTI_LIST_MIX_CONNECTIONS: 977 LOG(("B_MULTI_LIST_MIX_CONNECTIONS\n")); 978 return auvia_list_mix_connections(card, (multi_mix_connection_info *)data); 979 case B_MULTI_GET_BUFFERS: /* Fill out the struct for the first time; doesn't start anything. */ 980 LOG(("B_MULTI_GET_BUFFERS\n")); 981 return auvia_get_buffers(card, data); 982 case B_MULTI_SET_BUFFERS: /* Set what buffers to use, if the driver supports soft buffers. */ 983 LOG(("B_MULTI_SET_BUFFERS\n")); 984 return B_ERROR; /* we do not support soft buffers */ 985 case B_MULTI_SET_START_TIME: /* When to actually start */ 986 LOG(("B_MULTI_SET_START_TIME\n")); 987 return B_ERROR; 988 case B_MULTI_BUFFER_EXCHANGE: /* stop and go are derived from this being called */ 989 //TRACE(("B_MULTI_BUFFER_EXCHANGE\n")); 990 return auvia_buffer_exchange(card, (multi_buffer_info *)data); 991 case B_MULTI_BUFFER_FORCE_STOP: /* force stop of playback, nothing in data */ 992 LOG(("B_MULTI_BUFFER_FORCE_STOP\n")); 993 return auvia_buffer_force_stop(card); 994 } 995 LOG(("ERROR: unknown multi_control %#x\n",op)); 996 return B_ERROR; 997 } 998 999 static status_t auvia_open(const char *name, uint32 flags, void** cookie); 1000 static status_t auvia_close(void* cookie); 1001 static status_t auvia_free(void* cookie); 1002 static status_t auvia_control(void* cookie, uint32 op, void* arg, size_t len); 1003 static status_t auvia_read(void* cookie, off_t position, void *buf, size_t* num_bytes); 1004 static status_t auvia_write(void* cookie, off_t position, const void* buffer, size_t* num_bytes); 1005 1006 device_hooks multi_hooks = { 1007 auvia_open, /* -> open entry point */ 1008 auvia_close, /* -> close entry point */ 1009 auvia_free, /* -> free cookie */ 1010 auvia_control, /* -> control entry point */ 1011 auvia_read, /* -> read entry point */ 1012 auvia_write, /* -> write entry point */ 1013 NULL, /* start select */ 1014 NULL, /* stop select */ 1015 NULL, /* scatter-gather read from the device */ 1016 NULL /* scatter-gather write to the device */ 1017 }; 1018 1019 static status_t 1020 auvia_open(const char *name, uint32 flags, void** cookie) 1021 { 1022 auvia_dev *card = NULL; 1023 int ix; 1024 1025 LOG(("open()\n")); 1026 1027 for (ix=0; ix<num_cards; ix++) { 1028 if (!strcmp(cards[ix].name, name)) { 1029 card = &cards[ix]; 1030 } 1031 } 1032 1033 if(card == NULL) { 1034 LOG(("open() card not found %s\n", name)); 1035 for (ix=0; ix<num_cards; ix++) { 1036 LOG(("open() card available %s\n", cards[ix].name)); 1037 } 1038 return B_ERROR; 1039 } 1040 1041 LOG(("open() got card\n")); 1042 1043 if(card->pstream !=NULL) 1044 return B_ERROR; 1045 if(card->rstream !=NULL) 1046 return B_ERROR; 1047 1048 *cookie = card; 1049 card->multi.card = card; 1050 1051 LOG(("stream_new\n")); 1052 1053 card->rstream = auvia_stream_new(card, AUVIA_USE_RECORD, BUFFER_FRAMES, BUFFER_COUNT); 1054 card->pstream = auvia_stream_new(card, AUVIA_USE_PLAY, BUFFER_FRAMES, BUFFER_COUNT); 1055 1056 card->buffer_ready_sem = create_sem(0, "pbuffer ready"); 1057 1058 LOG(("stream_setaudio\n")); 1059 1060 auvia_stream_set_audioparms(card->pstream, 2, true, 48000); 1061 auvia_stream_set_audioparms(card->rstream, 2, true, 48000); 1062 1063 card->pstream->first_channel = 0; 1064 card->rstream->first_channel = 2; 1065 1066 auvia_stream_commit_parms(card->pstream); 1067 auvia_stream_commit_parms(card->rstream); 1068 1069 auvia_create_channels_list(&card->multi); 1070 1071 return B_OK; 1072 } 1073 1074 static status_t 1075 auvia_close(void* cookie) 1076 { 1077 //auvia_dev *card = cookie; 1078 LOG(("close()\n")); 1079 1080 return B_OK; 1081 } 1082 1083 static status_t 1084 auvia_free(void* cookie) 1085 { 1086 auvia_dev *card = cookie; 1087 auvia_stream *stream; 1088 LOG(("free()\n")); 1089 1090 if (card->buffer_ready_sem > B_OK) 1091 delete_sem(card->buffer_ready_sem); 1092 1093 LIST_FOREACH(stream, &card->streams, next) { 1094 auvia_stream_halt(stream); 1095 } 1096 1097 while(!LIST_EMPTY(&card->streams)) { 1098 auvia_stream_delete(LIST_FIRST(&card->streams)); 1099 } 1100 1101 return B_OK; 1102 } 1103 1104 static status_t 1105 auvia_control(void* cookie, uint32 op, void* arg, size_t len) 1106 { 1107 return auvia_multi_control(cookie, op, arg, len); 1108 } 1109 1110 static status_t 1111 auvia_read(void* cookie, off_t position, void *buf, size_t* num_bytes) 1112 { 1113 *num_bytes = 0; /* tell caller nothing was read */ 1114 return B_IO_ERROR; 1115 } 1116 1117 static status_t 1118 auvia_write(void* cookie, off_t position, const void* buffer, size_t* num_bytes) 1119 { 1120 *num_bytes = 0; /* tell caller nothing was written */ 1121 return B_IO_ERROR; 1122 } 1123