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

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

Fix incorrectly indented double-slash comments.

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