From patchwork Tue Feb 13 00:54:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wesley Cheng X-Patchwork-Id: 200137 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:bc8a:b0:106:860b:bbdd with SMTP id dn10csp270496dyb; Mon, 12 Feb 2024 17:33:39 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXA0IbPw+NjtYOmxdxNS+AiOx0YQSSOjAKczrN/EcYoP3AECMU5qrS6Ib03EnBeA9OPgsY5e5gMhz7bYIRiWOg+uojeZQ== X-Google-Smtp-Source: AGHT+IFMFxxdDYbiKAJW+5bxZqzr7CZyetUQvC1ls1TUOYvPLcavs9sREkeJr75jCogmVXuzVVNg X-Received: by 2002:a1f:e604:0:b0:4c0:fda:7d8c with SMTP id d4-20020a1fe604000000b004c00fda7d8cmr5180628vkh.2.1707788019359; Mon, 12 Feb 2024 17:33:39 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1707788019; cv=pass; d=google.com; s=arc-20160816; b=wct013kpzOScPNfrupkNPeOCup/Ro1/gLKQqckvUNBRFv+e4Iv+vIfcPaQJMCsfE7I b/ggoEouhODEn8Tl/4flOskLUAvr8Wki89GXMZKtrhbjV2bWgEmvn1bwRROHJhRL67l+ 3E8osomEsf+EpNg7vG3PpQL+Q5TffVJIBLEbBLUfmfVcWg44f4Ro1cj1AScHlizcHSoG izsGNEMdQU2URA525XLTzOQlZLor1dJnACWYsfnKdq+S9wkETNaAcxQK1VOn0nGOh6kj Xu9uC12QJkEySX+FH4LS0aN+D5SCLc8Rt1Owe5S1763mSDqb9cB93srXMDVZBiejhTxW X5rA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=mime-version:list-unsubscribe:list-subscribe:list-id:precedence :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=1wOpcy9jDvAAEHI/K11vsFGqT15VfQz1a4+qL0/PTVM=; fh=arDxJ+9tXyp6o5vrgSokuJAMrQsN9zHIX/+lyrJkEWU=; b=gf7T4DudSaDgGvIDYlGmmhdGAkfLZ/I181q+06yBdwaICG3oJkb9rmK/+9ixmzRdYE 2Ig2/nETPcYqw+BZDB5spP5impup5sF1Ew3K2Sa0tfm3yuvovBJxkTS7pOvvYrzVrRVy SZHCx4hurcoR4IdJikNs//QZWCvtYvAfuwFhLvAUCxuUgAIiqIvIfeCppIdwZlMGwo7D Ht+TSLNz8ARj/21jfiI57BCxMusl/+z+fhLOTQfd0sWJ4lETEKM9LbdibCEgvsivKG3W PYnD/B4oERgu7Ivwb671tTs/2TlknVp4pX0DKZh8t/7ftvo8G9AFm7DNSjUFovE+z69p I72w==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=TrZTsXpQ; arc=pass (i=1 spf=pass spfdomain=quicinc.com dkim=pass dkdomain=quicinc.com dmarc=pass fromdomain=quicinc.com); spf=pass (google.com: domain of linux-kernel+bounces-62802-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-62802-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com X-Forwarded-Encrypted: i=2; AJvYcCWDS5q//kk/wm8Ao3gmW0rBBHkGzvcP6lk5TksGjvjvjCxA51l5TC60Ai8QPribp5IOC/ULQID1uAC2/S3OH0qGDqdbfg== Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id dv7-20020ad44ee7000000b0068cd144e023si1846271qvb.329.2024.02.12.17.33.39 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Feb 2024 17:33:39 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-62802-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=TrZTsXpQ; arc=pass (i=1 spf=pass spfdomain=quicinc.com dkim=pass dkdomain=quicinc.com dmarc=pass fromdomain=quicinc.com); spf=pass (google.com: domain of linux-kernel+bounces-62802-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-62802-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 06F0D1C24B41 for ; Tue, 13 Feb 2024 01:33:39 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A933A612D7; Tue, 13 Feb 2024 00:55:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="TrZTsXpQ" Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7098A54656; Tue, 13 Feb 2024 00:55:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707785704; cv=none; b=t2rupQcP/9Ph9kiV/dozBZ844qEKmnS43m7ebF8+NH09pTlGLBQHgKyLK+eS2UW/6o+QylXNqU4WWB5YYEOi/dgBrDoXU4KWP2NAxTKU/SxlUtReEfzXHzeWLe/zKBKd34b33MFIvzEKoXW+zeOiac/yGnzgMgYOztXBiyqgPpo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1707785704; c=relaxed/simple; bh=WD2aYO20Jj6ylAcciZCsjRR8imXLNE0xsGdkB6cKWI4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=LlsP77pytpLKMvETRqIsI0+empaSYh/mpKgJQ/XWT4FamKZCJDI3HUZ3DndNZ8PpYcTZ5v6Qau4zSlasrAfPXV291qrB2Ra6tqb+3t/2x76HBxiYZZ3Jt9fKiRAlHWZiEWOPSQDlJIEt2Yif86PYES7FzGVpBL7PZSY0cua9hy4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com; spf=pass smtp.mailfrom=quicinc.com; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b=TrZTsXpQ; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=quicinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=quicinc.com Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41D0ltBU003549; Tue, 13 Feb 2024 00:54:45 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type; s=qcppdkim1; bh=1wOpcy9jDvAAEHI/K11v sFGqT15VfQz1a4+qL0/PTVM=; b=TrZTsXpQ0QIpfnLn5n+FuLyhTAP9VcQOPo5x CSgvyj+n1sl9/j7NEBzlf8DjjAmPBxgQZL5M5Xr0hBg/jC09317ng3iSJcRVdlXm 3qj60A18GAYbzJhWj/2NkC1MViQjv9c3W9vY5r8GZYcITpKWmbRYSmZETNwVd7/i UOfR4n3HYnwWC/WBS73KO9aJCT7nLUpzQw7uY1W5Dv9KJMSAVXNLLYzhNyzIxQcF Zr+WzrZRR8+itrlnhkCb1odT75Z+nJrGr2n6HK6RfE+R0FJ6YYL09cpGRuM0PuY8 PbKhfZe3hOGPpmp8acvHpg9p/1hLvEofBmX2XZFLacNnagspuA== Received: from nalasppmta02.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3w7gvjhuxd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 13 Feb 2024 00:54:45 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA02.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 41D0sii5030066 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 13 Feb 2024 00:54:44 GMT Received: from hu-wcheng-lv.qualcomm.com (10.49.16.6) by nalasex01b.na.qualcomm.com (10.47.209.197) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.40; Mon, 12 Feb 2024 16:54:43 -0800 From: Wesley Cheng To: , , , , , , , , , , , , , , CC: , , , , , , , Wesley Cheng Subject: [PATCH v15 40/50] ASoC: qcom: qdsp6: Add SOC USB offload select get/put callbacks Date: Mon, 12 Feb 2024 16:54:12 -0800 Message-ID: <20240213005422.3121-41-quic_wcheng@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240213005422.3121-1-quic_wcheng@quicinc.com> References: <20240213005422.3121-1-quic_wcheng@quicinc.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-ClientProxiedBy: nalasex01b.na.qualcomm.com (10.47.209.197) To nalasex01b.na.qualcomm.com (10.47.209.197) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: zaemku8G-V8hcOZk3Os4rjY06LrOPd3U X-Proofpoint-ORIG-GUID: zaemku8G-V8hcOZk3Os4rjY06LrOPd3U X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-12_20,2024-02-12_03,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 phishscore=0 suspectscore=0 spamscore=0 mlxscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 mlxlogscore=999 adultscore=0 bulkscore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2401310000 definitions=main-2402130004 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1790745530322203842 X-GMAIL-MSGID: 1790745530322203842 In order for device selection to be supported, the Q6USB backend DAI link will need to be notified about the device to start the offloading session on. Device selection is made possible by setting the Q6AFE device token. The audio DSP utilizes this parameter, and will pass this field back to the USB offload driver within the QMI stream requests. Signed-off-by: Wesley Cheng --- sound/soc/qcom/qdsp6/q6usb.c | 108 +++++++++++++++++++++++++++++++++-- 1 file changed, 104 insertions(+), 4 deletions(-) diff --git a/sound/soc/qcom/qdsp6/q6usb.c b/sound/soc/qcom/qdsp6/q6usb.c index e539b411c35e..61d30303a7bb 100644 --- a/sound/soc/qcom/qdsp6/q6usb.c +++ b/sound/soc/qcom/qdsp6/q6usb.c @@ -36,9 +36,12 @@ struct q6usb_port_data { struct q6afe_usb_cfg usb_cfg; struct snd_soc_usb *usb; struct q6usb_offload priv; - int active_usb_chip_idx; + struct mutex mutex; unsigned long available_card_slot; struct q6usb_status status[SNDRV_CARDS]; + bool idx_valid; + int sel_card_idx; + int sel_pcm_idx; }; static const struct snd_soc_dapm_widget q6usb_dai_widgets[] = { @@ -54,10 +57,34 @@ static int q6usb_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct q6usb_port_data *data = dev_get_drvdata(dai->dev); + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + struct q6afe_port *q6usb_afe; int direction = substream->stream; + int chip_idx; + int ret; + + mutex_lock(&data->mutex); + chip_idx = data->status[data->sel_card_idx].sdev->chip_idx; + + ret = snd_soc_usb_find_format(chip_idx, params, direction); + if (ret < 0) + goto out; + + q6usb_afe = q6afe_port_get_from_id(cpu_dai->dev, USB_RX); + if (IS_ERR(q6usb_afe)) + goto out; - return snd_soc_usb_find_format(data->active_usb_chip_idx, params, - direction); + ret = afe_port_send_usb_dev_param(q6usb_afe, data->sel_card_idx, + data->sel_pcm_idx); + if (ret < 0) + goto out; + + data->status[data->sel_card_idx].pcm_index = data->sel_pcm_idx; +out: + mutex_unlock(&data->mutex); + + return ret; } static const struct snd_soc_dai_ops q6usb_ops = { @@ -88,6 +115,63 @@ static struct snd_soc_dai_driver q6usb_be_dais[] = { }, }; +static int q6usb_get_offload_dev(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct q6usb_port_data *data = dev_get_drvdata(component->dev); + int pcm_idx; + int card_idx; + + mutex_lock(&data->mutex); + + if (!data->available_card_slot) { + card_idx = -1; + pcm_idx = -1; + } else { + card_idx = data->sel_card_idx; + pcm_idx = data->sel_pcm_idx; + } + + ucontrol->value.integer.value[0] = card_idx; + ucontrol->value.integer.value[1] = pcm_idx; + mutex_unlock(&data->mutex); + + return 0; +} + +static int q6usb_put_offload_dev(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct q6usb_port_data *data = dev_get_drvdata(component->dev); + int changed = 0; + int pcmidx; + int cardidx; + + cardidx = ucontrol->value.integer.value[0]; + pcmidx = ucontrol->value.integer.value[1]; + + mutex_lock(&data->mutex); + if ((cardidx >= 0 && test_bit(cardidx, &data->available_card_slot))) { + data->sel_card_idx = cardidx; + changed = 1; + } + + if ((pcmidx >= 0 && pcmidx < data->status[cardidx].sdev->num_playback)) { + data->sel_pcm_idx = pcmidx; + changed = 1; + } + + if (changed) + data->idx_valid = true; + +out: + mutex_unlock(&data->mutex); + + return changed; +} + static int q6usb_audio_ports_of_xlate_dai_name(struct snd_soc_component *component, const struct of_phandle_args *args, const char **dai_name) @@ -117,16 +201,28 @@ static int q6usb_alsa_connection_cb(struct snd_soc_usb *usb, data = dev_get_drvdata(usb->component->dev); + mutex_lock(&data->mutex); if (connected) { /* We only track the latest USB headset plugged in */ - data->active_usb_chip_idx = sdev->card_idx; + if (!data->idx_valid) { + data->sel_card_idx = sdev->card_idx; + data->sel_pcm_idx = 0; + } set_bit(sdev->card_idx, &data->available_card_slot); data->status[sdev->card_idx].sdev = sdev; } else { clear_bit(sdev->card_idx, &data->available_card_slot); data->status[sdev->card_idx].sdev = NULL; + + if (data->sel_card_idx == sdev->card_idx) { + data->idx_valid = false; + data->sel_card_idx = data->available_card_slot ? + ffs(data->available_card_slot) - 1 : 0; + data->sel_pcm_idx = 0; + } } + mutex_unlock(&data->mutex); return 0; } @@ -142,6 +238,8 @@ static int q6usb_component_probe(struct snd_soc_component *component) return -ENOMEM; usb->connection_status_cb = q6usb_alsa_connection_cb; + usb->put_offload_dev = q6usb_put_offload_dev; + usb->get_offload_dev = q6usb_get_offload_dev; ret = snd_soc_usb_add_port(usb); if (ret < 0) { @@ -205,6 +303,8 @@ static int q6usb_dai_dev_probe(struct platform_device *pdev) data->priv.domain = iommu_get_domain_for_dev(&pdev->dev); + mutex_init(&data->mutex); + data->priv.dev = dev; dev_set_drvdata(dev, data);