brintos

brintos / linux-shallow public Read only

0
0
Text · 3.8 KiB · 38aafb8 Raw
146 lines · c
1// SPDX-License-Identifier: GPL-2.0+2// Copyright 2017-2020 NXP3 4#include <linux/module.h>5#include <linux/rpmsg.h>6#include "imx-pcm-rpmsg.h"7 8/*9 * struct imx_audio_rpmsg: private data10 *11 * @rpmsg_pdev: pointer of platform device12 */13struct imx_audio_rpmsg {14	struct platform_device *rpmsg_pdev;15	struct platform_device *card_pdev;16};17 18static int imx_audio_rpmsg_cb(struct rpmsg_device *rpdev, void *data, int len,19			      void *priv, u32 src)20{21	struct imx_audio_rpmsg *rpmsg = dev_get_drvdata(&rpdev->dev);22	struct rpmsg_r_msg *r_msg = (struct rpmsg_r_msg *)data;23	struct rpmsg_info *info;24	struct rpmsg_msg *msg;25	unsigned long flags;26 27	if (!rpmsg->rpmsg_pdev)28		return 0;29 30	info = platform_get_drvdata(rpmsg->rpmsg_pdev);31 32	dev_dbg(&rpdev->dev, "get from%d: cmd:%d. %d\n",33		src, r_msg->header.cmd, r_msg->param.resp);34 35	switch (r_msg->header.type) {36	case MSG_TYPE_C:37		/* TYPE C is notification from M core */38		switch (r_msg->header.cmd) {39		case TX_PERIOD_DONE:40			spin_lock_irqsave(&info->lock[TX], flags);41			msg = &info->msg[TX_PERIOD_DONE + MSG_TYPE_A_NUM];42			msg->r_msg.param.buffer_tail =43						r_msg->param.buffer_tail;44			msg->r_msg.param.buffer_tail %= info->num_period[TX];45			spin_unlock_irqrestore(&info->lock[TX], flags);46			info->callback[TX](info->callback_param[TX]);47			break;48		case RX_PERIOD_DONE:49			spin_lock_irqsave(&info->lock[RX], flags);50			msg = &info->msg[RX_PERIOD_DONE + MSG_TYPE_A_NUM];51			msg->r_msg.param.buffer_tail =52						r_msg->param.buffer_tail;53			msg->r_msg.param.buffer_tail %= info->num_period[1];54			spin_unlock_irqrestore(&info->lock[RX], flags);55			info->callback[RX](info->callback_param[RX]);56			break;57		default:58			dev_warn(&rpdev->dev, "unknown msg command\n");59			break;60		}61		break;62	case MSG_TYPE_B:63		/* TYPE B is response msg */64		memcpy(&info->r_msg, r_msg, sizeof(struct rpmsg_r_msg));65		complete(&info->cmd_complete);66		break;67	default:68		dev_warn(&rpdev->dev, "unknown msg type\n");69		break;70	}71 72	return 0;73}74 75static int imx_audio_rpmsg_probe(struct rpmsg_device *rpdev)76{77	struct imx_audio_rpmsg *data;78	int ret = 0;79 80	dev_info(&rpdev->dev, "new channel: 0x%x -> 0x%x!\n",81		 rpdev->src, rpdev->dst);82 83	data = devm_kzalloc(&rpdev->dev, sizeof(*data), GFP_KERNEL);84	if (!data)85		return -ENOMEM;86 87	dev_set_drvdata(&rpdev->dev, data);88 89	/* Register platform driver for rpmsg routine */90	data->rpmsg_pdev = platform_device_register_data(&rpdev->dev,91							 rpdev->id.name,92							 PLATFORM_DEVID_NONE,93							 NULL, 0);94	if (IS_ERR(data->rpmsg_pdev)) {95		dev_err(&rpdev->dev, "failed to register rpmsg platform.\n");96		ret = PTR_ERR(data->rpmsg_pdev);97	}98 99	data->card_pdev = platform_device_register_data(&rpdev->dev,100							"imx-audio-rpmsg",101							PLATFORM_DEVID_AUTO,102							rpdev->id.name,103							strlen(rpdev->id.name) + 1);104	if (IS_ERR(data->card_pdev)) {105		dev_err(&rpdev->dev, "failed to register rpmsg card.\n");106		ret = PTR_ERR(data->card_pdev);107	}108 109	return ret;110}111 112static void imx_audio_rpmsg_remove(struct rpmsg_device *rpdev)113{114	struct imx_audio_rpmsg *data = dev_get_drvdata(&rpdev->dev);115 116	if (data->rpmsg_pdev)117		platform_device_unregister(data->rpmsg_pdev);118 119	if (data->card_pdev)120		platform_device_unregister(data->card_pdev);121 122	dev_info(&rpdev->dev, "audio rpmsg driver is removed\n");123}124 125static struct rpmsg_device_id imx_audio_rpmsg_id_table[] = {126	{ .name	= "rpmsg-audio-channel" },127	{ .name = "rpmsg-micfil-channel" },128	{ },129};130MODULE_DEVICE_TABLE(rpmsg, imx_audio_rpmsg_id_table);131 132static struct rpmsg_driver imx_audio_rpmsg_driver = {133	.drv.name	= "imx_audio_rpmsg",134	.id_table	= imx_audio_rpmsg_id_table,135	.probe		= imx_audio_rpmsg_probe,136	.callback	= imx_audio_rpmsg_cb,137	.remove		= imx_audio_rpmsg_remove,138};139 140module_rpmsg_driver(imx_audio_rpmsg_driver);141 142MODULE_DESCRIPTION("Freescale SoC Audio RPMSG interface");143MODULE_AUTHOR("Shengjiu Wang <shengjiu.wang@nxp.com>");144MODULE_ALIAS("rpmsg:imx_audio_rpmsg");145MODULE_LICENSE("GPL v2");146