Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Create a new sound card to access MICFIL based on rpmsg channel

Merge series from Chancel Liu <chancel.liu@nxp.com>:

At a previous time, we have successfully created a virtual sound card
based on rpmsg. The sound card works under this mechanism Cortex-A core
tells the Cortex-M core the format, rate, channel, .etc configuration
of the PCM parameters and Cortex-M controls real hardware devices such
as SAI and DMA. From the view of Linux side, the sound card is bound to
a rpmsg channel through which it can access SAI.

Here these patches are introduced to create a new virtual sound card to
access MICFIL based on a new created rpmsg channel. It's easy to create
a new rpmsg channel for MICFIL through rpmsg name service announcment.
Also the other ASoC components bound to this rpmsg MICFIL sound card
will be registered with these patches.

If other sound cards using different hardware devices needs to be
created over rpmsg in the future, these patches can be referred.

+51 -10
+34 -2
Documentation/devicetree/bindings/sound/fsl,rpmsg.yaml
··· 11 11 12 12 description: | 13 13 fsl_rpmsg is a virtual audio device. Mapping to real hardware devices 14 - are SAI, DMA controlled by Cortex M core. What we see from Linux 15 - side is a device which provides audio service by rpmsg channel. 14 + are SAI, MICFIL, DMA controlled by Cortex M core. What we see from 15 + Linux side is a device which provides audio service by rpmsg channel. 16 + We can create different sound cards which access different hardwares 17 + such as SAI, MICFIL, .etc through building rpmsg channels between 18 + Cortex-A and Cortex-M. 16 19 17 20 properties: 18 21 compatible: ··· 88 85 This is a boolean property. If present, the receiving function 89 86 will be enabled. 90 87 88 + fsl,rpmsg-channel-name: 89 + $ref: /schemas/types.yaml#/definitions/string 90 + description: | 91 + A string property to assign rpmsg channel this sound card sits on. 92 + This property can be omitted if there is only one sound card and it sits 93 + on "rpmsg-audio-channel". 94 + enum: 95 + - rpmsg-audio-channel 96 + - rpmsg-micfil-channel 97 + 91 98 required: 92 99 - compatible 93 100 - model ··· 120 107 <&clk IMX8MN_AUDIO_PLL2_OUT>; 121 108 clock-names = "ipg", "mclk", "dma", "pll8k", "pll11k"; 122 109 }; 110 + 111 + - | 112 + #include <dt-bindings/clock/imx8mm-clock.h> 113 + 114 + rpmsg_micfil: audio-controller { 115 + compatible = "fsl,imx8mm-rpmsg-audio"; 116 + model = "micfil-audio"; 117 + fsl,rpmsg-channel-name = "rpmsg-micfil-channel"; 118 + fsl,enable-lpa; 119 + fsl,rpmsg-in; 120 + clocks = <&clk IMX8MM_CLK_PDM_IPG>, 121 + <&clk IMX8MM_CLK_PDM_ROOT>, 122 + <&clk IMX8MM_CLK_SDMA3_ROOT>, 123 + <&clk IMX8MM_AUDIO_PLL1_OUT>, 124 + <&clk IMX8MM_AUDIO_PLL2_OUT>; 125 + clock-names = "ipg", "mclk", "dma", "pll8k", "pll11k"; 126 + }; 127 + 128 + ...
+3 -3
sound/soc/fsl/fsl_rpmsg.c
··· 117 117 .playback = { 118 118 .stream_name = "CPU-Playback", 119 119 .channels_min = 2, 120 - .channels_max = 2, 120 + .channels_max = 32, 121 121 .rates = SNDRV_PCM_RATE_KNOT, 122 122 .formats = FSL_RPMSG_FORMATS, 123 123 }, 124 124 .capture = { 125 125 .stream_name = "CPU-Capture", 126 126 .channels_min = 2, 127 - .channels_max = 2, 127 + .channels_max = 32, 128 128 .rates = SNDRV_PCM_RATE_KNOT, 129 129 .formats = FSL_RPMSG_FORMATS, 130 130 }, ··· 235 235 236 236 rpmsg->card_pdev = platform_device_register_data(&pdev->dev, 237 237 "imx-audio-rpmsg", 238 - PLATFORM_DEVID_NONE, 238 + PLATFORM_DEVID_AUTO, 239 239 NULL, 240 240 0); 241 241 if (IS_ERR(rpmsg->card_pdev)) {
+2 -1
sound/soc/fsl/imx-audio-rpmsg.c
··· 88 88 /* Register platform driver for rpmsg routine */ 89 89 data->rpmsg_pdev = platform_device_register_data(&rpdev->dev, 90 90 IMX_PCM_DRV_NAME, 91 - PLATFORM_DEVID_NONE, 91 + PLATFORM_DEVID_AUTO, 92 92 NULL, 0); 93 93 if (IS_ERR(data->rpmsg_pdev)) { 94 94 dev_err(&rpdev->dev, "failed to register rpmsg platform.\n"); ··· 110 110 111 111 static struct rpmsg_device_id imx_audio_rpmsg_id_table[] = { 112 112 { .name = "rpmsg-audio-channel" }, 113 + { .name = "rpmsg-micfil-channel" }, 113 114 { }, 114 115 }; 115 116
+7 -3
sound/soc/fsl/imx-pcm-rpmsg.c
··· 178 178 msg->s_msg.param.channels = RPMSG_CH_STEREO; 179 179 break; 180 180 default: 181 - ret = -EINVAL; 181 + msg->s_msg.param.channels = params_channels(params); 182 182 break; 183 183 } 184 184 ··· 684 684 info->rpdev = container_of(pdev->dev.parent, struct rpmsg_device, dev); 685 685 info->dev = &pdev->dev; 686 686 /* Setup work queue */ 687 - info->rpmsg_wq = alloc_ordered_workqueue("rpmsg_audio", 687 + info->rpmsg_wq = alloc_ordered_workqueue(info->rpdev->id.name, 688 688 WQ_HIGHPRI | 689 689 WQ_UNBOUND | 690 690 WQ_FREEZABLE); ··· 723 723 if (ret) 724 724 goto fail; 725 725 726 - component = snd_soc_lookup_component(&pdev->dev, IMX_PCM_DRV_NAME); 726 + component = snd_soc_lookup_component(&pdev->dev, NULL); 727 727 if (!component) { 728 728 ret = -EINVAL; 729 729 goto fail; 730 730 } 731 + 732 + /* platform component name is used by machine driver to link with */ 733 + component->name = info->rpdev->id.name; 734 + 731 735 #ifdef CONFIG_DEBUG_FS 732 736 component->debugfs_prefix = "rpmsg"; 733 737 #endif
+5 -1
sound/soc/fsl/imx-rpmsg.c
··· 58 58 struct platform_device *rpmsg_pdev = to_platform_device(dev); 59 59 struct device_node *np = rpmsg_pdev->dev.of_node; 60 60 struct of_phandle_args args; 61 + const char *platform_name; 61 62 struct imx_rpmsg *data; 62 63 int ret = 0; 63 64 ··· 110 109 } 111 110 112 111 data->dai.cpus->dai_name = dev_name(&rpmsg_pdev->dev); 113 - data->dai.platforms->name = IMX_PCM_DRV_NAME; 112 + if (!of_property_read_string(np, "fsl,rpmsg-channel-name", &platform_name)) 113 + data->dai.platforms->name = platform_name; 114 + else 115 + data->dai.platforms->name = "rpmsg-audio-channel"; 114 116 data->dai.playback_only = true; 115 117 data->dai.capture_only = true; 116 118 data->card.num_links = 1;