btsco.c revision 1.11.8.1 1 /* $NetBSD: btsco.c,v 1.11.8.1 2007/02/27 14:16:00 ad 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.11.8.1 2007/02/27 14:16:00 ad 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/systm.h>
48
49 #include <prop/proplib.h>
50
51 #include <netbt/bluetooth.h>
52 #include <netbt/rfcomm.h>
53 #include <netbt/sco.h>
54
55 #include <dev/audio_if.h>
56 #include <dev/auconv.h>
57 #include <dev/mulaw.h>
58
59 #include <dev/bluetooth/btdev.h>
60 #include <dev/bluetooth/btsco.h>
61
62 #undef DPRINTF
63 #undef DPRINTFN
64
65 #ifdef BTSCO_DEBUG
66 int btsco_debug = BTSCO_DEBUG;
67 #define DPRINTF(fmt, args...) do { \
68 if (btsco_debug) \
69 printf("%s: "fmt, __func__ , ##args); \
70 } while (/* CONSTCOND */0)
71
72 #define DPRINTFN(n, fmt, args...) do { \
73 if (btsco_debug > (n)) \
74 printf("%s: "fmt, __func__ , ##args); \
75 } while (/* CONSTCOND */0)
76 #else
77 #define DPRINTF(...)
78 #define DPRINTFN(...)
79 #endif
80
81 /*****************************************************************************
82 *
83 * Bluetooth SCO Audio device
84 */
85
86 /* btsco softc */
87 struct btsco_softc {
88 struct btdev sc_btdev;
89 uint16_t sc_flags;
90
91 struct device *sc_audio; /* MI audio device */
92 void *sc_intr; /* interrupt cookie */
93 kmutex_t sc_intr_lock; /* audio lock */
94 kmutex_t sc_lock; /* audio lock */
95
96 /* Bluetooth */
97 bdaddr_t sc_laddr; /* local address */
98 bdaddr_t sc_raddr; /* remote address */
99 uint16_t sc_state; /* link state */
100 struct sco_pcb *sc_sco; /* SCO handle */
101 struct sco_pcb *sc_sco_l; /* SCO listen handle */
102 uint16_t sc_mtu; /* SCO mtu */
103 uint8_t sc_channel; /* RFCOMM channel */
104 int sc_err; /* stored error */
105
106 /* Receive */
107 int sc_rx_want; /* bytes wanted */
108 uint8_t *sc_rx_block; /* receive block */
109 void (*sc_rx_intr)(void *); /* callback */
110 void *sc_rx_intrarg; /* callback arg */
111 struct mbuf *sc_rx_mbuf; /* leftover mbuf */
112
113 /* Transmit */
114 int sc_tx_size; /* bytes to send */
115 int sc_tx_pending; /* packets pending */
116 uint8_t *sc_tx_block; /* transmit block */
117 void (*sc_tx_intr)(void *); /* callback */
118 void *sc_tx_intrarg; /* callback arg */
119 void *sc_tx_buf; /* transmit buffer */
120 int sc_tx_refcnt; /* buffer refcnt */
121
122 /* mixer data */
123 int sc_vgs; /* speaker volume */
124 int sc_vgm; /* mic volume */
125 };
126
127 /* sc_state */
128 #define BTSCO_CLOSED 0
129 #define BTSCO_WAIT_CONNECT 1
130 #define BTSCO_OPEN 2
131
132 /* sc_flags */
133 #define BTSCO_LISTEN (1 << 1)
134
135 /* autoconf(9) glue */
136 static int btsco_match(struct device *, struct cfdata *, void *);
137 static void btsco_attach(struct device *, struct device *, void *);
138 static int btsco_detach(struct device *, int);
139
140 CFATTACH_DECL(btsco, sizeof(struct btsco_softc),
141 btsco_match, btsco_attach, btsco_detach, NULL);
142
143 /* audio(9) glue */
144 static int btsco_open(void *, int);
145 static void btsco_close(void *);
146 static int btsco_query_encoding(void *, struct audio_encoding *);
147 static int btsco_set_params(void *, int, int, audio_params_t *, audio_params_t *,
148 stream_filter_list_t *, stream_filter_list_t *);
149 static int btsco_round_blocksize(void *, int, int, const audio_params_t *);
150 static int btsco_start_output(void *, void *, int, void (*)(void *), void *);
151 static int btsco_start_input(void *, void *, int, void (*)(void *), void *);
152 static int btsco_halt_output(void *);
153 static int btsco_halt_input(void *);
154 static int btsco_getdev(void *, struct audio_device *);
155 static int btsco_setfd(void *, int);
156 static int btsco_set_port(void *, mixer_ctrl_t *);
157 static int btsco_get_port(void *, mixer_ctrl_t *);
158 static int btsco_query_devinfo(void *, mixer_devinfo_t *);
159 static void *btsco_allocm(void *, int, size_t, struct malloc_type *, int);
160 static void btsco_freem(void *, void *, struct malloc_type *);
161 static int btsco_get_props(void *);
162 static int btsco_dev_ioctl(void *, u_long, caddr_t, int, struct lwp *);
163 static void btsco_get_locks(void *, kmutex_t **, kmutex_t **);
164
165 static const struct audio_hw_if btsco_if = {
166 btsco_open, /* open */
167 btsco_close, /* close */
168 NULL, /* drain */
169 btsco_query_encoding, /* query_encoding */
170 btsco_set_params, /* set_params */
171 btsco_round_blocksize, /* round_blocksize */
172 NULL, /* commit_settings */
173 NULL, /* init_output */
174 NULL, /* init_input */
175 btsco_start_output, /* start_output */
176 btsco_start_input, /* start_input */
177 btsco_halt_output, /* halt_output */
178 btsco_halt_input, /* halt_input */
179 NULL, /* speaker_ctl */
180 btsco_getdev, /* getdev */
181 btsco_setfd, /* setfd */
182 btsco_set_port, /* set_port */
183 btsco_get_port, /* get_port */
184 btsco_query_devinfo, /* query_devinfo */
185 btsco_allocm, /* allocm */
186 btsco_freem, /* freem */
187 NULL, /* round_buffersize */
188 NULL, /* mappage */
189 btsco_get_props, /* get_props */
190 NULL, /* trigger_output */
191 NULL, /* trigger_input */
192 btsco_dev_ioctl, /* dev_ioctl */
193 NULL, /* powerstate */
194 btsco_get_locks, /* get_lock */
195 };
196
197 static const struct audio_device btsco_device = {
198 "Bluetooth Audio",
199 "",
200 "btsco"
201 };
202
203 /* Voice_Setting == 0x0060: 8000Hz, mono, 16-bit, slinear_le */
204 static const struct audio_format btsco_format = {
205 NULL, /* driver_data */
206 (AUMODE_PLAY | AUMODE_RECORD), /* mode */
207 AUDIO_ENCODING_SLINEAR_LE, /* encoding */
208 16, /* validbits */
209 16, /* precision */
210 1, /* channels */
211 AUFMT_MONAURAL, /* channel_mask */
212 1, /* frequency_type */
213 { 8000 } /* frequency */
214 };
215
216 /* bluetooth(9) glue for SCO */
217 static void btsco_sco_connecting(void *);
218 static void btsco_sco_connected(void *);
219 static void btsco_sco_disconnected(void *, int);
220 static void *btsco_sco_newconn(void *, struct sockaddr_bt *, struct sockaddr_bt *);
221 static void btsco_sco_complete(void *, int);
222 static void btsco_sco_input(void *, struct mbuf *);
223
224 static const struct btproto btsco_sco_proto = {
225 btsco_sco_connecting,
226 btsco_sco_connected,
227 btsco_sco_disconnected,
228 btsco_sco_newconn,
229 btsco_sco_complete,
230 btsco_sco_input,
231 };
232
233
234 /*****************************************************************************
235 *
236 * btsco definitions
237 */
238
239 /*
240 * btsco mixer class
241 */
242 #define BTSCO_VGS 0
243 #define BTSCO_VGM 1
244 #define BTSCO_INPUT_CLASS 2
245 #define BTSCO_OUTPUT_CLASS 3
246
247 /* connect timeout */
248 #define BTSCO_TIMEOUT (30 * hz)
249
250 /* misc btsco functions */
251 static void btsco_extfree(struct mbuf *, caddr_t, size_t, void *);
252 static void btsco_intr(void *);
253
254
255 /*****************************************************************************
256 *
257 * btsco autoconf(9) routines
258 */
259
260 static int
261 btsco_match(struct device *self, struct cfdata *cfdata,
262 void *aux)
263 {
264 prop_dictionary_t dict = aux;
265 prop_object_t obj;
266
267 obj = prop_dictionary_get(dict, BTDEVservice);
268 if (prop_string_equals_cstring(obj, "HSET"))
269 return 1;
270
271 if (prop_string_equals_cstring(obj, "HF"))
272 return 1;
273
274 return 0;
275 }
276
277 static void
278 btsco_attach(struct device *parent, struct device *self, void *aux)
279 {
280 struct btsco_softc *sc = (struct btsco_softc *)self;
281 prop_dictionary_t dict = aux;
282 prop_object_t obj;
283
284 /*
285 * Init softc
286 */
287 sc->sc_vgs = 200;
288 sc->sc_vgm = 200;
289 sc->sc_state = BTSCO_CLOSED;
290
291 mutex_init(&sc->sc_lock, MUTEX_DRIVER, IPL_NONE);
292 mutex_init(&sc->sc_intr_lock, MUTEX_DRIVER, IPL_SOFTNET);
293
294 /*
295 * copy in our configuration info
296 */
297 obj = prop_dictionary_get(dict, BTDEVladdr);
298 bdaddr_copy(&sc->sc_laddr, prop_data_data_nocopy(obj));
299
300 obj = prop_dictionary_get(dict, BTDEVraddr);
301 bdaddr_copy(&sc->sc_raddr, prop_data_data_nocopy(obj));
302
303 obj = prop_dictionary_get(dict, BTDEVservice);
304 if (prop_string_equals_cstring(obj, "HF")) {
305 sc->sc_flags |= BTSCO_LISTEN;
306 aprint_verbose(" listen mode");
307 }
308
309 obj = prop_dictionary_get(dict, BTSCOchannel);
310 if (prop_object_type(obj) != PROP_TYPE_NUMBER
311 || prop_number_integer_value(obj) < RFCOMM_CHANNEL_MIN
312 || prop_number_integer_value(obj) > RFCOMM_CHANNEL_MAX) {
313 aprint_error(" invalid %s", BTSCOchannel);
314 return;
315 }
316 sc->sc_channel = prop_number_integer_value(obj);
317
318 aprint_verbose(" channel %d", sc->sc_channel);
319 aprint_normal("\n");
320
321 DPRINTF("sc=%p\n", sc);
322
323 /*
324 * set up transmit interrupt
325 */
326 sc->sc_intr = softintr_establish(IPL_SOFTNET, btsco_intr, sc);
327 if (sc->sc_intr == NULL) {
328 aprint_error("%s: softintr_establish failed\n",
329 device_xname((struct device *)sc));
330 return;
331 }
332
333 /*
334 * attach audio device
335 */
336 sc->sc_audio = audio_attach_mi(&btsco_if, sc, (struct device *)sc);
337 if (sc->sc_audio == NULL) {
338 aprint_error("%s: audio_attach_mi failed\n",
339 device_xname((struct device *)sc));
340 return;
341 }
342 }
343
344 static int
345 btsco_detach(struct device *self, int flags)
346 {
347 struct btsco_softc *sc = (struct btsco_softc *)self;
348 int s;
349
350 DPRINTF("sc=%p\n", sc);
351
352 s = splsoftnet();
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 splx(s);
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 softintr_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 printf("%s: tx_refcnt=%d!\n",
385 device_xname((struct device *)sc), sc->sc_tx_refcnt);
386
387 if ((flags & DETACH_FORCE) == 0)
388 return EAGAIN;
389 }
390
391 return 0;
392 }
393
394 /*****************************************************************************
395 *
396 * bluetooth(9) methods for SCO
397 *
398 * All these are called from Bluetooth Protocol code, in a soft
399 * interrupt context at IPL_SOFTNET.
400 */
401
402 static void
403 btsco_sco_connecting(void *arg)
404 {
405 /* struct btsco_softc *sc = arg; */
406
407 /* dont care */
408 }
409
410 static void
411 btsco_sco_connected(void *arg)
412 {
413 struct btsco_softc *sc = arg;
414
415 DPRINTF("%s\n", device_xname((struct device *)sc));
416
417 KASSERT(sc->sc_sco != NULL);
418 KASSERT(sc->sc_state == BTSCO_WAIT_CONNECT);
419
420 /*
421 * If we are listening, no more need
422 */
423 if (sc->sc_sco_l != NULL)
424 sco_detach(&sc->sc_sco_l);
425
426 sc->sc_state = BTSCO_OPEN;
427 wakeup(sc);
428 }
429
430 static void
431 btsco_sco_disconnected(void *arg, int err)
432 {
433 struct btsco_softc *sc = arg;
434
435 DPRINTF("%s sc_state %d\n",
436 device_xname((struct device *)sc), sc->sc_state);
437
438 KASSERT(sc->sc_sco != NULL);
439
440 sc->sc_err = err;
441 sco_detach(&sc->sc_sco);
442
443 switch (sc->sc_state) {
444 case BTSCO_CLOSED: /* dont think this can happen */
445 break;
446
447 case BTSCO_WAIT_CONNECT: /* connect failed */
448 wakeup(sc);
449 break;
450
451 case BTSCO_OPEN: /* link lost */
452 /*
453 * If IO is in progress, tell the audio driver that it
454 * has completed so that when it tries to send more, we
455 * can indicate an error.
456 */
457 mutex_enter(&sc->sc_intr_lock);
458 if (sc->sc_tx_pending > 0) {
459 sc->sc_tx_pending = 0;
460 (*sc->sc_tx_intr)(sc->sc_tx_intrarg);
461 }
462 if (sc->sc_rx_want > 0) {
463 sc->sc_rx_want = 0;
464 (*sc->sc_rx_intr)(sc->sc_rx_intrarg);
465 }
466 mutex_exit(&sc->sc_intr_lock);
467 break;
468
469 default:
470 UNKNOWN(sc->sc_state);
471 }
472
473 sc->sc_state = BTSCO_CLOSED;
474 }
475
476 static void *
477 btsco_sco_newconn(void *arg, struct sockaddr_bt *laddr,
478 struct sockaddr_bt *raddr)
479 {
480 struct btsco_softc *sc = arg;
481
482 DPRINTF("%s\n", device_xname((struct device *)sc));
483 if (bdaddr_same(&raddr->bt_bdaddr, &sc->sc_raddr) == 0
484 || sc->sc_state != BTSCO_WAIT_CONNECT
485 || sc->sc_sco != NULL)
486 return NULL;
487
488 sco_attach(&sc->sc_sco, &btsco_sco_proto, sc);
489 return sc->sc_sco;
490 }
491
492 static void
493 btsco_sco_complete(void *arg, int count)
494 {
495 struct btsco_softc *sc = arg;
496
497 DPRINTFN(10, "%s count %d\n",
498 device_xname((struct device *)sc), count);
499
500 mutex_enter(&sc->sc_intr_lock);
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 mutex_exit(&sc->sc_intr_lock);
507 }
508
509 static void
510 btsco_sco_input(void *arg, struct mbuf *m)
511 {
512 struct btsco_softc *sc = arg;
513 int len, s;
514
515 DPRINTFN(10, "%s len=%d\n",
516 device_xname((struct device *)sc), m->m_pkthdr.len);
517
518 s = splsoftnet();
519 if (sc->sc_rx_want == 0) {
520 m_freem(m);
521 } else {
522 KASSERT(sc->sc_rx_intr != NULL);
523 KASSERT(sc->sc_rx_block != NULL);
524
525 len = MIN(sc->sc_rx_want, m->m_pkthdr.len);
526 m_copydata(m, 0, len, sc->sc_rx_block);
527
528 sc->sc_rx_want -= len;
529 sc->sc_rx_block += len;
530
531 if (len > m->m_pkthdr.len) {
532 if (sc->sc_rx_mbuf != NULL)
533 m_freem(sc->sc_rx_mbuf);
534
535 m_adj(m, len);
536 sc->sc_rx_mbuf = m;
537 } else {
538 m_freem(m);
539 }
540
541 mutex_enter(&sc->sc_intr_lock);
542 if (sc->sc_rx_want == 0)
543 (*sc->sc_rx_intr)(sc->sc_rx_intrarg);
544 mutex_exit(&sc->sc_intr_lock);
545
546 }
547 splx(s);
548 }
549
550
551 /*****************************************************************************
552 *
553 * audio(9) methods
554 *
555 */
556
557 static int
558 btsco_open(void *hdl, int flags)
559 {
560 struct sockaddr_bt sa;
561 struct btsco_softc *sc = hdl;
562 int err, s, timo;
563
564 DPRINTF("%s flags 0x%x\n",
565 device_xname((struct device *)sc), flags);
566 /* flags FREAD & FWRITE? */
567
568 if (sc->sc_sco != NULL || sc->sc_sco_l != NULL)
569 return EIO;
570
571 s = splsoftnet();
572
573 memset(&sa, 0, sizeof(sa));
574 sa.bt_len = sizeof(sa);
575 sa.bt_family = AF_BLUETOOTH;
576 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_laddr);
577
578 if (sc->sc_flags & BTSCO_LISTEN) {
579 err = sco_attach(&sc->sc_sco_l, &btsco_sco_proto, sc);
580 if (err)
581 goto done;
582
583 err = sco_bind(sc->sc_sco_l, &sa);
584 if (err) {
585 sco_detach(&sc->sc_sco_l);
586 goto done;
587 }
588
589 err = sco_listen(sc->sc_sco_l);
590 if (err) {
591 sco_detach(&sc->sc_sco_l);
592 goto done;
593 }
594
595 timo = 0; /* no timeout */
596 } else {
597 err = sco_attach(&sc->sc_sco, &btsco_sco_proto, sc);
598 if (err)
599 goto done;
600
601 err = sco_bind(sc->sc_sco, &sa);
602 if (err) {
603 sco_detach(&sc->sc_sco);
604 goto done;
605 }
606
607 bdaddr_copy(&sa.bt_bdaddr, &sc->sc_raddr);
608 err = sco_connect(sc->sc_sco, &sa);
609 if (err) {
610 sco_detach(&sc->sc_sco);
611 goto done;
612 }
613
614 timo = BTSCO_TIMEOUT;
615 }
616
617 sc->sc_state = BTSCO_WAIT_CONNECT;
618 while (err == 0 && sc->sc_state == BTSCO_WAIT_CONNECT)
619 err = tsleep(sc, PWAIT | PCATCH, "btsco", timo);
620
621 switch (sc->sc_state) {
622 case BTSCO_CLOSED: /* disconnected */
623 err = sc->sc_err;
624
625 /* fall through to */
626 case BTSCO_WAIT_CONNECT: /* error */
627 if (sc->sc_sco != NULL)
628 sco_detach(&sc->sc_sco);
629
630 if (sc->sc_sco_l != NULL)
631 sco_detach(&sc->sc_sco_l);
632
633 break;
634
635 case BTSCO_OPEN: /* hurrah */
636 sco_getopt(sc->sc_sco, SO_SCO_MTU, &sc->sc_mtu);
637 break;
638
639 default:
640 UNKNOWN(sc->sc_state);
641 break;
642 }
643
644 done:
645 splx(s);
646
647 DPRINTF("done err=%d, sc_state=%d, sc_mtu=%d\n",
648 err, sc->sc_state, sc->sc_mtu);
649 return err;
650 }
651
652 static void
653 btsco_close(void *hdl)
654 {
655 struct btsco_softc *sc = hdl;
656 int s;
657
658 DPRINTF("%s\n", device_xname((struct device *)sc));
659
660 s = splsoftnet();
661 if (sc->sc_sco != NULL) {
662 sco_disconnect(sc->sc_sco, 0);
663 sco_detach(&sc->sc_sco);
664 }
665
666 if (sc->sc_sco_l != NULL) {
667 sco_detach(&sc->sc_sco_l);
668 }
669 splx(s);
670
671 if (sc->sc_rx_mbuf != NULL) {
672 m_freem(sc->sc_rx_mbuf);
673 sc->sc_rx_mbuf = NULL;
674 }
675
676 sc->sc_rx_want = 0;
677 sc->sc_rx_block = NULL;
678 sc->sc_rx_intr = NULL;
679 sc->sc_rx_intrarg = NULL;
680
681 sc->sc_tx_size = 0;
682 sc->sc_tx_block = NULL;
683 sc->sc_tx_pending = 0;
684 sc->sc_tx_intr = NULL;
685 sc->sc_tx_intrarg = NULL;
686 }
687
688 static int
689 btsco_query_encoding(void *hdl, struct audio_encoding *ae)
690 {
691 /* struct btsco_softc *sc = hdl; */
692 int err = 0;
693
694 switch (ae->index) {
695 case 0:
696 strcpy(ae->name, AudioEslinear_le);
697 ae->encoding = AUDIO_ENCODING_SLINEAR_LE;
698 ae->precision = 16;
699 ae->flags = 0;
700 break;
701
702 default:
703 err = EINVAL;
704 }
705
706 return err;
707 }
708
709 static int
710 btsco_set_params(void *hdl, int setmode, int usemode,
711 audio_params_t *play, audio_params_t *rec,
712 stream_filter_list_t *pfil, stream_filter_list_t *rfil)
713 {
714 /* struct btsco_softc *sc = hdl; */
715 const struct audio_format *f;
716 int rv;
717
718 DPRINTF("setmode 0x%x usemode 0x%x\n", setmode, usemode);
719 DPRINTF("rate %d, precision %d, channels %d encoding %d\n",
720 play->sample_rate, play->precision, play->channels, play->encoding);
721
722 /*
723 * If we had a list of formats, we could check the HCI_Voice_Setting
724 * and select the appropriate one to use. Currently only one is
725 * supported: 0x0060 == 8000Hz, mono, 16-bit, slinear_le
726 */
727 f = &btsco_format;
728
729 if (setmode & AUMODE_PLAY) {
730 rv = auconv_set_converter(f, 1, AUMODE_PLAY, play, TRUE, pfil);
731 if (rv < 0)
732 return EINVAL;
733 }
734
735 if (setmode & AUMODE_RECORD) {
736 rv = auconv_set_converter(f, 1, AUMODE_RECORD, rec, TRUE, rfil);
737 if (rv < 0)
738 return EINVAL;
739 }
740
741 return 0;
742 }
743
744 /*
745 * If we have an MTU value to use, round the blocksize to that.
746 */
747 static int
748 btsco_round_blocksize(void *hdl, int bs, int mode,
749 const audio_params_t *param)
750 {
751 struct btsco_softc *sc = hdl;
752
753 if (sc->sc_mtu > 0) {
754 bs = (bs / sc->sc_mtu) * sc->sc_mtu;
755 if (bs == 0)
756 bs = sc->sc_mtu;
757 }
758
759 DPRINTF("%s mode=0x%x, bs=%d, sc_mtu=%d\n",
760 device_xname((struct device *)sc), mode, bs, sc->sc_mtu);
761
762 return bs;
763 }
764
765 /*
766 * Start Output
767 *
768 * We dont want to be calling the network stack at splaudio() so make
769 * a note of what is to be sent, and schedule an interrupt to bundle
770 * it up and queue it.
771 */
772 static int
773 btsco_start_output(void *hdl, void *block, int blksize,
774 void (*intr)(void *), void *intrarg)
775 {
776 struct btsco_softc *sc = hdl;
777
778 DPRINTFN(5, "%s blksize %d\n",
779 device_xname((struct device *)sc), 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 softintr_schedule(sc->sc_intr);
791 return 0;
792 }
793
794 /*
795 * Start Input
796 *
797 * When the SCO link is up, we are getting data in any case, so all we do
798 * is note what we want and where to put it and let the sco_input routine
799 * fill in the data.
800 *
801 * If there was any leftover data that didnt fit in the last block, retry
802 * it now.
803 */
804 static int
805 btsco_start_input(void *hdl, void *block, int blksize,
806 void (*intr)(void *), void *intrarg)
807 {
808 struct btsco_softc *sc = hdl;
809 struct mbuf *m;
810
811 DPRINTFN(5, "%s blksize %d\n",
812 device_xname((struct device *)sc), blksize);
813
814 if (sc->sc_sco == NULL)
815 return ENOTCONN;
816
817 sc->sc_rx_want = blksize;
818 sc->sc_rx_block = block;
819 sc->sc_rx_intr = intr;
820 sc->sc_rx_intrarg = intrarg;
821
822 if (sc->sc_rx_mbuf != NULL) {
823 m = sc->sc_rx_mbuf;
824 sc->sc_rx_mbuf = NULL;
825 btsco_sco_input(sc, m);
826 }
827
828 return 0;
829 }
830
831 /*
832 * Halt Output
833 *
834 * This doesnt really halt the output, but it will look
835 * that way to the audio driver. The current block will
836 * still be transmitted.
837 */
838 static int
839 btsco_halt_output(void *hdl)
840 {
841 struct btsco_softc *sc = hdl;
842
843 DPRINTFN(5, "%s\n", device_xname((struct device *)sc));
844
845 sc->sc_tx_size = 0;
846 sc->sc_tx_block = NULL;
847 sc->sc_tx_pending = 0;
848 sc->sc_tx_intr = NULL;
849 sc->sc_tx_intrarg = NULL;
850
851 return 0;
852 }
853
854 /*
855 * Halt Input
856 *
857 * This doesnt really halt the input, but it will look
858 * that way to the audio driver. Incoming data will be
859 * discarded.
860 */
861 static int
862 btsco_halt_input(void *hdl)
863 {
864 struct btsco_softc *sc = hdl;
865 struct mbuf *m;
866
867 DPRINTFN(5, "%s\n", device_xname((struct device *)sc));
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 = sc->sc_rx_mbuf;
876 sc->sc_rx_mbuf = NULL;
877 mutex_exit(&sc->sc_intr_lock);
878 m_freem(m);
879 mutex_enter(&sc->sc_intr_lock);
880 }
881
882 return 0;
883 }
884
885 static int
886 btsco_getdev(void *hdl, struct audio_device *ret)
887 {
888
889 *ret = btsco_device;
890 return 0;
891 }
892
893 static int
894 btsco_setfd(void *hdl, int fd)
895 {
896 DPRINTF("set %s duplex\n", fd ? "full" : "half");
897
898 return 0;
899 }
900
901 static int
902 btsco_set_port(void *hdl, mixer_ctrl_t *mc)
903 {
904 struct btsco_softc *sc = hdl;
905 int err = 0;
906
907 DPRINTF("%s dev %d type %d\n",
908 device_xname((struct device *)sc), mc->dev, mc->type);
909
910 switch (mc->dev) {
911 case BTSCO_VGS:
912 if (mc->type != AUDIO_MIXER_VALUE ||
913 mc->un.value.num_channels != 1) {
914 err = EINVAL;
915 break;
916 }
917
918 sc->sc_vgs = mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
919 break;
920
921 case BTSCO_VGM:
922 if (mc->type != AUDIO_MIXER_VALUE ||
923 mc->un.value.num_channels != 1) {
924 err = EINVAL;
925 break;
926 }
927
928 sc->sc_vgm = mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
929 break;
930
931 default:
932 err = EINVAL;
933 break;
934 }
935
936 return err;
937 }
938
939 static int
940 btsco_get_port(void *hdl, mixer_ctrl_t *mc)
941 {
942 struct btsco_softc *sc = hdl;
943 int err = 0;
944
945 DPRINTF("%s dev %d\n",
946 device_xname((struct device *)sc), 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",
1022 device_xname((struct device *)sc), size, direction);
1023
1024 addr = malloc(size, type, flags);
1025
1026 if (direction == AUMODE_PLAY) {
1027 sc->sc_tx_buf = addr;
1028 sc->sc_tx_refcnt = 0;
1029 }
1030
1031 return addr;
1032 }
1033
1034 /*
1035 * Free Ring Buffers.
1036 *
1037 * Because we used external memory for the tx mbufs, we dont
1038 * want to free the memory until all the mbufs are done with
1039 *
1040 * Just to be sure, dont free if something is still pending.
1041 * This would be a memory leak but at least there is a warning..
1042 */
1043 static void
1044 btsco_freem(void *hdl, void *addr, struct malloc_type *type)
1045 {
1046 struct btsco_softc *sc = hdl;
1047 int count = hz / 2;
1048
1049 if (addr == sc->sc_tx_buf) {
1050 DPRINTF("%s: tx_refcnt=%d\n",
1051 device_xname((struct device *)sc), sc->sc_tx_refcnt);
1052
1053 sc->sc_tx_buf = NULL;
1054
1055 while (sc->sc_tx_refcnt> 0 && count-- > 0)
1056 tsleep(sc, PWAIT, "drain", 1);
1057
1058 if (sc->sc_tx_refcnt > 0) {
1059 printf("%s: ring buffer unreleased!\n",
1060 device_xname((struct device *)sc));
1061 return;
1062 }
1063 }
1064
1065 free(addr, type);
1066 }
1067
1068 static int
1069 btsco_get_props(void *hdl)
1070 {
1071
1072 return AUDIO_PROP_FULLDUPLEX;
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, caddr_t 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",
1088 device_xname((struct device *)sc), cmd, flag);
1089
1090 switch (cmd) {
1091 case BTSCO_GETINFO:
1092 memset(bi, 0, sizeof(*bi));
1093 bdaddr_copy(&bi->laddr, &sc->sc_laddr);
1094 bdaddr_copy(&bi->raddr, &sc->sc_raddr);
1095 bi->channel = sc->sc_channel;
1096 bi->vgs = BTSCO_VGS;
1097 bi->vgm = BTSCO_VGM;
1098 break;
1099
1100 default:
1101 err = EPASSTHROUGH;
1102 break;
1103 }
1104
1105 return err;
1106 }
1107
1108 static void
1109 btsco_get_locks(void *hdl, kmutex_t **intr, kmutex_t **proc)
1110 {
1111 struct btsco_softc *sc = hdl;
1112
1113 *intr = &sc->sc_intr_lock;
1114 *proc = &sc->sc_lock;
1115 }
1116
1117
1118 /*****************************************************************************
1119 *
1120 * misc btsco functions
1121 *
1122 */
1123
1124 /*
1125 * Our transmit interrupt. This is triggered when a new block is to be
1126 * sent. We send mtu sized chunks of the block as mbufs with external
1127 * storage to sco_send()
1128 */
1129 static void
1130 btsco_intr(void *arg)
1131 {
1132 struct btsco_softc *sc = arg;
1133 struct mbuf *m;
1134 uint8_t *block;
1135 int mlen, size;
1136
1137 DPRINTFN(10, "%s block %p size %d\n",
1138 device_xname((struct device *)sc), sc->sc_tx_block, sc->sc_tx_size);
1139
1140 if (sc->sc_sco == NULL)
1141 return; /* connection is lost */
1142
1143 block = sc->sc_tx_block;
1144 size = sc->sc_tx_size;
1145 sc->sc_tx_block = NULL;
1146 sc->sc_tx_size = 0;
1147
1148 while (size > 0) {
1149 MGETHDR(m, M_DONTWAIT, MT_DATA);
1150 if (m == NULL)
1151 break;
1152
1153 mlen = MIN(sc->sc_mtu, size);
1154
1155 /* I think M_DEVBUF is true but not relevant */
1156 MEXTADD(m, block, mlen, M_DEVBUF, btsco_extfree, sc);
1157 if ((m->m_flags & M_EXT) == 0) {
1158 m_free(m);
1159 break;
1160 }
1161 sc->sc_tx_refcnt++;
1162
1163 m->m_pkthdr.len = m->m_len = mlen;
1164 sc->sc_tx_pending++;
1165
1166 if (sco_send(sc->sc_sco, m) > 0) {
1167 sc->sc_tx_pending--;
1168 break;
1169 }
1170
1171 block += mlen;
1172 size -= mlen;
1173 }
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, caddr_t addr, size_t size,
1182 void *arg)
1183 {
1184 struct btsco_softc *sc = arg;
1185
1186 if (m != NULL)
1187 pool_cache_put(&mbpool_cache, m);
1188
1189 sc->sc_tx_refcnt--;
1190 }
1191