Date: Sat, 25 Jun 2016 19:16:15 GMT From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r305548 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve Message-ID: <201606251916.u5PJGFur007429@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: iateaca Date: Sat Jun 25 19:16:14 2016 New Revision: 305548 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=305548 Log: implement the hda_codec_parse_format in order to get the sample rate, bits per sample and no. of channels parameters from the stream format implement the hda_codec_audio_output_do_setup function in order to set the stream parameters in the audio player call do_setup function when the stream is started just before to wake up the thread M bhyve/Makefile M bhyve/hda_codec.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/Makefile soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/Makefile ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/Makefile Sat Jun 25 18:28:22 2016 (r305547) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/Makefile Sat Jun 25 19:16:14 2016 (r305548) @@ -14,6 +14,7 @@ SRCS= \ atkbdc.c \ acpi.c \ + audio.c \ bhyverun.c \ block_if.c \ bootrom.c \ Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sat Jun 25 18:28:22 2016 (r305547) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sat Jun 25 19:16:14 2016 (r305548) @@ -4,6 +4,7 @@ #include <unistd.h> #include "pci_hda.h" +#include "audio.h" /* * HDA Codec defines @@ -26,6 +27,23 @@ #define HDA_CODEC_SUPP_STREAM_FORMATS_PCM (1 << HDA_PARAM_SUPP_STREAM_FORMATS_PCM_SHIFT) +#define HDA_CODEC_FMT_BASE_MASK (0x01 << 14) + +#define HDA_CODEC_FMT_MULT_MASK (0x07 << 11) +#define HDA_CODEC_FMT_MULT_2 (0x01 << 11) +#define HDA_CODEC_FMT_MULT_3 (0x02 << 11) +#define HDA_CODEC_FMT_MULT_4 (0x03 << 11) + +#define HDA_CODEC_FMT_DIV_MASK 0x07 +#define HDA_CODEC_FMT_DIV_SHIFT 8 + +#define HDA_CODEC_FMT_BITS_MASK (0x07 << 4) +#define HDA_CODEC_FMT_BITS_8 (0x00 << 4) +#define HDA_CODEC_FMT_BITS_16 (0x01 << 4) +#define HDA_CODEC_FMT_BITS_32 (0x04 << 4) + +#define HDA_CODEC_FMT_CHAN_MASK (0x0f << 0) + #define HDA_CODEC_AUDIO_WCAP_OUTPUT (0x00 << HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT) #define HDA_CODEC_AUDIO_WCAP_PIN (0x04 << HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT) #define HDA_CODEC_AUDIO_WCAP_CONN_LIST (1 << HDA_PARAM_AUDIO_WIDGET_CAP_CONN_LIST_SHIFT) @@ -57,6 +75,7 @@ */ typedef void (*transfer_func_t)(void *arg); +typedef int (*setup_func_t)(void *arg); struct hda_audio_ctxt { char name[64]; @@ -65,6 +84,7 @@ pthread_mutex_t mtx; pthread_cond_t cond; transfer_func_t do_transfer; + setup_func_t do_setup; void *priv; }; @@ -75,7 +95,7 @@ static void * hda_audio_ctxt_thr(void *arg); static int -hda_audio_ctxt_init(struct hda_audio_ctxt *actx, const char *tname, transfer_func_t do_transfer, void *priv); +hda_audio_ctxt_init(struct hda_audio_ctxt *actx, const char *tname, transfer_func_t do_transfer, setup_func_t do_setup, void *priv); static int hda_audio_ctxt_start(struct hda_audio_ctxt *actx); static int @@ -96,6 +116,7 @@ uint16_t fmt; struct hda_audio_ctxt actx; + struct audio *aud; }; struct hda_codec_softc { @@ -122,10 +143,14 @@ static int hda_codec_notify(struct hda_codec_inst *hci, uint8_t run, uint8_t stream, uint8_t dir); +static int hda_codec_parse_format(uint16_t fmt, struct audio_params *params); + static uint32_t hda_codec_audio_output_nid(struct hda_codec_softc *sc, uint16_t verb, uint16_t payload); static void hda_codec_audio_output_do_transfer(void *arg); +static int +hda_codec_audio_output_do_setup(void *arg); /* * HDA Codec global data @@ -202,6 +227,7 @@ hda_codec_init(struct hda_codec_inst *hci, const char *opts) { struct hda_codec_softc *sc = NULL; + struct hda_codec_stream *st = NULL; int err; DPRINTF("cad: 0x%x opts: %s\n", hci->cad, opts); @@ -219,9 +245,18 @@ sc->verb_handlers = hda_codec_verb_handlers; DPRINTF("HDA Codec nodes: %d\n", sc->no_nodes); - err = hda_audio_ctxt_init(&sc->streams[HDA_CODEC_STREAM_OUTPUT].actx, "hda-audio-output", hda_codec_audio_output_do_transfer, sc); + st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; + + err = hda_audio_ctxt_init(&st->actx, "hda-audio-output", hda_codec_audio_output_do_transfer, hda_codec_audio_output_do_setup, sc); assert(!err); + /* TODO Get the name of the sound device from the config string */ + st->aud = audio_init("/dev/dsp", 1); + if (!st->aud) { + DPRINTF("Fail to init the output audio player\n"); + return -1; + } + hci->priv = sc; return 0; @@ -333,7 +368,7 @@ DPRINTF("run: %d, stream: 0x%x, dir: %d\n", run, stream, dir); /* TODO search the right stream - * For now, there is only only stream + * For now, there is only one stream */ st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; @@ -350,6 +385,50 @@ return err; } +static int hda_codec_parse_format(uint16_t fmt, struct audio_params *params) +{ + uint8_t div = 0; + + /* Compute the Sample Rate */ + params->rate = (fmt & HDA_CODEC_FMT_BASE_MASK) ? 44100 : 48000; + + switch (fmt & HDA_CODEC_FMT_MULT_MASK) { + case HDA_CODEC_FMT_MULT_2: + params->rate *= 2; + break; + case HDA_CODEC_FMT_MULT_3: + params->rate *= 3; + break; + case HDA_CODEC_FMT_MULT_4: + params->rate *= 4; + break; + } + + div = (fmt >> HDA_CODEC_FMT_DIV_SHIFT) & HDA_CODEC_FMT_DIV_MASK; + params->rate /= (div + 1); + + /* Compute the Bits per Sample */ + switch (fmt & HDA_CODEC_FMT_BITS_MASK) { + case HDA_CODEC_FMT_BITS_8: + params->format = AFMT_U8; + break; + case HDA_CODEC_FMT_BITS_16: + params->format = AFMT_S16_LE; + break; + case HDA_CODEC_FMT_BITS_32: + params->format = AFMT_S32_LE; + break; + default: + DPRINTF("Unknown format bits: 0x%x\n", fmt & HDA_CODEC_FMT_BITS_MASK); + return -1; + } + + /* Compute the Number of Channels */ + params->channels = (fmt & HDA_CODEC_FMT_CHAN_MASK) + 1; + + return 0; +} + static uint32_t hda_codec_audio_output_nid(struct hda_codec_softc *sc, uint16_t verb, uint16_t payload) { @@ -379,14 +458,46 @@ static void hda_codec_audio_output_do_transfer(void *arg) { - /* - * TODO transfer betweenthe HDA and sound card - */ - DPRINTF("\n"); + struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; + struct hda_codec_stream *st = NULL; + struct audio *aud = NULL; + int err; + + st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; + aud = st->aud; + + memset(st->buf, 0x31, sizeof(st->buf)); + + err = audio_playback(aud, st->buf, sizeof(st->buf)); + assert(!err); + usleep(20 * 1000); + + DPRINTF("\n"); return; } +static int +hda_codec_audio_output_do_setup(void *arg) +{ + struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; + struct hda_codec_stream *st = NULL; + struct audio *aud = NULL; + struct audio_params params; + int err; + + st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; + aud = st->aud; + + err = hda_codec_parse_format(st->fmt, ¶ms); + if (err) + return -1; + + DPRINTF("rate: %d, channels: %d, format: 0x%x\n", params.rate, params.channels, params.format); + + return audio_set_params(aud, ¶ms); +} + struct hda_codec_class hda_codec = { .name = "hda_codec", .init = hda_codec_init, @@ -424,19 +535,21 @@ } static int -hda_audio_ctxt_init(struct hda_audio_ctxt *actx, const char *tname, transfer_func_t do_transfer, void *priv) +hda_audio_ctxt_init(struct hda_audio_ctxt *actx, const char *tname, transfer_func_t do_transfer, setup_func_t do_setup, void *priv) { int err; assert(actx); assert(tname); assert(do_transfer); + assert(do_setup); assert(priv); memset(actx, 0, sizeof(*actx)); actx->run = 0; actx->do_transfer = do_transfer; + actx->do_setup = do_setup; actx->priv = priv; if (strlen(tname) < sizeof(actx->name)) memcpy(actx->name, tname, strlen(tname) + 1); @@ -461,16 +574,21 @@ static int hda_audio_ctxt_start(struct hda_audio_ctxt *actx) { + int err = 0; + /* The stream is supposed to be stopped */ if (actx->run) return -1; pthread_mutex_lock(&actx->mtx); - actx->run = 1; - pthread_cond_signal(&actx->cond); + err = actx->do_setup(actx->priv); + if (!err) { + actx->run = 1; + pthread_cond_signal(&actx->cond); + } pthread_mutex_unlock(&actx->mtx); - return 0; + return err; } static int
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201606251916.u5PJGFur007429>