btsco.c revision 1.38 1 /* $NetBSD: btsco.c,v 1.38 2019/03/16 12:09:57 isaki 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.38 2019/03/16 12:09:57 isaki 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/kmem.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 kmutex_t sc_lock; /* for audio */
101
102 /* Bluetooth */
103 bdaddr_t sc_laddr; /* local address */
104 bdaddr_t sc_raddr; /* remote address */
105 uint16_t sc_state; /* link state */
106 struct sco_pcb *sc_sco; /* SCO handle */
107 struct sco_pcb *sc_sco_l; /* SCO listen handle */
108 uint16_t sc_mtu; /* SCO mtu */
109 uint8_t sc_channel; /* RFCOMM channel */
110 int sc_err; /* stored error */
111
112 /* Receive */
113 int sc_rx_want; /* bytes wanted */
114 uint8_t *sc_rx_block; /* receive block */
115 void (*sc_rx_intr)(void *); /* callback */
116 void *sc_rx_intrarg; /* callback arg */
117 struct mbuf *sc_rx_mbuf; /* leftover mbuf */
118
119 /* Transmit */
120 int sc_tx_size; /* bytes to send */
121 int sc_tx_pending; /* packets pending */
122 uint8_t *sc_tx_block; /* transmit block */
123 void (*sc_tx_intr)(void *); /* callback */
124 void *sc_tx_intrarg; /* callback arg */
125 void *sc_tx_buf; /* transmit buffer */
126 int sc_tx_refcnt; /* buffer refcnt */
127
128 /* mixer data */
129 int sc_vgs; /* speaker volume */
130 int sc_vgm; /* mic volume */
131 };
132
133 /* sc_state */
134 #define BTSCO_CLOSED 0
135 #define BTSCO_WAIT_CONNECT 1
136 #define BTSCO_OPEN 2
137
138 /* sc_flags */
139 #define BTSCO_LISTEN (1 << 1)
140
141 /* autoconf(9) glue */
142 static int btsco_match(device_t, cfdata_t, void *);
143 static void btsco_attach(device_t, device_t, void *);
144 static int btsco_detach(device_t, int);
145
146 CFATTACH_DECL_NEW(btsco, sizeof(struct btsco_softc),
147 btsco_match, btsco_attach, btsco_detach, NULL);
148
149 /* audio(9) glue */
150 static int btsco_open(void *, int);
151 static void btsco_close(void *);
152 static int btsco_query_encoding(void *, struct audio_encoding *);
153 static int btsco_set_params(void *, int, int, audio_params_t *, audio_params_t *,
154 stream_filter_list_t *, stream_filter_list_t *);
155 static int btsco_round_blocksize(void *, int, int, const audio_params_t *);
156 static int btsco_start_output(void *, void *, int, void (*)(void *), void *);
157 static int btsco_start_input(void *, void *, int, void (*)(void *), void *);
158 static int btsco_halt_output(void *);
159 static int btsco_halt_input(void *);
160 static int btsco_getdev(void *, struct audio_device *);
161 static int btsco_setfd(void *, int);
162 static int btsco_set_port(void *, mixer_ctrl_t *);
163 static int btsco_get_port(void *, mixer_ctrl_t *);
164 static int btsco_query_devinfo(void *, mixer_devinfo_t *);
165 static void *btsco_allocm(void *, int, size_t);
166 static void btsco_freem(void *, void *, size_t);
167 static int btsco_get_props(void *);
168 static int btsco_dev_ioctl(void *, u_long, void *, int, struct lwp *);
169 static void btsco_get_locks(void *, kmutex_t **, kmutex_t **);
170
171 static const struct audio_hw_if btsco_if = {
172 .open = btsco_open,
173 .close = btsco_close,
174 .query_encoding = btsco_query_encoding,
175 .set_params = btsco_set_params,
176 .round_blocksize = btsco_round_blocksize,
177 .start_output = btsco_start_output,
178 .start_input = btsco_start_input,
179 .halt_output = btsco_halt_output,
180 .halt_input = btsco_halt_input,
181 .getdev = btsco_getdev,
182 .setfd = btsco_setfd,
183 .set_port = btsco_set_port,
184 .get_port = btsco_get_port,
185 .query_devinfo = btsco_query_devinfo,
186 .allocm = btsco_allocm,
187 .freem = btsco_freem,
188 .get_props = btsco_get_props,
189 .dev_ioctl = btsco_dev_ioctl,
190 .get_locks = btsco_get_locks,
191 };
192
193 static const struct audio_device btsco_device = {
194 "Bluetooth Audio",
195 "",
196 "btsco"
197 };
198
199 /* Voice_Setting == 0x0060: 8000Hz, mono, 16-bit, slinear_le */
200 static const struct audio_format btsco_format = {
201 NULL, /* driver_data */
202 (AUMODE_PLAY | AUMODE_RECORD), /* mode */
203 AUDIO_ENCODING_SLINEAR_LE, /* encoding */
204 16, /* validbits */
205 16, /* precision */
206 1, /* channels */
207 AUFMT_MONAURAL, /* channel_mask */
208 1, /* frequency_type */
209 { 8000 } /* frequency */
210 };
211
212 /* bluetooth(9) glue for SCO */
213 static void btsco_sco_connecting(void *);
214 static void btsco_sco_connected(void *);
215 static void btsco_sco_disconnected(void *, int);
216 static void *btsco_sco_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
217 static void btsco_sco_complete(void *, int);
218 static void btsco_sco_linkmode(void *, int);
219 static void btsco_sco_input(void *, struct mbuf *);
220
221 static const struct btproto btsco_sco_proto = {
222 btsco_sco_connecting,
223 btsco_sco_connected,
224 btsco_sco_disconnected,
225 btsco_sco_newconn,
226 btsco_sco_complete,
227 btsco_sco_linkmode,
228 btsco_sco_input,
229 };
230
231
232 /*****************************************************************************
233 *
234 * btsco definitions
235 */
236
237 /*
238 * btsco mixer class
239 */
240 #define BTSCO_VGS 0
241 #define BTSCO_VGM 1
242 #define BTSCO_INPUT_CLASS 2
243 #define BTSCO_OUTPUT_CLASS 3
244
245 /* connect timeout */
246 #define BTSCO_TIMEOUT (30 * hz)
247
248 /* misc btsco functions */
249 static void btsco_extfree(struct mbuf *, void *, size_t, void *);
250 static void btsco_intr(void *);
251
252
253 /*****************************************************************************
254 *
255 * btsco autoconf(9) routines
256 */
257
258 static int
259 btsco_match(device_t self, cfdata_t cfdata, void *aux)
260 {
261 prop_dictionary_t dict = aux;
262 prop_object_t obj;
263
264 obj = prop_dictionary_get(dict, BTDEVservice);
265 if (prop_string_equals_cstring(obj, "HSET"))
266 return 1;
267
268 if (prop_string_equals_cstring(obj, "HF"))
269 return 1;
270
271 return 0;
272 }
273
274 static void
275 btsco_attach(device_t parent, device_t self, void *aux)
276 {
277 struct btsco_softc *sc = device_private(self);
278 prop_dictionary_t dict = aux;
279 prop_object_t obj;
280
281 /*
282 * Init softc
283 */
284 sc->sc_vgs = 200;
285 sc->sc_vgm = 200;
286 sc->sc_state = BTSCO_CLOSED;
287 sc->sc_name = device_xname(self);
288 cv_init(&sc->sc_connect, "connect");
289 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
290
291 /*
292 * copy in our configuration info
293 */
294 obj = prop_dictionary_get(dict, BTDEVladdr);
295 bdaddr_copy(&sc->sc_laddr, prop_data_data_nocopy(obj));
296
297 obj = prop_dictionary_get(dict, BTDEVraddr);
298 bdaddr_copy(&sc->sc_raddr, prop_data_data_nocopy(obj));
299
300 obj = prop_dictionary_get(dict, BTDEVservice);
301 if (prop_string_equals_cstring(obj, "HF")) {
302 sc->sc_flags |= BTSCO_LISTEN;
303 aprint_verbose(" listen mode");
304 }
305
306 obj = prop_dictionary_get(dict, BTSCOchannel);
307 if (prop_object_type(obj) != PROP_TYPE_NUMBER
308 || prop_number_integer_value(obj) < RFCOMM_CHANNEL_MIN
309 || prop_number_integer_value(obj) > RFCOMM_CHANNEL_MAX) {
310 aprint_error(" invalid %s", BTSCOchannel);
311 return;
312 }
313 sc->sc_channel = prop_number_integer_value(obj);
314
315 aprint_verbose(" channel %d", sc->sc_channel);
316 aprint_normal("\n");
317
318 DPRINTF("sc=%p\n", sc);
319
320 /*
321 * set up transmit interrupt
322 */
323 sc->sc_intr = softint_establish(SOFTINT_NET, btsco_intr, sc);
324 if (sc->sc_intr == NULL) {
325 aprint_error_dev(self, "softint_establish failed\n");
326 return;
327 }
328
329 /*
330 * attach audio device
331 */
332 sc->sc_audio = audio_attach_mi(&btsco_if, sc, self);
333 if (sc->sc_audio == NULL) {
334 aprint_error_dev(self, "audio_attach_mi failed\n");
335 return;
336 }
337
338 pmf_device_register(self, NULL, NULL);
339 }
340
341 static int
342 btsco_detach(device_t self, int flags)
343 {
344 struct btsco_softc *sc = device_private(self);
345
346 DPRINTF("sc=%p\n", sc);
347
348 pmf_device_deregister(self);
349
350 mutex_enter(bt_lock);
351 if (sc->sc_sco != NULL) {
352 DPRINTF("sc_sco=%p\n", sc->sc_sco);
353 sco_disconnect_pcb(sc->sc_sco, 0);
354 sco_detach_pcb(&sc->sc_sco);
355 sc->sc_sco = NULL;
356 }
357
358 if (sc->sc_sco_l != NULL) {
359 DPRINTF("sc_sco_l=%p\n", sc->sc_sco_l);
360 sco_detach_pcb(&sc->sc_sco_l);
361 sc->sc_sco_l = NULL;
362 }
363 mutex_exit(bt_lock);
364
365 if (sc->sc_audio != NULL) {
366 DPRINTF("sc_audio=%p\n", sc->sc_audio);
367 config_detach(sc->sc_audio, flags);
368 sc->sc_audio = NULL;
369 }
370
371 if (sc->sc_intr != NULL) {
372 softint_disestablish(sc->sc_intr);
373 sc->sc_intr = NULL;
374 }
375
376 mutex_enter(bt_lock);
377 if (sc->sc_rx_mbuf != NULL) {
378 m_freem(sc->sc_rx_mbuf);
379 sc->sc_rx_mbuf = NULL;
380 }
381 mutex_exit(bt_lock);
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 mutex_destroy(&sc->sc_lock);
392
393 return 0;
394 }
395
396 /*****************************************************************************
397 *
398 * bluetooth(9) methods for SCO
399 *
400 * All these are called from Bluetooth Protocol code, in a soft
401 * interrupt context at IPL_SOFTNET.
402 */
403
404 static void
405 btsco_sco_connecting(void *arg)
406 {
407 /* struct btsco_softc *sc = arg; */
408
409 /* dont care */
410 }
411
412 static void
413 btsco_sco_connected(void *arg)
414 {
415 struct btsco_softc *sc = arg;
416
417 DPRINTF("%s\n", sc->sc_name);
418
419 KASSERT(sc->sc_sco != NULL);
420 KASSERT(sc->sc_state == BTSCO_WAIT_CONNECT);
421
422 /*
423 * If we are listening, no more need
424 */
425 if (sc->sc_sco_l != NULL)
426 sco_detach_pcb(&sc->sc_sco_l);
427
428 sc->sc_state = BTSCO_OPEN;
429 cv_broadcast(&sc->sc_connect);
430 }
431
432 static void
433 btsco_sco_disconnected(void *arg, int err)
434 {
435 struct btsco_softc *sc = arg;
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_pcb(&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 mutex_enter(bt_lock);
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 mutex_exit(bt_lock);
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_pcb(&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
499 DPRINTFN(10, "%s count %d\n", sc->sc_name, count);
500
501 if (sc->sc_tx_pending > 0) {
502 sc->sc_tx_pending -= count;
503 if (sc->sc_tx_pending == 0)
504 (*sc->sc_tx_intr)(sc->sc_tx_intrarg);
505 }
506 }
507
508 static void
509 btsco_sco_linkmode(void *arg, int new)
510 {
511 /* struct btsco_softc *sc = arg; */
512
513 /* dont care */
514 }
515
516 static void
517 btsco_sco_input(void *arg, struct mbuf *m)
518 {
519 struct btsco_softc *sc = arg;
520 int len;
521
522 DPRINTFN(10, "%s len=%d\n", sc->sc_name, m->m_pkthdr.len);
523
524 if (sc->sc_rx_want == 0) {
525 m_freem(m);
526 } else {
527 KASSERT(sc->sc_rx_intr != NULL);
528 KASSERT(sc->sc_rx_block != NULL);
529
530 len = MIN(sc->sc_rx_want, m->m_pkthdr.len);
531 m_copydata(m, 0, len, sc->sc_rx_block);
532
533 sc->sc_rx_want -= len;
534 sc->sc_rx_block += len;
535
536 if (len > m->m_pkthdr.len) {
537 if (sc->sc_rx_mbuf != NULL)
538 m_freem(sc->sc_rx_mbuf);
539
540 m_adj(m, len);
541 sc->sc_rx_mbuf = m;
542 } else {
543 m_freem(m);
544 }
545
546 if (sc->sc_rx_want == 0)
547 (*sc->sc_rx_intr)(sc->sc_rx_intrarg);
548 }
549 }
550
551
552 /*****************************************************************************
553 *
554 * audio(9) methods
555 *
556 */
557
558 static int
559 btsco_open(void *hdl, int flags)
560 {
561 struct sockaddr_bt sa;
562 struct btsco_softc *sc = hdl;
563 struct sockopt sopt;
564 int err, timo;
565
566 DPRINTF("%s flags 0x%x\n", sc->sc_name, flags);
567 /* flags FREAD & FWRITE? */
568
569 if (sc->sc_sco != NULL || sc->sc_sco_l != NULL)
570 return EIO;
571
572 KASSERT(mutex_owned(bt_lock));
573
574 memset(&sa, 0, sizeof(sa));
575 sa.bt_len = sizeof(sa);
576 sa.bt_family = AF_BLUETOOTH;
577 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
578
579 if (sc->sc_flags & BTSCO_LISTEN) {
580 err = sco_attach_pcb(&sc->sc_sco_l, &btsco_sco_proto, sc);
581 if (err)
582 goto done;
583
584 err = sco_bind_pcb(sc->sc_sco_l, &sa);
585 if (err) {
586 sco_detach_pcb(&sc->sc_sco_l);
587 goto done;
588 }
589
590 err = sco_listen_pcb(sc->sc_sco_l);
591 if (err) {
592 sco_detach_pcb(&sc->sc_sco_l);
593 goto done;
594 }
595
596 timo = 0; /* no timeout */
597 } else {
598 err = sco_attach_pcb(&sc->sc_sco, &btsco_sco_proto, sc);
599 if (err)
600 goto done;
601
602 err = sco_bind_pcb(sc->sc_sco, &sa);
603 if (err) {
604 sco_detach_pcb(&sc->sc_sco);
605 goto done;
606 }
607
608 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr);
609 err = sco_connect_pcb(sc->sc_sco, &sa);
610 if (err) {
611 sco_detach_pcb(&sc->sc_sco);
612 goto done;
613 }
614
615 timo = BTSCO_TIMEOUT;
616 }
617
618 sc->sc_state = BTSCO_WAIT_CONNECT;
619 while (err == 0 && sc->sc_state == BTSCO_WAIT_CONNECT)
620 err = cv_timedwait_sig(&sc->sc_connect, bt_lock, timo);
621
622 switch (sc->sc_state) {
623 case BTSCO_CLOSED: /* disconnected */
624 err = sc->sc_err;
625
626 /* FALLTHROUGH */
627 case BTSCO_WAIT_CONNECT: /* error */
628 if (sc->sc_sco != NULL)
629 sco_detach_pcb(&sc->sc_sco);
630
631 if (sc->sc_sco_l != NULL)
632 sco_detach_pcb(&sc->sc_sco_l);
633
634 break;
635
636 case BTSCO_OPEN: /* hurrah */
637 sockopt_init(&sopt, BTPROTO_SCO, SO_SCO_MTU, 0);
638 (void)sco_getopt(sc->sc_sco, &sopt);
639 (void)sockopt_get(&sopt, &sc->sc_mtu, sizeof(sc->sc_mtu));
640 sockopt_destroy(&sopt);
641 break;
642
643 default:
644 UNKNOWN(sc->sc_state);
645 break;
646 }
647
648 done:
649 DPRINTF("done err=%d, sc_state=%d, sc_mtu=%d\n",
650 err, sc->sc_state, sc->sc_mtu);
651 return err;
652 }
653
654 static void
655 btsco_close(void *hdl)
656 {
657 struct btsco_softc *sc = hdl;
658
659 DPRINTF("%s\n", sc->sc_name);
660
661 KASSERT(mutex_owned(bt_lock));
662
663 if (sc->sc_sco != NULL) {
664 sco_disconnect_pcb(sc->sc_sco, 0);
665 sco_detach_pcb(&sc->sc_sco);
666 }
667
668 if (sc->sc_sco_l != NULL) {
669 sco_detach_pcb(&sc->sc_sco_l);
670 }
671
672 if (sc->sc_rx_mbuf != NULL) {
673 m_freem(sc->sc_rx_mbuf);
674 sc->sc_rx_mbuf = NULL;
675 }
676
677 sc->sc_rx_want = 0;
678 sc->sc_rx_block = NULL;
679 sc->sc_rx_intr = NULL;
680 sc->sc_rx_intrarg = NULL;
681
682 sc->sc_tx_size = 0;
683 sc->sc_tx_block = NULL;
684 sc->sc_tx_pending = 0;
685 sc->sc_tx_intr = NULL;
686 sc->sc_tx_intrarg = NULL;
687 }
688
689 static int
690 btsco_query_encoding(void *hdl, struct audio_encoding *ae)
691 {
692 /* struct btsco_softc *sc = hdl; */
693 int err = 0;
694
695 switch (ae->index) {
696 case 0:
697 strcpy(ae->name, AudioEslinear_le);
698 ae->encoding = AUDIO_ENCODING_SLINEAR_LE;
699 ae->precision = 16;
700 ae->flags = 0;
701 break;
702
703 default:
704 err = EINVAL;
705 }
706
707 return err;
708 }
709
710 static int
711 btsco_set_params(void *hdl, int setmode, int usemode,
712 audio_params_t *play, audio_params_t *rec,
713 stream_filter_list_t *pfil, stream_filter_list_t *rfil)
714 {
715 /* struct btsco_softc *sc = hdl; */
716 const struct audio_format *f;
717 int rv;
718
719 DPRINTF("setmode 0x%x usemode 0x%x\n", setmode, usemode);
720 DPRINTF("rate %d, precision %d, channels %d encoding %d\n",
721 play->sample_rate, play->precision, play->channels, play->encoding);
722
723 /*
724 * If we had a list of formats, we could check the HCI_Voice_Setting
725 * and select the appropriate one to use. Currently only one is
726 * supported: 0x0060 == 8000Hz, mono, 16-bit, slinear_le
727 */
728 f = &btsco_format;
729
730 if (setmode & AUMODE_PLAY) {
731 rv = auconv_set_converter(f, 1, AUMODE_PLAY, play, TRUE, pfil);
732 if (rv < 0)
733 return EINVAL;
734 }
735
736 if (setmode & AUMODE_RECORD) {
737 rv = auconv_set_converter(f, 1, AUMODE_RECORD, rec, TRUE, rfil);
738 if (rv < 0)
739 return EINVAL;
740 }
741
742 return 0;
743 }
744
745 /*
746 * If we have an MTU value to use, round the blocksize to that.
747 */
748 static int
749 btsco_round_blocksize(void *hdl, int bs, int mode,
750 const audio_params_t *param)
751 {
752 struct btsco_softc *sc = hdl;
753
754 if (sc->sc_mtu > 0) {
755 bs = (bs / sc->sc_mtu) * sc->sc_mtu;
756 if (bs == 0)
757 bs = sc->sc_mtu;
758 }
759
760 DPRINTF("%s mode=0x%x, bs=%d, sc_mtu=%d\n",
761 sc->sc_name, mode, bs, sc->sc_mtu);
762
763 return bs;
764 }
765
766 /*
767 * Start Output
768 *
769 * We dont want to be calling the network stack with bt_lock held
770 * so make a note of what is to be sent, and schedule an interrupt to
771 * bundle it up and queue it.
772 */
773 static int
774 btsco_start_output(void *hdl, void *block, int blksize,
775 void (*intr)(void *), void *intrarg)
776 {
777 struct btsco_softc *sc = hdl;
778
779 DPRINTFN(5, "%s blksize %d\n", sc->sc_name, blksize);
780
781 if (sc->sc_sco == NULL)
782 return ENOTCONN; /* connection lost */
783
784 sc->sc_tx_block = block;
785 sc->sc_tx_pending = 0;
786 sc->sc_tx_size = blksize;
787 sc->sc_tx_intr = intr;
788 sc->sc_tx_intrarg = intrarg;
789
790 kpreempt_disable();
791 softint_schedule(sc->sc_intr);
792 kpreempt_enable();
793 return 0;
794 }
795
796 /*
797 * Start Input
798 *
799 * When the SCO link is up, we are getting data in any case, so all we do
800 * is note what we want and where to put it and let the sco_input routine
801 * fill in the data.
802 *
803 * If there was any leftover data that didnt fit in the last block, retry
804 * it now.
805 */
806 static int
807 btsco_start_input(void *hdl, void *block, int blksize,
808 void (*intr)(void *), void *intrarg)
809 {
810 struct btsco_softc *sc = hdl;
811 struct mbuf *m;
812
813 DPRINTFN(5, "%s blksize %d\n", sc->sc_name, blksize);
814
815 if (sc->sc_sco == NULL)
816 return ENOTCONN;
817
818 sc->sc_rx_want = blksize;
819 sc->sc_rx_block = block;
820 sc->sc_rx_intr = intr;
821 sc->sc_rx_intrarg = intrarg;
822
823 if (sc->sc_rx_mbuf != NULL) {
824 m = sc->sc_rx_mbuf;
825 sc->sc_rx_mbuf = NULL;
826 btsco_sco_input(sc, m);
827 }
828
829 return 0;
830 }
831
832 /*
833 * Halt Output
834 *
835 * This doesnt really halt the output, but it will look
836 * that way to the audio driver. The current block will
837 * still be transmitted.
838 */
839 static int
840 btsco_halt_output(void *hdl)
841 {
842 struct btsco_softc *sc = hdl;
843
844 DPRINTFN(5, "%s\n", sc->sc_name);
845
846 sc->sc_tx_size = 0;
847 sc->sc_tx_block = NULL;
848 sc->sc_tx_pending = 0;
849 sc->sc_tx_intr = NULL;
850 sc->sc_tx_intrarg = NULL;
851
852 return 0;
853 }
854
855 /*
856 * Halt Input
857 *
858 * This doesnt really halt the input, but it will look
859 * that way to the audio driver. Incoming data will be
860 * discarded.
861 */
862 static int
863 btsco_halt_input(void *hdl)
864 {
865 struct btsco_softc *sc = hdl;
866
867 DPRINTFN(5, "%s\n", sc->sc_name);
868
869 sc->sc_rx_want = 0;
870 sc->sc_rx_block = NULL;
871 sc->sc_rx_intr = NULL;
872 sc->sc_rx_intrarg = NULL;
873
874 if (sc->sc_rx_mbuf != NULL) {
875 m_freem(sc->sc_rx_mbuf);
876 sc->sc_rx_mbuf = NULL;
877 }
878
879 return 0;
880 }
881
882 static int
883 btsco_getdev(void *hdl, struct audio_device *ret)
884 {
885
886 *ret = btsco_device;
887 return 0;
888 }
889
890 static int
891 btsco_setfd(void *hdl, int fd)
892 {
893 DPRINTF("set %s duplex\n", fd ? "full" : "half");
894
895 return 0;
896 }
897
898 static int
899 btsco_set_port(void *hdl, mixer_ctrl_t *mc)
900 {
901 struct btsco_softc *sc = hdl;
902 int err = 0;
903
904 DPRINTF("%s dev %d type %d\n", sc->sc_name, mc->dev, mc->type);
905
906 switch (mc->dev) {
907 case BTSCO_VGS:
908 if (mc->type != AUDIO_MIXER_VALUE ||
909 mc->un.value.num_channels != 1) {
910 err = EINVAL;
911 break;
912 }
913
914 sc->sc_vgs = mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
915 break;
916
917 case BTSCO_VGM:
918 if (mc->type != AUDIO_MIXER_VALUE ||
919 mc->un.value.num_channels != 1) {
920 err = EINVAL;
921 break;
922 }
923
924 sc->sc_vgm = mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
925 break;
926
927 default:
928 err = EINVAL;
929 break;
930 }
931
932 return err;
933 }
934
935 static int
936 btsco_get_port(void *hdl, mixer_ctrl_t *mc)
937 {
938 struct btsco_softc *sc = hdl;
939 int err = 0;
940
941 DPRINTF("%s dev %d\n", sc->sc_name, mc->dev);
942
943 switch (mc->dev) {
944 case BTSCO_VGS:
945 mc->type = AUDIO_MIXER_VALUE;
946 mc->un.value.num_channels = 1;
947 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_vgs;
948 break;
949
950 case BTSCO_VGM:
951 mc->type = AUDIO_MIXER_VALUE;
952 mc->un.value.num_channels = 1;
953 mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->sc_vgm;
954 break;
955
956 default:
957 err = EINVAL;
958 break;
959 }
960
961 return err;
962 }
963
964 static int
965 btsco_query_devinfo(void *hdl, mixer_devinfo_t *di)
966 {
967 /* struct btsco_softc *sc = hdl; */
968 int err = 0;
969
970 switch(di->index) {
971 case BTSCO_VGS:
972 di->mixer_class = BTSCO_INPUT_CLASS;
973 di->next = di->prev = AUDIO_MIXER_LAST;
974 strcpy(di->label.name, AudioNspeaker);
975 di->type = AUDIO_MIXER_VALUE;
976 strcpy(di->un.v.units.name, AudioNvolume);
977 di->un.v.num_channels = 1;
978 di->un.v.delta = BTSCO_DELTA;
979 break;
980
981 case BTSCO_VGM:
982 di->mixer_class = BTSCO_INPUT_CLASS;
983 di->next = di->prev = AUDIO_MIXER_LAST;
984 strcpy(di->label.name, AudioNmicrophone);
985 di->type = AUDIO_MIXER_VALUE;
986 strcpy(di->un.v.units.name, AudioNvolume);
987 di->un.v.num_channels = 1;
988 di->un.v.delta = BTSCO_DELTA;
989 break;
990
991 case BTSCO_INPUT_CLASS:
992 di->mixer_class = BTSCO_INPUT_CLASS;
993 di->next = di->prev = AUDIO_MIXER_LAST;
994 strcpy(di->label.name, AudioCinputs);
995 di->type = AUDIO_MIXER_CLASS;
996 break;
997
998 default:
999 err = ENXIO;
1000 break;
1001 }
1002
1003 return err;
1004 }
1005
1006 /*
1007 * Allocate Ring Buffers.
1008 */
1009 static void *
1010 btsco_allocm(void *hdl, int direction, size_t size)
1011 {
1012 struct btsco_softc *sc = hdl;
1013 void *addr;
1014
1015 DPRINTF("%s: size %d direction %d\n", sc->sc_name, size, direction);
1016
1017 addr = kmem_alloc(size, KM_SLEEP);
1018
1019 if (direction == AUMODE_PLAY) {
1020 sc->sc_tx_buf = addr;
1021 sc->sc_tx_refcnt = 0;
1022 }
1023
1024 return addr;
1025 }
1026
1027 /*
1028 * Free Ring Buffers.
1029 *
1030 * Because we used external memory for the tx mbufs, we dont
1031 * want to free the memory until all the mbufs are done with
1032 *
1033 * Just to be sure, dont free if something is still pending.
1034 * This would be a memory leak but at least there is a warning..
1035 */
1036 static void
1037 btsco_freem(void *hdl, void *addr, size_t size)
1038 {
1039 struct btsco_softc *sc = hdl;
1040 int count = hz / 2;
1041
1042 if (addr == sc->sc_tx_buf) {
1043 DPRINTF("%s: tx_refcnt=%d\n", sc->sc_name, sc->sc_tx_refcnt);
1044
1045 sc->sc_tx_buf = NULL;
1046
1047 while (sc->sc_tx_refcnt> 0 && count-- > 0)
1048 kpause("drain", false, 1, NULL);
1049
1050 if (sc->sc_tx_refcnt > 0) {
1051 aprint_error("%s: ring buffer unreleased!\n", sc->sc_name);
1052 return;
1053 }
1054 }
1055
1056 kmem_free(addr, size);
1057 }
1058
1059 static int
1060 btsco_get_props(void *hdl)
1061 {
1062
1063 return AUDIO_PROP_FULLDUPLEX;
1064 }
1065
1066 static void
1067 btsco_get_locks(void *hdl, kmutex_t **intr, kmutex_t **thread)
1068 {
1069 struct btsco_softc *sc = hdl;
1070
1071 *thread = &sc->sc_lock;
1072 *intr = bt_lock;
1073 }
1074
1075 /*
1076 * Handle private ioctl. We pass information out about how to talk
1077 * to the device and mixer.
1078 */
1079 static int
1080 btsco_dev_ioctl(void *hdl, u_long cmd, void *addr, int flag,
1081 struct lwp *l)
1082 {
1083 struct btsco_softc *sc = hdl;
1084 struct btsco_info *bi = (struct btsco_info *)addr;
1085 int err = 0;
1086
1087 DPRINTF("%s cmd 0x%lx flag %d\n", sc->sc_name, cmd, flag);
1088
1089 switch (cmd) {
1090 case BTSCO_GETINFO:
1091 memset(bi, 0, sizeof(*bi));
1092 bdaddr_copy(&bi->laddr, &sc->sc_laddr);
1093 bdaddr_copy(&bi->raddr, &sc->sc_raddr);
1094 bi->channel = sc->sc_channel;
1095 bi->vgs = BTSCO_VGS;
1096 bi->vgm = BTSCO_VGM;
1097 break;
1098
1099 default:
1100 err = EPASSTHROUGH;
1101 break;
1102 }
1103
1104 return err;
1105 }
1106
1107
1108 /*****************************************************************************
1109 *
1110 * misc btsco functions
1111 *
1112 */
1113
1114 /*
1115 * Our transmit interrupt. This is triggered when a new block is to be
1116 * sent. We send mtu sized chunks of the block as mbufs with external
1117 * storage to sco_send_pcb()
1118 */
1119 static void
1120 btsco_intr(void *arg)
1121 {
1122 struct btsco_softc *sc = arg;
1123 struct mbuf *m;
1124 uint8_t *block;
1125 int mlen, size;
1126
1127 DPRINTFN(10, "%s block %p size %d\n",
1128 sc->sc_name, sc->sc_tx_block, sc->sc_tx_size);
1129
1130 if (sc->sc_sco == NULL)
1131 return; /* connection is lost */
1132
1133 mutex_enter(bt_lock);
1134 block = sc->sc_tx_block;
1135 size = sc->sc_tx_size;
1136 sc->sc_tx_block = NULL;
1137 sc->sc_tx_size = 0;
1138
1139 while (size > 0) {
1140 MGETHDR(m, M_DONTWAIT, MT_DATA);
1141 if (m == NULL)
1142 break;
1143
1144 mlen = MIN(sc->sc_mtu, size);
1145
1146 /* I think M_DEVBUF is true but not relevant */
1147 MEXTADD(m, block, mlen, M_DEVBUF, btsco_extfree, sc);
1148 if ((m->m_flags & M_EXT) == 0) {
1149 m_free(m);
1150 break;
1151 }
1152 sc->sc_tx_refcnt++;
1153
1154 m->m_pkthdr.len = m->m_len = mlen;
1155 sc->sc_tx_pending++;
1156
1157 if (sco_send_pcb(sc->sc_sco, m) > 0) {
1158 sc->sc_tx_pending--;
1159 break;
1160 }
1161
1162 block += mlen;
1163 size -= mlen;
1164 }
1165 mutex_exit(bt_lock);
1166 }
1167
1168 /*
1169 * Release the mbuf, we keep a reference count on the tx buffer so
1170 * that we dont release it before its free.
1171 */
1172 static void
1173 btsco_extfree(struct mbuf *m, void *addr, size_t size,
1174 void *arg)
1175 {
1176 struct btsco_softc *sc = arg;
1177
1178 if (m != NULL)
1179 pool_cache_put(mb_cache, m);
1180
1181 sc->sc_tx_refcnt--;
1182 }
1183