From nobody Tue Oct 7 14:59:15 2025 Received: from mailout2.samsung.com (mailout2.samsung.com [203.254.224.25]) (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 3A84614A8B for ; Wed, 9 Jul 2025 00:21:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=203.254.224.25 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752020518; cv=none; b=pTuhJUfxg8RpWEdDEFsl1E67KgeCMgkJe+JNiophxRPPeG35SdA3w44pvyr2a25WH6ZiKVmZcb8u1EYSE2nS4zZzpCEGu+clPlHDduDCyT97AnmaHEakBG/LFC1QUAjJRgpRV0e4LWoTPlH0TFz8RQKv9zxL2ks9aIbcNcqMa6I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1752020518; c=relaxed/simple; bh=xb+WjUz+lEEdvuqmh9rXRLz2uGGnmWbIOOnVKo/Xtgk=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version:Content-Type: References; b=mBBMMV80zyM5QrHJZR1PLzO+T6qnFjM/d4aJ8nWQ9FOFVz64bkDLqbEe/+m8llk8P75SmUYWVK2RUuE3hiE8jyfPfw8zSjq1DQLKun12pCFMN4/HlrGoSfgP7sVWvlewxjlnDvXNrMIfYibtkCQZ+s4TjXXYU2EolWjBog7rnnY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com; spf=pass smtp.mailfrom=samsung.com; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b=efs/NAjg; arc=none smtp.client-ip=203.254.224.25 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=samsung.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=samsung.com header.i=@samsung.com header.b="efs/NAjg" Received: from epcas2p3.samsung.com (unknown [182.195.41.55]) by mailout2.samsung.com (KnoxPortal) with ESMTP id 20250709002152epoutp027c002d47934faf2c4e9d291f6723bbdc~QbV_NrL3B2093120931epoutp02t for ; Wed, 9 Jul 2025 00:21:52 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20250709002152epoutp027c002d47934faf2c4e9d291f6723bbdc~QbV_NrL3B2093120931epoutp02t DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1752020512; bh=F6OYWVPAwdzfoNMORMWcRQkwJY9pihVX6JYS/KO/YSo=; h=From:To:Cc:Subject:Date:References:From; b=efs/NAjg5y5Bn131tVxPuYkyl5La99HWAGS4kOb/4nIW54ddMe7fmUPyAQQjLh2ou KuOT2m/Wr2WS14fBuvfvDZUDTT+yrha9VSDDadrVA/tAY/YP3S2fGfx3ns2iMWMI1R 8pnozXoKv840HbgdyVNyyeMeuuMmtjPYtrau5Lio= Received: from epsnrtp02.localdomain (unknown [182.195.42.154]) by epcas2p3.samsung.com (KnoxPortal) with ESMTPS id 20250709002151epcas2p3d16e2fa3daddbc27ec0ca5cb52c151eb~QbV9pPffb0865008650epcas2p3w; Wed, 9 Jul 2025 00:21:51 +0000 (GMT) Received: from epcas2p4.samsung.com (unknown [182.195.36.101]) by epsnrtp02.localdomain (Postfix) with ESMTP id 4bcJZ659c0z2SSKZ; Wed, 9 Jul 2025 00:21:50 +0000 (GMT) Received: from epsmtip1.samsung.com (unknown [182.195.34.30]) by epcas2p4.samsung.com (KnoxPortal) with ESMTPA id 20250709002150epcas2p467416bdbc16754726599a0cacb1feecc~QbV8S1R_a1045510455epcas2p4E; Wed, 9 Jul 2025 00:21:50 +0000 (GMT) Received: from AProject.dsn.sec.samsung.com (unknown [10.229.9.52]) by epsmtip1.samsung.com (KnoxPortal) with ESMTPA id 20250709002150epsmtip1065851fc540dddf908051e2e773133e6~QbV8Nnik_3069530695epsmtip1W; Wed, 9 Jul 2025 00:21:50 +0000 (GMT) From: ew.kim@samsung.com To: s.nawrocki@samsung.com, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com Cc: linux-sound@vger.kernel.org, alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, ew kim Subject: [PATCH] ASoC: samsung: Implement abox generic structure Date: Wed, 9 Jul 2025 09:10:02 +0900 Message-Id: <20250709001002.378246-1-ew.kim@samsung.com> X-Mailer: git-send-email 2.25.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CMS-MailID: 20250709002150epcas2p467416bdbc16754726599a0cacb1feecc X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-Sendblock-Type: AUTO_CONFIDENTIAL CMS-TYPE: 102P cpgsPolicy: CPGSC10-234,Y X-CFilter-Loop: Reflected X-CMS-RootMailID: 20250709002150epcas2p467416bdbc16754726599a0cacb1feecc References: From: ew kim Implemet basic abox generic drivers. This driver is a management driver for the generic drivers used in Automotive Abox, connecting them to SOC drivers. It supports various Exynos Automotive SOCs. Signed-off-by: ew kim --- sound/soc/samsung/Kconfig | 2 + sound/soc/samsung/Makefile | 1 + sound/soc/samsung/auto_abox/Kconfig | 14 + sound/soc/samsung/auto_abox/generic/Kbuild | 12 + .../samsung/auto_abox/generic/abox_generic.c | 568 ++++++++++++++++++ .../auto_abox/generic/include/abox_generic.h | 87 +++ 6 files changed, 684 insertions(+) create mode 100644 sound/soc/samsung/auto_abox/Kconfig create mode 100644 sound/soc/samsung/auto_abox/generic/Kbuild create mode 100644 sound/soc/samsung/auto_abox/generic/abox_generic.c create mode 100644 sound/soc/samsung/auto_abox/generic/include/abox_generi= c.h diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 60b4b7b75215..359aa67f49db 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -148,4 +148,6 @@ config SND_SOC_SAMSUNG_MIDAS_WM1811 help Say Y if you want to add support for SoC audio on the Midas boards. =20 +source "sound/soc/samsung/auto_abox/Kconfig" + endif #SND_SOC_SAMSUNG diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 8d5f09147900..5d99cfbfa71c 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -42,3 +42,4 @@ obj-$(CONFIG_SND_SOC_ARNDALE) +=3D snd-soc-arndale.o obj-$(CONFIG_SND_SOC_SAMSUNG_TM2_WM5110) +=3D snd-soc-tm2-wm5110.o obj-$(CONFIG_SND_SOC_SAMSUNG_ARIES_WM8994) +=3D snd-soc-aries-wm8994.o obj-$(CONFIG_SND_SOC_SAMSUNG_MIDAS_WM1811) +=3D snd-soc-midas-wm1811.o +obj-$(CONFIG_SND_SOC_SAMSUNG_AUTO_ABOX) +=3D auto_abox/generic/ \ No newline at end of file diff --git a/sound/soc/samsung/auto_abox/Kconfig b/sound/soc/samsung/auto_a= box/Kconfig new file mode 100644 index 000000000000..d5f565d3d9c2 --- /dev/null +++ b/sound/soc/samsung/auto_abox/Kconfig @@ -0,0 +1,14 @@ +#: SPDX-License-Identifier: GPL-2.0-only + +menu "Exynosauto Automotive Abox Modules Options" + +config SND_SOC_SAMSUNG_AUTO_ABOX + tristate "ASoC support for Samsung Exynosauto Automotive ABOX Audio" + select SND_SOC_COMPRESS + help + Say Y or M if you want to add support for codecs attached to + the Samsung SoC Auto ABOX interface. You will also need to + select the audio interfaces to support below. + +endmenu + diff --git a/sound/soc/samsung/auto_abox/generic/Kbuild b/sound/soc/samsung= /auto_abox/generic/Kbuild new file mode 100644 index 000000000000..fa6ba7091730 --- /dev/null +++ b/sound/soc/samsung/auto_abox/generic/Kbuild @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0 +# Exynosauto Automotive Abox Driver Support + +snd-soc-samsung-abox-generic-$(CONFIG_SND_SOC_SAMSUNG_AUTO_ABOX) :=3D \ + abox_generic.o + +ccflags-y +=3D -I./include + +obj-$(CONFIG_SND_SOC_SAMSUNG_AUTO_ABOX) +=3D \ + snd-soc-samsung-abox-generic.o + + diff --git a/sound/soc/samsung/auto_abox/generic/abox_generic.c b/sound/soc= /samsung/auto_abox/generic/abox_generic.c new file mode 100644 index 000000000000..c4588e0a6a60 --- /dev/null +++ b/sound/soc/samsung/auto_abox/generic/abox_generic.c @@ -0,0 +1,568 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * http://www.samsung.com/ + * + * EXYNOS - sound/soc/samsung/auto_abox/generic/abox_generic.c + */ + +//#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "include/abox_generic.h" + +static struct abox_generic_data *g_abox_generic_data; + +/** + * @cnotice + * @prdcode + * @Sub_SW_Component{abox_generic} + * @ALM_Link {work item url} + * @purpose "get value from virtual address" + * @logic "return global abox_generic_data" + * \image html + * @params + * @param{in, -, -, -} + * @endparam + * @retval {-, struct *abox_generic_data, !NULL, NULL} + */ +struct abox_generic_data *abox_generic_get_abox_generic_data(void) +{ + return g_abox_generic_data; +} + +static struct abox_generic_data *abox_generic_get_generic_data_from_child(= struct device *child_dev) +{ + struct device *generic_dev =3D child_dev->parent; + struct abox_generic_data *generic_data =3D NULL; + + if (!generic_dev) { + pr_err("%s Failed to get generic device\n", __func__); + return NULL; + } + generic_data =3D dev_get_drvdata(generic_dev); + if (!generic_data) { + dev_err(generic_dev, "%s Failed to get generic data\n", __func__); + return NULL; + } + return generic_data; +} + +int abox_generic_set_dma_buffer(struct device *pcm_dev) +{ + struct abox_generic_data *generic_data =3D abox_generic_get_generic_data_= from_child(pcm_dev); + int ret =3D 0; + + if (!generic_data) { + dev_err(pcm_dev, "%s Failed to get generic data\n", __func__); + return 0; + } + + if (!generic_data->soc_ioctl) { + dev_err(pcm_dev, "%s Failed to get soc_ioctl\n", __func__); + return 0; + } + ret =3D generic_data->soc_ioctl(generic_data->soc_dev, ABOX_SOC_IOCTL_SET= _DMA_BUFFER, pcm_dev); + + return ret; +} + +int abox_generic_set_pp_pointer(struct device *pcm_dev) +{ + struct abox_generic_data *generic_data =3D abox_generic_get_generic_data_= from_child(pcm_dev); + int ret =3D 0; + + if (!generic_data) { + dev_err(pcm_dev, "%s Failed to get generic data\n", __func__); + return 0; + } + if (!generic_data->soc_ioctl) { + dev_err(pcm_dev, "%s Failed to get soc_ioctl\n", __func__); + return 0; + } + ret =3D generic_data->soc_ioctl(generic_data->soc_dev, ABOX_SOC_IOCTL_SET= _PP_POINTER, pcm_dev); + + return ret; +} + +int abox_generic_attach_soc_callback(struct device *soc_dev, + SOC_IOCTL soc_ioctl) +{ + struct abox_generic_data *generic_data =3D ABOX_GENERIC_DATA; + + dev_info(soc_dev, "%s(%d) Attach SoC IOCTL\n", __func__, __LINE__); + if (!generic_data) { + dev_err(soc_dev, "%s Generic Drv is not ready\n", __func__); + return -ENODATA; + } + generic_data->soc_dev =3D soc_dev; + generic_data->soc_ioctl =3D soc_ioctl; + + generic_data->num_of_rdma =3D generic_data->soc_ioctl(generic_data->soc_d= ev, + ABOX_SOC_IOCTL_GET_NUM_OF_RDMA, NULL); + generic_data->num_of_wdma =3D generic_data->soc_ioctl(generic_data->soc_d= ev, + ABOX_SOC_IOCTL_GET_NUM_OF_WDMA, NULL); + generic_data->num_of_uaif =3D generic_data->soc_ioctl(generic_data->soc_d= ev, + ABOX_SOC_IOCTL_GET_NUM_OF_UAIF, NULL); + dev_info(soc_dev, "%s(%d) num_of_rdma:%d\n", __func__, __LINE__, generic_= data->num_of_rdma); + dev_info(soc_dev, "%s(%d) num_of_wdma:%d\n", __func__, __LINE__, generic_= data->num_of_wdma); + dev_info(soc_dev, "%s(%d) num_of_uaif:%d\n", __func__, __LINE__, generic_= data->num_of_uaif); + + return 0; +} +EXPORT_SYMBOL(abox_generic_attach_soc_callback); + +struct platform_device *abox_generic_get_pcm_platform_dev(int pcm_id, int = stream_type) +{ + struct abox_generic_data *generic_data =3D ABOX_GENERIC_DATA; + struct platform_device **pdev_pcm =3D NULL; + + if (stream_type =3D=3D SNDRV_PCM_STREAM_PLAYBACK) + pdev_pcm =3D generic_data->pdev_pcm_playback; + else + pdev_pcm =3D generic_data->pdev_pcm_capture; + + return pdev_pcm[pcm_id]; +} +EXPORT_SYMBOL(abox_generic_get_pcm_platform_dev); + +int abox_generic_get_num_of_pcm(int stream_type) +{ + struct abox_generic_data *generic_data =3D ABOX_GENERIC_DATA; + + if (!generic_data) { + pr_err("%s Failed to get abox_generic_data\n", __func__); + return -ENODATA; + } + + return (stream_type =3D=3D SNDRV_PCM_STREAM_PLAYBACK) ? generic_data->num= _of_pcm_playback : + generic_data->num_of_pcm_capture; +} +EXPORT_SYMBOL(abox_generic_get_num_of_pcm); + +int abox_generic_get_num_of_i2s_dummy(void) +{ + struct abox_generic_data *generic_data =3D ABOX_GENERIC_DATA; + + if (!generic_data) { + pr_err("%s Failed to get abox_generic_data\n", __func__); + return -ENODATA; + } + + return generic_data->num_of_i2s_dummy; +} +EXPORT_SYMBOL(abox_generic_get_num_of_i2s_dummy); + +int abox_generic_get_num_of_dma(struct device *pcm_dev, int stream_type) +{ + struct abox_generic_data *generic_data =3D abox_generic_get_generic_data_= from_child(pcm_dev); + + return (stream_type =3D=3D SNDRV_PCM_STREAM_PLAYBACK) ? + generic_data->num_of_rdma : generic_data->num_of_wdma; +} + +/** + * @cnotice + * @prdcode + * @Sub_SW_Component{abox generic} + * @ALM_Link {work item url} + * @purpose "Registering the pcm_playback/pcm_capture pdev to abox driver" + * @logic "Get the pcm playback instance and update the pcm playback/captu= re id and + * increament the pcm playback/capture count" + * \image html + * @params + * @param{in, pdev_pcm_dev, struct platform_device *, !NULL} + * @param{in, id, unsigned int, 0 ~ 32} + * @param{in, stream_type, int, 0 ~ 1} + * @endparam + * @retval{ret, int, Undefined, 0, <0} + */ +int abox_generic_register_pcm_dev(struct platform_device *pdev_pcm, + unsigned int id, int stream_type) +{ + struct device *pcm_dev =3D &pdev_pcm->dev; + struct abox_generic_data *generic_data =3D abox_generic_get_generic_data_= from_child(pcm_dev); + int num_of_pcm_dev =3D 0; + + dev_dbg(pcm_dev, "[%s] PCM%d Attached Stream_type:%d\n", __func__, id, st= ream_type); + num_of_pcm_dev =3D (stream_type =3D=3D SNDRV_PCM_STREAM_PLAYBACK) ? + generic_data->num_of_pcm_playback : generic_data->num_of_pcm_capture; + if (id >=3D num_of_pcm_dev) { + dev_err(pcm_dev, "%s: invalid id(%u) : Stream Type:%d\n", __func__, id, = stream_type); + return -EINVAL; + } + + if (stream_type =3D=3D SNDRV_PCM_STREAM_PLAYBACK) + generic_data->pdev_pcm_playback[id] =3D pdev_pcm; + else + generic_data->pdev_pcm_capture[id] =3D pdev_pcm; + + return 0; +} + +/** + * @cnotice + * @prdcode + * @Sub_SW_Component{abox} + * @ALM_Link {work item url} + * @purpose "finding struct device of frontend from backend" + * @logic "get device of backend using component and alsa macro" + * \image html audio-interface_abox_abox_find_fe_dev_from_rtd.png + * @params + * @param{in, be, struct snd_soc_pcm_runtime *, -} + * @endparam + * @retval {-, struct device *, !NULL, NULL} + */ +struct device *abox_generic_find_fe_dev_from_rtd(struct snd_soc_pcm_runtim= e *be) +{ + struct abox_generic_data *generic_data =3D ABOX_GENERIC_DATA; + struct snd_soc_dpcm *dpcm =3D NULL; + struct snd_soc_pcm_runtime *fe =3D NULL; + int stream_type =3D 0; + + if (!generic_data) + return NULL; + + for (stream_type =3D 0; stream_type <=3D SNDRV_PCM_STREAM_LAST; stream_ty= pe++) { + int cmpnt_index =3D 0; + struct snd_soc_component *component =3D NULL; + + for_each_dpcm_fe(be, stream_type, dpcm) { + fe =3D dpcm->fe; + if (fe) + break; + } + if (!fe) + continue; + + for_each_rtd_components(fe, cmpnt_index, component) { + struct platform_device **pdev =3D NULL; + int num_of_pcm_dev =3D 0; + int i =3D 0; + + if (stream_type =3D=3D SNDRV_PCM_STREAM_PLAYBACK) { + num_of_pcm_dev =3D generic_data->num_of_pcm_playback; + pdev =3D generic_data->pdev_pcm_playback; + } else { + num_of_pcm_dev =3D generic_data->num_of_pcm_capture; + pdev =3D generic_data->pdev_pcm_capture; + } + for (i =3D 0; i < num_of_pcm_dev; i++) + if (pdev[i] && component->dev =3D=3D &pdev[i]->dev) + return component->dev; + } + } + + return NULL; +} +EXPORT_SYMBOL_GPL(abox_generic_find_fe_dev_from_rtd); + +int abox_generic_request_soc_ioctl(struct device *generic_dev, enum abox_s= oc_ioctl_cmd cmd, + void *data) +{ + struct abox_generic_data *generic_data =3D dev_get_drvdata(generic_dev); + struct device *soc_dev =3D generic_data->soc_dev; + + if (IS_ERR_OR_NULL(soc_dev)) { + dev_err(generic_dev, "%s SoC Device is not ready\n", __func__); + return -ENODATA; + } + return generic_data->soc_ioctl(soc_dev, cmd, data); +} + +/** + * @cnotice + * @prdcode + * @Sub_SW_Component{abox generic} + * @ALM_Link + * @purpose "suspend of the abox generic to be called by S2R" + * @logic + * \image html + * @params + * @param{in, dev, struct device *, !NULL} + * @endparam + * @retval{ret, int, Undefined, 0, <0} + */ +static int abox_generic_suspend(struct device *dev) +{ + struct abox_generic_data *data =3D dev_get_drvdata(dev); + int ret =3D 0; + + dev_info(dev, "%s start\n", __func__); + if (!data) { + dev_err(dev, "%s: Invalid abox generic data\n", __func__); + return -ENODATA; + } + + dev_info(dev, "%s end\n", __func__); + + return ret; +} + +/** + * @cnotice + * @prdcode + * @Sub_SW_Component{abox generic} + * @ALM_Link + * @purpose "Resume the abox generic during S2R operation" + * @logic + * \image html + * @params + * @param{in, dev, struct device *, !NULL} + * @endparam + * @retval{ret, int, Undefined, 0, <0} + */ +static int abox_generic_resume(struct device *dev) +{ + struct abox_generic_data *data =3D dev_get_drvdata(dev); + int ret =3D 0; + + dev_info(dev, "%s start\n", __func__); + if (!data) { + dev_err(dev, "%s: Invalid abox generic data\n", __func__); + return -ENODATA; + } + + dev_info(dev, "%s end\n", __func__); + return ret; +} + +static struct platform_driver *abox_generic_sub_drivers[] =3D { +}; + +/** + * @cnotice + * @prdcode + * @Sub_SW_Component{abox} + * @ALM_Link {work item url} + * @purpose "Read property from device tree node" + * @logic + * \image html + * @params + * @param{in, dev, struct:: device *, !NULL} + * @param{in, dev->of_node, struct:: device_node, !NULL} + * @param{out, data->num_of_pcm_playback, unsigned int, 0} + * @param{out, data->num_of_pcm_capture, unsigned int, 0} + * @param{out, data->num_of_i2s_dummy, unsigned int, 0} + * @param{out, abox_sfr_set, int, 0} + * @endparam + * @retval{ret, int, 0, 0, > 0} + */ +static int abox_generic_read_property_from_dt(struct device *dev, struct a= box_generic_data *data) +{ + struct device_node *np =3D dev->of_node; + int ret =3D 0; + + ret =3D of_property_read_u32(np, "samsung,num-of-pcm_playback", &data->nu= m_of_pcm_playback); + if (ret < 0) { + dev_err(dev, "%s property reading fail\n", "samsung,num-of-pcm_playback"= ); + return ret; + } + ret =3D of_property_read_u32(np, "samsung,num-of-pcm_capture", &data->num= _of_pcm_capture); + if (ret < 0) { + dev_err(dev, "%s property reading fail\n", "samsung,num-of-pcm_capture"); + return ret; + } + ret =3D of_property_read_u32(np, "samsung,num-of-i2s-dummy-backend", &dat= a->num_of_i2s_dummy); + if (ret < 0) { + dev_err(dev, "%s property reading fail\n", "samsung,num-of-i2s-dummy-bac= kend"); + return ret; + } + + return ret; +} + +/** + * @cnotice + * @prdcode + * @Sub_SW_Component{abox generic} + * @ALM_Link {work item url} + * @purpose "Allocate memory for abox generic" + * @logic + * \image html + * @params + * @param{in, dev, struct:: device *, !NULL} + * @param{in, data, struct:: abox_gneric_data, !NULL} + * @param{out, data->pdev_pcm_playback, struct:: platform_device, !NULL} + * @param{out, data->pdev_pcm_capture, struct:: platform_device, !NULL} + * @endparam + * @retval{ret, int, 0, 0, > 0} + */ +static int abox_generic_allocate_memory(struct device *dev, struct abox_ge= neric_data *data) +{ + int ret =3D 0; + + data->pdev_pcm_playback =3D devm_kzalloc(dev, + sizeof(struct platform_device *) * data->num_of_pcm_playback, GFP_KERNEL= ); + if (!data->pdev_pcm_playback) { + dev_err(dev, "%s Can't allocate memory for pdev_pcm_playback\n", __func_= _); + ret =3D -ENOMEM; + return ret; + } + data->pdev_pcm_capture =3D devm_kzalloc(dev, + sizeof(struct platform_device *) * data->num_of_pcm_capture, GFP_KERNEL); + if (!data->pdev_pcm_capture) { + dev_err(dev, "%s Can't allocate memory for pdev_pcm_capture\n", __func__= ); + ret =3D -ENOMEM; + return ret; + } + + return ret; +} + +/** + * @cnotice + * @prdcode + * @Sub_SW_Component{abox generic} + * @ALM_Link {work item url} + * @purpose "Probing the abox generic" + * @logic + * \image html + * @params + * @param{in, pdev, struct platform_device *, !NULL} + * @param{in, pdev->dev, struct:: device, !NULL} + * @endparam + * @retval{ret, int, 0, 0, > 0} + */ +static int samsung_abox_generic_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct device_node *np =3D dev->of_node; + struct abox_generic_data *data; + int ret =3D 0; + + dev_info(dev, "%s\n", __func__); + data =3D devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) { + return -ENOMEM; + } + + data->pdev =3D pdev; + ret =3D abox_generic_read_property_from_dt(dev, data); + if (ret < 0) { + dev_err(dev, "%s Failed to read property. ret:%d\n", __func__, ret); + return ret; + } + ret =3D abox_generic_allocate_memory(dev, data); + if (ret < 0) { + dev_err(dev, "%s Failed to allocate memory. ret:%d\n", __func__, ret); + return ret; + } + g_abox_generic_data =3D data; + platform_set_drvdata(pdev, data); + + platform_register_drivers(abox_generic_sub_drivers, ARRAY_SIZE(abox_gener= ic_sub_drivers)); + ret =3D of_platform_populate(np, NULL, NULL, dev); + if (ret < 0) { + dev_err(dev, "Failed to populate sub-platform_devices. ret:%d\n", ret); + return ret; + } + + return ret; +} + +/** + * @cnotice + * @prdcode + * @Sub_SW_Component{abox generic} + * @ALM_Link {work item url} + * @purpose "Disbaling the abox generic" + * @logic "Disbale the abox generic" + * \image html + * @params + * @param{in, pdev->dev, struct::device, !NULL} + * @endparam + * @noret + */ +static void samsung_abox_generic_remove(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct abox_generic_data *data =3D dev_get_drvdata(dev); + + dev_info(dev, "%s\n", __func__); + + if (!data) { + dev_err(dev, "%s: Invalid abox generic data\n", __func__); + return; + } + return; +} + +/** + * @cnotice + * @prdcode + * @Sub_SW_Component{abox generic} + * @ALM_Link {work item url} + * @purpose "shutdown of the abox generic" + * @logic "Disbale the abox hardware by calling the following function + * pm_runtime_disable(dev)" + * \image html + * @params + * @param{in, pdev->dev, struct:: device, !NULL} + * @endparam + * @noret + */ +static void samsung_abox_generic_shutdown(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct abox_generic_data *data =3D dev_get_drvdata(dev); + + if (!data) { + dev_err(dev, "%s: Invalid abox generic data\n", __func__); + return; + } + return; +} + +static const struct of_device_id samsung_abox_generic_match[] =3D { + { + .compatible =3D "samsung,abox_generic", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, samsung_abox_generic_match); + +static const struct dev_pm_ops samsung_abox_generic_pm =3D { + SET_SYSTEM_SLEEP_PM_OPS(abox_generic_suspend, abox_generic_resume) +}; + +struct platform_driver samsung_abox_generic_driver =3D { + .probe =3D samsung_abox_generic_probe, + .remove =3D samsung_abox_generic_remove, + .shutdown =3D samsung_abox_generic_shutdown, + .driver =3D { + .name =3D "samsung-abox-generic", + .owner =3D THIS_MODULE, + .of_match_table =3D of_match_ptr(samsung_abox_generic_match), + .pm =3D &samsung_abox_generic_pm, + }, +}; + +module_platform_driver(samsung_abox_generic_driver); +/* Module information */ +MODULE_AUTHOR("Eunwoo Kim, "); +MODULE_DESCRIPTION("Samsung ASoC A-Box Generic Driver"); +MODULE_ALIAS("platform:samsung-abox-generic"); +MODULE_LICENSE("GPL v2"); + diff --git a/sound/soc/samsung/auto_abox/generic/include/abox_generic.h b/s= ound/soc/samsung/auto_abox/generic/include/abox_generic.h new file mode 100644 index 000000000000..1c954272e2b5 --- /dev/null +++ b/sound/soc/samsung/auto_abox/generic/include/abox_generic.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * ALSA SoC - Samsung ABOX Share Function and Data structure + * for Exynos specific extensions + * + * Copyright (C) 2013-2020 Samsung Electronics Co., Ltd. + * + * EXYNOS - sound/soc/samsung/abox/include/abox_generic.h + */ + +#ifndef __SND_SOC_ABOX_GENERIC_BASE_H +#define __SND_SOC_ABOX_GENERIC_BASE_H + +#define ABOX_GENERIC_DATA abox_generic_get_abox_generic_data(); + +struct snd_soc_pcm_runtime; + +enum abox_soc_ioctl_cmd { + ABOX_SOC_IOCTL_GET_NUM_OF_RDMA, + ABOX_SOC_IOCTL_GET_NUM_OF_WDMA, + ABOX_SOC_IOCTL_GET_NUM_OF_UAIF, + ABOX_SOC_IOCTL_GET_SOC_TIMER, + ABOX_SOC_IOCTL_SET_DMA_BUFFER, + ABOX_SOC_IOCTL_SET_PP_POINTER, + ABOX_SOC_IOCTL_SET_PERF_PERIOD, + ABOX_SOC_IOCTL_CHECK_TIME_MUTEX, + ABOX_SOC_IOCTL_CHECK_TIME_NO_MUTEX, + ABOX_SOC_IOCTL_PCM_DUMP_INTR, + ABOX_SOC_IOCTL_PCM_DUMP_CLOSE, + ABOX_SOC_IOCTL_PCM_DUMP_ADD_CONTROL, + ABOX_SOC_IOCTL_MAX +}; + +typedef int (*SOC_IOCTL)(struct device *soc_dev, enum abox_soc_ioctl_cmd c= md, void *data); + +struct abox_generic_data { + struct platform_device *pdev; + struct platform_device **pdev_pcm_playback; + struct platform_device **pdev_pcm_capture; + unsigned int num_of_pcm_playback; + unsigned int num_of_pcm_capture; + unsigned int num_of_i2s_dummy; + unsigned int num_of_rdma; + unsigned int num_of_wdma; + unsigned int num_of_uaif; + struct device *soc_dev; + SOC_IOCTL soc_ioctl; +}; + + +/************ Internal API ************/ + +struct abox_generic_data *abox_generic_get_abox_generic_data(void); + +int abox_generic_set_dma_buffer(struct device *pcm_dev); + +int abox_generic_request_soc_ioctl(struct device *generic_dev, enum abox_s= oc_ioctl_cmd cmd, + void *data); + +int abox_generic_set_pp_pointer(struct device *pcm_dev); + + + + +/************ External API ************/ + +extern struct device *abox_generic_find_fe_dev_from_rtd(struct snd_soc_pcm= _runtime *be); + +extern struct platform_device *abox_generic_get_pcm_platform_dev(int pcm_i= d, + int stream_type); + +extern int abox_generic_get_num_of_pcm(int stream_type); + +extern int abox_generic_get_num_of_i2s_dummy(void); + +extern int abox_generic_get_num_of_dma(struct device *pcm_dev, + int stream_type); + +extern int abox_generic_attach_soc_callback(struct device *soc_dev, + SOC_IOCTL soc_ioctl); + +extern int abox_generic_register_pcm_dev(struct platform_device *pdev_pcm_= dev, + unsigned int id, int stream_type); + + +#endif //__SND_SOC_ABOX_GENERIC_BASE_H + --=20 2.25.1