linux/sound/soc/sof/intel/hda-compress.c
<<
>>
Prefs
   1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
   2//
   3// This file is provided under a dual BSD/GPLv2 license.  When using or
   4// redistributing this file, you may do so under either license.
   5//
   6// Copyright(c) 2019-2020 Intel Corporation. All rights reserved.
   7//
   8// Author: Cezary Rojewski <cezary.rojewski@intel.com>
   9//
  10
  11#include <sound/hdaudio_ext.h>
  12#include <sound/soc.h>
  13#include "../sof-priv.h"
  14#include "hda.h"
  15
  16static inline struct hdac_ext_stream *
  17hda_compr_get_stream(struct snd_compr_stream *cstream)
  18{
  19        return cstream->runtime->private_data;
  20}
  21
  22int hda_probe_compr_assign(struct snd_sof_dev *sdev,
  23                           struct snd_compr_stream *cstream,
  24                           struct snd_soc_dai *dai)
  25{
  26        struct hdac_ext_stream *stream;
  27
  28        stream = hda_dsp_stream_get(sdev, cstream->direction);
  29        if (!stream)
  30                return -EBUSY;
  31
  32        hdac_stream(stream)->curr_pos = 0;
  33        hdac_stream(stream)->cstream = cstream;
  34        cstream->runtime->private_data = stream;
  35
  36        return hdac_stream(stream)->stream_tag;
  37}
  38
  39int hda_probe_compr_free(struct snd_sof_dev *sdev,
  40                         struct snd_compr_stream *cstream,
  41                         struct snd_soc_dai *dai)
  42{
  43        struct hdac_ext_stream *stream = hda_compr_get_stream(cstream);
  44        int ret;
  45
  46        ret = hda_dsp_stream_put(sdev, cstream->direction,
  47                                 hdac_stream(stream)->stream_tag);
  48        if (ret < 0) {
  49                dev_dbg(sdev->dev, "stream put failed: %d\n", ret);
  50                return ret;
  51        }
  52
  53        hdac_stream(stream)->cstream = NULL;
  54        cstream->runtime->private_data = NULL;
  55
  56        return 0;
  57}
  58
  59int hda_probe_compr_set_params(struct snd_sof_dev *sdev,
  60                               struct snd_compr_stream *cstream,
  61                               struct snd_compr_params *params,
  62                               struct snd_soc_dai *dai)
  63{
  64        struct hdac_ext_stream *stream = hda_compr_get_stream(cstream);
  65        struct hdac_stream *hstream = hdac_stream(stream);
  66        struct snd_dma_buffer *dmab;
  67        u32 bits, rate;
  68        int bps, ret;
  69
  70        dmab = cstream->runtime->dma_buffer_p;
  71        /* compr params do not store bit depth, default to S32_LE */
  72        bps = snd_pcm_format_physical_width(SNDRV_PCM_FORMAT_S32_LE);
  73        if (bps < 0)
  74                return bps;
  75        bits = hda_dsp_get_bits(sdev, bps);
  76        rate = hda_dsp_get_mult_div(sdev, params->codec.sample_rate);
  77
  78        hstream->format_val = rate | bits | (params->codec.ch_out - 1);
  79        hstream->bufsize = cstream->runtime->buffer_size;
  80        hstream->period_bytes = cstream->runtime->fragment_size;
  81        hstream->no_period_wakeup = 0;
  82
  83        ret = hda_dsp_stream_hw_params(sdev, stream, dmab, NULL);
  84        if (ret < 0) {
  85                dev_err(sdev->dev, "error: hdac prepare failed: %x\n", ret);
  86                return ret;
  87        }
  88
  89        return 0;
  90}
  91
  92int hda_probe_compr_trigger(struct snd_sof_dev *sdev,
  93                            struct snd_compr_stream *cstream, int cmd,
  94                            struct snd_soc_dai *dai)
  95{
  96        struct hdac_ext_stream *stream = hda_compr_get_stream(cstream);
  97
  98        return hda_dsp_stream_trigger(sdev, stream, cmd);
  99}
 100
 101int hda_probe_compr_pointer(struct snd_sof_dev *sdev,
 102                            struct snd_compr_stream *cstream,
 103                            struct snd_compr_tstamp *tstamp,
 104                            struct snd_soc_dai *dai)
 105{
 106        struct hdac_ext_stream *stream = hda_compr_get_stream(cstream);
 107        struct snd_soc_pcm_stream *pstream;
 108
 109        pstream = &dai->driver->capture;
 110        tstamp->copied_total = hdac_stream(stream)->curr_pos;
 111        tstamp->sampling_rate = snd_pcm_rate_bit_to_rate(pstream->rates);
 112
 113        return 0;
 114}
 115