alsa compress driver

发布时间 2023-04-12 22:58:04作者: fellow_jing

 

platform driver 例子:https://elixir.bootlin.com/linux/v5.4.240/source/sound/soc/intel/atom/sst-mfld-platform-pcm.c#L525

static struct snd_soc_dai_driver sst_platform_dai[] = {
...
{
    .name = "compress-cpu-dai",
    .compress_new = snd_soc_new_compress,
    .ops = &sst_compr_dai_ops,
    .playback = {
        .stream_name = "Compress Playback",
        .channels_min = 1,
    },
},
...
};

static const struct snd_soc_dai_ops sst_media_dai_ops = {
    .startup = sst_media_open,
    .shutdown = sst_media_close,
    .prepare = sst_media_prepare,
    .hw_params = sst_media_hw_params,
    .hw_free = sst_media_hw_free,
    .mute_stream = sst_media_digital_mute,
};

static const struct snd_soc_component_driver sst_soc_platform_drv  = {
    .name        = DRV_NAME,
    .probe        = sst_soc_probe,
    .remove        = sst_soc_remove,
    .ops        = &sst_platform_ops,
    .compr_ops    = &sst_platform_compr_ops,
    .pcm_new    = sst_pcm_new,
};

const struct snd_compr_ops sst_platform_compr_ops = {

    .open = sst_platform_compr_open,
    .free = sst_platform_compr_free,
    .set_params = sst_platform_compr_set_params,
    .set_metadata = sst_platform_compr_set_metadata,
    .trigger = sst_platform_compr_trigger,
    .pointer = sst_platform_compr_pointer,
    .ack = sst_platform_compr_ack,
    .get_caps = sst_platform_compr_get_caps,
    .get_codec_caps = sst_platform_compr_get_codec_caps,
};

static int sst_platform_probe(struct platform_device *pdev)
{
    struct sst_data *drv;
    int ret;
    struct sst_platform_data *pdata;

    drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
    if (drv == NULL) {
        return -ENOMEM;
    }

    pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
    if (pdata == NULL) {
        return -ENOMEM;
    }

    pdata->pdev_strm_map = dpcm_strm_map;
    pdata->strm_map_size = ARRAY_SIZE(dpcm_strm_map);
    drv->pdata = pdata;
    drv->pdev = pdev;
    mutex_init(&drv->lock);
    dev_set_drvdata(&pdev->dev, drv);

    ret = devm_snd_soc_register_component(&pdev->dev, &sst_soc_platform_drv,
                sst_platform_dai, ARRAY_SIZE(sst_platform_dai));
    if (ret)
        dev_err(&pdev->dev, "registering cpu dais failed\n");

    return ret;
}

 

machine driver例子:https://elixir.bootlin.com/linux/v5.4.240/source/sound/soc/intel/boards/cht_bsw_nau8824.c#L191

SND_SOC_DAILINK_DEF(compress,
    DAILINK_COMP_ARRAY(COMP_CPU("compress-cpu-dai")));
static struct snd_soc_dai_link cht_dailink[] = {
    ...
    [MERR_DPCM_COMPR] = {
        .name = "Compressed Port",
        .stream_name = "Compress",
        SND_SOC_DAILINK_REG(compress, dummy, platform),
    },
    ...
};

/* SoC card */
static struct snd_soc_card snd_soc_card_cht = {
    .name = "chtnau8824",
    .owner = THIS_MODULE,
    .dai_link = cht_dailink,
    .num_links = ARRAY_SIZE(cht_dailink),
    .dapm_widgets = cht_dapm_widgets,
    .num_dapm_widgets = ARRAY_SIZE(cht_dapm_widgets),
    .dapm_routes = cht_audio_map,
    .num_dapm_routes = ARRAY_SIZE(cht_audio_map),
    .controls = cht_mc_controls,
    .num_controls = ARRAY_SIZE(cht_mc_controls),
};

static int snd_cht_mc_probe(struct platform_device *pdev)
{
    .....

    /* register the soc card */
    ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cht);
    if (ret_val) {
        dev_err(&pdev->dev,
            "snd_soc_register_card failed %d\n", ret_val);
        return ret_val;
    }
    platform_set_drvdata(pdev, &snd_soc_card_cht);

    return ret_val;
}