source: mainline/uspace/drv/audio/hdaudio/codec.c@ 09ab0a9a

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 09ab0a9a was e8975278, checked in by Jiri Svoboda <jiri@…>, 7 years ago

A few more cstyle fixes.

  • Property mode set to 100644
File size: 16.4 KB
Line 
1/*
2 * Copyright (c) 2014 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup hdaudio
30 * @{
31 */
32/** @file High Definition Audio codec
33 */
34
35#include <async.h>
36#include <bitops.h>
37#include <ddf/log.h>
38#include <errno.h>
39#include <str_error.h>
40#include <stdlib.h>
41
42#include "codec.h"
43#include "hdactl.h"
44#include "spec/codec.h"
45#include "spec/fmt.h"
46#include "stream.h"
47
48static errno_t hda_ccmd(hda_codec_t *codec, int node, uint32_t vid, uint32_t payload,
49 uint32_t *resp)
50{
51 uint32_t verb;
52 uint32_t myresp;
53
54 if (resp == NULL)
55 resp = &myresp;
56
57 if ((vid & 0x700) != 0) {
58 verb = (codec->address << 28) |
59 ((node & 0x1ff) << 20) |
60 ((vid & 0xfff) << 8) |
61 (payload & 0xff);
62 } else {
63 verb = (codec->address << 28) |
64 ((node & 0x1ff) << 20) |
65 ((vid & 0xf) << 16) |
66 (payload & 0xffff);
67 }
68 errno_t rc = hda_cmd(codec->hda, verb, resp);
69
70#if 0
71 if (resp != NULL) {
72 ddf_msg(LVL_NOTE, "verb 0x%" PRIx32 " -> 0x%" PRIx32, verb,
73 *resp);
74 } else {
75 ddf_msg(LVL_NOTE, "verb 0x%" PRIx32, verb);
76 }
77#endif
78 return rc;
79}
80
81static errno_t hda_get_parameter(hda_codec_t *codec, int node, hda_param_id_t param,
82 uint32_t *resp)
83{
84 return hda_ccmd(codec, node, hda_param_get, param, resp);
85}
86
87static errno_t hda_get_subnc(hda_codec_t *codec, int node, int *startnode,
88 int *nodecount)
89{
90 errno_t rc;
91 uint32_t resp;
92
93 rc = hda_get_parameter(codec, node, hda_sub_nc, &resp);
94 if (rc != EOK)
95 return rc;
96
97 *startnode = BIT_RANGE_EXTRACT(uint32_t, subnc_startnode_h,
98 subnc_startnode_l, resp);
99 *nodecount = BIT_RANGE_EXTRACT(uint32_t, subnc_nodecount_h,
100 subnc_nodecount_l, resp);
101
102 return EOK;
103}
104
105/** Get Function Group Type */
106static errno_t hda_get_fgrp_type(hda_codec_t *codec, int node, bool *unsol,
107 hda_fgrp_type_t *type)
108{
109 errno_t rc;
110 uint32_t resp;
111
112 rc = hda_get_parameter(codec, node, hda_fgrp_type, &resp);
113 if (rc != EOK)
114 return rc;
115
116 *unsol = (resp & BIT_V(uint32_t, fgrpt_unsol)) != 0;
117 *type = BIT_RANGE_EXTRACT(uint32_t, fgrpt_type_h, fgrpt_type_l, resp);
118
119 return EOK;
120}
121
122static errno_t hda_get_clist_len(hda_codec_t *codec, int node, bool *longform,
123 int *items)
124{
125 errno_t rc;
126 uint32_t resp;
127
128 rc = hda_get_parameter(codec, node, hda_clist_len, &resp);
129 if (rc != EOK)
130 return rc;
131
132 ddf_msg(LVL_DEBUG2, "hda_get_clist_len: resp=0x%x", resp);
133 *longform = resp & BIT_V(uint32_t, cll_longform);
134 *items = resp & BIT_RANGE_EXTRACT(uint32_t, cll_len_h, cll_len_l, resp);
135 return EOK;
136}
137
138static errno_t hda_get_clist_entry(hda_codec_t *codec, int node, int n, uint32_t *resp)
139{
140 return hda_ccmd(codec, node, hda_clist_entry_get, n, resp);
141}
142
143static errno_t hda_get_eapd_btl_enable(hda_codec_t *codec, int node, uint32_t *resp)
144{
145 return hda_ccmd(codec, node, hda_eapd_btl_enable_get, 0, resp);
146}
147
148static errno_t hda_set_eapd_btl_enable(hda_codec_t *codec, int node, uint8_t payload)
149{
150 return hda_ccmd(codec, node, hda_eapd_btl_enable_set, payload, NULL);
151}
152
153/** Get Suppported PCM Size, Rates */
154static errno_t hda_get_supp_rates(hda_codec_t *codec, int node, uint32_t *rates)
155{
156 return hda_get_parameter(codec, node, hda_supp_rates, rates);
157}
158
159/** Get Suppported Stream Formats */
160static errno_t hda_get_supp_formats(hda_codec_t *codec, int node, uint32_t *fmts)
161{
162 return hda_get_parameter(codec, node, hda_supp_formats, fmts);
163}
164
165static errno_t hda_set_converter_fmt(hda_codec_t *codec, int node, uint16_t fmt)
166{
167 return hda_ccmd(codec, node, hda_converter_fmt_set, fmt, NULL);
168}
169
170static errno_t hda_set_converter_ctl(hda_codec_t *codec, int node, uint8_t stream,
171 uint8_t channel)
172{
173 uint32_t ctl;
174
175 ctl = (stream << cctl_stream_l) | (channel << cctl_channel_l);
176 return hda_ccmd(codec, node, hda_converter_ctl_set, ctl, NULL);
177}
178
179static errno_t hda_set_pin_ctl(hda_codec_t *codec, int node, uint8_t pctl)
180{
181 return hda_ccmd(codec, node, hda_pin_ctl_set, pctl, NULL);
182}
183
184static errno_t hda_get_pin_ctl(hda_codec_t *codec, int node, uint8_t *pctl)
185{
186 errno_t rc;
187 uint32_t resp;
188
189 rc = hda_ccmd(codec, node, hda_pin_ctl_get, 0, &resp);
190 if (rc != EOK)
191 return rc;
192
193 *pctl = resp;
194 return EOK;
195}
196
197/** Get Audio Widget Capabilities */
198static errno_t hda_get_aw_caps(hda_codec_t *codec, int node,
199 hda_awidget_type_t *type, uint32_t *caps)
200{
201 errno_t rc;
202 uint32_t resp;
203
204 rc = hda_get_parameter(codec, node, hda_aw_caps, &resp);
205 if (rc != EOK)
206 return rc;
207
208 *type = BIT_RANGE_EXTRACT(uint32_t, awc_type_h, awc_type_l, resp);
209 *caps = resp;
210
211 return EOK;
212}
213
214/** Get Pin Capabilities */
215static errno_t hda_get_pin_caps(hda_codec_t *codec, int node, uint32_t *caps)
216{
217 return hda_get_parameter(codec, node, hda_pin_caps, caps);
218}
219
220/** Get Power State */
221static errno_t hda_get_power_state(hda_codec_t *codec, int node, uint32_t *pstate)
222{
223 return hda_ccmd(codec, node, hda_power_state_get, 0, pstate);
224}
225
226/** Get Configuration Default */
227static errno_t hda_get_cfg_def(hda_codec_t *codec, int node, uint32_t *cfgdef)
228{
229 return hda_ccmd(codec, node, hda_cfg_def_get, 0, cfgdef);
230}
231
232static errno_t hda_get_conn_sel(hda_codec_t *codec, int node, uint32_t *conn)
233{
234 return hda_ccmd(codec, node, hda_conn_sel_get, 0, conn);
235}
236
237/** Get Amplifier Gain / Mute */
238static errno_t hda_get_amp_gain_mute(hda_codec_t *codec, int node, uint16_t payload,
239 uint32_t *resp)
240{
241 ddf_msg(LVL_DEBUG2, "hda_get_amp_gain_mute(codec, %d, %x)",
242 node, payload);
243 errno_t rc = hda_ccmd(codec, node, hda_amp_gain_mute_get, payload, resp);
244 ddf_msg(LVL_DEBUG2, "hda_get_amp_gain_mute(codec, %d, %x, resp=%x)",
245 node, payload, *resp);
246 return rc;
247}
248
249/** Get GP I/O Count */
250static errno_t hda_get_gpio_cnt(hda_codec_t *codec, int node, uint32_t *resp)
251{
252 return hda_get_parameter(codec, node, hda_gpio_cnt, resp);
253}
254
255static errno_t hda_set_amp_gain_mute(hda_codec_t *codec, int node, uint16_t payload)
256{
257 ddf_msg(LVL_DEBUG2, "hda_set_amp_gain_mute(codec, %d, %x)",
258 node, payload);
259 return hda_ccmd(codec, node, hda_amp_gain_mute_set, payload, NULL);
260}
261
262static errno_t hda_set_out_amp_max(hda_codec_t *codec, uint8_t aw)
263{
264 uint32_t ampcaps;
265 uint32_t gmleft, gmright;
266 uint32_t offset;
267 errno_t rc;
268
269 rc = hda_get_parameter(codec, aw,
270 hda_out_amp_caps, &ampcaps);
271 if (rc != EOK)
272 goto error;
273
274 offset = ampcaps & 0x7f;
275 ddf_msg(LVL_NOTE, "out amp caps 0x%x (offset=0x%x)",
276 ampcaps, offset);
277
278 rc = hda_set_amp_gain_mute(codec, aw, 0xb000 + offset);
279 if (rc != EOK)
280 goto error;
281
282 rc = hda_get_amp_gain_mute(codec, aw, 0x8000, &gmleft);
283 if (rc != EOK)
284 goto error;
285
286 rc = hda_get_amp_gain_mute(codec, aw, 0xa000, &gmright);
287 if (rc != EOK)
288 goto error;
289
290 ddf_msg(LVL_NOTE, "gain/mute: L:0x%x R:0x%x", gmleft, gmright);
291
292 return EOK;
293error:
294 return rc;
295}
296
297static errno_t hda_set_in_amp_max(hda_codec_t *codec, uint8_t aw)
298{
299 uint32_t ampcaps;
300 uint32_t gmleft, gmright;
301 uint32_t offset;
302 int i;
303 errno_t rc;
304
305 rc = hda_get_parameter(codec, aw,
306 hda_out_amp_caps, &ampcaps);
307 if (rc != EOK)
308 goto error;
309
310 offset = ampcaps & 0x7f;
311 ddf_msg(LVL_NOTE, "in amp caps 0x%x (offset=0x%x)", ampcaps, offset);
312
313 for (i = 0; i < 15; i++) {
314 rc = hda_set_amp_gain_mute(codec, aw, 0x7000 + (i << 8) + offset);
315 if (rc != EOK)
316 goto error;
317
318 rc = hda_get_amp_gain_mute(codec, aw, 0x0000 + i, &gmleft);
319 if (rc != EOK)
320 goto error;
321
322 rc = hda_get_amp_gain_mute(codec, aw, 0x2000 + i, &gmright);
323 if (rc != EOK)
324 goto error;
325
326 ddf_msg(LVL_NOTE, "in:%d gain/mute: L:0x%x R:0x%x",
327 i, gmleft, gmright);
328 }
329
330 return EOK;
331error:
332 return rc;
333}
334
335static errno_t hda_clist_dump(hda_codec_t *codec, uint8_t aw)
336{
337 errno_t rc;
338 bool longform;
339 int len;
340 uint32_t resp;
341 uint32_t mask;
342 uint32_t cidx;
343 int shift;
344 int epresp;
345 int i, j;
346
347 ddf_msg(LVL_NOTE, "Connections for widget %d:", aw);
348
349 rc = hda_get_clist_len(codec, aw, &longform, &len);
350 if (rc != EOK) {
351 ddf_msg(LVL_ERROR, "Failed getting connection list length.");
352 return rc;
353 }
354
355 if (len > 1) {
356 rc = hda_get_conn_sel(codec, aw, &cidx);
357 if (rc != EOK) {
358 ddf_msg(LVL_ERROR, "Failed getting connection select");
359 return rc;
360 }
361 } else {
362 cidx = 0;
363 }
364
365 ddf_msg(LVL_DEBUG2, "longform:%d len:%d", longform, len);
366
367 if (longform) {
368 epresp = 2;
369 mask = 0xffff;
370 shift = 16;
371 } else {
372 epresp = 4;
373 mask = 0xff;
374 shift = 8;
375 }
376
377 i = 0;
378 while (i < len) {
379 rc = hda_get_clist_entry(codec, aw, i, &resp);
380 if (rc != EOK) {
381 ddf_msg(LVL_ERROR, "Failed getting connection list entry.");
382 return rc;
383 }
384
385 for (j = 0; j < epresp && i < len; j++) {
386 ddf_msg(LVL_NOTE, "<- %d%s", resp & mask,
387 (int)cidx == i ? " *** current *** " : "");
388 resp = resp >> shift;
389 ++i;
390 }
391
392 }
393
394 return rc;
395}
396
397static errno_t hda_pin_init(hda_codec_t *codec, uint8_t aw)
398{
399 errno_t rc;
400 uint32_t cfgdef;
401 uint32_t pcaps;
402 uint32_t eapd;
403 uint8_t pctl;
404
405 rc = hda_get_cfg_def(codec, aw, &cfgdef);
406 if (rc != EOK)
407 goto error;
408 ddf_msg(LVL_NOTE, "aw %d: PIN cdfgef=0x%x",
409 aw, cfgdef);
410
411 rc = hda_get_pin_caps(codec, aw, &pcaps);
412 if (rc != EOK)
413 goto error;
414 ddf_msg(LVL_NOTE, "aw %d : PIN caps=0x%x",
415 aw, pcaps);
416
417 if ((pcaps & BIT_V(uint32_t, pwc_eapd)) != 0) {
418 rc = hda_get_eapd_btl_enable(codec, aw, &eapd);
419 if (rc != EOK)
420 goto error;
421
422 ddf_msg(LVL_NOTE, "PIN %d had EAPD value=0x%x", aw, eapd);
423
424 rc = hda_set_eapd_btl_enable(codec, aw, eapd | 2);
425 if (rc != EOK)
426 goto error;
427
428 rc = hda_get_eapd_btl_enable(codec, aw, &eapd);
429 if (rc != EOK)
430 goto error;
431
432 ddf_msg(LVL_NOTE, "PIN %d now has EAPD value=0x%x", aw, eapd);
433 }
434
435 pctl = 0;
436 if ((pcaps & BIT_V(uint32_t, pwc_output)) != 0) {
437 ddf_msg(LVL_NOTE, "PIN %d will enable output", aw);
438 pctl = pctl | BIT_V(uint8_t, pctl_out_enable);
439 }
440
441 if ((pcaps & BIT_V(uint32_t, pwc_input)) != 0) {
442 ddf_msg(LVL_NOTE, "PIN %d will enable input", aw);
443 pctl = pctl | BIT_V(uint8_t, pctl_in_enable);
444 }
445
446 if ((pcaps & BIT_V(uint32_t, pwc_hpd)) != 0) {
447 ddf_msg(LVL_NOTE, "PIN %d will enable headphone drive", aw);
448 pctl = pctl | BIT_V(uint8_t, pctl_hpd_enable);
449 }
450
451#if 0
452 if ((pcaps & BIT_V(uint32_t, pwc_input)) != 0) {
453 ddf_msg(LVL_NOTE, "PIN %d will enable input");
454 pctl = pctl | BIT_V(uint8_t, pctl_input_enable);
455 }
456#endif
457 ddf_msg(LVL_NOTE, "Setting PIN %d ctl to 0x%x", aw, pctl);
458 rc = hda_set_pin_ctl(codec, aw, pctl);
459 if (rc != EOK)
460 goto error;
461
462 pctl = 0;
463 rc = hda_get_pin_ctl(codec, aw, &pctl);
464 if (rc != EOK)
465 goto error;
466
467 ddf_msg(LVL_NOTE, "PIN %d ctl reads as 0x%x", aw, pctl);
468
469 return EOK;
470error:
471 return rc;
472}
473
474/** Init power-control in wiget capable of doing so. */
475static errno_t hda_power_ctl_init(hda_codec_t *codec, uint8_t aw)
476{
477 errno_t rc;
478 uint32_t pwrstate;
479
480 ddf_msg(LVL_NOTE, "aw %d is power control-capable", aw);
481
482 rc = hda_get_power_state(codec, aw, &pwrstate);
483 if (rc != EOK)
484 goto error;
485 ddf_msg(LVL_NOTE, "aw %d: power state = 0x%x", aw, pwrstate);
486
487 return EOK;
488error:
489 return rc;
490}
491
492hda_codec_t *hda_codec_init(hda_t *hda, uint8_t address)
493{
494 hda_codec_t *codec;
495 errno_t rc;
496 int sfg, nfg;
497 int saw, naw;
498 int fg, aw;
499 bool unsol;
500 hda_fgrp_type_t grptype;
501 hda_awidget_type_t awtype;
502 uint32_t awcaps;
503 uint32_t rates;
504 uint32_t formats;
505 uint32_t gpio;
506
507 codec = calloc(1, sizeof(hda_codec_t));
508 if (codec == NULL)
509 return NULL;
510
511 codec->hda = hda;
512 codec->address = address;
513 codec->in_aw = -1;
514
515 rc = hda_get_subnc(codec, 0, &sfg, &nfg);
516 if (rc != EOK)
517 goto error;
518
519 ddf_msg(LVL_NOTE, "hda_get_subnc -> %s", str_error_name(rc));
520 ddf_msg(LVL_NOTE, "sfg=%d nfg=%d", sfg, nfg);
521
522 for (fg = sfg; fg < sfg + nfg; fg++) {
523 ddf_msg(LVL_NOTE, "Enumerate FG %d", fg);
524
525 rc = hda_get_fgrp_type(codec, fg, &unsol, &grptype);
526 if (rc != EOK)
527 goto error;
528
529 ddf_msg(LVL_NOTE, "hda_get_fgrp_type -> %s", str_error_name(rc));
530 ddf_msg(LVL_NOTE, "unsol: %d, grptype: %d", unsol, grptype);
531
532 rc = hda_get_gpio_cnt(codec, fg, &gpio);
533 if (rc != EOK)
534 goto error;
535
536 ddf_msg(LVL_NOTE, "GPIO: wake=%d unsol=%d gpis=%d gpos=%d gpios=%d",
537 (gpio & BIT_V(uint32_t, 31)) != 0,
538 (gpio & BIT_V(uint32_t, 30)) != 0,
539 BIT_RANGE_EXTRACT(uint32_t, 23, 16, gpio),
540 BIT_RANGE_EXTRACT(uint32_t, 15, 8, gpio),
541 BIT_RANGE_EXTRACT(uint32_t, 7, 0, gpio));
542
543 rc = hda_power_ctl_init(codec, fg);
544 if (rc != EOK)
545 goto error;
546
547 rc = hda_get_subnc(codec, fg, &saw, &naw);
548 if (rc != EOK)
549 goto error;
550
551 ddf_msg(LVL_NOTE, "hda_get_subnc -> %s", str_error_name(rc));
552 ddf_msg(LVL_NOTE, "saw=%d baw=%d", saw, naw);
553
554 for (aw = saw; aw < saw + naw; aw++) {
555 rc = hda_get_aw_caps(codec, aw, &awtype, &awcaps);
556 if (rc != EOK)
557 goto error;
558 ddf_msg(LVL_NOTE, "aw %d: type=0x%x caps=0x%x",
559 aw, awtype, awcaps);
560
561 if ((awcaps & BIT_V(uint32_t, awc_power_cntrl)) != 0) {
562 rc = hda_power_ctl_init(codec, aw);
563 if (rc != EOK)
564 goto error;
565 }
566
567 switch (awtype) {
568 case awt_audio_input:
569 case awt_audio_mixer:
570 case awt_audio_selector:
571 case awt_pin_complex:
572 case awt_power_widget:
573 rc = hda_clist_dump(codec, aw);
574 if (rc != EOK)
575 goto error;
576 break;
577 default:
578 break;
579 }
580
581 if (awtype == awt_pin_complex) {
582 rc = hda_pin_init(codec, aw);
583 if (rc != EOK)
584 goto error;
585 } else if (awtype == awt_audio_output) {
586 codec->out_aw_list[codec->out_aw_num++] = aw;
587
588 rc = hda_get_supp_rates(codec, aw, &rates);
589 if (rc != EOK)
590 goto error;
591
592 rc = hda_get_supp_formats(codec, aw, &formats);
593 if (rc != EOK)
594 goto error;
595
596 ddf_msg(LVL_NOTE, "Output widget %d: rates=0x%x formats=0x%x",
597 aw, rates, formats);
598 } else if (awtype == awt_audio_input) {
599 if (codec->in_aw < 0) {
600 ddf_msg(LVL_NOTE, "Selected input "
601 "widget %d\n", aw);
602 codec->in_aw = aw;
603 } else {
604 ddf_msg(LVL_NOTE, "Ignoring input "
605 "widget %d\n", aw);
606 }
607
608 rc = hda_get_supp_rates(codec, aw, &rates);
609 if (rc != EOK)
610 goto error;
611
612 rc = hda_get_supp_formats(codec, aw, &formats);
613 if (rc != EOK)
614 goto error;
615
616 ddf_msg(LVL_NOTE, "Input widget %d: rates=0x%x formats=0x%x",
617 aw, rates, formats);
618 }
619
620 if ((awcaps & BIT_V(uint32_t, awc_out_amp_present)) != 0)
621 hda_set_out_amp_max(codec, aw);
622
623 if ((awcaps & BIT_V(uint32_t, awc_in_amp_present)) != 0)
624 hda_set_in_amp_max(codec, aw);
625 }
626 }
627
628 hda_ctl_dump_info(hda->ctl);
629
630 ddf_msg(LVL_NOTE, "Codec OK");
631 return codec;
632error:
633 free(codec);
634 return NULL;
635}
636
637void hda_codec_fini(hda_codec_t *codec)
638{
639 ddf_msg(LVL_NOTE, "hda_codec_fini()");
640 free(codec);
641}
642
643errno_t hda_out_converter_setup(hda_codec_t *codec, hda_stream_t *stream)
644{
645 errno_t rc;
646 int out_aw;
647 int i;
648
649 for (i = 0; i < codec->out_aw_num; i++) {
650 out_aw = codec->out_aw_list[i];
651
652 /* Configure converter */
653
654 ddf_msg(LVL_NOTE, "Configure output converter format");
655 rc = hda_set_converter_fmt(codec, out_aw, stream->fmt);
656 if (rc != EOK)
657 goto error;
658
659 ddf_msg(LVL_NOTE, "Configure output converter stream, channel");
660 rc = hda_set_converter_ctl(codec, out_aw, stream->sid, 0);
661 if (rc != EOK)
662 goto error;
663 }
664
665 return EOK;
666error:
667 return rc;
668}
669
670errno_t hda_in_converter_setup(hda_codec_t *codec, hda_stream_t *stream)
671{
672 errno_t rc;
673
674 /* Configure converter */
675
676 ddf_msg(LVL_NOTE, "Configure input converter format");
677 rc = hda_set_converter_fmt(codec, codec->in_aw, stream->fmt);
678 if (rc != EOK)
679 goto error;
680
681 ddf_msg(LVL_NOTE, "Configure input converter stream, channel");
682 rc = hda_set_converter_ctl(codec, codec->in_aw, stream->sid, 0);
683 if (rc != EOK)
684 goto error;
685
686 return EOK;
687error:
688 return rc;
689}
690
691/** @}
692 */
Note: See TracBrowser for help on using the repository browser.