Received: by 2002:ab2:6991:0:b0:1f7:f6c3:9cb1 with SMTP id v17csp92204lqo; Tue, 7 May 2024 13:12:08 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCWaawS15QvtgHLeK9qavfTYG7iriTLiMIkby7wDADMXDg4uODI2DR3vBgCCBMOsKbyNaOc+l7UVxkAEHS2sFYy/Phe/h/coAVx+CsZjBA== X-Google-Smtp-Source: AGHT+IF98WThpw7NYnKW7IPeUe4azd58aeD0Fr1fAFUYLPZuVLH/u+tk+EoIInm/vVUOZBhiewg4 X-Received: by 2002:a17:90a:e014:b0:2ae:c590:b06f with SMTP id 98e67ed59e1d1-2b6165a66b8mr657223a91.18.1715112728453; Tue, 07 May 2024 13:12:08 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1715112728; cv=pass; d=google.com; s=arc-20160816; b=vfR7dukcI206gtgMlXu70PfArJ0VGAx4YRSTJ+mDL09mZMiL+uCg1aY2OQtFd/2tvp d1uWIntBkMvnPGkHhRay5p3u1gdQwy+tNZ+PZhbVMRiR56EVPhOkaS9Tmt0SoaCpCS7L Z52disH2v1Z3pn6czclrsKM0ViwpN/rVULaem98LJjKWnmVGyWzrVtczW0cwbNWTQtOF bp9hyltsicLql9gdEeCzezY5xGgpFJQhfAC4GvuEqv0G32xLoGw7oxUJiHjuFEH+hv+R cDdH+o/0bzUVt/WeXuGWynj9IIBE5ZsgvI16hoWPtIuKdfCHiWmwayzOxu8JYsgr6Kbo zo9A== 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=qni3Yhd3ey4b88YK8j3DpMdzYme61RIbOY14L9yVuRQ=; fh=tk8sqZoIP78riW3PYc75n3+DQFkqFrW+9GPE0/sstVA=; b=z+bvdSup6rG+w1fLiwY8O5Vvh2TNxGKtRk8XmxcBYlzrltBcFv779SXrMtC5PHmONO GxpuZSpsNm+RvtuOCmzNshoTb6kvbKBMNuUQYFNyfxQqDJg9JPXapMkVjpIq9DbWyN8i GmbU6XQlHJ8NN7JQQMUV8cdc1jerDjXQrIbZCEVRW4/0NIZL8uaMGN5UAPXNlDjI5PQF hLMWYe61EtnJa5KQ6fep166ZtZTmlJYbjcQ3CXaNDVi2vWmOSbAX23kw+sBrNytG1gQx KVH33rrQXeUx8tqJae04M5VZyoRrqQ8k6LoU7rIAr/ja0mFv5Qr31XfiLdvdNCZrbi1j yAqw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=edgHcWry; 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-172110-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-172110-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Return-Path: Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id x14-20020a17090a530e00b002b6226adda0si11636pjh.53.2024.05.07.13.12.07 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 May 2024 13:12:08 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-172110-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=edgHcWry; 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-172110-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-172110-linux.lists.archive=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 sy.mirrors.kernel.org (Postfix) with ESMTPS id E1F5BB2594D for ; Tue, 7 May 2024 20:04:38 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5CD67184ED5; Tue, 7 May 2024 19:52:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="edgHcWry" Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.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 3ED5317EBAD; Tue, 7 May 2024 19:52:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715111535; cv=none; b=OGDVG0jVEg9N8Gb1wKPc8eJXshgMeNYZmH3AObIIHVnpAVVgh7hCewuWfQem8aRy/8l5GNuJL1lpYLkOkd5kvKQjl5U4pihVP72/gci9ugBDevM+Zqy7Zv714Ja0lTeRROth8iryxalZ9emJEhJxifmBQmS/DGoEOrBi7dO1ptY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1715111535; c=relaxed/simple; bh=ISNFv8W1cks7kD63ehVm1Nyct/Njy8ps9PMx9cwGJvQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Uvk3kdQSYsHOPX2ZoT7XSpTH9IfWvmpLewxdEzp1wIQTSAe209cnw/X6rGFzKgGXn1qhhsRVoGgwP5jCFF7/zEUZCmEkOMMHAaS91c/kI83tkw8ObXVzRz37vAvK16rYvftEweZcLVybc0qLm0HTlNe1JCYChi43PFeKrZoRO44= 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=edgHcWry; arc=none smtp.client-ip=205.220.168.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 (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 447IKHZr001553; Tue, 7 May 2024 19:51:36 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=qni3Yhd3ey4b88YK8j3D pMdzYme61RIbOY14L9yVuRQ=; b=edgHcWryR3cTkYM7J90C84UKs6UTuNNkDVdY f3TyhPAm2CofnCTy/W75HbTKnUaIICnbH/jpcdi/eGQEI4oe2BwLDxDTdYkIHL7Z X2j2NZrwXAvCnb7Cqpfj8vr7iQ4p8d2iHf2lez/B798WUDPHJGj9nDExunfH/evq dg9W2yUGXVN6ir2IDs+IMqDjYjEQghCXXJENZ4zDuGwzi9NITT8dBJwnVYk1KQNw ZdX1l6RmO9qC58bNiaAdEBuMixICvg74k6h4SRBSMQm+adC6eVFtBaknBP/153po imwYoS70CY9nFrUlMJ2pDI2alj+bhrqhM6sRMA5/ly/gWhed0A== Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3xysg405v7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 07 May 2024 19:51:36 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA04.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 447JpZa6019840 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 7 May 2024 19:51:35 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.1544.9; Tue, 7 May 2024 12:51:34 -0700 From: Wesley Cheng To: , , , , , , , , , , , , , , , CC: , , , , , , , Wesley Cheng Subject: [PATCH v21 28/39] ASoC: qcom: qdsp6: Add SOC USB offload select get/put callbacks Date: Tue, 7 May 2024 12:51:05 -0700 Message-ID: <20240507195116.9464-29-quic_wcheng@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240507195116.9464-1-quic_wcheng@quicinc.com> References: <20240507195116.9464-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 Content-Type: text/plain X-ClientProxiedBy: nalasex01a.na.qualcomm.com (10.47.209.196) 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: vehB6wrRddRDIr6PxL3TqH-8nKzIvWxu X-Proofpoint-ORIG-GUID: vehB6wrRddRDIr6PxL3TqH-8nKzIvWxu X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.650,FMLib:17.11.176.26 definitions=2024-05-07_12,2024-05-06_02,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 phishscore=0 spamscore=0 mlxlogscore=999 impostorscore=0 mlxscore=0 lowpriorityscore=0 clxscore=1015 malwarescore=0 priorityscore=1501 suspectscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2405010000 definitions=main-2405070138 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 | 115 +++++++++++++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 4 deletions(-) diff --git a/sound/soc/qcom/qdsp6/q6usb.c b/sound/soc/qcom/qdsp6/q6usb.c index 1e85636bc6cb..d83dbd10bdcc 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_supported_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_supported_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,70 @@ 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, + enum snd_soc_usb_kctl type) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct q6usb_port_data *data = dev_get_drvdata(component->dev); + int idx; + + mutex_lock(&data->mutex); + + if (!data->available_card_slot) { + idx = -1; + } else { + if (type == SND_SOC_USB_KCTL_CARD_ROUTE) + idx = data->sel_card_idx; + else + idx = data->sel_pcm_idx; + } + + ucontrol->value.integer.value[0] = idx; + mutex_unlock(&data->mutex); + + return 0; +} + +static int q6usb_put_offload_dev(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol, + enum snd_soc_usb_kctl type) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct q6usb_port_data *data = dev_get_drvdata(component->dev); + int changed = 0; + int idx; + + idx = ucontrol->value.integer.value[0]; + + mutex_lock(&data->mutex); + switch (type) { + case SND_SOC_USB_KCTL_CARD_ROUTE: + if (idx >= 0 && test_bit(idx, &data->available_card_slot)) { + data->sel_card_idx = idx; + changed = 1; + } + break; + case SND_SOC_USB_KCTL_PCM_ROUTE: + if (idx >= 0 && data->sel_card_idx >= 0 && + idx < data->status[data->sel_card_idx].sdev->num_playback) { + data->sel_pcm_idx = idx; + changed = 1; + } + break; + default: + break; + } + + 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 +208,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 +245,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 +310,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);