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