Changeset 99cb9bf in mainline for uspace/drv/audio/hdaudio/pcm_iface.c


Ignore:
Timestamp:
2014-08-26T08:58:47Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
159c722d
Parents:
93c3163
Message:

Implement more of audio_pcm_iface.

File:
1 edited

Legend:

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

    r93c3163 r99cb9bf  
    4040#include <stdbool.h>
    4141
     42#include "codec.h"
     43#include "hdactl.h"
     44#include "hdaudio.h"
     45#include "spec/fmt.h"
     46#include "stream.h"
     47
    4248static int hda_get_info_str(ddf_fun_t *, const char **);
    4349static unsigned hda_query_cap(ddf_fun_t *, audio_cap_t);
     
    7480};
    7581
     82enum {
     83        max_buffer_size = 65536 /* XXX this is completely arbitrary */
     84};
     85
     86static hda_t *fun_to_hda(ddf_fun_t *fun)
     87{
     88        return (hda_t *)ddf_dev_data_get(ddf_fun_get_dev(fun));
     89}
     90
    7691static int hda_get_info_str(ddf_fun_t *fun, const char **name)
    7792{
    7893        ddf_msg(LVL_NOTE, "hda_get_info_str()");
    79         return ENOTSUP;
     94        if (name)
     95                *name = "High Definition Audio";
     96        return EOK;
    8097}
    8198
    8299static unsigned hda_query_cap(ddf_fun_t *fun, audio_cap_t cap)
    83100{
    84         ddf_msg(LVL_NOTE, "hda_query_cap()");
    85         return ENOTSUP;
     101        ddf_msg(LVL_NOTE, "hda_query_cap(%d)", cap);
     102        switch (cap) {
     103        case AUDIO_CAP_PLAYBACK:
     104        case AUDIO_CAP_INTERRUPT:
     105                return 1;
     106        case AUDIO_CAP_BUFFER_POS:
     107        case AUDIO_CAP_CAPTURE:
     108                return 0;
     109        case AUDIO_CAP_MAX_BUFFER:
     110                return max_buffer_size;
     111        case AUDIO_CAP_INTERRUPT_MIN_FRAMES:
     112                return 128;
     113        case AUDIO_CAP_INTERRUPT_MAX_FRAMES:
     114                return 16384;
     115        default:
     116                return ENOTSUP;
     117        }
    86118}
    87119
     
    89121    unsigned *rate, pcm_sample_format_t *format)
    90122{
    91         ddf_msg(LVL_NOTE, "hda_test_format()");
    92         return ENOTSUP;
     123        int rc = EOK;
     124
     125        ddf_msg(LVL_NOTE, "hda_test_format(%u, %u, %d)\n",
     126            *channels, *rate, *format);
     127
     128        if (*channels != 1) {
     129                *channels = 1;
     130                rc = ELIMIT;
     131        }
     132
     133        if (*format != PCM_SAMPLE_SINT16_LE) {
     134                *format = PCM_SAMPLE_SINT16_LE;
     135                rc = ELIMIT;
     136        }
     137
     138        if (*rate != 48000) {
     139                *rate = 48000;
     140                rc = ELIMIT;
     141        }
     142
     143        return rc;
    93144}
    94145
    95146static int hda_get_buffer(ddf_fun_t *fun, void **buffer, size_t *size)
    96147{
    97         ddf_msg(LVL_NOTE, "hda_get_buffer()");
    98         return ENOTSUP;
     148        hda_t *hda = fun_to_hda(fun);
     149
     150        ddf_msg(LVL_NOTE, "hda_get_buffer(): hda=%p", hda);
     151        if (hda->pcm_stream != NULL)
     152                return EBUSY;
     153
     154        /* XXX Choose appropriate parameters */
     155        uint32_t fmt;
     156        /* 48 kHz, 16-bits, 1 channel */
     157        fmt = fmt_bits_16 << fmt_bits_l;
     158
     159        ddf_msg(LVL_NOTE, "hda_get_buffer() - create stream");
     160        hda->pcm_stream = hda_stream_create(hda, sdir_output, fmt);
     161        if (hda->pcm_stream == NULL)
     162                return EIO;
     163
     164        ddf_msg(LVL_NOTE, "hda_get_buffer() - fill info");
     165        /* XXX This is only one buffer */
     166        *buffer = hda->pcm_stream->buf[0];
     167        *size = hda->pcm_stream->bufsize;
     168
     169        ddf_msg(LVL_NOTE, "hda_get_buffer() retturing EOK, buffer=%p, size=%zu",
     170            *buffer, *size);
     171        return EOK;
    99172}
    100173
     
    119192static int hda_release_buffer(ddf_fun_t *fun)
    120193{
     194        hda_t *hda = fun_to_hda(fun);
     195
    121196        ddf_msg(LVL_NOTE, "hda_release_buffer()");
    122         return ENOTSUP;
     197        if (hda->pcm_stream == NULL)
     198                return EINVAL;
     199
     200        hda_stream_destroy(hda->pcm_stream);
     201        hda->pcm_stream = NULL;
     202        return EOK;
    123203}
    124204
     
    126206    unsigned channels, unsigned rate, pcm_sample_format_t format)
    127207{
     208        hda_t *hda = fun_to_hda(fun);
     209        int rc;
     210
    128211        ddf_msg(LVL_NOTE, "hda_start_playback()");
    129         return ENOTSUP;
     212
     213        rc = hda_out_converter_setup(hda->ctl->codec, hda->pcm_stream->sid);
     214        if (rc != EOK)
     215                return rc;
     216
     217        hda_stream_start(hda->pcm_stream);
     218        return EOK;
    130219}
    131220
Note: See TracChangeset for help on using the changeset viewer.