Changeset 1412a184 in mainline for uspace/drv/audio/hdaudio/codec.c


Ignore:
Timestamp:
2014-08-16T15:34:44Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a333b7f
Parents:
65b09c1
Message:

Stream management. Attempt some playback.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/audio/hdaudio/codec.c

    r65b09c1 r1412a184  
    4242#include "hdactl.h"
    4343#include "spec/codec.h"
     44#include "spec/fmt.h"
     45#include "stream.h"
     46
     47static int hda_ccmd(hda_codec_t *codec, int node, uint32_t vid, uint32_t payload,
     48    uint32_t *resp)
     49{
     50        uint32_t verb;
     51
     52        verb = (codec->address << 28) | (node << 20) | (vid << 8) | payload;
     53        return hda_cmd(codec->hda, verb, resp);
     54}
    4455
    4556static int hda_get_parameter(hda_codec_t *codec, int node, hda_param_id_t param,
    4657    uint32_t *resp)
    4758{
    48         uint32_t verb;
    49 
    50         verb = (codec->address << 28) | (node << 20) | ((hda_param_get) << 8) | param;
    51         return hda_cmd(codec->hda, verb, resp);
     59        return hda_ccmd(codec, node, hda_param_get, param, resp);
    5260}
    5361
     
    8795}
    8896
     97/** Get Suppported PCM Size, Rates */
     98static int hda_get_supp_rates(hda_codec_t *codec, int node, uint32_t *rates)
     99{
     100        return hda_get_parameter(codec, node, hda_supp_rates, rates);
     101}
     102
     103/** Get Suppported Stream Formats */
     104static int hda_get_supp_formats(hda_codec_t *codec, int node, uint32_t *fmts)
     105{
     106        return hda_get_parameter(codec, node, hda_supp_formats, fmts);
     107}
     108
     109static int hda_set_converter_fmt(hda_codec_t *codec, int node, uint16_t fmt)
     110{
     111        return hda_ccmd(codec, node, hda_converter_fmt_set, fmt, NULL);
     112}
     113
     114static int hda_set_converter_ctl(hda_codec_t *codec, int node, uint8_t stream,
     115    uint8_t channel)
     116{
     117        uint32_t ctl;
     118
     119        ctl = (stream << cctl_stream_l) | (channel << cctl_channel_l);
     120        return hda_ccmd(codec, node, hda_converter_ctl_set, ctl, NULL);
     121}
     122
    89123/** Get Audio Widget Capabilities */
    90124static int hda_get_aw_caps(hda_codec_t *codec, int node,
     
    107141static int hda_get_cfg_def(hda_codec_t *codec, int node, uint32_t *cfgdef)
    108142{
    109         uint32_t verb;
    110 
    111         verb = (codec->address << 28) | (node << 20) | ((hda_cfg_def_get) << 8) | 0;
    112         return hda_cmd(codec->hda, verb, cfgdef);
     143        return hda_ccmd(codec, node, hda_cfg_def_get, 0, cfgdef);
     144}
     145
     146/** Get Amplifier Gain / Mute  */
     147static int hda_get_amp_gain_mute(hda_codec_t *codec, int node, uint16_t payload,
     148    uint32_t *resp)
     149{
     150        return hda_ccmd(codec, node, hda_amp_gain_mute_get, payload, resp);
     151}
     152
     153static int hda_set_amp_gain_mute(hda_codec_t *codec, int node, uint16_t payload)
     154{
     155        return hda_ccmd(codec, node, hda_amp_gain_mute_set, payload, NULL);
    113156}
    114157
     
    125168        uint32_t awcaps;
    126169        uint32_t cfgdef;
     170        uint32_t rates;
     171        uint32_t formats;
    127172
    128173        codec = calloc(1, sizeof(hda_codec_t));
     
    171216                                    aw, cfgdef);
    172217
     218                        } else if (awtype == awt_audio_output) {
     219                                codec->out_aw = aw;
     220                        }
     221
     222                        if ((awcaps & BIT_V(uint32_t, awc_out_amp_present)) != 0) {
     223                                uint32_t ampcaps;
     224                                uint32_t gmleft, gmright;
     225
     226                                rc = hda_get_parameter(codec, aw,
     227                                    hda_out_amp_caps, &ampcaps);
     228                                if (rc != EOK)
     229                                        goto error;
     230
     231                                rc = hda_get_amp_gain_mute(codec, aw, 0x8000, &gmleft);
     232                                if (rc != EOK)
     233                                        goto error;
     234
     235                                rc = hda_get_amp_gain_mute(codec, aw, 0xc000, &gmright);
     236                                if (rc != EOK)
     237                                        goto error;
     238
     239                                ddf_msg(LVL_NOTE, "out amp caps 0x%x "
     240                                    "gain/mute: L:0x%x R:0x%x",
     241                                    ampcaps, gmleft, gmright);
     242
     243                                rc = hda_set_amp_gain_mute(codec, aw, 0xb04a);
     244                                if (rc != EOK)
     245                                        goto error;
    173246                        }
    174247                }
    175248        }
    176249
     250        rc = hda_get_supp_rates(codec, codec->out_aw, &rates);
     251        if (rc != EOK)
     252                goto error;
     253
     254        rc = hda_get_supp_formats(codec, codec->out_aw, &formats);
     255        if (rc != EOK)
     256                goto error;
     257
     258        ddf_msg(LVL_NOTE, "Output widget %d: rates=0x%x formats=0x%x",
     259            codec->out_aw, rates, formats);
     260
     261        /* XXX Choose appropriate parameters */
     262        uint32_t fmt;
     263        /* 48 kHz, 16-bits, 1 channel */
     264        fmt = fmt_bits_16 << fmt_bits_l;
     265
     266        /* Create stream */
     267        ddf_msg(LVL_NOTE, "Create stream");
     268        hda_stream_t *stream;
     269        stream = hda_stream_create(hda, sdir_output, fmt);
     270        if (stream == NULL)
     271                goto error;
     272
     273        /* Configure converter */
     274
     275        ddf_msg(LVL_NOTE, "Configure converter format");
     276        rc = hda_set_converter_fmt(codec, codec->out_aw, fmt);
     277        if (rc != EOK)
     278                goto error;
     279
     280        ddf_msg(LVL_NOTE, "Configure converter stream, channel");
     281        rc = hda_set_converter_ctl(codec, codec->out_aw, stream->sid, 0);
     282        if (rc != EOK)
     283                goto error;
     284
     285        ddf_msg(LVL_NOTE, "Start stream");
     286        hda_stream_start(stream);
     287
     288        ddf_msg(LVL_NOTE, "Codec OK");
    177289        return codec;
    178290error:
Note: See TracChangeset for help on using the changeset viewer.