From patchwork Tue Jan 2 21:45:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wesley Cheng X-Patchwork-Id: 184475 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:6f82:b0:100:9c79:88ff with SMTP id tb2csp4699302dyb; Tue, 2 Jan 2024 13:48:07 -0800 (PST) X-Google-Smtp-Source: AGHT+IEkDToHzemVH9WXFwgyiBUP5DSIftMvtqsLL+0N2e86Y5cecHiPoyGPhp5ffvlgPuSqB9ES X-Received: by 2002:a05:6e02:1be4:b0:35f:f678:a520 with SMTP id y4-20020a056e021be400b0035ff678a520mr21492751ilv.13.1704232087370; Tue, 02 Jan 2024 13:48:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1704232087; cv=none; d=google.com; s=arc-20160816; b=l3+/GOHM/sb/PTQIYXRFpL9BnGbrJyAhPOCH+/S103rEnAaTyGXVbBCGVheuepYXBx dnFaYW7b2EsZ6qnQYr8PJhJQ0/WaBi5ujUeX7RFtjqBokrNYsNP+pth8w2FTJMkWI2lo GR/xzyUw4KCv+6IhOr7aqSxSggpBjCMYzXyjEH/DUwZKldDqSTCDbZ8i9CXRvqEX0DKi k2IUW3jaPntIE2ojLkXkwmTGfrHynudUQw6OBvbS1rlCzWeF8Gxn7EmYyZZzPvCJ4b4E LHTXmXaqzBS2941izRZFZ0BqkvKHy4GVuXM5p+hiBwGcxx5sYGZhEAqF26fGjbnE218k 6QTA== ARC-Message-Signature: i=1; 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=0KzismZj+xI0Z//ZGdqKIH/FO9LtSZM7Yj4P0VtrCz0=; b=Tt1pGp6R2n1lsWr3GEIeGJRnovi3hEyhDRaL+oqB+ppu5WE7Voyn43lL+s6dopMvXG N8Z6CDvVArHxPjz5/z0bFFtWaQyIOwGi1g7uKRMkr6VhI25GhDxWnzq8dtZjSkk5liSE SsbLoatZIgpMK9V2Fg9nq69SZA7rfRFr87wOMQ6ay15Cj6x7zFIq6DogwSZKsoumriqc M0If6h9878RN6CfFu48ukZWH06DTHXDsjz3DPBB/sYKSxSsKqa23qsH8QOwekaXquQy7 Av97pO9PKA384jxgWyot+vzIxBtjhqp1O/uqA4gB/dNrldRryH9/ZBPZDOwi0iT7Rgqs 0Tgg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=Agz1sCNz; spf=pass (google.com: domain of linux-kernel+bounces-14862-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-14862-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=quicinc.com Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [139.178.88.99]) by mx.google.com with ESMTPS id n188-20020a6327c5000000b0059779ae58a0si19023100pgn.465.2024.01.02.13.48.07 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 02 Jan 2024 13:48:07 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-14862-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) client-ip=139.178.88.99; Authentication-Results: mx.google.com; dkim=pass header.i=@quicinc.com header.s=qcppdkim1 header.b=Agz1sCNz; spf=pass (google.com: domain of linux-kernel+bounces-14862-ouuuleilei=gmail.com@vger.kernel.org designates 139.178.88.99 as permitted sender) smtp.mailfrom="linux-kernel+bounces-14862-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 sv.mirrors.kernel.org (Postfix) with ESMTPS id D4FA32845D5 for ; Tue, 2 Jan 2024 21:48:06 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 809881802E; Tue, 2 Jan 2024 21:46:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=quicinc.com header.i=@quicinc.com header.b="Agz1sCNz" X-Original-To: linux-kernel@vger.kernel.org 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 55C60168A8; Tue, 2 Jan 2024 21:46:40 +0000 (UTC) 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 (m0279865.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 402LcmkW011270; Tue, 2 Jan 2024 21:46:28 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=Agz1sCNzrL0pnrn0aE9LHUiRdIgAoN9t2OrD weXQGXMR8MXltY/InpFTgcPaxa3kjnPeIi23iCbLQFK3L4MLHQzqvqYzUBE5RKmw Ke9skUdLnhhTRczk1UbF460UkhRu+ero3lRRTn7jyAWDZfuSahbOJegB+XRrMy+X Pshc55+SPtOk5BGEB8lws4Oc7ZC9xqfmHZ7RpVLMsJNQlXDVELGp5eQFwWGX1arX x++Bri+4Bdm/WF8hJAtJKN9A9uvzqCVX5iYjUFTpxdMX78aA64DmM06msBzMaOwG RGoLoplbjXuMuszu3u67RrR4IjPO8BdEkMC7LoRVHvq6NZxtxA== Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3vcets9g2u-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 02 Jan 2024 21:46:27 +0000 (GMT) Received: from nalasex01b.na.qualcomm.com (nalasex01b.na.qualcomm.com [10.47.209.197]) by NALASPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 402LkRgW003274 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 2 Jan 2024 21:46:27 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; Tue, 2 Jan 2024 13:46:26 -0800 From: Wesley Cheng To: , , , , , , , , , , , , , , , CC: , , , , , , , Wesley Cheng Subject: [PATCH v12 30/41] ASoC: qcom: qdsp6: Add SOC USB offload select get/put callbacks Date: Tue, 2 Jan 2024 13:45:38 -0800 Message-ID: <20240102214549.22498-31-quic_wcheng@quicinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20240102214549.22498-1-quic_wcheng@quicinc.com> References: <20240102214549.22498-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: nalasex01c.na.qualcomm.com (10.47.97.35) 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-ORIG-GUID: D4tM0_W4R2NuTeMe_-VE9RE02O5jOHGp X-Proofpoint-GUID: D4tM0_W4R2NuTeMe_-VE9RE02O5jOHGp X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-12-09_01,2023-12-07_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 suspectscore=0 bulkscore=0 clxscore=1015 priorityscore=1501 spamscore=0 lowpriorityscore=0 phishscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2311290000 definitions=main-2401020161 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1787016865109152687 X-GMAIL-MSGID: 1787016865109152687 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);