mirror of
https://github.com/brain-hackers/linux-brain.git
synced 2024-06-09 23:36:23 +09:00
MA-17777 ASoC: imx-pcm-rpmsg: Move i2s rpmsg driver to individual file
Move i2s rpmsg driver to a new file: imx-i2s-rpmsg.c This new driver should be probed after fsl_rpmsg_i2s, which calls imx_rpmsg_platform_register (in imx-pcm-rpmsg) to fill global variable: i2s_info_g. Signed-off-by: Jindong <jindong.yue@nxp.com> Reviewed-by: Shengjiu Wang <shengjiu.wang@nxp.com>
This commit is contained in:
parent
a8a7d970e2
commit
4e1aa17692
|
@ -143,6 +143,10 @@ config SND_SOC_IMX_PCM_RPMSG
|
|||
depends on HAVE_IMX_RPMSG
|
||||
select SND_SOC_GENERIC_DMAENGINE_PCM
|
||||
|
||||
config SND_SOC_IMX_I2S_RPMSG
|
||||
tristate
|
||||
depends on SND_SOC_FSL_RPMSG_I2S
|
||||
|
||||
config SND_SOC_IMX_AUDMUX
|
||||
tristate "Digital Audio Mux module support"
|
||||
help
|
||||
|
@ -450,6 +454,7 @@ config SND_SOC_IMX_RPMSG
|
|||
tristate "SoC Audio support for i.MX boards with rpmsg"
|
||||
depends on HAVE_IMX_RPMSG
|
||||
select SND_SOC_IMX_PCM_RPMSG
|
||||
select SND_SOC_IMX_I2S_RPMSG
|
||||
select SND_SOC_FSL_RPMSG_I2S
|
||||
select SND_SOC_RPMSG_WM8960
|
||||
select SND_SOC_RPMSG_AK4497
|
||||
|
|
|
@ -74,6 +74,7 @@ obj-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o imx-pcm-dma-v2.o
|
|||
obj-$(CONFIG_SND_SOC_IMX_PCM_DMA) += imx-pcm-dma.o
|
||||
obj-$(CONFIG_SND_SOC_IMX_HDMI_DMA) += imx-hdmi-dma.o hdmi_pcm.o
|
||||
obj-$(CONFIG_SND_SOC_IMX_PCM_RPMSG) += imx-pcm-rpmsg.o
|
||||
obj-$(CONFIG_SND_SOC_IMX_I2S_RPMSG) += imx-i2s-rpmsg.o
|
||||
|
||||
# i.MX Machine Support
|
||||
snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o
|
||||
|
|
170
sound/soc/fsl/imx-i2s-rpmsg.c
Normal file
170
sound/soc/fsl/imx-i2s-rpmsg.c
Normal file
|
@ -0,0 +1,170 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
// Copyright 2020 NXP
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/rpmsg.h>
|
||||
#include <linux/imx_rpmsg.h>
|
||||
|
||||
#include "fsl_rpmsg_i2s.h"
|
||||
|
||||
extern struct i2s_info *i2s_info_g;
|
||||
|
||||
static int i2s_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,
|
||||
void *priv, u32 src)
|
||||
{
|
||||
struct i2s_rpmsg_r *msg = (struct i2s_rpmsg_r *)data;
|
||||
struct i2s_rpmsg *rpmsg;
|
||||
unsigned long flags;
|
||||
|
||||
dev_dbg(&rpdev->dev, "get from%d: cmd:%d. %d\n",
|
||||
src, msg->header.cmd, msg->param.resp);
|
||||
|
||||
if (msg->header.type == I2S_TYPE_C) {
|
||||
if (msg->header.cmd == I2S_TX_PERIOD_DONE) {
|
||||
spin_lock_irqsave(&i2s_info_g->lock[0], flags);
|
||||
rpmsg = &i2s_info_g->rpmsg[I2S_TX_PERIOD_DONE + I2S_TYPE_A_NUM];
|
||||
|
||||
if (msg->header.major == 1 && msg->header.minor == 2)
|
||||
rpmsg->recv_msg.param.buffer_tail =
|
||||
msg->param.buffer_tail;
|
||||
else
|
||||
rpmsg->recv_msg.param.buffer_tail++;
|
||||
|
||||
rpmsg->recv_msg.param.buffer_tail %=
|
||||
i2s_info_g->num_period[0];
|
||||
|
||||
spin_unlock_irqrestore(&i2s_info_g->lock[0], flags);
|
||||
i2s_info_g->callback[0](i2s_info_g->callback_param[0]);
|
||||
|
||||
} else if (msg->header.cmd == I2S_RX_PERIOD_DONE) {
|
||||
spin_lock_irqsave(&i2s_info_g->lock[1], flags);
|
||||
rpmsg = &i2s_info_g->rpmsg[I2S_RX_PERIOD_DONE + I2S_TYPE_A_NUM];
|
||||
|
||||
if (msg->header.major == 1 && msg->header.minor == 2)
|
||||
rpmsg->recv_msg.param.buffer_tail =
|
||||
msg->param.buffer_tail;
|
||||
else
|
||||
rpmsg->recv_msg.param.buffer_tail++;
|
||||
|
||||
rpmsg->recv_msg.param.buffer_tail %=
|
||||
i2s_info_g->num_period[1];
|
||||
spin_unlock_irqrestore(&i2s_info_g->lock[1], flags);
|
||||
i2s_info_g->callback[1](i2s_info_g->callback_param[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (msg->header.type == I2S_TYPE_B) {
|
||||
memcpy(&i2s_info_g->recv_msg, msg, sizeof(struct i2s_rpmsg_r));
|
||||
complete(&i2s_info_g->cmd_complete);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2s_rpmsg_probe(struct rpmsg_device *rpdev)
|
||||
{
|
||||
struct platform_device *codec_pdev;
|
||||
struct fsl_rpmsg_i2s *rpmsg_i2s = NULL;
|
||||
struct fsl_rpmsg_codec rpmsg_codec[3];
|
||||
int ret;
|
||||
|
||||
if (!i2s_info_g)
|
||||
return 0;
|
||||
|
||||
i2s_info_g->rpdev = rpdev;
|
||||
|
||||
init_completion(&i2s_info_g->cmd_complete);
|
||||
|
||||
dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
|
||||
rpdev->src, rpdev->dst);
|
||||
|
||||
rpmsg_i2s = container_of(i2s_info_g, struct fsl_rpmsg_i2s, i2s_info);
|
||||
|
||||
if (rpmsg_i2s->codec_in_dt)
|
||||
return 0;
|
||||
|
||||
if (rpmsg_i2s->codec_wm8960) {
|
||||
rpmsg_codec[0].audioindex = rpmsg_i2s->codec_wm8960 >> 16;
|
||||
rpmsg_codec[0].shared_lrclk = true;
|
||||
rpmsg_codec[0].capless = false;
|
||||
codec_pdev = platform_device_register_data(
|
||||
&rpmsg_i2s->pdev->dev,
|
||||
RPMSG_CODEC_DRV_NAME_WM8960,
|
||||
PLATFORM_DEVID_NONE,
|
||||
&rpmsg_codec[0], sizeof(struct fsl_rpmsg_codec));
|
||||
if (IS_ERR(codec_pdev)) {
|
||||
dev_err(&rpdev->dev,
|
||||
"failed to register rpmsg audio codec\n");
|
||||
ret = PTR_ERR(codec_pdev);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (rpmsg_i2s->codec_cs42888) {
|
||||
rpmsg_codec[1].audioindex = rpmsg_i2s->codec_cs42888 >> 16;
|
||||
strcpy(rpmsg_codec[1].name, "cs42888");
|
||||
rpmsg_codec[1].num_adcs = 2;
|
||||
|
||||
codec_pdev = platform_device_register_data(
|
||||
&rpmsg_i2s->pdev->dev,
|
||||
RPMSG_CODEC_DRV_NAME_CS42888,
|
||||
PLATFORM_DEVID_NONE,
|
||||
&rpmsg_codec[1], sizeof(struct fsl_rpmsg_codec));
|
||||
if (IS_ERR(codec_pdev)) {
|
||||
dev_err(&rpdev->dev,
|
||||
"failed to register rpmsg audio codec\n");
|
||||
ret = PTR_ERR(codec_pdev);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (rpmsg_i2s->codec_ak4497) {
|
||||
rpmsg_codec[2].audioindex = rpmsg_i2s->codec_ak4497 >> 16;
|
||||
codec_pdev = platform_device_register_data(
|
||||
&rpmsg_i2s->pdev->dev,
|
||||
RPMSG_CODEC_DRV_NAME_AK4497,
|
||||
PLATFORM_DEVID_NONE,
|
||||
&rpmsg_codec[2], sizeof(struct fsl_rpmsg_codec));
|
||||
if (IS_ERR(codec_pdev)) {
|
||||
dev_err(&rpdev->dev,
|
||||
"failed to register rpmsg audio codec\n");
|
||||
ret = PTR_ERR(codec_pdev);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void i2s_rpmsg_remove(struct rpmsg_device *rpdev)
|
||||
{
|
||||
dev_info(&rpdev->dev, "i2s rpmsg driver is removed\n");
|
||||
}
|
||||
|
||||
static struct rpmsg_device_id i2s_rpmsg_id_table[] = {
|
||||
{ .name = "rpmsg-audio-channel" },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct rpmsg_driver i2s_rpmsg_driver = {
|
||||
.drv.name = "i2s_rpmsg",
|
||||
.drv.owner = THIS_MODULE,
|
||||
.id_table = i2s_rpmsg_id_table,
|
||||
.probe = i2s_rpmsg_probe,
|
||||
.callback = i2s_rpmsg_cb,
|
||||
.remove = i2s_rpmsg_remove,
|
||||
};
|
||||
|
||||
static int __init i2s_rpmsg_init(void)
|
||||
{
|
||||
return register_rpmsg_driver(&i2s_rpmsg_driver);
|
||||
}
|
||||
|
||||
static void __exit i2s_rpmsg_exit(void)
|
||||
{
|
||||
unregister_rpmsg_driver(&i2s_rpmsg_driver);
|
||||
}
|
||||
module_init(i2s_rpmsg_init);
|
||||
module_exit(i2s_rpmsg_exit);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -11,8 +11,6 @@
|
|||
#include <linux/dma-mapping.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/rpmsg.h>
|
||||
#include <linux/imx_rpmsg.h>
|
||||
#include <linux/delay.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
|
@ -27,6 +25,7 @@
|
|||
#define DRV_NAME "imx_pcm_rpmsg"
|
||||
|
||||
struct i2s_info *i2s_info_g;
|
||||
EXPORT_SYMBOL(i2s_info_g);
|
||||
|
||||
static struct snd_pcm_hardware imx_rpmsg_pcm_hardware = {
|
||||
.info = SNDRV_PCM_INFO_INTERLEAVED |
|
||||
|
@ -735,162 +734,4 @@ int imx_rpmsg_platform_register(struct device *dev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(imx_rpmsg_platform_register);
|
||||
|
||||
static int i2s_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,
|
||||
void *priv, u32 src)
|
||||
{
|
||||
struct i2s_rpmsg_r *msg = (struct i2s_rpmsg_r *)data;
|
||||
struct i2s_rpmsg *rpmsg;
|
||||
unsigned long flags;
|
||||
|
||||
dev_dbg(&rpdev->dev, "get from%d: cmd:%d. %d\n",
|
||||
src, msg->header.cmd, msg->param.resp);
|
||||
|
||||
if (msg->header.type == I2S_TYPE_C) {
|
||||
if (msg->header.cmd == I2S_TX_PERIOD_DONE) {
|
||||
spin_lock_irqsave(&i2s_info_g->lock[0], flags);
|
||||
rpmsg = &i2s_info_g->rpmsg[I2S_TX_PERIOD_DONE + I2S_TYPE_A_NUM];
|
||||
|
||||
if (msg->header.major == 1 && msg->header.minor == 2)
|
||||
rpmsg->recv_msg.param.buffer_tail =
|
||||
msg->param.buffer_tail;
|
||||
else
|
||||
rpmsg->recv_msg.param.buffer_tail++;
|
||||
|
||||
rpmsg->recv_msg.param.buffer_tail %=
|
||||
i2s_info_g->num_period[0];
|
||||
|
||||
spin_unlock_irqrestore(&i2s_info_g->lock[0], flags);
|
||||
i2s_info_g->callback[0](i2s_info_g->callback_param[0]);
|
||||
|
||||
} else if (msg->header.cmd == I2S_RX_PERIOD_DONE) {
|
||||
spin_lock_irqsave(&i2s_info_g->lock[1], flags);
|
||||
rpmsg = &i2s_info_g->rpmsg[I2S_RX_PERIOD_DONE + I2S_TYPE_A_NUM];
|
||||
|
||||
if (msg->header.major == 1 && msg->header.minor == 2)
|
||||
rpmsg->recv_msg.param.buffer_tail =
|
||||
msg->param.buffer_tail;
|
||||
else
|
||||
rpmsg->recv_msg.param.buffer_tail++;
|
||||
|
||||
rpmsg->recv_msg.param.buffer_tail %=
|
||||
i2s_info_g->num_period[1];
|
||||
spin_unlock_irqrestore(&i2s_info_g->lock[1], flags);
|
||||
i2s_info_g->callback[1](i2s_info_g->callback_param[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (msg->header.type == I2S_TYPE_B) {
|
||||
memcpy(&i2s_info_g->recv_msg, msg, sizeof(struct i2s_rpmsg_r));
|
||||
complete(&i2s_info_g->cmd_complete);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2s_rpmsg_probe(struct rpmsg_device *rpdev)
|
||||
{
|
||||
struct platform_device *codec_pdev;
|
||||
struct fsl_rpmsg_i2s *rpmsg_i2s = NULL;
|
||||
struct fsl_rpmsg_codec rpmsg_codec[3];
|
||||
int ret;
|
||||
|
||||
if (!i2s_info_g)
|
||||
return 0;
|
||||
|
||||
i2s_info_g->rpdev = rpdev;
|
||||
|
||||
init_completion(&i2s_info_g->cmd_complete);
|
||||
|
||||
dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",
|
||||
rpdev->src, rpdev->dst);
|
||||
|
||||
rpmsg_i2s = container_of(i2s_info_g, struct fsl_rpmsg_i2s, i2s_info);
|
||||
|
||||
if (rpmsg_i2s->codec_in_dt)
|
||||
return 0;
|
||||
|
||||
if (rpmsg_i2s->codec_wm8960) {
|
||||
rpmsg_codec[0].audioindex = rpmsg_i2s->codec_wm8960 >> 16;
|
||||
rpmsg_codec[0].shared_lrclk = true;
|
||||
rpmsg_codec[0].capless = false;
|
||||
codec_pdev = platform_device_register_data(
|
||||
&rpmsg_i2s->pdev->dev,
|
||||
RPMSG_CODEC_DRV_NAME_WM8960,
|
||||
PLATFORM_DEVID_NONE,
|
||||
&rpmsg_codec[0], sizeof(struct fsl_rpmsg_codec));
|
||||
if (IS_ERR(codec_pdev)) {
|
||||
dev_err(&rpdev->dev,
|
||||
"failed to register rpmsg audio codec\n");
|
||||
ret = PTR_ERR(codec_pdev);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (rpmsg_i2s->codec_cs42888) {
|
||||
rpmsg_codec[1].audioindex = rpmsg_i2s->codec_cs42888 >> 16;
|
||||
strcpy(rpmsg_codec[1].name, "cs42888");
|
||||
rpmsg_codec[1].num_adcs = 2;
|
||||
|
||||
codec_pdev = platform_device_register_data(
|
||||
&rpmsg_i2s->pdev->dev,
|
||||
RPMSG_CODEC_DRV_NAME_CS42888,
|
||||
PLATFORM_DEVID_NONE,
|
||||
&rpmsg_codec[1], sizeof(struct fsl_rpmsg_codec));
|
||||
if (IS_ERR(codec_pdev)) {
|
||||
dev_err(&rpdev->dev,
|
||||
"failed to register rpmsg audio codec\n");
|
||||
ret = PTR_ERR(codec_pdev);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (rpmsg_i2s->codec_ak4497) {
|
||||
rpmsg_codec[2].audioindex = rpmsg_i2s->codec_ak4497 >> 16;
|
||||
codec_pdev = platform_device_register_data(
|
||||
&rpmsg_i2s->pdev->dev,
|
||||
RPMSG_CODEC_DRV_NAME_AK4497,
|
||||
PLATFORM_DEVID_NONE,
|
||||
&rpmsg_codec[2], sizeof(struct fsl_rpmsg_codec));
|
||||
if (IS_ERR(codec_pdev)) {
|
||||
dev_err(&rpdev->dev,
|
||||
"failed to register rpmsg audio codec\n");
|
||||
ret = PTR_ERR(codec_pdev);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void i2s_rpmsg_remove(struct rpmsg_device *rpdev)
|
||||
{
|
||||
dev_info(&rpdev->dev, "i2s rpmsg driver is removed\n");
|
||||
}
|
||||
|
||||
static struct rpmsg_device_id i2s_rpmsg_id_table[] = {
|
||||
{ .name = "rpmsg-audio-channel" },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct rpmsg_driver i2s_rpmsg_driver = {
|
||||
.drv.name = "i2s_rpmsg",
|
||||
.drv.owner = THIS_MODULE,
|
||||
.id_table = i2s_rpmsg_id_table,
|
||||
.probe = i2s_rpmsg_probe,
|
||||
.callback = i2s_rpmsg_cb,
|
||||
.remove = i2s_rpmsg_remove,
|
||||
};
|
||||
|
||||
static int __init i2s_rpmsg_init(void)
|
||||
{
|
||||
return register_rpmsg_driver(&i2s_rpmsg_driver);
|
||||
}
|
||||
|
||||
static void __exit i2s_rpmsg_exit(void)
|
||||
{
|
||||
unregister_rpmsg_driver(&i2s_rpmsg_driver);
|
||||
}
|
||||
module_init(i2s_rpmsg_init);
|
||||
module_exit(i2s_rpmsg_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
Loading…
Reference in New Issue
Block a user