1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Copyright (C) 2019 Pengutronix, Michael Tretter <kernel@pengutronix.de> |
4 | * |
5 | * Helper functions for handling messages that are send via mailbox to the |
6 | * Allegro VCU firmware. |
7 | */ |
8 | |
9 | #include <linux/bitfield.h> |
10 | #include <linux/export.h> |
11 | #include <linux/errno.h> |
12 | #include <linux/string.h> |
13 | #include <linux/videodev2.h> |
14 | |
15 | #include "allegro-mail.h" |
16 | |
17 | const char *msg_type_name(enum mcu_msg_type type) |
18 | { |
19 | static char buf[13]; |
20 | |
21 | switch (type) { |
22 | case MCU_MSG_TYPE_INIT: |
23 | return "INIT" ; |
24 | case MCU_MSG_TYPE_CREATE_CHANNEL: |
25 | return "CREATE_CHANNEL" ; |
26 | case MCU_MSG_TYPE_DESTROY_CHANNEL: |
27 | return "DESTROY_CHANNEL" ; |
28 | case MCU_MSG_TYPE_ENCODE_FRAME: |
29 | return "ENCODE_FRAME" ; |
30 | case MCU_MSG_TYPE_PUT_STREAM_BUFFER: |
31 | return "PUT_STREAM_BUFFER" ; |
32 | case MCU_MSG_TYPE_PUSH_BUFFER_INTERMEDIATE: |
33 | return "PUSH_BUFFER_INTERMEDIATE" ; |
34 | case MCU_MSG_TYPE_PUSH_BUFFER_REFERENCE: |
35 | return "PUSH_BUFFER_REFERENCE" ; |
36 | default: |
37 | snprintf(buf, size: sizeof(buf), fmt: "(0x%04x)" , type); |
38 | return buf; |
39 | } |
40 | } |
41 | EXPORT_SYMBOL(msg_type_name); |
42 | |
43 | static ssize_t |
44 | allegro_enc_init(u32 *dst, struct mcu_msg_init_request *msg) |
45 | { |
46 | unsigned int i = 0; |
47 | enum mcu_msg_version version = msg->header.version; |
48 | |
49 | dst[i++] = msg->reserved0; |
50 | dst[i++] = msg->suballoc_dma; |
51 | dst[i++] = msg->suballoc_size; |
52 | dst[i++] = msg->encoder_buffer_size; |
53 | dst[i++] = msg->encoder_buffer_color_depth; |
54 | dst[i++] = msg->num_cores; |
55 | if (version >= MCU_MSG_VERSION_2019_2) { |
56 | dst[i++] = msg->clk_rate; |
57 | dst[i++] = 0; |
58 | } |
59 | |
60 | return i * sizeof(*dst); |
61 | } |
62 | |
63 | static inline u32 settings_get_mcu_codec(struct create_channel_param *param) |
64 | { |
65 | enum mcu_msg_version version = param->version; |
66 | u32 pixelformat = param->codec; |
67 | |
68 | if (version < MCU_MSG_VERSION_2019_2) { |
69 | switch (pixelformat) { |
70 | case V4L2_PIX_FMT_HEVC: |
71 | return 2; |
72 | case V4L2_PIX_FMT_H264: |
73 | default: |
74 | return 1; |
75 | } |
76 | } else { |
77 | switch (pixelformat) { |
78 | case V4L2_PIX_FMT_HEVC: |
79 | return 1; |
80 | case V4L2_PIX_FMT_H264: |
81 | default: |
82 | return 0; |
83 | } |
84 | } |
85 | } |
86 | |
87 | ssize_t |
88 | allegro_encode_config_blob(u32 *dst, struct create_channel_param *param) |
89 | { |
90 | enum mcu_msg_version version = param->version; |
91 | unsigned int i = 0; |
92 | unsigned int j = 0; |
93 | u32 val; |
94 | unsigned int codec = settings_get_mcu_codec(param); |
95 | |
96 | if (version >= MCU_MSG_VERSION_2019_2) |
97 | dst[i++] = param->layer_id; |
98 | dst[i++] = FIELD_PREP(GENMASK(31, 16), param->height) | |
99 | FIELD_PREP(GENMASK(15, 0), param->width); |
100 | if (version >= MCU_MSG_VERSION_2019_2) |
101 | dst[i++] = param->videomode; |
102 | dst[i++] = param->format; |
103 | if (version < MCU_MSG_VERSION_2019_2) |
104 | dst[i++] = param->colorspace; |
105 | dst[i++] = param->src_mode; |
106 | if (version >= MCU_MSG_VERSION_2019_2) |
107 | dst[i++] = param->src_bit_depth; |
108 | dst[i++] = FIELD_PREP(GENMASK(31, 24), codec) | |
109 | FIELD_PREP(GENMASK(23, 8), param->constraint_set_flags) | |
110 | FIELD_PREP(GENMASK(7, 0), param->profile); |
111 | dst[i++] = FIELD_PREP(GENMASK(31, 16), param->tier) | |
112 | FIELD_PREP(GENMASK(15, 0), param->level); |
113 | |
114 | val = 0; |
115 | val |= param->temporal_mvp_enable ? BIT(20) : 0; |
116 | val |= FIELD_PREP(GENMASK(7, 4), param->log2_max_frame_num); |
117 | if (version >= MCU_MSG_VERSION_2019_2) |
118 | val |= FIELD_PREP(GENMASK(3, 0), param->log2_max_poc - 1); |
119 | else |
120 | val |= FIELD_PREP(GENMASK(3, 0), param->log2_max_poc); |
121 | dst[i++] = val; |
122 | |
123 | val = 0; |
124 | val |= param->enable_reordering ? BIT(0) : 0; |
125 | val |= param->dbf_ovr_en ? BIT(2) : 0; |
126 | val |= param->override_lf ? BIT(12) : 0; |
127 | dst[i++] = val; |
128 | |
129 | if (version >= MCU_MSG_VERSION_2019_2) { |
130 | val = 0; |
131 | val |= param->custom_lda ? BIT(2) : 0; |
132 | val |= param->rdo_cost_mode ? BIT(20) : 0; |
133 | dst[i++] = val; |
134 | |
135 | val = 0; |
136 | val |= param->lf ? BIT(2) : 0; |
137 | val |= param->lf_x_tile ? BIT(3) : 0; |
138 | val |= param->lf_x_slice ? BIT(4) : 0; |
139 | dst[i++] = val; |
140 | } else { |
141 | val = 0; |
142 | dst[i++] = val; |
143 | } |
144 | |
145 | dst[i++] = FIELD_PREP(GENMASK(15, 8), param->beta_offset) | |
146 | FIELD_PREP(GENMASK(7, 0), param->tc_offset); |
147 | dst[i++] = param->unknown11; |
148 | dst[i++] = param->unknown12; |
149 | dst[i++] = param->num_slices; |
150 | dst[i++] = param->encoder_buffer_offset; |
151 | dst[i++] = param->encoder_buffer_enabled; |
152 | |
153 | dst[i++] = FIELD_PREP(GENMASK(31, 16), param->clip_vrt_range) | |
154 | FIELD_PREP(GENMASK(15, 0), param->clip_hrz_range); |
155 | dst[i++] = FIELD_PREP(GENMASK(31, 16), param->me_range[1]) | |
156 | FIELD_PREP(GENMASK(15, 0), param->me_range[0]); |
157 | dst[i++] = FIELD_PREP(GENMASK(31, 16), param->me_range[3]) | |
158 | FIELD_PREP(GENMASK(15, 0), param->me_range[2]); |
159 | dst[i++] = FIELD_PREP(GENMASK(31, 24), param->min_tu_size) | |
160 | FIELD_PREP(GENMASK(23, 16), param->max_tu_size) | |
161 | FIELD_PREP(GENMASK(15, 8), param->min_cu_size) | |
162 | FIELD_PREP(GENMASK(8, 0), param->max_cu_size); |
163 | dst[i++] = FIELD_PREP(GENMASK(15, 8), param->max_transfo_depth_intra) | |
164 | FIELD_PREP(GENMASK(7, 0), param->max_transfo_depth_inter); |
165 | dst[i++] = param->entropy_mode; |
166 | dst[i++] = param->wp_mode; |
167 | |
168 | dst[i++] = param->rate_control_mode; |
169 | dst[i++] = param->initial_rem_delay; |
170 | dst[i++] = param->cpb_size; |
171 | dst[i++] = FIELD_PREP(GENMASK(31, 16), param->clk_ratio) | |
172 | FIELD_PREP(GENMASK(15, 0), param->framerate); |
173 | dst[i++] = param->target_bitrate; |
174 | dst[i++] = param->max_bitrate; |
175 | dst[i++] = FIELD_PREP(GENMASK(31, 16), param->min_qp) | |
176 | FIELD_PREP(GENMASK(15, 0), param->initial_qp); |
177 | dst[i++] = FIELD_PREP(GENMASK(31, 16), param->ip_delta) | |
178 | FIELD_PREP(GENMASK(15, 0), param->max_qp); |
179 | dst[i++] = FIELD_PREP(GENMASK(31, 16), param->golden_ref) | |
180 | FIELD_PREP(GENMASK(15, 0), param->pb_delta); |
181 | dst[i++] = FIELD_PREP(GENMASK(31, 16), param->golden_ref_frequency) | |
182 | FIELD_PREP(GENMASK(15, 0), param->golden_delta); |
183 | if (version >= MCU_MSG_VERSION_2019_2) |
184 | dst[i++] = param->rate_control_option; |
185 | else |
186 | dst[i++] = 0; |
187 | |
188 | if (version >= MCU_MSG_VERSION_2019_2) { |
189 | dst[i++] = param->num_pixel; |
190 | dst[i++] = FIELD_PREP(GENMASK(31, 16), param->max_pixel_value) | |
191 | FIELD_PREP(GENMASK(15, 0), param->max_psnr); |
192 | for (j = 0; j < 3; j++) |
193 | dst[i++] = param->maxpicturesize[j]; |
194 | } |
195 | |
196 | if (version >= MCU_MSG_VERSION_2019_2) |
197 | dst[i++] = param->gop_ctrl_mode; |
198 | else |
199 | dst[i++] = 0; |
200 | |
201 | if (version >= MCU_MSG_VERSION_2019_2) |
202 | dst[i++] = FIELD_PREP(GENMASK(31, 24), param->freq_golden_ref) | |
203 | FIELD_PREP(GENMASK(23, 16), param->num_b) | |
204 | FIELD_PREP(GENMASK(15, 0), param->gop_length); |
205 | dst[i++] = param->freq_idr; |
206 | if (version >= MCU_MSG_VERSION_2019_2) |
207 | dst[i++] = param->enable_lt; |
208 | dst[i++] = param->freq_lt; |
209 | dst[i++] = param->gdr_mode; |
210 | if (version < MCU_MSG_VERSION_2019_2) |
211 | dst[i++] = FIELD_PREP(GENMASK(31, 24), param->freq_golden_ref) | |
212 | FIELD_PREP(GENMASK(23, 16), param->num_b) | |
213 | FIELD_PREP(GENMASK(15, 0), param->gop_length); |
214 | |
215 | if (version >= MCU_MSG_VERSION_2019_2) |
216 | dst[i++] = param->tmpdqp; |
217 | |
218 | dst[i++] = param->subframe_latency; |
219 | dst[i++] = param->lda_control_mode; |
220 | if (version < MCU_MSG_VERSION_2019_2) |
221 | dst[i++] = param->unknown41; |
222 | |
223 | if (version >= MCU_MSG_VERSION_2019_2) { |
224 | for (j = 0; j < 6; j++) |
225 | dst[i++] = param->lda_factors[j]; |
226 | dst[i++] = param->max_num_merge_cand; |
227 | } |
228 | |
229 | return i * sizeof(*dst); |
230 | } |
231 | |
232 | static ssize_t |
233 | allegro_enc_create_channel(u32 *dst, struct mcu_msg_create_channel *msg) |
234 | { |
235 | enum mcu_msg_version version = msg->header.version; |
236 | unsigned int i = 0; |
237 | |
238 | dst[i++] = msg->user_id; |
239 | |
240 | if (version >= MCU_MSG_VERSION_2019_2) { |
241 | dst[i++] = msg->blob_mcu_addr; |
242 | } else { |
243 | memcpy(&dst[i], msg->blob, msg->blob_size); |
244 | i += msg->blob_size / sizeof(*dst); |
245 | } |
246 | |
247 | if (version >= MCU_MSG_VERSION_2019_2) |
248 | dst[i++] = msg->ep1_addr; |
249 | |
250 | return i * sizeof(*dst); |
251 | } |
252 | |
253 | ssize_t allegro_decode_config_blob(struct create_channel_param *param, |
254 | struct mcu_msg_create_channel_response *msg, |
255 | u32 *src) |
256 | { |
257 | enum mcu_msg_version version = msg->header.version; |
258 | |
259 | if (version >= MCU_MSG_VERSION_2019_2) { |
260 | param->num_ref_idx_l0 = FIELD_GET(GENMASK(7, 4), src[9]); |
261 | param->num_ref_idx_l1 = FIELD_GET(GENMASK(11, 8), src[9]); |
262 | } else { |
263 | param->num_ref_idx_l0 = msg->num_ref_idx_l0; |
264 | param->num_ref_idx_l1 = msg->num_ref_idx_l1; |
265 | } |
266 | |
267 | return 0; |
268 | } |
269 | |
270 | static ssize_t |
271 | allegro_enc_destroy_channel(u32 *dst, struct mcu_msg_destroy_channel *msg) |
272 | { |
273 | unsigned int i = 0; |
274 | |
275 | dst[i++] = msg->channel_id; |
276 | |
277 | return i * sizeof(*dst); |
278 | } |
279 | |
280 | static ssize_t |
281 | allegro_enc_push_buffers(u32 *dst, struct mcu_msg_push_buffers_internal *msg) |
282 | { |
283 | unsigned int i = 0; |
284 | struct mcu_msg_push_buffers_internal_buffer *buffer; |
285 | unsigned int num_buffers = msg->num_buffers; |
286 | unsigned int j; |
287 | |
288 | dst[i++] = msg->channel_id; |
289 | |
290 | for (j = 0; j < num_buffers; j++) { |
291 | buffer = &msg->buffer[j]; |
292 | dst[i++] = buffer->dma_addr; |
293 | dst[i++] = buffer->mcu_addr; |
294 | dst[i++] = buffer->size; |
295 | } |
296 | |
297 | return i * sizeof(*dst); |
298 | } |
299 | |
300 | static ssize_t |
301 | allegro_enc_put_stream_buffer(u32 *dst, |
302 | struct mcu_msg_put_stream_buffer *msg) |
303 | { |
304 | unsigned int i = 0; |
305 | |
306 | dst[i++] = msg->channel_id; |
307 | dst[i++] = msg->dma_addr; |
308 | dst[i++] = msg->mcu_addr; |
309 | dst[i++] = msg->size; |
310 | dst[i++] = msg->offset; |
311 | dst[i++] = lower_32_bits(msg->dst_handle); |
312 | dst[i++] = upper_32_bits(msg->dst_handle); |
313 | |
314 | return i * sizeof(*dst); |
315 | } |
316 | |
317 | static ssize_t |
318 | allegro_enc_encode_frame(u32 *dst, struct mcu_msg_encode_frame *msg) |
319 | { |
320 | enum mcu_msg_version version = msg->header.version; |
321 | unsigned int i = 0; |
322 | |
323 | dst[i++] = msg->channel_id; |
324 | |
325 | dst[i++] = msg->reserved; |
326 | dst[i++] = msg->encoding_options; |
327 | dst[i++] = FIELD_PREP(GENMASK(31, 16), msg->padding) | |
328 | FIELD_PREP(GENMASK(15, 0), msg->pps_qp); |
329 | |
330 | if (version >= MCU_MSG_VERSION_2019_2) { |
331 | dst[i++] = 0; |
332 | dst[i++] = 0; |
333 | dst[i++] = 0; |
334 | dst[i++] = 0; |
335 | } |
336 | |
337 | dst[i++] = lower_32_bits(msg->user_param); |
338 | dst[i++] = upper_32_bits(msg->user_param); |
339 | dst[i++] = lower_32_bits(msg->src_handle); |
340 | dst[i++] = upper_32_bits(msg->src_handle); |
341 | dst[i++] = msg->request_options; |
342 | dst[i++] = msg->src_y; |
343 | dst[i++] = msg->src_uv; |
344 | if (version >= MCU_MSG_VERSION_2019_2) |
345 | dst[i++] = msg->is_10_bit; |
346 | dst[i++] = msg->stride; |
347 | if (version >= MCU_MSG_VERSION_2019_2) |
348 | dst[i++] = msg->format; |
349 | dst[i++] = msg->ep2; |
350 | dst[i++] = lower_32_bits(msg->ep2_v); |
351 | dst[i++] = upper_32_bits(msg->ep2_v); |
352 | |
353 | return i * sizeof(*dst); |
354 | } |
355 | |
356 | static ssize_t |
357 | allegro_dec_init(struct mcu_msg_init_response *msg, u32 *src) |
358 | { |
359 | unsigned int i = 0; |
360 | |
361 | msg->reserved0 = src[i++]; |
362 | |
363 | return i * sizeof(*src); |
364 | } |
365 | |
366 | static ssize_t |
367 | allegro_dec_create_channel(struct mcu_msg_create_channel_response *msg, |
368 | u32 *src) |
369 | { |
370 | enum mcu_msg_version version = msg->header.version; |
371 | unsigned int i = 0; |
372 | |
373 | msg->channel_id = src[i++]; |
374 | msg->user_id = src[i++]; |
375 | /* |
376 | * Version >= MCU_MSG_VERSION_2019_2 is handled in |
377 | * allegro_decode_config_blob(). |
378 | */ |
379 | if (version < MCU_MSG_VERSION_2019_2) { |
380 | msg->options = src[i++]; |
381 | msg->num_core = src[i++]; |
382 | msg->num_ref_idx_l0 = FIELD_GET(GENMASK(7, 4), src[i]); |
383 | msg->num_ref_idx_l1 = FIELD_GET(GENMASK(11, 8), src[i++]); |
384 | } |
385 | msg->int_buffers_count = src[i++]; |
386 | msg->int_buffers_size = src[i++]; |
387 | msg->rec_buffers_count = src[i++]; |
388 | msg->rec_buffers_size = src[i++]; |
389 | msg->reserved = src[i++]; |
390 | msg->error_code = src[i++]; |
391 | |
392 | return i * sizeof(*src); |
393 | } |
394 | |
395 | static ssize_t |
396 | allegro_dec_destroy_channel(struct mcu_msg_destroy_channel_response *msg, |
397 | u32 *src) |
398 | { |
399 | unsigned int i = 0; |
400 | |
401 | msg->channel_id = src[i++]; |
402 | |
403 | return i * sizeof(*src); |
404 | } |
405 | |
406 | static ssize_t |
407 | allegro_dec_encode_frame(struct mcu_msg_encode_frame_response *msg, u32 *src) |
408 | { |
409 | enum mcu_msg_version version = msg->header.version; |
410 | unsigned int i = 0; |
411 | unsigned int j; |
412 | |
413 | msg->channel_id = src[i++]; |
414 | |
415 | msg->dst_handle = src[i++]; |
416 | msg->dst_handle |= (((u64)src[i++]) << 32); |
417 | msg->user_param = src[i++]; |
418 | msg->user_param |= (((u64)src[i++]) << 32); |
419 | msg->src_handle = src[i++]; |
420 | msg->src_handle |= (((u64)src[i++]) << 32); |
421 | msg->skip = FIELD_GET(GENMASK(31, 16), src[i]); |
422 | msg->is_ref = FIELD_GET(GENMASK(15, 0), src[i++]); |
423 | msg->initial_removal_delay = src[i++]; |
424 | msg->dpb_output_delay = src[i++]; |
425 | msg->size = src[i++]; |
426 | msg->frame_tag_size = src[i++]; |
427 | msg->stuffing = src[i++]; |
428 | msg->filler = src[i++]; |
429 | msg->num_row = FIELD_GET(GENMASK(31, 16), src[i]); |
430 | msg->num_column = FIELD_GET(GENMASK(15, 0), src[i++]); |
431 | msg->num_ref_idx_l1 = FIELD_GET(GENMASK(31, 24), src[i]); |
432 | msg->num_ref_idx_l0 = FIELD_GET(GENMASK(23, 16), src[i]); |
433 | msg->qp = FIELD_GET(GENMASK(15, 0), src[i++]); |
434 | msg->partition_table_offset = src[i++]; |
435 | msg->partition_table_size = src[i++]; |
436 | msg->sum_complex = src[i++]; |
437 | for (j = 0; j < 4; j++) |
438 | msg->tile_width[j] = src[i++]; |
439 | for (j = 0; j < 22; j++) |
440 | msg->tile_height[j] = src[i++]; |
441 | msg->error_code = src[i++]; |
442 | msg->slice_type = src[i++]; |
443 | msg->pic_struct = src[i++]; |
444 | msg->reserved = FIELD_GET(GENMASK(31, 24), src[i]); |
445 | msg->is_last_slice = FIELD_GET(GENMASK(23, 16), src[i]); |
446 | msg->is_first_slice = FIELD_GET(GENMASK(15, 8), src[i]); |
447 | msg->is_idr = FIELD_GET(GENMASK(7, 0), src[i++]); |
448 | |
449 | msg->reserved1 = FIELD_GET(GENMASK(31, 16), src[i]); |
450 | msg->pps_qp = FIELD_GET(GENMASK(15, 0), src[i++]); |
451 | |
452 | msg->reserved2 = src[i++]; |
453 | if (version >= MCU_MSG_VERSION_2019_2) { |
454 | msg->reserved3 = src[i++]; |
455 | msg->reserved4 = src[i++]; |
456 | msg->reserved5 = src[i++]; |
457 | msg->reserved6 = src[i++]; |
458 | } |
459 | |
460 | return i * sizeof(*src); |
461 | } |
462 | |
463 | /** |
464 | * allegro_encode_mail() - Encode allegro messages to firmware format |
465 | * @dst: Pointer to the memory that will be filled with data |
466 | * @msg: The allegro message that will be encoded |
467 | */ |
468 | ssize_t allegro_encode_mail(u32 *dst, void *msg) |
469 | { |
470 | const struct mcu_msg_header * = msg; |
471 | ssize_t size; |
472 | |
473 | if (!msg || !dst) |
474 | return -EINVAL; |
475 | |
476 | switch (header->type) { |
477 | case MCU_MSG_TYPE_INIT: |
478 | size = allegro_enc_init(dst: &dst[1], msg); |
479 | break; |
480 | case MCU_MSG_TYPE_CREATE_CHANNEL: |
481 | size = allegro_enc_create_channel(dst: &dst[1], msg); |
482 | break; |
483 | case MCU_MSG_TYPE_DESTROY_CHANNEL: |
484 | size = allegro_enc_destroy_channel(dst: &dst[1], msg); |
485 | break; |
486 | case MCU_MSG_TYPE_ENCODE_FRAME: |
487 | size = allegro_enc_encode_frame(dst: &dst[1], msg); |
488 | break; |
489 | case MCU_MSG_TYPE_PUT_STREAM_BUFFER: |
490 | size = allegro_enc_put_stream_buffer(dst: &dst[1], msg); |
491 | break; |
492 | case MCU_MSG_TYPE_PUSH_BUFFER_INTERMEDIATE: |
493 | case MCU_MSG_TYPE_PUSH_BUFFER_REFERENCE: |
494 | size = allegro_enc_push_buffers(dst: &dst[1], msg); |
495 | break; |
496 | default: |
497 | return -EINVAL; |
498 | } |
499 | |
500 | /* |
501 | * The encoded messages might have different length depending on |
502 | * the firmware version or certain fields. Therefore, we have to |
503 | * set the body length after encoding the message. |
504 | */ |
505 | dst[0] = FIELD_PREP(GENMASK(31, 16), header->type) | |
506 | FIELD_PREP(GENMASK(15, 0), size); |
507 | |
508 | return size + sizeof(*dst); |
509 | } |
510 | |
511 | /** |
512 | * allegro_decode_mail() - Parse allegro messages from the firmware. |
513 | * @msg: The mcu_msg_response that will be filled with parsed values. |
514 | * @src: Pointer to the memory that will be parsed |
515 | * |
516 | * The message format in the mailbox depends on the firmware. Parse the |
517 | * different formats into a uniform message format that can be used without |
518 | * taking care of the firmware version. |
519 | */ |
520 | int allegro_decode_mail(void *msg, u32 *src) |
521 | { |
522 | struct mcu_msg_header *; |
523 | |
524 | if (!src || !msg) |
525 | return -EINVAL; |
526 | |
527 | header = msg; |
528 | header->type = FIELD_GET(GENMASK(31, 16), src[0]); |
529 | |
530 | src++; |
531 | switch (header->type) { |
532 | case MCU_MSG_TYPE_INIT: |
533 | allegro_dec_init(msg, src); |
534 | break; |
535 | case MCU_MSG_TYPE_CREATE_CHANNEL: |
536 | allegro_dec_create_channel(msg, src); |
537 | break; |
538 | case MCU_MSG_TYPE_DESTROY_CHANNEL: |
539 | allegro_dec_destroy_channel(msg, src); |
540 | break; |
541 | case MCU_MSG_TYPE_ENCODE_FRAME: |
542 | allegro_dec_encode_frame(msg, src); |
543 | break; |
544 | default: |
545 | return -EINVAL; |
546 | } |
547 | |
548 | return 0; |
549 | } |
550 | |