1 /* $NetBSD: btsco.c,v 1.24 2011/03/16 21:38:54 plunky Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 Itronix Inc. 5 * All rights reserved. 6 * 7 * Written by Iain Hibbert for Itronix Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. The name of Itronix Inc. may not be used to endorse 18 * or promote products derived from this software without specific 19 * prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28 * ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 __KERNEL_RCSID(0, "$NetBSD: btsco.c,v 1.24 2011/03/16 21:38:54 plunky Exp $"); 36 37 #include <sys/param.h> 38 #include <sys/audioio.h> 39 #include <sys/conf.h> 40 #include <sys/device.h> 41 #include <sys/fcntl.h> 42 #include <sys/kernel.h> 43 #include <sys/queue.h> 44 #include <sys/malloc.h> 45 #include <sys/mbuf.h> 46 #include <sys/proc.h> 47 #include <sys/socketvar.h> 48 #include <sys/systm.h> 49 #include <sys/intr.h> 50 51 #include <prop/proplib.h> 52 53 #include <netbt/bluetooth.h> 54 #include <netbt/rfcomm.h> 55 #include <netbt/sco.h> 56 57 #include <dev/audio_if.h> 58 #include <dev/auconv.h> 59 #include <dev/mulaw.h> 60 61 #include <dev/bluetooth/btdev.h> 62 #include <dev/bluetooth/btsco.h> 63 64 #undef DPRINTF 65 #undef DPRINTFN 66 67 #ifdef BTSCO_DEBUG 68 int btsco_debug = BTSCO_DEBUG; 69 #define DPRINTF(...) do { \ 70 if (btsco_debug) { \ 71 printf("%s: ", __func__); \ 72 printf(__VA_ARGS__); \ 73 } \ 74 } while (/* CONSTCOND */0) 75 76 #define DPRINTFN(n, ...) do { \ 77 if (btsco_debug > (n)) { \ 78 printf("%s: ", __func__); \ 79 printf(__VA_ARGS__); \ 80 } \ 81 } while (/* CONSTCOND */0) 82 #else 83 #define DPRINTF(...) 84 #define DPRINTFN(...) 85 #endif 86 87 /***************************************************************************** 88 * 89 * Bluetooth SCO Audio device 90 */ 91 92 /* btsco softc */ 93 struct btsco_softc { 94 uint16_t sc_flags; 95 const char *sc_name; /* our device_xname */ 96 97 device_t sc_audio; /* MI audio device */ 98 void *sc_intr; /* interrupt cookie */ 99 kcondvar_t sc_connect; /* connect wait */ 100 101 /* Bluetooth */ 102 bdaddr_t sc_laddr; /* local address */ 103 bdaddr_t sc_raddr; /* remote address */ 104 uint16_t sc_state; /* link state */ 105 struct sco_pcb *sc_sco; /* SCO handle */ 106 struct sco_pcb *sc_sco_l; /* SCO listen handle */ 107 uint16_t sc_mtu; /* SCO mtu */ 108 uint8_t sc_channel; /* RFCOMM channel */ 109 int sc_err; /* stored error */ 110 111 /* Receive */ 112 int sc_rx_want; /* bytes wanted */ 113 uint8_t *sc_rx_block; /* receive block */ 114 void (*sc_rx_intr)(void *); /* callback */ 115 void *sc_rx_intrarg; /* callback arg */ 116 struct mbuf *sc_rx_mbuf; /* leftover mbuf */ 117 118 /* Transmit */ 119 int sc_tx_size; /* bytes to send */ 120 int sc_tx_pending; /* packets pending */ 121 uint8_t *sc_tx_block; /* transmit block */ 122 void (*sc_tx_intr)(void *); /* callback */ 123 void *sc_tx_intrarg; /* callback arg */ 124 void *sc_tx_buf; /* transmit buffer */ 125 int sc_tx_refcnt; /* buffer refcnt */ 126 127 /* mixer data */ 128 int sc_vgs; /* speaker volume */ 129 int sc_vgm; /* mic volume */ 130 }; 131 132 /* sc_state */ 133 #define BTSCO_CLOSED 0 134 #define BTSCO_WAIT_CONNECT 1 135 #define BTSCO_OPEN 2 136 137 /* sc_flags */ 138 #define BTSCO_LISTEN (1 << 1) 139 140 /* autoconf(9) glue */ 141 static int btsco_match(device_t, cfdata_t, void *); 142 static void btsco_attach(device_t, device_t, void *); 143 static int btsco_detach(device_t, int); 144 145 CFATTACH_DECL_NEW(btsco, sizeof(struct btsco_softc), 146 btsco_match, btsco_attach, btsco_detach, NULL); 147 148 /* audio(9) glue */ 149 static int btsco_open(void *, int); 150 static void btsco_close(void *); 151 static int btsco_query_encoding(void *, struct audio_encoding *); 152 static int btsco_set_params(void *, int, int, audio_params_t *, audio_params_t *, 153 stream_filter_list_t *, stream_filter_list_t *); 154 static int btsco_round_blocksize(void *, int, int, const audio_params_t *); 155 static int btsco_start_output(void *, void *, int, void (*)(void *), void *); 156 static int btsco_start_input(void *, void *, int, void (*)(void *), void *); 157 static int btsco_halt_output(void *); 158 static int btsco_halt_input(void *); 159 static int btsco_getdev(void *, struct audio_device *); 160 static int btsco_setfd(void *, int); 161 static int btsco_set_port(void *, mixer_ctrl_t *); 162 static int btsco_get_port(void *, mixer_ctrl_t *); 163 static int btsco_query_devinfo(void *, mixer_devinfo_t *); 164 static void *btsco_allocm(void *, int, size_t, struct malloc_type *, int); 165 static void btsco_freem(void *, void *, struct malloc_type *); 166 static int btsco_get_props(void *); 167 static int btsco_dev_ioctl(void *, u_long, void *, int, struct lwp *); 168 169 static const struct audio_hw_if btsco_if = { 170 btsco_open, /* open */ 171 btsco_close, /* close */ 172 NULL, /* drain */ 173 btsco_query_encoding, /* query_encoding */ 174 btsco_set_params, /* set_params */ 175 btsco_round_blocksize, /* round_blocksize */ 176 NULL, /* commit_settings */ 177 NULL, /* init_output */ 178 NULL, /* init_input */ 179 btsco_start_output, /* start_output */ 180 btsco_start_input, /* start_input */ 181 btsco_halt_output, /* halt_output */ 182 btsco_halt_input, /* halt_input */ 183 NULL, /* speaker_ctl */ 184 btsco_getdev, /* getdev */ 185 btsco_setfd, /* setfd */ 186 btsco_set_port, /* set_port */ 187 btsco_get_port, /* get_port */ 188 btsco_query_devinfo, /* query_devinfo */ 189 btsco_allocm, /* allocm */ 190 btsco_freem, /* freem */ 191 NULL, /* round_buffersize */ 192 NULL, /* mappage */ 193 btsco_get_props, /* get_props */ 194 NULL, /* trigger_output */ 195 NULL, /* trigger_input */ 196 btsco_dev_ioctl, /* dev_ioctl */ 197 NULL, /* powerstate */ 198 }; 199 200 static const struct audio_device btsco_device = { 201 "Bluetooth Audio", 202 "", 203 "btsco" 204 }; 205 206 /* Voice_Setting == 0x0060: 8000Hz, mono, 16-bit, slinear_le */ 207 static const struct audio_format btsco_format = { 208 NULL, /* driver_data */ 209 (AUMODE_PLAY | AUMODE_RECORD), /* mode */ 210 AUDIO_ENCODING_SLINEAR_LE, /* encoding */ 211 16, /* validbits */ 212 16, /* precision */ 213 1, /* channels */ 214 AUFMT_MONAURAL, /* channel_mask */ 215 1, /* frequency_type */ 216 { 8000 } /* frequency */ 217 }; 218 219 /* bluetooth(9) glue for SCO */ 220 static void btsco_sco_connecting(void *); 221 static void btsco_sco_connected(void *); 222 static void btsco_sco_disconnected(void *, int); 223 static void *btsco_sco_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *); 224 static void btsco_sco_complete(void *, int); 225 static void btsco_sco_linkmode(void *, int); 226 static void btsco_sco_input(void *, struct mbuf *); 227 228 static const struct btproto btsco_sco_proto = { 229 btsco_sco_connecting, 230 btsco_sco_connected, 231 btsco_sco_disconnected, 232 btsco_sco_newconn, 233 btsco_sco_complete, 234 btsco_sco_linkmode, 235 btsco_sco_input, 236 }; 237 238 239 /***************************************************************************** 240 * 241 * btsco definitions 242 */ 243 244 /* 245 * btsco mixer class 246 */ 247 #define BTSCO_VGS 0 248 #define BTSCO_VGM 1 249 #define BTSCO_INPUT_CLASS 2 250 #define BTSCO_OUTPUT_CLASS 3 251 252 /* connect timeout */ 253 #define BTSCO_TIMEOUT (30 * hz) 254 255 /* misc btsco functions */ 256 static void btsco_extfree(struct mbuf *, void *, size_t, void *); 257 static void btsco_intr(void *); 258 259 260 /***************************************************************************** 261 * 262 * btsco autoconf(9) routines 263 */ 264 265 static int 266 btsco_match(device_t self, cfdata_t cfdata, void *aux) 267 { 268 prop_dictionary_t dict = aux; 269 prop_object_t obj; 270 271 obj = prop_dictionary_get(dict, BTDEVservice); 272 if (prop_string_equals_cstring(obj, "HSET")) 273 return 1; 274 275 if (prop_string_equals_cstring(obj, "HF")) 276 return 1; 277 278 return 0; 279 } 280 281 static void 282 btsco_attach(device_t parent, device_t self, void *aux) 283 { 284 struct btsco_softc *sc = device_private(self); 285 prop_dictionary_t dict = aux; 286 prop_object_t obj; 287 288 /* 289 * Init softc 290 */ 291 sc->sc_vgs = 200; 292 sc->sc_vgm = 200; 293 sc->sc_state = BTSCO_CLOSED; 294 sc->sc_name = device_xname(self); 295 cv_init(&sc->sc_connect, "connect"); 296 297 /* 298 * copy in our configuration info 299 */ 300 obj = prop_dictionary_get(dict, BTDEVladdr); 301 bdaddr_copy(&sc->sc_laddr, prop_data_data_nocopy(obj)); 302 303 obj = prop_dictionary_get(dict, BTDEVraddr); 304 bdaddr_copy(&sc->sc_raddr, prop_data_data_nocopy(obj)); 305 306 obj = prop_dictionary_get(dict, BTDEVservice); 307 if (prop_string_equals_cstring(obj, "HF")) { 308 sc->sc_flags |= BTSCO_LISTEN; 309 aprint_verbose(" listen mode"); 310 } 311 312 obj = prop_dictionary_get(dict, BTSCOchannel); 313 if (prop_object_type(obj) != PROP_TYPE_NUMBER 314 || prop_number_integer_value(obj) < RFCOMM_CHANNEL_MIN 315 || prop_number_integer_value(obj) > RFCOMM_CHANNEL_MAX) { 316 aprint_error(" invalid %s", BTSCOchannel); 317 return; 318 } 319 sc->sc_channel = prop_number_integer_value(obj); 320 321 aprint_verbose(" channel %d", sc->sc_channel); 322 aprint_normal("\n"); 323 324 DPRINTF("sc=%p\n", sc); 325 326 /* 327 * set up transmit interrupt 328 */ 329 sc->sc_intr = softint_establish(SOFTINT_NET, btsco_intr, sc); 330 if (sc->sc_intr == NULL) { 331 aprint_error_dev(self, "softint_establish failed\n"); 332 return; 333 } 334 335 /* 336 * attach audio device 337 */ 338 sc->sc_audio = audio_attach_mi(&btsco_if, sc, self); 339 if (sc->sc_audio == NULL) { 340 aprint_error_dev(self, "audio_attach_mi failed\n"); 341 return; 342 } 343 } 344 345 static int 346 btsco_detach(device_t self, int flags) 347 { 348 struct btsco_softc *sc = device_private(self); 349 350 DPRINTF("sc=%p\n", sc); 351 352 mutex_enter(bt_lock); 353 if (sc->sc_sco != NULL) { 354 DPRINTF("sc_sco=%p\n", sc->sc_sco); 355 sco_disconnect(sc->sc_sco, 0); 356 sco_detach(&sc->sc_sco); 357 sc->sc_sco = NULL; 358 } 359 360 if (sc->sc_sco_l != NULL) { 361 DPRINTF("sc_sco_l=%p\n", sc->sc_sco_l); 362 sco_detach(&sc->sc_sco_l); 363 sc->sc_sco_l = NULL; 364 } 365 mutex_exit(bt_lock); 366 367 if (sc->sc_audio != NULL) { 368 DPRINTF("sc_audio=%p\n", sc->sc_audio); 369 config_detach(sc->sc_audio, flags); 370 sc->sc_audio = NULL; 371 } 372 373 if (sc->sc_intr != NULL) { 374 softint_disestablish(sc->sc_intr); 375 sc->sc_intr = NULL; 376 } 377 378 if (sc->sc_rx_mbuf != NULL) { 379 m_freem(sc->sc_rx_mbuf); 380 sc->sc_rx_mbuf = NULL; 381 } 382 383 if (sc->sc_tx_refcnt > 0) { 384 aprint_error_dev(self, "tx_refcnt=%d!\n", sc->sc_tx_refcnt); 385 386 if ((flags & DETACH_FORCE) == 0) 387 return EAGAIN; 388 } 389 390 cv_destroy(&sc->sc_connect); 391 392 return 0; 393 } 394 395 /***************************************************************************** 396 * 397 * bluetooth(9) methods for SCO 398 * 399 * All these are called from Bluetooth Protocol code, in a soft 400 * interrupt context at IPL_SOFTNET. 401 */ 402 403 static void 404 btsco_sco_connecting(void *arg) 405 { 406 /* struct btsco_softc *sc = arg; */ 407 408 /* dont care */ 409 } 410 411 static void 412 btsco_sco_connected(void *arg) 413 { 414 struct btsco_softc *sc = arg; 415 416 DPRINTF("%s\n", sc->sc_name); 417 418 KASSERT(sc->sc_sco != NULL); 419 KASSERT(sc->sc_state == BTSCO_WAIT_CONNECT); 420 421 /* 422 * If we are listening, no more need 423 */ 424 if (sc->sc_sco_l != NULL) 425 sco_detach(&sc->sc_sco_l); 426 427 sc->sc_state = BTSCO_OPEN; 428 cv_broadcast(&sc->sc_connect); 429 } 430 431 static void 432 btsco_sco_disconnected(void *arg, int err) 433 { 434 struct btsco_softc *sc = arg; 435 int s; 436 437 DPRINTF("%s sc_state %d\n", sc->sc_name, sc->sc_state); 438 439 KASSERT(sc->sc_sco != NULL); 440 441 sc->sc_err = err; 442 sco_detach(&sc->sc_sco); 443 444 switch (sc->sc_state) { 445 case BTSCO_CLOSED: /* dont think this can happen */ 446 break; 447 448 case BTSCO_WAIT_CONNECT: /* connect failed */ 449 cv_broadcast(&sc->sc_connect); 450 break; 451 452 case BTSCO_OPEN: /* link lost */ 453 /* 454 * If IO is in progress, tell the audio driver that it 455 * has completed so that when it tries to send more, we 456 * can indicate an error. 457 */ 458 s = splaudio(); 459 if (sc->sc_tx_pending > 0) { 460 sc->sc_tx_pending = 0; 461 (*sc->sc_tx_intr)(sc->sc_tx_intrarg); 462 } 463 if (sc->sc_rx_want > 0) { 464 sc->sc_rx_want = 0; 465 (*sc->sc_rx_intr)(sc->sc_rx_intrarg); 466 } 467 splx(s); 468 break; 469 470 default: 471 UNKNOWN(sc->sc_state); 472 } 473 474 sc->sc_state = BTSCO_CLOSED; 475 } 476 477 static void * 478 btsco_sco_newconn(void *arg, struct sockaddr_bt *laddr, 479 struct sockaddr_bt *raddr) 480 { 481 struct btsco_softc *sc = arg; 482 483 DPRINTF("%s\n", sc->sc_name); 484 485 if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0 486 || sc->sc_state != BTSCO_WAIT_CONNECT 487 || sc->sc_sco != NULL) 488 return NULL; 489 490 sco_attach(&sc->sc_sco, &btsco_sco_proto, sc); 491 return sc->sc_sco; 492 } 493 494 static void 495 btsco_sco_complete(void *arg, int count) 496 { 497 struct btsco_softc *sc = arg; 498 int s; 499 500 DPRINTFN(10, "%s count %d\n", sc->sc_name, count); 501 502 s = splaudio(); 503 if (sc->sc_tx_pending > 0) { 504 sc->sc_tx_pending -= count; 505 if (sc->sc_tx_pending == 0) 506 (*sc->sc_tx_intr)(sc->sc_tx_intrarg); 507 } 508 splx(s); 509 } 510 511 static void 512 btsco_sco_linkmode(void *arg, int new) 513 { 514 /* struct btsco_softc *sc = arg; */ 515 516 /* dont care */ 517 } 518 519 static void 520 btsco_sco_input(void *arg, struct mbuf *m) 521 { 522 struct btsco_softc *sc = arg; 523 int len, s; 524 525 DPRINTFN(10, "%s len=%d\n", sc->sc_name, m->m_pkthdr.len); 526 527 s = splaudio(); 528 if (sc->sc_rx_want == 0) { 529 m_freem(m); 530 } else { 531 KASSERT(sc->sc_rx_intr != NULL); 532 KASSERT(sc->sc_rx_block != NULL); 533 534 len = MIN(sc->sc_rx_want, m->m_pkthdr.len); 535 m_copydata(m, 0, len, sc->sc_rx_block); 536 537 sc->sc_rx_want -= len; 538 sc->sc_rx_block += len; 539 540 if (len > m->m_pkthdr.len) { 541 if (sc->sc_rx_mbuf != NULL) 542 m_freem(sc->sc_rx_mbuf); 543 544 m_adj(m, len); 545 sc->sc_rx_mbuf = m; 546 } else { 547 m_freem(m); 548 } 549 550 if (sc->sc_rx_want == 0) 551 (*sc->sc_rx_intr)(sc->sc_rx_intrarg); 552 } 553 splx(s); 554 } 555 556 557 /***************************************************************************** 558 * 559 * audio(9) methods 560 * 561 */ 562 563 static int 564 btsco_open(void *hdl, int flags) 565 { 566 struct sockaddr_bt sa; 567 struct btsco_softc *sc = hdl; 568 struct sockopt sopt; 569 int err, timo; 570 571 DPRINTF("%s flags 0x%x\n", sc->sc_name, flags); 572 /* flags FREAD & FWRITE? */ 573 574 if (sc->sc_sco != NULL || sc->sc_sco_l != NULL) 575 return EIO; 576 577 mutex_enter(bt_lock); 578 579 memset(&sa, 0, sizeof(sa)); 580 sa.bt_len = sizeof(sa); 581 sa.bt_family = AF_BLUETOOTH; 582 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr); 583 584 if (sc->sc_flags & BTSCO_LISTEN) { 585 err = sco_attach(&sc->sc_sco_l, &btsco_sco_proto, sc); 586 if (err) 587 goto done; 588 589 err = sco_bind(sc->sc_sco_l, &sa); 590 if (err) { 591 sco_detach(&sc->sc_sco_l); 592 goto done; 593 } 594 595 err = sco_listen(sc->sc_sco_l); 596 if (err) { 597 sco_detach(&sc->sc_sco_l); 598 goto done; 599 } 600 601 timo = 0; /* no timeout */ 602 } else { 603 err = sco_attach(&sc->sc_sco, &btsco_sco_proto, sc); 604 if (err) 605 goto done; 606 607 err = sco_bind(sc->sc_sco, &sa); 608 if (err) { 609 sco_detach(&sc->sc_sco); 610 goto done; 611 } 612 613 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr); 614 err = sco_connect(sc->sc_sco, &sa); 615 if (err) { 616 sco_detach(&sc->sc_sco); 617 goto done; 618 } 619 620 timo = BTSCO_TIMEOUT; 621 } 622 623 sc->sc_state = BTSCO_WAIT_CONNECT; 624 while (err == 0 && sc->sc_state == BTSCO_WAIT_CONNECT) 625 err = cv_timedwait_sig(&sc->sc_connect, bt_lock, timo); 626 627 switch (sc->sc_state) { 628 case BTSCO_CLOSED: /* disconnected */ 629 err = sc->sc_err; 630 631 /* fall through to */ 632 case BTSCO_WAIT_CONNECT: /* error */ 633 if (sc->sc_sco != NULL) 634 sco_detach(&sc->sc_sco); 635 636 if (sc->sc_sco_l != NULL) 637 sco_detach(&sc->sc_sco_l); 638 639 break; 640 641 case BTSCO_OPEN: /* hurrah */ 642 sockopt_init(&sopt, BTPROTO_SCO, SO_SCO_MTU, 0); 643 (void)sco_getopt(sc->sc_sco, &sopt); 644 (void)sockopt_get(&sopt, &sc->sc_mtu, sizeof(sc->sc_mtu)); 645 sockopt_destroy(&sopt); 646 break; 647 648 default: 649 UNKNOWN(sc->sc_state); 650 break; 651 } 652 653 done: 654 mutex_exit(bt_lock); 655 656 DPRINTF("done err=%d, sc_state=%d, sc_mtu=%d\n", 657 err, sc->sc_state, sc->sc_mtu); 658 return err; 659 } 660 661 static void 662 btsco_close(void *hdl) 663 { 664 struct btsco_softc *sc = hdl; 665 666 DPRINTF("%s\n", sc->sc_name); 667 668 mutex_enter(bt_lock); 669 if (sc->sc_sco != NULL) { 670 sco_disconnect(sc->sc_sco, 0); 671 sco_detach(&sc->sc_sco); 672 } 673 674 if (sc->sc_sco_l != NULL) { 675 sco_detach(&sc->sc_sco_l); 676 } 677 mutex_exit(bt_lock); 678 679 if (sc->sc_rx_mbuf != NULL) { 680 m_freem(sc->sc_rx_mbuf); 681 sc->sc_rx_mbuf = NULL; 682 } 683 684 sc->sc_rx_want = 0; 685 sc->sc_rx_block = NULL; 686 sc->sc_rx_intr = NULL; 687 sc->sc_rx_intrarg = NULL; 688 689 sc->sc_tx_size = 0; 690 sc->sc_tx_block = NULL; 691 sc->sc_tx_pending = 0; 692 sc->sc_tx_intr = NULL; 693 sc->sc_tx_intrarg = NULL; 694 } 695 696 static int 697 btsco_query_encoding(void *hdl, struct audio_encoding *ae) 698 { 699 /* struct btsco_softc *sc = hdl; */ 700 int err = 0; 701 702 switch (ae->index) { 703 case 0: 704 strcpy(ae->name, AudioEslinear_le); 705 ae->encoding = AUDIO_ENCODING_SLINEAR_LE; 706 ae->precision = 16; 707 ae->flags = 0; 708 break; 709 710 default: 711 err = EINVAL; 712 } 713 714 return err; 715 } 716 717 static int 718 btsco_set_params(void *hdl, int setmode, int usemode, 719 audio_params_t *play, audio_params_t *rec, 720 stream_filter_list_t *pfil, stream_filter_list_t *rfil) 721 { 722 /* struct btsco_softc *sc = hdl; */ 723 const struct audio_format *f; 724 int rv; 725 726 DPRINTF("setmode 0x%x usemode 0x%x\n", setmode, usemode); 727 DPRINTF("rate %d, precision %d, channels %d encoding %d\n", 728 play->sample_rate, play->precision, play->channels, play->encoding); 729 730 /* 731 * If we had a list of formats, we could check the HCI_Voice_Setting 732 * and select the appropriate one to use. Currently only one is 733 * supported: 0x0060 == 8000Hz, mono, 16-bit, slinear_le 734 */ 735 f = &btsco_format; 736 737 if (setmode & AUMODE_PLAY) { 738 rv = auconv_set_converter(f, 1, AUMODE_PLAY, play, TRUE, pfil); 739 if (rv < 0) 740 return EINVAL; 741 } 742 743 if (setmode & AUMODE_RECORD) { 744 rv = auconv_set_converter(f, 1, AUMODE_RECORD, rec, TRUE, rfil); 745 if (rv < 0) 746 return EINVAL; 747 } 748 749 return 0; 750 } 751 752 /* 753 * If we have an MTU value to use, round the blocksize to that. 754 */ 755 static int 756 btsco_round_blocksize(void *hdl, int bs, int mode, 757 const audio_params_t *param) 758 { 759 struct btsco_softc *sc = hdl; 760 761 if (sc->sc_mtu > 0) { 762 bs = (bs / sc->sc_mtu) * sc->sc_mtu; 763 if (bs == 0) 764 bs = sc->sc_mtu; 765 } 766 767 DPRINTF("%s mode=0x%x, bs=%d, sc_mtu=%d\n", 768 sc->sc_name, mode, bs, sc->sc_mtu); 769 770 return bs; 771 } 772 773 /* 774 * Start Output 775 * 776 * We dont want to be calling the network stack at splaudio() so make 777 * a note of what is to be sent, and schedule an interrupt to bundle 778 * it up and queue it. 779 */ 780 static int 781 btsco_start_output(void *hdl, void *block, int blksize, 782 void (*intr)(void *), void *intrarg) 783 { 784 struct btsco_softc *sc = hdl; 785 786 DPRINTFN(5, "%s blksize %d\n", sc->sc_name, blksize); 787 788 if (sc->sc_sco == NULL) 789 return ENOTCONN; /* connection lost */ 790 791 sc->sc_tx_block = block; 792 sc->sc_tx_pending = 0; 793 sc->sc_tx_size = blksize; 794 sc->sc_tx_intr = intr; 795 sc->sc_tx_intrarg = intrarg; 796 797 softint_schedule(sc->sc_intr); 798 return 0; 799 } 800 801 /* 802 * Start Input 803 * 804 * When the SCO link is up, we are getting data in any case, so all we do 805 * is note what we want and where to put it and let the sco_input routine 806 * fill in the data. 807 * 808 * If there was any leftover data that didnt fit in the last block, retry 809 * it now. 810 */ 811 static int 812 btsco_start_input(void *hdl, void *block, int blksize, 813 void (*intr)(void *), void *intrarg) 814 { 815 struct btsco_softc *sc = hdl; 816 struct mbuf *m; 817 818 DPRINTFN(5, "%s blksize %d\n", sc->sc_name, blksize); 819 820 if (sc->sc_sco == NULL) 821 return ENOTCONN; 822 823 sc->sc_rx_want = blksize; 824 sc->sc_rx_block = block; 825 sc->sc_rx_intr = intr; 826 sc->sc_rx_intrarg = intrarg; 827 828 if (sc->sc_rx_mbuf != NULL) { 829 m = sc->sc_rx_mbuf; 830 sc->sc_rx_mbuf = NULL; 831 btsco_sco_input(sc, m); 832 } 833 834 return 0; 835 } 836 837 /* 838 * Halt Output 839 * 840 * This doesnt really halt the output, but it will look 841 * that way to the audio driver. The current block will 842 * still be transmitted. 843 */ 844 static int 845 btsco_halt_output(void *hdl) 846 { 847 struct btsco_softc *sc = hdl; 848 849 DPRINTFN(5, "%s\n", sc->sc_name); 850 851 sc->sc_tx_size = 0; 852 sc->sc_tx_block = NULL; 853 sc->sc_tx_pending = 0; 854 sc->sc_tx_intr = NULL; 855 sc->sc_tx_intrarg = NULL; 856 857 return 0; 858 } 859 860 /* 861 * Halt Input 862 * 863 * This doesnt really halt the input, but it will look 864 * that way to the audio driver. Incoming data will be 865 * discarded. 866 */ 867 static int 868 btsco_halt_input(void *hdl) 869 { 870 struct btsco_softc *sc = hdl; 871 872 DPRINTFN(5, "%s\n", sc->sc_name); 873 874 sc->sc_rx_want = 0; 875 sc->sc_rx_block = NULL; 876 sc->sc_rx_intr = NULL; 877 sc->sc_rx_intrarg = NULL; 878 879 if (sc->sc_rx_mbuf != NULL) { 880 m_freem(sc->sc_rx_mbuf); 881 sc->sc_rx_mbuf = NULL; 882 } 883 884 return 0; 885 } 886 887 static int 888 btsco_getdev(void *hdl, struct audio_device *ret) 889 { 890 891 *ret = btsco_device; 892 return 0; 893 } 894 895 static int 896 btsco_setfd(void *hdl, int fd) 897 { 898 DPRINTF("set %s duplex\n", fd ? "full" : "half"); 899 900 return 0; 901 } 902 903 static int 904 btsco_set_port(void *hdl, mixer_ctrl_t *mc) 905 { 906 struct btsco_softc *sc = hdl; 907 int err = 0; 908 909 DPRINTF("%s dev %d type %d\n", sc->sc_name, mc->dev, mc->type); 910 911 switch (mc->dev) { 912 case BTSCO_VGS: 913 if (mc->type != AUDIO_MIXER_VALUE || 914 mc->un.value.num_channels != 1) { 915 err = EINVAL; 916 break; 917 } 918 919 sc->sc_vgs = mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 920 break; 921 922 case BTSCO_VGM: 923 if (mc->type != AUDIO_MIXER_VALUE || 924 mc->un.value.num_channels != 1) { 925 err = EINVAL; 926 break; 927 } 928 929 sc->sc_vgm = mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]; 930 break; 931 932 default: 933 err = EINVAL; 934 break; 935 } 936 937 return err; 938 } 939 940 static int 941 btsco_get_port(void *hdl, mixer_ctrl_t *mc) 942 { 943 struct btsco_softc *sc = hdl; 944 int err = 0; 945 946 DPRINTF("%s dev %d\n", sc->sc_name, mc->dev); 947 948 switch (mc->dev) { 949 case BTSCO_VGS: 950 mc->type = AUDIO_MIXER_VALUE; 951 mc->un.value.num_channels = 1; 952 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_vgs; 953 break; 954 955 case BTSCO_VGM: 956 mc->type = AUDIO_MIXER_VALUE; 957 mc->un.value.num_channels = 1; 958 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_vgm; 959 break; 960 961 default: 962 err = EINVAL; 963 break; 964 } 965 966 return err; 967 } 968 969 static int 970 btsco_query_devinfo(void *hdl, mixer_devinfo_t *di) 971 { 972 /* struct btsco_softc *sc = hdl; */ 973 int err = 0; 974 975 switch(di->index) { 976 case BTSCO_VGS: 977 di->mixer_class = BTSCO_INPUT_CLASS; 978 di->next = di->prev = AUDIO_MIXER_LAST; 979 strcpy(di->label.name, AudioNspeaker); 980 di->type = AUDIO_MIXER_VALUE; 981 strcpy(di->un.v.units.name, AudioNvolume); 982 di->un.v.num_channels = 1; 983 di->un.v.delta = BTSCO_DELTA; 984 break; 985 986 case BTSCO_VGM: 987 di->mixer_class = BTSCO_INPUT_CLASS; 988 di->next = di->prev = AUDIO_MIXER_LAST; 989 strcpy(di->label.name, AudioNmicrophone); 990 di->type = AUDIO_MIXER_VALUE; 991 strcpy(di->un.v.units.name, AudioNvolume); 992 di->un.v.num_channels = 1; 993 di->un.v.delta = BTSCO_DELTA; 994 break; 995 996 case BTSCO_INPUT_CLASS: 997 di->mixer_class = BTSCO_INPUT_CLASS; 998 di->next = di->prev = AUDIO_MIXER_LAST; 999 strcpy(di->label.name, AudioCinputs); 1000 di->type = AUDIO_MIXER_CLASS; 1001 break; 1002 1003 default: 1004 err = ENXIO; 1005 break; 1006 } 1007 1008 return err; 1009 } 1010 1011 /* 1012 * Allocate Ring Buffers. 1013 */ 1014 static void * 1015 btsco_allocm(void *hdl, int direction, size_t size, 1016 struct malloc_type *type, int flags) 1017 { 1018 struct btsco_softc *sc = hdl; 1019 void *addr; 1020 1021 DPRINTF("%s: size %d direction %d\n", sc->sc_name, size, direction); 1022 1023 addr = malloc(size, type, flags); 1024 1025 if (direction == AUMODE_PLAY) { 1026 sc->sc_tx_buf = addr; 1027 sc->sc_tx_refcnt = 0; 1028 } 1029 1030 return addr; 1031 } 1032 1033 /* 1034 * Free Ring Buffers. 1035 * 1036 * Because we used external memory for the tx mbufs, we dont 1037 * want to free the memory until all the mbufs are done with 1038 * 1039 * Just to be sure, dont free if something is still pending. 1040 * This would be a memory leak but at least there is a warning.. 1041 */ 1042 static void 1043 btsco_freem(void *hdl, void *addr, struct malloc_type *type) 1044 { 1045 struct btsco_softc *sc = hdl; 1046 int count = hz / 2; 1047 1048 if (addr == sc->sc_tx_buf) { 1049 DPRINTF("%s: tx_refcnt=%d\n", sc->sc_name, sc->sc_tx_refcnt); 1050 1051 sc->sc_tx_buf = NULL; 1052 1053 while (sc->sc_tx_refcnt> 0 && count-- > 0) 1054 tsleep(sc, PWAIT, "drain", 1); 1055 1056 if (sc->sc_tx_refcnt > 0) { 1057 aprint_error("%s: ring buffer unreleased!\n", sc->sc_name); 1058 return; 1059 } 1060 } 1061 1062 free(addr, type); 1063 } 1064 1065 static int 1066 btsco_get_props(void *hdl) 1067 { 1068 1069 return AUDIO_PROP_FULLDUPLEX; 1070 } 1071 1072 /* 1073 * Handle private ioctl. We pass information out about how to talk 1074 * to the device and mixer. 1075 */ 1076 static int 1077 btsco_dev_ioctl(void *hdl, u_long cmd, void *addr, int flag, 1078 struct lwp *l) 1079 { 1080 struct btsco_softc *sc = hdl; 1081 struct btsco_info *bi = (struct btsco_info *)addr; 1082 int err = 0; 1083 1084 DPRINTF("%s cmd 0x%lx flag %d\n", sc->sc_name, cmd, flag); 1085 1086 switch (cmd) { 1087 case BTSCO_GETINFO: 1088 memset(bi, 0, sizeof(*bi)); 1089 bdaddr_copy(&bi->laddr, &sc->sc_laddr); 1090 bdaddr_copy(&bi->raddr, &sc->sc_raddr); 1091 bi->channel = sc->sc_channel; 1092 bi->vgs = BTSCO_VGS; 1093 bi->vgm = BTSCO_VGM; 1094 break; 1095 1096 default: 1097 err = EPASSTHROUGH; 1098 break; 1099 } 1100 1101 return err; 1102 } 1103 1104 1105 /***************************************************************************** 1106 * 1107 * misc btsco functions 1108 * 1109 */ 1110 1111 /* 1112 * Our transmit interrupt. This is triggered when a new block is to be 1113 * sent. We send mtu sized chunks of the block as mbufs with external 1114 * storage to sco_send() 1115 */ 1116 static void 1117 btsco_intr(void *arg) 1118 { 1119 struct btsco_softc *sc = arg; 1120 struct mbuf *m; 1121 uint8_t *block; 1122 int mlen, size; 1123 1124 DPRINTFN(10, "%s block %p size %d\n", 1125 sc->sc_name, sc->sc_tx_block, sc->sc_tx_size); 1126 1127 if (sc->sc_sco == NULL) 1128 return; /* connection is lost */ 1129 1130 block = sc->sc_tx_block; 1131 size = sc->sc_tx_size; 1132 sc->sc_tx_block = NULL; 1133 sc->sc_tx_size = 0; 1134 1135 mutex_enter(bt_lock); 1136 while (size > 0) { 1137 MGETHDR(m, M_DONTWAIT, MT_DATA); 1138 if (m == NULL) 1139 break; 1140 1141 mlen = MIN(sc->sc_mtu, size); 1142 1143 /* I think M_DEVBUF is true but not relevant */ 1144 MEXTADD(m, block, mlen, M_DEVBUF, btsco_extfree, sc); 1145 if ((m->m_flags & M_EXT) == 0) { 1146 m_free(m); 1147 break; 1148 } 1149 sc->sc_tx_refcnt++; 1150 1151 m->m_pkthdr.len = m->m_len = mlen; 1152 sc->sc_tx_pending++; 1153 1154 if (sco_send(sc->sc_sco, m) > 0) { 1155 sc->sc_tx_pending--; 1156 break; 1157 } 1158 1159 block += mlen; 1160 size -= mlen; 1161 } 1162 mutex_exit(bt_lock); 1163 } 1164 1165 /* 1166 * Release the mbuf, we keep a reference count on the tx buffer so 1167 * that we dont release it before its free. 1168 */ 1169 static void 1170 btsco_extfree(struct mbuf *m, void *addr, size_t size, 1171 void *arg) 1172 { 1173 struct btsco_softc *sc = arg; 1174 1175 if (m != NULL) 1176 pool_cache_put(mb_cache, m); 1177 1178 sc->sc_tx_refcnt--; 1179 } 1180