1 // SPDX-License-Identifier: GPL-2.0-only
3 // Copyright(c) 2020 Intel Corporation. All rights reserved.
5 // Author: Cezary Rojewski <cezary.rojewski@intel.com>
8 #include <linux/slab.h>
11 #include "registers.h"
13 int catpt_ipc_get_fw_version(struct catpt_dev
*cdev
,
14 struct catpt_fw_version
*version
)
16 union catpt_global_msg msg
= CATPT_GLOBAL_MSG(GET_FW_VERSION
);
17 struct catpt_ipc_msg request
= {{0}}, reply
;
20 request
.header
= msg
.val
;
21 reply
.size
= sizeof(*version
);
24 ret
= catpt_dsp_send_msg(cdev
, request
, &reply
);
26 dev_err(cdev
->dev
, "get fw version failed: %d\n", ret
);
31 struct catpt_alloc_stream_input
{
32 enum catpt_path_id path_id
:8;
33 enum catpt_stream_type stream_type
:8;
34 enum catpt_format_id format_id
:8;
36 struct catpt_audio_format input_format
;
37 struct catpt_ring_info ring_info
;
39 /* flex array with entries here */
40 struct catpt_memory_info persistent_mem
;
41 struct catpt_memory_info scratch_mem
;
42 u32 num_notifications
; /* obsolete */
45 int catpt_ipc_alloc_stream(struct catpt_dev
*cdev
,
46 enum catpt_path_id path_id
,
47 enum catpt_stream_type type
,
48 struct catpt_audio_format
*afmt
,
49 struct catpt_ring_info
*rinfo
,
51 struct catpt_module_entry
*modules
,
52 struct resource
*persistent
,
53 struct resource
*scratch
,
54 struct catpt_stream_info
*sinfo
)
56 union catpt_global_msg msg
= CATPT_GLOBAL_MSG(ALLOCATE_STREAM
);
57 struct catpt_alloc_stream_input input
;
58 struct catpt_ipc_msg request
, reply
;
64 off
= offsetof(struct catpt_alloc_stream_input
, persistent_mem
);
65 arrsz
= sizeof(*modules
) * num_modules
;
66 size
= sizeof(input
) + arrsz
;
68 payload
= kzalloc(size
, GFP_KERNEL
);
72 memset(&input
, 0, sizeof(input
));
73 input
.path_id
= path_id
;
74 input
.stream_type
= type
;
75 input
.format_id
= CATPT_FORMAT_PCM
;
76 input
.input_format
= *afmt
;
77 input
.ring_info
= *rinfo
;
78 input
.num_entries
= num_modules
;
79 input
.persistent_mem
.offset
= catpt_to_dsp_offset(persistent
->start
);
80 input
.persistent_mem
.size
= resource_size(persistent
);
82 input
.scratch_mem
.offset
= catpt_to_dsp_offset(scratch
->start
);
83 input
.scratch_mem
.size
= resource_size(scratch
);
86 /* re-arrange the input: account for flex array 'entries' */
87 memcpy(payload
, &input
, sizeof(input
));
88 memmove(payload
+ off
+ arrsz
, payload
+ off
, sizeof(input
) - off
);
89 memcpy(payload
+ off
, modules
, arrsz
);
91 request
.header
= msg
.val
;
93 request
.data
= payload
;
94 reply
.size
= sizeof(*sinfo
);
97 ret
= catpt_dsp_send_msg(cdev
, request
, &reply
);
99 dev_err(cdev
->dev
, "alloc stream type %d failed: %d\n",
106 int catpt_ipc_free_stream(struct catpt_dev
*cdev
, u8 stream_hw_id
)
108 union catpt_global_msg msg
= CATPT_GLOBAL_MSG(FREE_STREAM
);
109 struct catpt_ipc_msg request
;
112 request
.header
= msg
.val
;
113 request
.size
= sizeof(stream_hw_id
);
114 request
.data
= &stream_hw_id
;
116 ret
= catpt_dsp_send_msg(cdev
, request
, NULL
);
118 dev_err(cdev
->dev
, "free stream %d failed: %d\n",
124 int catpt_ipc_set_device_format(struct catpt_dev
*cdev
,
125 struct catpt_ssp_device_format
*devfmt
)
127 union catpt_global_msg msg
= CATPT_GLOBAL_MSG(SET_DEVICE_FORMATS
);
128 struct catpt_ipc_msg request
;
131 request
.header
= msg
.val
;
132 request
.size
= sizeof(*devfmt
);
133 request
.data
= devfmt
;
135 ret
= catpt_dsp_send_msg(cdev
, request
, NULL
);
137 dev_err(cdev
->dev
, "set device format failed: %d\n", ret
);
142 int catpt_ipc_enter_dxstate(struct catpt_dev
*cdev
, enum catpt_dx_state state
,
143 struct catpt_dx_context
*context
)
145 union catpt_global_msg msg
= CATPT_GLOBAL_MSG(ENTER_DX_STATE
);
146 struct catpt_ipc_msg request
, reply
;
149 request
.header
= msg
.val
;
150 request
.size
= sizeof(state
);
151 request
.data
= &state
;
152 reply
.size
= sizeof(*context
);
153 reply
.data
= context
;
155 ret
= catpt_dsp_send_msg(cdev
, request
, &reply
);
157 dev_err(cdev
->dev
, "enter dx state failed: %d\n", ret
);
162 int catpt_ipc_get_mixer_stream_info(struct catpt_dev
*cdev
,
163 struct catpt_mixer_stream_info
*info
)
165 union catpt_global_msg msg
= CATPT_GLOBAL_MSG(GET_MIXER_STREAM_INFO
);
166 struct catpt_ipc_msg request
= {{0}}, reply
;
169 request
.header
= msg
.val
;
170 reply
.size
= sizeof(*info
);
173 ret
= catpt_dsp_send_msg(cdev
, request
, &reply
);
175 dev_err(cdev
->dev
, "get mixer info failed: %d\n", ret
);
180 int catpt_ipc_reset_stream(struct catpt_dev
*cdev
, u8 stream_hw_id
)
182 union catpt_stream_msg msg
= CATPT_STREAM_MSG(RESET_STREAM
);
183 struct catpt_ipc_msg request
= {{0}};
186 msg
.stream_hw_id
= stream_hw_id
;
187 request
.header
= msg
.val
;
189 ret
= catpt_dsp_send_msg(cdev
, request
, NULL
);
191 dev_err(cdev
->dev
, "reset stream %d failed: %d\n",
197 int catpt_ipc_pause_stream(struct catpt_dev
*cdev
, u8 stream_hw_id
)
199 union catpt_stream_msg msg
= CATPT_STREAM_MSG(PAUSE_STREAM
);
200 struct catpt_ipc_msg request
= {{0}};
203 msg
.stream_hw_id
= stream_hw_id
;
204 request
.header
= msg
.val
;
206 ret
= catpt_dsp_send_msg(cdev
, request
, NULL
);
208 dev_err(cdev
->dev
, "pause stream %d failed: %d\n",
214 int catpt_ipc_resume_stream(struct catpt_dev
*cdev
, u8 stream_hw_id
)
216 union catpt_stream_msg msg
= CATPT_STREAM_MSG(RESUME_STREAM
);
217 struct catpt_ipc_msg request
= {{0}};
220 msg
.stream_hw_id
= stream_hw_id
;
221 request
.header
= msg
.val
;
223 ret
= catpt_dsp_send_msg(cdev
, request
, NULL
);
225 dev_err(cdev
->dev
, "resume stream %d failed: %d\n",
231 struct catpt_set_volume_input
{
238 int catpt_ipc_set_volume(struct catpt_dev
*cdev
, u8 stream_hw_id
,
239 u32 channel
, u32 volume
,
241 enum catpt_audio_curve_type curve_type
)
243 union catpt_stream_msg msg
= CATPT_STAGE_MSG(SET_VOLUME
);
244 struct catpt_ipc_msg request
;
245 struct catpt_set_volume_input input
;
248 msg
.stream_hw_id
= stream_hw_id
;
249 input
.channel
= channel
;
250 input
.target_volume
= volume
;
251 input
.curve_duration
= curve_duration
;
252 input
.curve_type
= curve_type
;
254 request
.header
= msg
.val
;
255 request
.size
= sizeof(input
);
256 request
.data
= &input
;
258 ret
= catpt_dsp_send_msg(cdev
, request
, NULL
);
260 dev_err(cdev
->dev
, "set stream %d volume failed: %d\n",
266 struct catpt_set_write_pos_input
{
272 int catpt_ipc_set_write_pos(struct catpt_dev
*cdev
, u8 stream_hw_id
,
273 u32 pos
, bool eob
, bool ll
)
275 union catpt_stream_msg msg
= CATPT_STAGE_MSG(SET_WRITE_POSITION
);
276 struct catpt_ipc_msg request
;
277 struct catpt_set_write_pos_input input
;
280 msg
.stream_hw_id
= stream_hw_id
;
281 input
.new_write_pos
= pos
;
282 input
.end_of_buffer
= eob
;
283 input
.low_latency
= ll
;
285 request
.header
= msg
.val
;
286 request
.size
= sizeof(input
);
287 request
.data
= &input
;
289 ret
= catpt_dsp_send_msg(cdev
, request
, NULL
);
291 dev_err(cdev
->dev
, "set stream %d write pos failed: %d\n",
297 int catpt_ipc_mute_loopback(struct catpt_dev
*cdev
, u8 stream_hw_id
, bool mute
)
299 union catpt_stream_msg msg
= CATPT_STAGE_MSG(MUTE_LOOPBACK
);
300 struct catpt_ipc_msg request
;
303 msg
.stream_hw_id
= stream_hw_id
;
304 request
.header
= msg
.val
;
305 request
.size
= sizeof(mute
);
306 request
.data
= &mute
;
308 ret
= catpt_dsp_send_msg(cdev
, request
, NULL
);
310 dev_err(cdev
->dev
, "mute loopback failed: %d\n", ret
);