[PATCH v9 02/14] ASoC: Intel: catpt: Implement IPC protocol
Rojewski, Cezary
cezary.rojewski at intel.com
Mon Sep 28 18:52:41 CEST 2020
On 2020-09-28 3:44 PM, Andy Shevchenko wrote:
> On Sat, Sep 26, 2020 at 10:58:58AM +0200, Cezary Rojewski wrote:
>> Implement IRQ handlers for immediate and delayed replies and
>> notifications. Communication is synchronous and allows for serialization
>> of maximum one message at a time.
>>
>> DSP may respond with ADSP_PENDING status for a request - known as
>> delayed reply - and when situation occurs, framework keeps the lock and
>> awaits upcoming response through IPCD channel which is handled in
>> bottom-half. Immediate replies spawn no BH at all as their processing is
>> very short.
...
>> +static int catpt_dsp_do_send_msg(struct catpt_dev *cdev,
>> + struct catpt_ipc_msg request,
>> + struct catpt_ipc_msg *reply, int timeout)
>> +{
>> + struct catpt_ipc *ipc = &cdev->ipc;
>> + unsigned long flags;
>> + int ret;
>> +
>> + if (!ipc->ready)
>> + return -EPERM;
>> + if (request.size > ipc->config.outbox_size ||
>> + (reply && reply->size > ipc->config.outbox_size))
>> + return -EINVAL;
>> +
>> + spin_lock_irqsave(&ipc->lock, flags);
>> + catpt_ipc_msg_init(ipc, reply);
>> + catpt_dsp_send_tx(cdev, &request);
>> + spin_unlock_irqrestore(&ipc->lock, flags);
>> +
>> + ret = catpt_wait_msg_completion(cdev, timeout);
>> + if (ret) {
>> + dev_crit(cdev->dev, "communication severed: %d, rebooting dsp..\n",
>> + ret);
>> + ipc->ready = false;
>> + /* TODO: attempt recovery */
>> + return ret;
>> + }
>
>> + ret = ipc->rx.rsp.status;
>> + if (reply) {
>> + reply->header = ipc->rx.header;
>> + if (!ret && reply->data)
>> + memcpy(reply->data, ipc->rx.data, reply->size);
>> + }
>> +
>> + return ret;
>
> One more looking into this... What about
>
> if (reply)
> reply->header = ipc->rx.header;
>
> ret = ipc->rx.rsp.status; // or even directly if (status) return status.
> if (ret)
> return ret;
>
> if (reply->data)
> memcpy(reply->data, ipc->rx.data, reply->size);
>
> return 0;
>
> It may be verbose but I think readability is better here.
>
>> +}
>
In your example, last 'if' will cause exception if reply==NULL.
Got your point, although that's just few lines which already involve
'if' with { } spacing. After removing size-checks you suggested this
code is quite thin already.
>> + CATPT_CHANNEL_CONFIG_5_POINT_0 = 7, /* L, C, R, Ls & Rs */
>> + CATPT_CHANNEL_CONFIG_5_POINT_1 = 8, /* L, C, R, Ls, Rs & LFE */
>> + CATPT_CHANNEL_CONFIG_DUAL_MONO = 9, /* One channel replicated in two */
>> + CATPT_CHANNEL_CONFIG_INVALID = 10,
>
> Hmm... I think I got the point why DUAL_MONO was at the end of the switch-case.
>
Well, well. Indeed we found where Willy is..
>> +enum catpt_module_id {
>> + CATPT_MODID_BASE_FW = 0x0,
>> + CATPT_MODID_MP3 = 0x1,
>> + CATPT_MODID_AAC_5_1 = 0x2,
>> + CATPT_MODID_AAC_2_0 = 0x3,
>> + CATPT_MODID_SRC = 0x4,
>> + CATPT_MODID_WAVES = 0x5,
>> + CATPT_MODID_DOLBY = 0x6,
>> + CATPT_MODID_BOOST = 0x7,
>> + CATPT_MODID_LPAL = 0x8,
>> + CATPT_MODID_DTS = 0x9,
>> + CATPT_MODID_PCM_CAPTURE = 0xA,
>> + CATPT_MODID_PCM_SYSTEM = 0xB,
>> + CATPT_MODID_PCM_REFERENCE = 0xC,
>> + CATPT_MODID_PCM = 0xD, /* offload */
>> + CATPT_MODID_BLUETOOTH_RENDER = 0xE,
>> + CATPT_MODID_BLUETOOTH_CAPTURE = 0xF,
>> + CATPT_MODID_LAST = CATPT_MODID_BLUETOOTH_CAPTURE,
>> +};
>
> if you indent the values to be on the same column it will increase readability.
>
Sure, can indent for readability reasons.
>> +enum catpt_mclk_frequency {
>> + CATPT_MCLK_OFF = 0,
>> + CATPT_MCLK_FREQ_6_MHZ = 1,
>> + CATPT_MCLK_FREQ_21_MHZ = 2,
>> + CATPT_MCLK_FREQ_24_MHZ = 3,
>> +};
>
> Looks like a 3 MHz as base frequency with multiplicators 0, 2, 7, 8.
>
Naming based on FW enum type equivalent.
>> +#define CATPT_STREAM_MSG(msg_type) \
>> +{ \
>> + .stream_msg_type = CATPT_STRM_##msg_type, \
>> + .global_msg_type = CATPT_GLB_STREAM_MESSAGE }
>> +#define CATPT_STAGE_MSG(msg_type) \
>> +{ \
>> + .stage_action = CATPT_STG_##msg_type, \
>> + .stream_msg_type = CATPT_STRM_STAGE_MESSAGE, \
>> + .global_msg_type = CATPT_GLB_STREAM_MESSAGE }
>
> Hmm... This split is interesting. I would rather move } to a new line.
>
As basically everything in my code, style is based on existing example -
usually stuff from ASoC core - here, it's include/sound/soc.h. It's full
of such definitions so because catpt belongs to ASoC subsystem, I've
used the exact same style. No problem changing if that's your preference.
>> @@ -15,7 +15,6 @@
>> #define CATPT_SHIM_REGS_SIZE 4096
>> #define CATPT_DMA_REGS_SIZE 1024
>> #define CATPT_DMA_COUNT 2
>
>> -#define CATPT_SSP_COUNT 2
>
> Why is this?
>
Declaration of struct catpt_spec in patch 01/14 requires this while the
actual, logical (I'm not sure that's the right word here but I bet you
know what I mean) definition - one based on enum catpt_ssp_iface - is
available only here (02/14), with all other messages structs. I'd rather
modify the location of this constant than play with declaration of
struct catpt_spec between the patches.
Czarek
More information about the Alsa-devel
mailing list