forked from Minki/linux
ASoC: mediatek: btcvsd add loopback
add direct loopback path from rx to tx Signed-off-by: KaiChieh Chuang <kaichieh.chuang@mediatek.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
7b6b0049e2
commit
f060f46f09
@ -49,6 +49,7 @@ enum bt_sco_state {
|
||||
BT_SCO_STATE_IDLE,
|
||||
BT_SCO_STATE_RUNNING,
|
||||
BT_SCO_STATE_ENDING,
|
||||
BT_SCO_STATE_LOOPBACK,
|
||||
};
|
||||
|
||||
enum bt_sco_direct {
|
||||
@ -486,7 +487,8 @@ static irqreturn_t mtk_btcvsd_snd_irq_handler(int irq_id, void *dev)
|
||||
if (bt->rx->state != BT_SCO_STATE_RUNNING &&
|
||||
bt->rx->state != BT_SCO_STATE_ENDING &&
|
||||
bt->tx->state != BT_SCO_STATE_RUNNING &&
|
||||
bt->tx->state != BT_SCO_STATE_ENDING) {
|
||||
bt->tx->state != BT_SCO_STATE_ENDING &&
|
||||
bt->tx->state != BT_SCO_STATE_LOOPBACK) {
|
||||
dev_warn(bt->dev, "%s(), in idle state: rx->state: %d, tx->state: %d\n",
|
||||
__func__, bt->rx->state, bt->tx->state);
|
||||
goto irq_handler_exit;
|
||||
@ -512,6 +514,42 @@ static irqreturn_t mtk_btcvsd_snd_irq_handler(int irq_id, void *dev)
|
||||
buf_cnt_tx = btsco_packet_info[packet_type][2];
|
||||
buf_cnt_rx = btsco_packet_info[packet_type][3];
|
||||
|
||||
if (bt->tx->state == BT_SCO_STATE_LOOPBACK) {
|
||||
u8 *src, *dst;
|
||||
unsigned long connsys_addr_rx, ap_addr_rx;
|
||||
unsigned long connsys_addr_tx, ap_addr_tx;
|
||||
|
||||
connsys_addr_rx = *bt->bt_reg_pkt_r;
|
||||
ap_addr_rx = (unsigned long)bt->bt_sram_bank2_base +
|
||||
(connsys_addr_rx & 0xFFFF);
|
||||
|
||||
connsys_addr_tx = *bt->bt_reg_pkt_w;
|
||||
ap_addr_tx = (unsigned long)bt->bt_sram_bank2_base +
|
||||
(connsys_addr_tx & 0xFFFF);
|
||||
|
||||
if (connsys_addr_tx == 0xdeadfeed ||
|
||||
connsys_addr_rx == 0xdeadfeed) {
|
||||
/* bt return 0xdeadfeed if read reg during bt sleep */
|
||||
dev_warn(bt->dev, "%s(), connsys_addr_tx == 0xdeadfeed\n",
|
||||
__func__);
|
||||
goto irq_handler_exit;
|
||||
}
|
||||
|
||||
src = (u8 *)ap_addr_rx;
|
||||
dst = (u8 *)ap_addr_tx;
|
||||
|
||||
mtk_btcvsd_snd_data_transfer(BT_SCO_DIRECT_BT2ARM, src,
|
||||
bt->tx->temp_packet_buf,
|
||||
packet_length,
|
||||
packet_num);
|
||||
mtk_btcvsd_snd_data_transfer(BT_SCO_DIRECT_ARM2BT,
|
||||
bt->tx->temp_packet_buf, dst,
|
||||
packet_length,
|
||||
packet_num);
|
||||
bt->rx->rw_cnt++;
|
||||
bt->tx->rw_cnt++;
|
||||
}
|
||||
|
||||
if (bt->rx->state == BT_SCO_STATE_RUNNING ||
|
||||
bt->rx->state == BT_SCO_STATE_ENDING) {
|
||||
if (bt->rx->xrun) {
|
||||
@ -1067,6 +1105,33 @@ static int btcvsd_band_set(struct snd_kcontrol *kcontrol,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int btcvsd_loopback_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
|
||||
struct mtk_btcvsd_snd *bt = snd_soc_component_get_drvdata(cmpnt);
|
||||
bool lpbk_en = bt->tx->state == BT_SCO_STATE_LOOPBACK;
|
||||
|
||||
ucontrol->value.integer.value[0] = lpbk_en;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int btcvsd_loopback_set(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
|
||||
struct mtk_btcvsd_snd *bt = snd_soc_component_get_drvdata(cmpnt);
|
||||
|
||||
if (ucontrol->value.integer.value[0]) {
|
||||
mtk_btcvsd_snd_set_state(bt, bt->tx, BT_SCO_STATE_LOOPBACK);
|
||||
mtk_btcvsd_snd_set_state(bt, bt->rx, BT_SCO_STATE_LOOPBACK);
|
||||
} else {
|
||||
mtk_btcvsd_snd_set_state(bt, bt->tx, BT_SCO_STATE_RUNNING);
|
||||
mtk_btcvsd_snd_set_state(bt, bt->rx, BT_SCO_STATE_RUNNING);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int btcvsd_tx_mute_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
@ -1202,6 +1267,8 @@ static int btcvsd_tx_timestamp_get(struct snd_kcontrol *kcontrol,
|
||||
static const struct snd_kcontrol_new mtk_btcvsd_snd_controls[] = {
|
||||
SOC_ENUM_EXT("BTCVSD Band", btcvsd_enum[0],
|
||||
btcvsd_band_get, btcvsd_band_set),
|
||||
SOC_SINGLE_BOOL_EXT("BTCVSD Loopback Switch", 0,
|
||||
btcvsd_loopback_get, btcvsd_loopback_set),
|
||||
SOC_SINGLE_BOOL_EXT("BTCVSD Tx Mute Switch", 0,
|
||||
btcvsd_tx_mute_get, btcvsd_tx_mute_set),
|
||||
SOC_SINGLE_BOOL_EXT("BTCVSD Tx Irq Received Switch", 0,
|
||||
|
Loading…
Reference in New Issue
Block a user