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