/* SPDX-License-Identifier: GPL-2.0+ */1/*2* Copyright 2017-2021 NXP3*4******************************************************************************5* Communication stack of audio with rpmsg6******************************************************************************7* Packet structure:8* A SRTM message consists of a 10 bytes header followed by 0~N bytes of data9*10* +---------------+-------------------------------+11* | | Content |12* +---------------+-------------------------------+13* | Byte Offset | 7 6 5 4 3 2 1 0 |14* +---------------+---+---+---+---+---+---+---+---+15* | 0 | Category |16* +---------------+---+---+---+---+---+---+---+---+17* | 1 ~ 2 | Version |18* +---------------+---+---+---+---+---+---+---+---+19* | 3 | Type |20* +---------------+---+---+---+---+---+---+---+---+21* | 4 | Command |22* +---------------+---+---+---+---+---+---+---+---+23* | 5 | Reserved0 |24* +---------------+---+---+---+---+---+---+---+---+25* | 6 | Reserved1 |26* +---------------+---+---+---+---+---+---+---+---+27* | 7 | Reserved2 |28* +---------------+---+---+---+---+---+---+---+---+29* | 8 | Reserved3 |30* +---------------+---+---+---+---+---+---+---+---+31* | 9 | Reserved4 |32* +---------------+---+---+---+---+---+---+---+---+33* | 10 | DATA 0 |34* +---------------+---+---+---+---+---+---+---+---+35* : : : : : : : : : : : : :36* +---------------+---+---+---+---+---+---+---+---+37* | N + 10 - 1 | DATA N-1 |38* +---------------+---+---+---+---+---+---+---+---+39*40* +----------+------------+------------------------------------------------+41* | Field | Byte | |42* +----------+------------+------------------------------------------------+43* | Category | 0 | The destination category. |44* +----------+------------+------------------------------------------------+45* | Version | 1 ~ 2 | The category version of the sender of the |46* | | | packet. |47* | | | The first byte represent the major version of |48* | | | the packet.The second byte represent the minor |49* | | | version of the packet. |50* +----------+------------+------------------------------------------------+51* | Type | 3 | The message type of current message packet. |52* +----------+------------+------------------------------------------------+53* | Command | 4 | The command byte sent to remote processor/SoC. |54* +----------+------------+------------------------------------------------+55* | Reserved | 5 ~ 9 | Reserved field for future extension. |56* +----------+------------+------------------------------------------------+57* | Data | N | The data payload of the message packet. |58* +----------+------------+------------------------------------------------+59*60* Audio control:61* SRTM Audio Control Category Request Command Table:62* +----------+---------+------+---------+-------------------------------+-----------------------+63* | Category | Version | Type | Command | Data | Function |64* +----------+---------+------+---------+-------------------------------+-----------------------+65* | 0x03 | 0x0100 | 0x00 | 0x00 | Data[0]: Audio Device Index | Open a TX Instance. |66* | | | | | Data[1]: format | |67* | | | | | Data[2]: channels | |68* | | | | | Data[3-6]: samplerate | |69* | | | | | Data[7-10]: buffer_addr | |70* | | | | | Data[11-14]: buffer_size | |71* | | | | | Data[15-18]: period_size | |72* | | | | | Data[19-22]: buffer_tail | |73* +----------+---------+------+---------+-------------------------------+-----------------------+74* | 0x03 | 0x0100 | 0x00 | 0x01 | Data[0]: Audio Device Index | Start a TX Instance. |75* | | | | | Same as above command | |76* +----------+---------+------+---------+-------------------------------+-----------------------+77* | 0x03 | 0x0100 | 0x00 | 0x02 | Data[0]: Audio Device Index | Pause a TX Instance. |78* | | | | | Same as above command | |79* +----------+---------+------+---------+-------------------------------+-----------------------+80* | 0x03 | 0x0100 | 0x00 | 0x03 | Data[0]: Audio Device Index | Resume a TX Instance. |81* +----------+---------+------+---------+-------------------------------+-----------------------+82* | 0x03 | 0x0100 | 0x00 | 0x04 | Data[0]: Audio Device Index | Stop a TX Instance. |83* +----------+---------+------+---------+-------------------------------+-----------------------+84* | 0x03 | 0x0100 | 0x00 | 0x05 | Data[0]: Audio Device Index | Close a TX Instance. |85* +----------+---------+------+---------+-------------------------------+-----------------------+86* | 0x03 | 0x0100 | 0x00 | 0x06 | Data[0]: Audio Device Index | Set Parameters for |87* | | | | | Data[1]: format | a TX Instance. |88* | | | | | Data[2]: channels | |89* | | | | | Data[3-6]: samplerate | |90* | | | | | Data[7-22]: reserved | |91* +----------+---------+------+---------+-------------------------------+-----------------------+92* | 0x03 | 0x0100 | 0x00 | 0x07 | Data[0]: Audio Device Index | Set TX Buffer. |93* | | | | | Data[1-6]: reserved | |94* | | | | | Data[7-10]: buffer_addr | |95* | | | | | Data[11-14]: buffer_size | |96* | | | | | Data[15-18]: period_size | |97* | | | | | Data[19-22]: buffer_tail | |98* +----------+---------+------+---------+-------------------------------+-----------------------+99* | 0x03 | 0x0100 | 0x00 | 0x08 | Data[0]: Audio Device Index | Suspend a TX Instance |100* +----------+---------+------+---------+-------------------------------+-----------------------+101* | 0x03 | 0x0100 | 0x00 | 0x09 | Data[0]: Audio Device Index | Resume a TX Instance. |102* | | | | | Data[1]: format | |103* | | | | | Data[2]: channels | |104* | | | | | Data[3-6]: samplerate | |105* | | | | | Data[7-10]: buffer_addr | |106* | | | | | Data[11-14]: buffer_size | |107* | | | | | Data[15-18]: period_size | |108* | | | | | Data[19-22]: buffer_tail | |109* +----------+---------+------+---------+-------------------------------+-----------------------+110* | 0x03 | 0x0100 | 0x00 | 0x0A | Data[0]: Audio Device Index | Open a RX Instance. |111* +----------+---------+------+---------+-------------------------------+-----------------------+112* | 0x03 | 0x0100 | 0x00 | 0x0B | Data[0]: Audio Device Index | Start a RX Instance. |113* +----------+---------+------+---------+-------------------------------+-----------------------+114* | 0x03 | 0x0100 | 0x00 | 0x0C | Data[0]: Audio Device Index | Pause a RX Instance. |115* +----------+---------+------+---------+-------------------------------+-----------------------+116* | 0x03 | 0x0100 | 0x00 | 0x0D | Data[0]: Audio Device Index | Resume a RX Instance. |117* +----------+---------+------+---------+-------------------------------+-----------------------+118* | 0x03 | 0x0100 | 0x00 | 0x0E | Data[0]: Audio Device Index | Stop a RX Instance. |119* +----------+---------+------+---------+-------------------------------+-----------------------+120* | 0x03 | 0x0100 | 0x00 | 0x0F | Data[0]: Audio Device Index | Close a RX Instance. |121* +----------+---------+------+---------+-------------------------------+-----------------------+122* | 0x03 | 0x0100 | 0x00 | 0x10 | Data[0]: Audio Device Index | Set Parameters for |123* | | | | | Data[1]: format | a RX Instance. |124* | | | | | Data[2]: channels | |125* | | | | | Data[3-6]: samplerate | |126* | | | | | Data[7-22]: reserved | |127* +----------+---------+------+---------+-------------------------------+-----------------------+128* | 0x03 | 0x0100 | 0x00 | 0x11 | Data[0]: Audio Device Index | Set RX Buffer. |129* | | | | | Data[1-6]: reserved | |130* | | | | | Data[7-10]: buffer_addr | |131* | | | | | Data[11-14]: buffer_size | |132* | | | | | Data[15-18]: period_size | |133* | | | | | Data[19-22]: buffer_tail | |134* +----------+---------+------+---------+-------------------------------+-----------------------+135* | 0x03 | 0x0100 | 0x00 | 0x12 | Data[0]: Audio Device Index | Suspend a RX Instance.|136* +----------+---------+------+---------+-------------------------------+-----------------------+137* | 0x03 | 0x0100 | 0x00 | 0x13 | Data[0]: Audio Device Index | Resume a RX Instance. |138* | | | | | Data[1]: format | |139* | | | | | Data[2]: channels | |140* | | | | | Data[3-6]: samplerate | |141* | | | | | Data[7-10]: buffer_addr | |142* | | | | | Data[11-14]: buffer_size | |143* | | | | | Data[15-18]: period_size | |144* | | | | | Data[19-22]: buffer_tail | |145* +----------+---------+------+---------+-------------------------------+-----------------------+146* | 0x03 | 0x0100 | 0x00 | 0x14 | Data[0]: Audio Device Index | Set register value |147* | | | | | Data[1-6]: reserved | to codec |148* | | | | | Data[7-10]: register | |149* | | | | | Data[11-14]: value | |150* | | | | | Data[15-22]: reserved | |151* +----------+---------+------+---------+-------------------------------+-----------------------+152* | 0x03 | 0x0100 | 0x00 | 0x15 | Data[0]: Audio Device Index | Get register value |153* | | | | | Data[1-6]: reserved | from codec |154* | | | | | Data[7-10]: register | |155* | | | | | Data[11-22]: reserved | |156* +----------+---------+------+---------+-------------------------------+-----------------------+157* Note 1: See <List of Sample Format> for available value of158* Sample Format;159* Note 2: See <List of Audio Channels> for available value of Channels;160* Note 3: Sample Rate of Set Parameters for an Audio TX Instance161* Command and Set Parameters for an Audio RX Instance Command is162* in little-endian format.163*164* SRTM Audio Control Category Response Command Table:165* +----------+---------+------+---------+-------------------------------+-----------------------+166* | Category | Version | Type | Command | Data | Function |167* +----------+---------+------+---------+-------------------------------+-----------------------+168* | 0x03 | 0x0100 | 0x01 | 0x00 | Data[0]: Audio Device Index | Reply for Open |169* | | | | | Data[1]: Return code | a TX Instance |170* +----------+---------+------+---------+-------------------------------+-----------------------+171* | 0x03 | 0x0100 | 0x01 | 0x01 | Data[0]: Audio Device Index | Reply for Start |172* | | | | | Data[1]: Return code | a TX Instance |173* +----------+---------+------+---------+-------------------------------+-----------------------+174* | 0x03 | 0x0100 | 0x01 | 0x02 | Data[0]: Audio Device Index | Reply for Pause |175* | | | | | Data[1]: Return code | a TX Instance |176* +----------+---------+------+---------+-------------------------------+-----------------------+177* | 0x03 | 0x0100 | 0x01 | 0x03 | Data[0]: Audio Device Index | Reply for Resume |178* | | | | | Data[1]: Return code | a TX Instance |179* +----------+---------+------+---------+-------------------------------+-----------------------+180* | 0x03 | 0x0100 | 0x01 | 0x04 | Data[0]: Audio Device Index | Reply for Stop |181* | | | | | Data[1]: Return code | a TX Instance |182* +----------+---------+------+---------+-------------------------------+-----------------------+183* | 0x03 | 0x0100 | 0x01 | 0x05 | Data[0]: Audio Device Index | Reply for Close |184* | | | | | Data[1]: Return code | a TX Instance |185* +----------+---------+------+---------+-------------------------------+-----------------------+186* | 0x03 | 0x0100 | 0x01 | 0x06 | Data[0]: Audio Device Index | Reply for Set Param |187* | | | | | Data[1]: Return code | for a TX Instance. |188* +----------+---------+------+---------+-------------------------------+-----------------------+189* | 0x03 | 0x0100 | 0x01 | 0x07 | Data[0]: Audio Device Index | Reply for Set |190* | | | | | Data[1]: Return code | TX Buffer |191* +----------+---------+------+---------+-------------------------------+-----------------------+192* | 0x03 | 0x0100 | 0x01 | 0x08 | Data[0]: Audio Device Index | Reply for Suspend |193* | | | | | Data[1]: Return code | a TX Instance |194* +----------+---------+------+---------+-------------------------------+-----------------------+195* | 0x03 | 0x0100 | 0x01 | 0x09 | Data[0]: Audio Device Index | Reply for Resume |196* | | | | | Data[1]: Return code | a TX Instance |197* +----------+---------+------+---------+-------------------------------+-----------------------+198* | 0x03 | 0x0100 | 0x01 | 0x0A | Data[0]: Audio Device Index | Reply for Open |199* | | | | | Data[1]: Return code | a TX Instance |200* +----------+---------+------+---------+-------------------------------+-----------------------+201* | 0x03 | 0x0100 | 0x01 | 0x0B | Data[0]: Audio Device Index | Reply for Start |202* | | | | | Data[1]: Return code | a TX Instance |203* +----------+---------+------+---------+-------------------------------+-----------------------+204* | 0x03 | 0x0100 | 0x01 | 0x0C | Data[0]: Audio Device Index | Reply for Pause |205* | | | | | Data[1]: Return code | a TX Instance |206* +----------+---------+------+---------+-------------------------------+-----------------------+207* | 0x03 | 0x0100 | 0x01 | 0x0D | Data[0]: Audio Device Index | Reply for Resume |208* | | | | | Data[1]: Return code | a RX Instance |209* +----------+---------+------+---------+-------------------------------+-----------------------+210* | 0x03 | 0x0100 | 0x01 | 0x0E | Data[0]: Audio Device Index | Reply for Stop |211* | | | | | Data[1]: Return code | a RX Instance |212* +----------+---------+------+---------+-------------------------------+-----------------------+213* | 0x03 | 0x0100 | 0x01 | 0x0F | Data[0]: Audio Device Index | Reply for Close |214* | | | | | Data[1]: Return code | a RX Instance |215* +----------+---------+------+---------+-------------------------------+-----------------------+216* | 0x03 | 0x0100 | 0x01 | 0x10 | Data[0]: Audio Device Index | Reply for Set Param |217* | | | | | Data[1]: Return code | for a RX Instance. |218* +----------+---------+------+---------+-------------------------------+-----------------------+219* | 0x03 | 0x0100 | 0x01 | 0x11 | Data[0]: Audio Device Index | Reply for Set |220* | | | | | Data[1]: Return code | RX Buffer |221* +----------+---------+------+---------+-------------------------------+-----------------------+222* | 0x03 | 0x0100 | 0x01 | 0x12 | Data[0]: Audio Device Index | Reply for Suspend |223* | | | | | Data[1]: Return code | a RX Instance |224* +----------+---------+------+---------+-------------------------------+-----------------------+225* | 0x03 | 0x0100 | 0x01 | 0x13 | Data[0]: Audio Device Index | Reply for Resume |226* | | | | | Data[1]: Return code | a RX Instance |227* +----------+---------+------+---------+-------------------------------+-----------------------+228* | 0x03 | 0x0100 | 0x01 | 0x14 | Data[0]: Audio Device Index | Reply for Set codec |229* | | | | | Data[1]: Return code | register value |230* +----------+---------+------+---------+-------------------------------+-----------------------+231* | 0x03 | 0x0100 | 0x01 | 0x15 | Data[0]: Audio Device Index | Reply for Get codec |232* | | | | | Data[1]: Return code | register value |233* | | | | | Data[2-6]: reserved | |234* | | | | | Data[7-10]: register | |235* | | | | | Data[11-14]: value | |236* | | | | | Data[15-22]: reserved | |237* +----------+---------+------+---------+-------------------------------+-----------------------+238*239* SRTM Audio Control Category Notification Command Table:240* +----------+---------+------+---------+-------------------------------+-----------------------+241* | Category | Version | Type | Command | Data | Function |242* +----------+---------+------+---------+-------------------------------+-----------------------+243* | 0x03 | 0x0100 | 0x02 | 0x00 | Data[0]: Audio Device Index | Notify one TX period |244* | | | | | | is finished |245* +----------+---------+------+---------+-------------------------------+-----------------------+246* | 0x03 | 0x0100 | 0x02 | 0x01 | Data[0]: Audio Device Index | Notify one RX period |247* | | | | | | is finished |248* +----------+---------+------+---------+-------------------------------+-----------------------+249*250* List of Sample Format:251* +------------------+-----------------------+252* | Sample Format | Description |253* +------------------+-----------------------+254* | 0x0 | S16_LE |255* +------------------+-----------------------+256* | 0x1 | S24_LE |257* +------------------+-----------------------+258*259* List of Audio Channels260* +------------------+-----------------------+261* | Audio Channel | Description |262* +------------------+-----------------------+263* | 0x0 | Left Channel |264* +------------------+-----------------------+265* | 0x1 | Right Channel |266* +------------------+---------------- ------+267* | 0x2 | Left & Right Channel |268* +------------------+-----------------------+269*270*/271272#ifndef _IMX_PCM_RPMSG_H273#define _IMX_PCM_RPMSG_H274275#include <linux/pm_qos.h>276#include <linux/interrupt.h>277#include <sound/dmaengine_pcm.h>278279#define RPMSG_TIMEOUT 1000280281/* RPMSG Command (TYPE A)*/282#define TX_OPEN 0x0283#define TX_START 0x1284#define TX_PAUSE 0x2285#define TX_RESTART 0x3286#define TX_TERMINATE 0x4287#define TX_CLOSE 0x5288#define TX_HW_PARAM 0x6289#define TX_BUFFER 0x7290#define TX_SUSPEND 0x8291#define TX_RESUME 0x9292293#define RX_OPEN 0xA294#define RX_START 0xB295#define RX_PAUSE 0xC296#define RX_RESTART 0xD297#define RX_TERMINATE 0xE298#define RX_CLOSE 0xF299#define RX_HW_PARAM 0x10300#define RX_BUFFER 0x11301#define RX_SUSPEND 0x12302#define RX_RESUME 0x13303#define SET_CODEC_VALUE 0x14304#define GET_CODEC_VALUE 0x15305#define TX_POINTER 0x16306#define RX_POINTER 0x17307/* Total msg numver for type A */308#define MSG_TYPE_A_NUM 0x18309310/* RPMSG Command (TYPE C)*/311#define TX_PERIOD_DONE 0x0312#define RX_PERIOD_DONE 0x1313/* Total msg numver for type C */314#define MSG_TYPE_C_NUM 0x2315316#define MSG_MAX_NUM (MSG_TYPE_A_NUM + MSG_TYPE_C_NUM)317318#define MSG_TYPE_A 0x0319#define MSG_TYPE_B 0x1320#define MSG_TYPE_C 0x2321322#define RESP_NONE 0x0323#define RESP_NOT_ALLOWED 0x1324#define RESP_SUCCESS 0x2325#define RESP_FAILED 0x3326327#define RPMSG_S16_LE 0x0328#define RPMSG_S24_LE 0x1329#define RPMSG_S32_LE 0x2330#define RPMSG_DSD_U16_LE 49 /* SNDRV_PCM_FORMAT_DSD_U16_LE */331#define RPMSG_DSD_U24_LE 0x4332#define RPMSG_DSD_U32_LE 50 /* SNDRV_PCM_FORMAT_DSD_U32_LE */333334#define RPMSG_CH_LEFT 0x0335#define RPMSG_CH_RIGHT 0x1336#define RPMSG_CH_STEREO 0x2337338#define WORK_MAX_NUM 0x30339340/* Category define */341#define IMX_RMPSG_LIFECYCLE 1342#define IMX_RPMSG_PMIC 2343#define IMX_RPMSG_AUDIO 3344#define IMX_RPMSG_KEY 4345#define IMX_RPMSG_GPIO 5346#define IMX_RPMSG_RTC 6347#define IMX_RPMSG_SENSOR 7348349/* rpmsg version */350#define IMX_RMPSG_MAJOR 1351#define IMX_RMPSG_MINOR 0352353#define TX SNDRV_PCM_STREAM_PLAYBACK354#define RX SNDRV_PCM_STREAM_CAPTURE355356/**357* struct rpmsg_head: rpmsg header structure358*359* @cate: category360* @major: major version361* @minor: minor version362* @type: message type (A/B/C)363* @cmd: message command364* @reserved: reserved space365*/366struct rpmsg_head {367u8 cate;368u8 major;369u8 minor;370u8 type;371u8 cmd;372u8 reserved[5];373} __packed;374375/**376* struct param_s: sent rpmsg parameter377*378* @audioindex: audio instance index379* @format: audio format380* @channels: audio channel number381* @rate: sample rate382* @buffer_addr: dma buffer physical address or register for SET_CODEC_VALUE383* @buffer_size: dma buffer size or register value for SET_CODEC_VALUE384* @period_size: period size385* @buffer_tail: current period index386*/387struct param_s {388unsigned char audioindex;389unsigned char format;390unsigned char channels;391unsigned int rate;392unsigned int buffer_addr;393unsigned int buffer_size;394unsigned int period_size;395unsigned int buffer_tail;396} __packed;397398/**399* struct param_s: send rpmsg parameter400*401* @audioindex: audio instance index402* @resp: response value403* @reserved1: reserved space404* @buffer_offset: the consumed offset of buffer405* @reg_addr: register addr of codec406* @reg_data: register value of codec407* @reserved2: reserved space408* @buffer_tail: current period index409*/410struct param_r {411unsigned char audioindex;412unsigned char resp;413unsigned char reserved1[1];414unsigned int buffer_offset;415unsigned int reg_addr;416unsigned int reg_data;417unsigned char reserved2[4];418unsigned int buffer_tail;419} __packed;420421/* Struct of sent message */422struct rpmsg_s_msg {423struct rpmsg_head header;424struct param_s param;425};426427/* Struct of received message */428struct rpmsg_r_msg {429struct rpmsg_head header;430struct param_r param;431};432433/* Struct of rpmsg */434struct rpmsg_msg {435struct rpmsg_s_msg s_msg;436struct rpmsg_r_msg r_msg;437};438439/* Struct of rpmsg for workqueue */440struct work_of_rpmsg {441struct rpmsg_info *info;442/* Sent msg for each work */443struct rpmsg_msg msg;444struct work_struct work;445};446447/* Struct of timer */448struct stream_timer {449struct timer_list timer;450struct rpmsg_info *info;451struct snd_pcm_substream *substream;452};453454typedef void (*dma_callback)(void *arg);455456/**457* struct rpmsg_info: rpmsg audio information458*459* @rpdev: pointer of rpmsg_device460* @dev: pointer for imx_pcm_rpmsg device461* @cmd_complete: command is finished462* @pm_qos_req: request of pm qos463* @r_msg: received rpmsg464* @msg: array of rpmsg465* @notify: notification msg (type C) for TX & RX466* @notify_updated: notification flag for TX & RX467* @rpmsg_wq: rpmsg workqueue468* @work_list: array of work list for workqueue469* @work_write_index: write index of work list470* @work_read_index: read index of work list471* @msg_drop_count: counter of dropped msg for TX & RX472* @num_period: period number for TX & RX473* @callback_param: parameter for period elapse callback for TX & RX474* @callback: period elapse callback for TX & RX475* @send_message: function pointer for send message476* @lock: spin lock for TX & RX477* @wq_lock: lock for work queue478* @msg_lock: lock for send message479* @stream_timer: timer for tigger workqueue480*/481struct rpmsg_info {482struct rpmsg_device *rpdev;483struct device *dev;484struct completion cmd_complete;485struct pm_qos_request pm_qos_req;486487/* Received msg (global) */488struct rpmsg_r_msg r_msg;489struct rpmsg_msg msg[MSG_MAX_NUM];490/* period done */491struct rpmsg_msg notify[2];492bool notify_updated[2];493494struct workqueue_struct *rpmsg_wq;495struct work_of_rpmsg work_list[WORK_MAX_NUM];496int work_write_index;497int work_read_index;498int msg_drop_count[2];499int num_period[2];500void *callback_param[2];501dma_callback callback[2];502int (*send_message)(struct rpmsg_msg *msg, struct rpmsg_info *info);503spinlock_t lock[2]; /* spin lock for resource protection */504spinlock_t wq_lock; /* spin lock for resource protection */505struct mutex msg_lock; /* mutex for resource protection */506struct stream_timer stream_timer[2];507};508509#define IMX_PCM_DRV_NAME "imx_pcm_rpmsg"510511#endif /* IMX_PCM_RPMSG_H */512513514