Loading drivers/bluetooth/btfm_slim.h +2 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ enum { BTFM_BT_SCO_SLIM_TX, BTFM_BT_SCO_A2DP_SLIM_RX, BTFM_BT_SPLIT_A2DP_SLIM_RX, BTFM_BT_SPLIT_A2DP_SLIM_TX, BTFM_SLIM_NUM_CODEC_DAIS }; Loading Loading @@ -69,6 +70,7 @@ struct btfmslim { uint32_t num_rx_port; uint32_t num_tx_port; uint32_t sample_rate; int dai_id; struct btfmslim_ch *rx_chs; struct btfmslim_ch *tx_chs; Loading drivers/bluetooth/btfm_slim_codec.c +41 −0 Original line number Diff line number Diff line Loading @@ -129,6 +129,10 @@ static void btfm_slim_dai_shutdown(struct snd_pcm_substream *substream, ch = btfmslim->rx_chs; rxport = 1; break; case BTFM_BT_SPLIT_A2DP_SLIM_TX: ch = btfmslim->tx_chs; rxport = 0; break; case BTFM_SLIM_NUM_CODEC_DAIS: default: BTFMSLIM_ERR("dai->id is invalid:%d", dai->id); Loading @@ -155,10 +159,13 @@ static int btfm_slim_dai_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct btfmslim *btfmslim = dai->dev->platform_data; BTFMSLIM_DBG("dai->name = %s DAI-ID %x rate %d num_ch %d", dai->name, dai->id, params_rate(params), params_channels(params)); btfmslim->dai_id = dai->id; return 0; } Loading Loading @@ -193,6 +200,10 @@ static int btfm_slim_dai_prepare(struct snd_pcm_substream *substream, ch = btfmslim->rx_chs; rxport = 1; break; case BTFM_BT_SPLIT_A2DP_SLIM_TX: ch = btfmslim->tx_chs; rxport = 0; break; case BTFM_SLIM_NUM_CODEC_DAIS: default: BTFMSLIM_ERR("dai->id is invalid:%d", dai->id); Loading Loading @@ -310,6 +321,20 @@ static int btfm_slim_dai_get_channel_map(struct snd_soc_dai *dai, *tx_num = num; *rx_num = 0; break; case BTFM_BT_SPLIT_A2DP_SLIM_TX: if (!tx_slot || !tx_num) { BTFMSLIM_ERR("Invalid tx_slot %p or tx_num %p", tx_slot, tx_num); return -EINVAL; } ch = btfmslim->tx_chs; if (!ch) return -EINVAL; slot = tx_slot; *rx_slot = 0; *tx_num = num; *rx_num = 0; break; case BTFM_BT_SCO_A2DP_SLIM_RX: case BTFM_BT_SPLIT_A2DP_SLIM_RX: if (!rx_slot || !rx_num) { Loading Loading @@ -431,6 +456,22 @@ static struct snd_soc_dai_driver btfmslim_dai[] = { }, .ops = &btfmslim_dai_ops, }, { /* Bluetooth Split A2DP sink: bt -> adsp */ .name = "btfm_bt_split_a2dp_slim_tx", .id = BTFM_BT_SPLIT_A2DP_SLIM_TX, .capture = { .stream_name = "A2DP Tx Capture", /* 8 KHz or 16 KHz */ .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000, .formats = SNDRV_PCM_FMTBIT_S16_LE, /* 16 bits */ .rate_max = 96000, .rate_min = 44100, .channels_min = 1, .channels_max = 1, }, .ops = &btfmslim_dai_ops, }, }; static struct snd_soc_codec_driver btfmslim_codec = { Loading drivers/bluetooth/btfm_slim_wcn3990.c +22 −7 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ struct btfmslim_ch wcn3990_txport[] = { .port = CHRK_SB_PGD_PORT_TX2_FM}, {.id = BTFM_BT_SCO_SLIM_TX, .name = "SCO_Tx", .port = CHRK_SB_PGD_PORT_TX_SCO}, {.id = BTFM_BT_SPLIT_A2DP_SLIM_TX, .name = "A2DP_Tx", .port = CHRK_SB_PGD_PORT_TX_A2DP}, {.id = BTFM_SLIM_NUM_CODEC_DAIS, .name = "", .port = BTFM_SLIM_PGD_PORT_LAST}, }; Loading Loading @@ -69,12 +71,10 @@ int btfm_slim_chrk_hw_init(struct btfmslim *btfmslim) return ret; } static inline int is_fm_port(uint8_t port_num) static inline int is_fm_port(struct btfmslim *btfmslim) { if (port_num == CHRK_SB_PGD_PORT_TX1_FM || port_num == CHRKVER3_SB_PGD_PORT_TX1_FM || port_num == CHRKVER3_SB_PGD_PORT_TX2_FM || port_num == CHRK_SB_PGD_PORT_TX2_FM) BTFMSLIM_INFO("dai id is %d", btfmslim->dai_id); if (btfmslim->dai_id == BTFM_FM_SLIM_TX) return 1; else return 0; Loading Loading @@ -139,7 +139,7 @@ int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num, /* txport */ /* Multiple Channel Setting */ if (is_fm_port(port_num)) { if (is_fm_port(btfmslim)) { if (port_num == CHRKVER3_SB_PGD_PORT_TX1_FM) reg_val = (0x1 << CHRKVER3_SB_PGD_PORT_TX1_FM); else if (port_num == CHRKVER3_SB_PGD_PORT_TX2_FM) Loading Loading @@ -167,6 +167,18 @@ int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num, ret, reg); goto error; } } else if (port_num == CHRK_SB_PGD_PORT_TX_A2DP) { /* SCO Tx */ reg_val = 0x1 << CHRK_SB_PGD_PORT_TX_A2DP; reg = CHRK_SB_PGD_TX_PORTn_MULTI_CHNL_0(port_num); BTFMSLIM_DBG("writing reg_val (%d) to reg(%x)", reg_val, reg); ret = btfm_slim_write(btfmslim, reg, 1, ®_val, IFD); if (ret) { BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg); goto error; } } /* Enable Tx port hw auto recovery for underrun or overrun error */ Loading @@ -189,7 +201,7 @@ int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num, else en = CHRK_SB_PGD_PORT_DISABLE; if (is_fm_port(port_num)) if (is_fm_port(btfmslim)) reg_val = en | CHRK_SB_PGD_PORT_WM_L8; else if (port_num == CHRK_SB_PGD_PORT_TX_SCO) reg_val = enable ? en | CHRK_SB_PGD_PORT_WM_L1 : en; Loading @@ -199,6 +211,9 @@ int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num, if (enable && port_num == CHRK_SB_PGD_PORT_TX_SCO) BTFMSLIM_INFO("programming SCO Tx with reg_val %d to reg 0x%x", reg_val, reg); else if (enable && port_num == CHRK_SB_PGD_PORT_TX_A2DP) BTFMSLIM_INFO("programming A2DP Tx with reg_val %d to reg 0x%x", reg_val, reg); ret = btfm_slim_write(btfmslim, reg, 1, ®_val, IFD); if (ret) Loading drivers/bluetooth/btfm_slim_wcn3990.h +1 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ #define CHRKVER3_SB_PGD_PORT_TX2_FM 5 #define CHRK_SB_PGD_PORT_RX_SCO 16 #define CHRK_SB_PGD_PORT_RX_A2P 17 #define CHRK_SB_PGD_PORT_TX_A2DP 2 enum { QCA_CHEROKEE_SOC_ID_0100 = 0x40010100, Loading Loading
drivers/bluetooth/btfm_slim.h +2 −0 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ enum { BTFM_BT_SCO_SLIM_TX, BTFM_BT_SCO_A2DP_SLIM_RX, BTFM_BT_SPLIT_A2DP_SLIM_RX, BTFM_BT_SPLIT_A2DP_SLIM_TX, BTFM_SLIM_NUM_CODEC_DAIS }; Loading Loading @@ -69,6 +70,7 @@ struct btfmslim { uint32_t num_rx_port; uint32_t num_tx_port; uint32_t sample_rate; int dai_id; struct btfmslim_ch *rx_chs; struct btfmslim_ch *tx_chs; Loading
drivers/bluetooth/btfm_slim_codec.c +41 −0 Original line number Diff line number Diff line Loading @@ -129,6 +129,10 @@ static void btfm_slim_dai_shutdown(struct snd_pcm_substream *substream, ch = btfmslim->rx_chs; rxport = 1; break; case BTFM_BT_SPLIT_A2DP_SLIM_TX: ch = btfmslim->tx_chs; rxport = 0; break; case BTFM_SLIM_NUM_CODEC_DAIS: default: BTFMSLIM_ERR("dai->id is invalid:%d", dai->id); Loading @@ -155,10 +159,13 @@ static int btfm_slim_dai_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct btfmslim *btfmslim = dai->dev->platform_data; BTFMSLIM_DBG("dai->name = %s DAI-ID %x rate %d num_ch %d", dai->name, dai->id, params_rate(params), params_channels(params)); btfmslim->dai_id = dai->id; return 0; } Loading Loading @@ -193,6 +200,10 @@ static int btfm_slim_dai_prepare(struct snd_pcm_substream *substream, ch = btfmslim->rx_chs; rxport = 1; break; case BTFM_BT_SPLIT_A2DP_SLIM_TX: ch = btfmslim->tx_chs; rxport = 0; break; case BTFM_SLIM_NUM_CODEC_DAIS: default: BTFMSLIM_ERR("dai->id is invalid:%d", dai->id); Loading Loading @@ -310,6 +321,20 @@ static int btfm_slim_dai_get_channel_map(struct snd_soc_dai *dai, *tx_num = num; *rx_num = 0; break; case BTFM_BT_SPLIT_A2DP_SLIM_TX: if (!tx_slot || !tx_num) { BTFMSLIM_ERR("Invalid tx_slot %p or tx_num %p", tx_slot, tx_num); return -EINVAL; } ch = btfmslim->tx_chs; if (!ch) return -EINVAL; slot = tx_slot; *rx_slot = 0; *tx_num = num; *rx_num = 0; break; case BTFM_BT_SCO_A2DP_SLIM_RX: case BTFM_BT_SPLIT_A2DP_SLIM_RX: if (!rx_slot || !rx_num) { Loading Loading @@ -431,6 +456,22 @@ static struct snd_soc_dai_driver btfmslim_dai[] = { }, .ops = &btfmslim_dai_ops, }, { /* Bluetooth Split A2DP sink: bt -> adsp */ .name = "btfm_bt_split_a2dp_slim_tx", .id = BTFM_BT_SPLIT_A2DP_SLIM_TX, .capture = { .stream_name = "A2DP Tx Capture", /* 8 KHz or 16 KHz */ .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000, .formats = SNDRV_PCM_FMTBIT_S16_LE, /* 16 bits */ .rate_max = 96000, .rate_min = 44100, .channels_min = 1, .channels_max = 1, }, .ops = &btfmslim_dai_ops, }, }; static struct snd_soc_codec_driver btfmslim_codec = { Loading
drivers/bluetooth/btfm_slim_wcn3990.c +22 −7 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ struct btfmslim_ch wcn3990_txport[] = { .port = CHRK_SB_PGD_PORT_TX2_FM}, {.id = BTFM_BT_SCO_SLIM_TX, .name = "SCO_Tx", .port = CHRK_SB_PGD_PORT_TX_SCO}, {.id = BTFM_BT_SPLIT_A2DP_SLIM_TX, .name = "A2DP_Tx", .port = CHRK_SB_PGD_PORT_TX_A2DP}, {.id = BTFM_SLIM_NUM_CODEC_DAIS, .name = "", .port = BTFM_SLIM_PGD_PORT_LAST}, }; Loading Loading @@ -69,12 +71,10 @@ int btfm_slim_chrk_hw_init(struct btfmslim *btfmslim) return ret; } static inline int is_fm_port(uint8_t port_num) static inline int is_fm_port(struct btfmslim *btfmslim) { if (port_num == CHRK_SB_PGD_PORT_TX1_FM || port_num == CHRKVER3_SB_PGD_PORT_TX1_FM || port_num == CHRKVER3_SB_PGD_PORT_TX2_FM || port_num == CHRK_SB_PGD_PORT_TX2_FM) BTFMSLIM_INFO("dai id is %d", btfmslim->dai_id); if (btfmslim->dai_id == BTFM_FM_SLIM_TX) return 1; else return 0; Loading Loading @@ -139,7 +139,7 @@ int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num, /* txport */ /* Multiple Channel Setting */ if (is_fm_port(port_num)) { if (is_fm_port(btfmslim)) { if (port_num == CHRKVER3_SB_PGD_PORT_TX1_FM) reg_val = (0x1 << CHRKVER3_SB_PGD_PORT_TX1_FM); else if (port_num == CHRKVER3_SB_PGD_PORT_TX2_FM) Loading Loading @@ -167,6 +167,18 @@ int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num, ret, reg); goto error; } } else if (port_num == CHRK_SB_PGD_PORT_TX_A2DP) { /* SCO Tx */ reg_val = 0x1 << CHRK_SB_PGD_PORT_TX_A2DP; reg = CHRK_SB_PGD_TX_PORTn_MULTI_CHNL_0(port_num); BTFMSLIM_DBG("writing reg_val (%d) to reg(%x)", reg_val, reg); ret = btfm_slim_write(btfmslim, reg, 1, ®_val, IFD); if (ret) { BTFMSLIM_ERR("failed to write (%d) reg 0x%x", ret, reg); goto error; } } /* Enable Tx port hw auto recovery for underrun or overrun error */ Loading @@ -189,7 +201,7 @@ int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num, else en = CHRK_SB_PGD_PORT_DISABLE; if (is_fm_port(port_num)) if (is_fm_port(btfmslim)) reg_val = en | CHRK_SB_PGD_PORT_WM_L8; else if (port_num == CHRK_SB_PGD_PORT_TX_SCO) reg_val = enable ? en | CHRK_SB_PGD_PORT_WM_L1 : en; Loading @@ -199,6 +211,9 @@ int btfm_slim_chrk_enable_port(struct btfmslim *btfmslim, uint8_t port_num, if (enable && port_num == CHRK_SB_PGD_PORT_TX_SCO) BTFMSLIM_INFO("programming SCO Tx with reg_val %d to reg 0x%x", reg_val, reg); else if (enable && port_num == CHRK_SB_PGD_PORT_TX_A2DP) BTFMSLIM_INFO("programming A2DP Tx with reg_val %d to reg 0x%x", reg_val, reg); ret = btfm_slim_write(btfmslim, reg, 1, ®_val, IFD); if (ret) Loading
drivers/bluetooth/btfm_slim_wcn3990.h +1 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ #define CHRKVER3_SB_PGD_PORT_TX2_FM 5 #define CHRK_SB_PGD_PORT_RX_SCO 16 #define CHRK_SB_PGD_PORT_RX_A2P 17 #define CHRK_SB_PGD_PORT_TX_A2DP 2 enum { QCA_CHEROKEE_SOC_ID_0100 = 0x40010100, Loading