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