Skip to content

Commit 29a6514

Browse files
fdanis-ossVudentz
authored andcommitted
Bluetooth: SCO: Add support for 16 bits transparent voice setting
The voice setting is used by sco_connect() or sco_conn_defer_accept() after being set by sco_sock_setsockopt(). The PCM part of the voice setting is used for offload mode through PCM chipset port. This commits add support for mSBC 16 bits offloading, i.e. audio data not transported over HCI. The BCM4349B1 supports 16 bits transparent data on its I2S port. If BT_VOICE_TRANSPARENT is used when accepting a SCO connection, this gives only garbage audio while using BT_VOICE_TRANSPARENT_16BIT gives correct audio. This has been tested with connection to iPhone 14 and Samsung S24. Fixes: ad10b1a ("Bluetooth: Add Bluetooth socket voice option") Signed-off-by: Frédéric Danis <frederic.danis@collabora.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
1 parent 9bde7c3 commit 29a6514

File tree

2 files changed

+16
-14
lines changed

2 files changed

+16
-14
lines changed

include/net/bluetooth/bluetooth.h

+1
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ struct bt_voice {
123123

124124
#define BT_VOICE_TRANSPARENT 0x0003
125125
#define BT_VOICE_CVSD_16BIT 0x0060
126+
#define BT_VOICE_TRANSPARENT_16BIT 0x0063
126127

127128
#define BT_SNDMTU 12
128129
#define BT_RCVMTU 13

net/bluetooth/sco.c

+15-14
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,13 @@ static int sco_connect(struct sock *sk)
319319
else
320320
type = SCO_LINK;
321321

322-
if (sco_pi(sk)->setting == BT_VOICE_TRANSPARENT &&
323-
(!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev))) {
324-
err = -EOPNOTSUPP;
325-
goto unlock;
322+
switch (sco_pi(sk)->setting & SCO_AIRMODE_MASK) {
323+
case SCO_AIRMODE_TRANSP:
324+
if (!lmp_transp_capable(hdev) || !lmp_esco_capable(hdev)) {
325+
err = -EOPNOTSUPP;
326+
goto unlock;
327+
}
328+
break;
326329
}
327330

328331
hcon = hci_connect_sco(hdev, type, &sco_pi(sk)->dst,
@@ -920,23 +923,21 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname,
920923
if (err)
921924
break;
922925

923-
/* Explicitly check for these values */
924-
if (voice.setting != BT_VOICE_TRANSPARENT &&
925-
voice.setting != BT_VOICE_CVSD_16BIT) {
926-
err = -EINVAL;
927-
break;
928-
}
929-
930926
sco_pi(sk)->setting = voice.setting;
931927
hdev = hci_get_route(&sco_pi(sk)->dst, &sco_pi(sk)->src,
932928
BDADDR_BREDR);
933929
if (!hdev) {
934930
err = -EBADFD;
935931
break;
936932
}
937-
if (enhanced_sync_conn_capable(hdev) &&
938-
voice.setting == BT_VOICE_TRANSPARENT)
939-
sco_pi(sk)->codec.id = BT_CODEC_TRANSPARENT;
933+
934+
switch (sco_pi(sk)->setting & SCO_AIRMODE_MASK) {
935+
case SCO_AIRMODE_TRANSP:
936+
if (enhanced_sync_conn_capable(hdev))
937+
sco_pi(sk)->codec.id = BT_CODEC_TRANSPARENT;
938+
break;
939+
}
940+
940941
hci_dev_put(hdev);
941942
break;
942943

0 commit comments

Comments
 (0)