// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <digest/digest.h>
#include <fbl/algorithm.h>
#include <fbl/alloc_checker.h>
#include <limits>
#include <soc/aml-s912/s912-audio.h>
#include <utility>

#include "hdmitx.h"
#include "vim-display.h"
#include "vim-spdif-audio-stream.h"

#define SHIFTED_MASK(_name)      ((_name##_MASK) << (_name##_SHIFT))
#define SHIFTED_VAL(_name, _val) ((_val & _name##_MASK) << _name##_SHIFT)
#define MOD_FIELD(_name, _val) SHFTED_MASK(_name), SHIFTED_VAL(_name, _val)

namespace audio {
namespace vim2 {

namespace {
// 128 bytes per frame.  Why?  I have no idea.  This is clearly not an audio
// frame, nor is it a SPDIF block.  I suspect that it may be the amount of
// data which the DMA engine tries to fetch each time it jumps on the bus,
// but I don't really know for certain.
constexpr uint32_t AIU_958_BYTES_PER_FRAME = 128;

static const struct {
    uint32_t rate;
    uint32_t N;
} STANDARD_FRAME_RATE_N_LUT[] = {
    { .rate =  32000, .N =  4096 },
    { .rate =  48000, .N =  6144 },
    { .rate =  96000, .N = 12288 },
    { .rate = 192000, .N = 25467 },
    { .rate =  44100, .N =  6272 },
    { .rate =  88200, .N = 12544 },
    { .rate = 176400, .N = 28028 },
};
}   // anon namespace

Vim2SpdifAudioStream::Vim2SpdifAudioStream(const vim2_display* display,
                                           fbl::RefPtr<Registers> regs,
                                           fbl::RefPtr<RefCountedVmo> ring_buffer_vmo,
                                           fzl::PinnedVmo pinned_ring_buffer,
                                           uint64_t display_id)
    : SimpleAudioStream(display->parent, false),
      display_(display),
      display_id_(display_id),
      regs_(std::move(regs)),
      ring_buffer_vmo_(std::move(ring_buffer_vmo)),
      pinned_ring_buffer_(std::move(pinned_ring_buffer)) {
}

void Vim2SpdifAudioStream::ShutdownHook() {
    vim2_display_disable_audio(display_);
    Disable(*regs_);
}

void Vim2SpdifAudioStream::RingBufferShutdown() {
    vim2_display_disable_audio(display_);
}

zx_status_t Vim2SpdifAudioStream::ChangeFormat(const audio_proto::StreamSetFmtReq& req) {
    // Figure out the maximum number of audio frames we can fit into our ring
    // buffer while still guaranteeing...
    //
    // 1) The buffer is a multiple of audio frame size
    // 2) The buffer is a multiple of AIU frame size
    //
    ZX_DEBUG_ASSERT(frame_size_ > 0);
    usable_buffer_size_ = fbl::round_down(static_cast<uint32_t>(pinned_ring_buffer_.region(0).size),
                                          fbl::lcm(AIU_958_BYTES_PER_FRAME, frame_size_));

    // TODO(johngro): figure out the proper value for this
    fifo_depth_ = 512;

    // TODO(johngro): fill this out based on the estimate given by EDID (if any)
    external_delay_nsec_  = 0;

    // Figure out the proper values for N and CTS based on this audio mode and
    // pixel clock.
    // Start by going through our table of standard audio modes for standard
    // audio clocks.  If we cannot find the answer in the LUT, then fall back on
    // computing the answer on the fly using the recommended N as a starting
    // point to compute CTS.
    //
    // See section 7.2 (Audio Sample Clock Capture and Regeneration) of the HDMI
    // 1.3a spec (or later) for details.
    uint32_t N = 0;
    for (const auto& entry : STANDARD_FRAME_RATE_N_LUT) {
        if (entry.rate == req.frames_per_second) {
            N = entry.N;
            break;
        }
    }

    // This should never happen (As we are not advertising any frame rates which
    // are not in the LUT), but JiC.
    if (!N) {
        zxlogf(ERROR, "Failed to find starting N value for audio frame rate (%u).\n",
               req.frames_per_second);
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Given our suggested starting value for N, CTS should be computed as...
    //
    // CTS = pixel_clock * N / (128 * audio_frame_rate)
    //
    // Since our pixel clock is already expressed in KHz, this becomes
    // CTS = pkhz * N * 1000 / (128 * audio_frame_rate)
    //     = pkhz * N * 125  / (16 * audio_frame_rate)
    //
    // If our numerator is not divisible by 16 * frame_rate, then we would (in
    // theory) need to dither the N/CTS values being sent, which is something we
    // currently do not support.  For now, if this happens, return an error
    // instead.
    uint64_t numer = static_cast<uint64_t>(display_->p->timings.pfreq) * N * 125;
    uint32_t denom = req.frames_per_second << 4;

    if (numer % denom) {
        zxlogf(ERROR, "Failed to find CTS value (pclk %u, N %u, frame_rate %u)\n",
               display_->p->timings.pfreq, N, req.frames_per_second);
        return ZX_ERR_NOT_SUPPORTED;
    }

    uint32_t CTS = static_cast<uint32_t>(numer / denom);
    uint32_t bits_per_sample;
    switch (req.sample_format) {
    case AUDIO_SAMPLE_FORMAT_16BIT:         bits_per_sample = 16; break;
    case AUDIO_SAMPLE_FORMAT_24BIT_PACKED:  __FALLTHROUGH;
    case AUDIO_SAMPLE_FORMAT_24BIT_IN32:    bits_per_sample = 24; break;
    default:
        zxlogf(ERROR, "Unsupported requested sample format (0x%08x)!\n", req.sample_format);
        return ZX_ERR_NOT_SUPPORTED;
    }

    // Set up the registers to match our format choice.
    SetMode(req.frames_per_second, req.sample_format);

    // Tell the HDMI driver about the mode we just configured.
    zx_status_t res;
    res = vim2_display_configure_audio_mode(display_,
                                            N, CTS,
                                            req.frames_per_second, bits_per_sample);
    if (res != ZX_OK) {
        zxlogf(ERROR, "Failed to configure VIM2 HDMI TX audio parameters! (res %d)\n", res);
        return res;
    }

    return ZX_OK;
}

zx_status_t Vim2SpdifAudioStream::GetBuffer(const audio_proto::RingBufGetBufferReq& req,
                                            uint32_t* out_num_rb_frames,
                                            zx::vmo* out_buffer) {
    uint32_t rb_frames = usable_buffer_size_ / frame_size_;
    if (req.min_ring_buffer_frames > rb_frames) {
        return ZX_ERR_OUT_OF_RANGE;
    }

    constexpr uint32_t rights = ZX_RIGHT_READ | ZX_RIGHT_WRITE | ZX_RIGHT_MAP | ZX_RIGHT_TRANSFER;
    zx_status_t res = ring_buffer_vmo_->vmo().duplicate(rights, out_buffer);
    if (res != ZX_OK) {
        return res;
    }

    *out_num_rb_frames = rb_frames;
    SetupBuffer();
    return ZX_OK;
}

zx_status_t Vim2SpdifAudioStream::Start(uint64_t* out_start_time) {
    uint64_t a, b;

    Mute(cur_gain_state_.cur_mute);
    a = zx_clock_get(ZX_CLOCK_MONOTONIC);
    Enable();
    b = zx_clock_get(ZX_CLOCK_MONOTONIC);
    *out_start_time = ((b - a) >> 1) + a;

    return ZX_OK;
}

zx_status_t Vim2SpdifAudioStream::Stop() {
    Disable(*regs_);
    Mute(false);
    return ZX_OK;
}

zx_status_t Vim2SpdifAudioStream::SetGain(const audio_proto::SetGainReq& req) {
    if (req.flags & AUDIO_SGF_MUTE_VALID) {
        cur_gain_state_.cur_mute = ((req.flags & AUDIO_SGF_MUTE) != 0);
        Mute(cur_gain_state_.cur_mute);
    }

    return ZX_OK;
}

zx_status_t Vim2SpdifAudioStream::Init() {
    zx_status_t res;

    if (!regs_) {
        zxlogf(ERROR, "null or invalid registers in %s\n", __PRETTY_FUNCTION__);
        return ZX_ERR_INVALID_ARGS;
    }

    Disable(*regs_);

    if (!ring_buffer_vmo_ || !ring_buffer_vmo_->vmo().is_valid()) {
        zxlogf(ERROR, "Bad ring buffer VMO passed to %s\n", __PRETTY_FUNCTION__);
        return ZX_ERR_INVALID_ARGS;
    }

    // Set up the DMA addresses.
    if ((pinned_ring_buffer_.region_count() != 1) ||
        (pinned_ring_buffer_.region(0).size < PAGE_SIZE) ||
       ((pinned_ring_buffer_.region(0).phys_addr + pinned_ring_buffer_.region(0).size)
        >= std::numeric_limits<uint32_t>::max())) {
        zxlogf(ERROR, "Bad ring buffer scatter/gather list passed to %s\n", __PRETTY_FUNCTION__);
        return ZX_ERR_INVALID_ARGS;
    }

    res = CreateFormatList();
    if (res != ZX_OK) {
        return res;
    }

    // Set our gain capabilities.
    cur_gain_state_.cur_gain = 0.0;
    cur_gain_state_.cur_mute = false;
    cur_gain_state_.cur_agc  = false;

    cur_gain_state_.min_gain = 0.0;
    cur_gain_state_.max_gain = 0.0;
    cur_gain_state_.gain_step = 0.0;
    cur_gain_state_.can_mute = true;
    cur_gain_state_.can_agc  = false;

    // Set our device node name.
    snprintf(device_name_, sizeof(device_name_), "vim2-spdif-out");

    // Create our unique ID by hashing portions of the EDID we get from our
    // display.  In particular, look for and hash...
    //
    // 1) The vendor/product ID.
    // 2) The first monitor descriptor, if present.
    // 3) The monitor serial number, if present.
    //
    // We deliberately do not simply hash contents the entire EDID.  Timing
    // and other configuration information can change, esp. when a device is
    // connected to an AV receiver and changes are made to the processing
    // configuration of the AVR.  We want to focus on attempting to identify the
    // device we are connected to, and not the mode that it is operating in.
    //
    // While we are parsing this information, also extract the manufacturer name
    // (from the vendor/product ID section), and the device name (from the first
    // monitor descriptor, if present).
    //
    // TODO(johngro): Someday, when this gets split into separate DAI/Codec
    // drivers, this code belongs in the HDMI codec section of things.
    digest::Digest sha;
    res = sha.Init();
    if (res != ZX_OK) {
        zxlogf(WARN, "Failed to initialize digest while computing unique ID.  (res %d)\n", res);
        return res;
    }

    // Seed our SHA with a constant number taken from 'uuidgen'.
    static const uint8_t SEED[] = { 0xd8, 0x27, 0x52, 0xb7, 0x60, 0x9a, 0x46, 0xd4,
                                    0xa6, 0xc4, 0xdc, 0x32, 0xf5, 0xce, 0x1b, 0x7d };
    sha.Update(SEED, sizeof(SEED));

    snprintf(mfr_name_, sizeof(mfr_name_), "%s",
             strlen(display_->manufacturer_name) ? display_->manufacturer_name : "<unknown>");
    snprintf(prod_name_, sizeof(prod_name_), "%s",
             strlen(display_->monitor_name) ? display_->monitor_name : "Generic HDMI");

    sha.Update(mfr_name_, strnlen(mfr_name_, sizeof(mfr_name_)));
    sha.Update(prod_name_, strnlen(prod_name_, sizeof(prod_name_)));
    sha.Update(display_->monitor_serial,
               strnlen(display_->monitor_serial, sizeof(display_->monitor_serial)));

    // Finish the SHA and attempt to copy as much of the results to our internal
    // cached representation as we can.
    uint8_t digest_out[digest::Digest::kLength];
    sha.Final();
    res = sha.CopyTo(digest_out, sizeof(digest_out));
    if (res != ZX_OK) {
        zxlogf(ERROR, "Failed to copy digest while computing unique ID.  (res %d)", res);
        return res;
    }
    ::memset(unique_id_.data, 0, sizeof(unique_id_.data));
    ::memcpy(unique_id_.data, digest_out, fbl::min(sizeof(digest_out), sizeof(unique_id_.data)));

    return ZX_OK;
}

void Vim2SpdifAudioStream::Disable(const Registers& regs) {
    regs.Write32(0, AIU_958_DCU_FF_CTRL); // Disable the FIFO
    regs.ClearBits32(AIU_958_MCTRL_FILL_ENB | AIU_958_MCTRL_EMPTY_ENB,
                     AIU_MEM_IEC958_CONTROL); // Disable the DMA
    regs.Write32(AIU_RS_958_FAST_DOMAIN, AIU_RST_SOFT); // reset the unit
}

zx_status_t Vim2SpdifAudioStream::CreateFormatList() {
    // Compute the list of audio formats that we support.  To do this, we need
    // to intersect the capabilities of the display sink we are connect to, with
    // the capabilities of the S912 audio hardware.
    //
    // The DesignWare HDMI transmitter which is integrated into the S912 can be
    // fed a couple of different ways; either from one or more I2S units acting
    // in parallel, or one or more SPDIF units acting in parallel.  Each unit
    // can carry up to 2 channels of audio.  The DesignWare block also has
    // options to synthesize its own independent DMA engine (which would have
    // been super convenient), but these features were not enabled when the S912
    // was synthesized.
    //
    // The S912 has only 1 SPDIF unit (as well as only one I2S unit), which
    // limits our maximum number of channels to 2.
    //
    // In addition, the way that the clocks are being set up on VIM2, there is
    // no factor of 7 in the clock feeding the audio units.  Because of this, we
    // cannot generate any of the 44.1k family of audio rates.  We can, however,
    // generate clock rates up to 192KHz, and can generate 16, 20, and 24 bit audio.
    for (unsigned i = 0; i < display_->audio_format_count; i++) {
        audio_stream_format_range_t range;
        zx_status_t status = display_controller_interface_get_audio_format(
            &display_->dc_intf, display_->display_id, i, &range);
        ZX_ASSERT(status == ZX_OK);

        constexpr uint32_t SUPPORTED_FORMATS = AUDIO_SAMPLE_FORMAT_16BIT |
                AUDIO_SAMPLE_FORMAT_24BIT_PACKED | AUDIO_SAMPLE_FORMAT_24BIT_IN32;
        range.sample_formats =
                static_cast<audio_sample_format_t>(range.sample_formats & SUPPORTED_FORMATS);
        if (range.sample_formats == 0) {
            continue;
        }

        // Require stereo
        if (range.max_channels <  2) {
            continue;
        }
        range.max_channels = fbl::min<uint8_t>(range.max_channels, 2);

        constexpr uint32_t MIN_SUPPORTED_RATE = 32000;
        constexpr uint32_t MAX_SUPPORTED_RATE = 192000;
        range.flags &= ASF_RANGE_FLAG_FPS_48000_FAMILY;
        if (range.flags == 0
                || range.max_frames_per_second < MIN_SUPPORTED_RATE
                || range.min_frames_per_second > MAX_SUPPORTED_RATE) {
            continue;
        }
        range.max_frames_per_second = fbl::min(MAX_SUPPORTED_RATE, range.max_frames_per_second);
        range.min_frames_per_second = fbl::max(MIN_SUPPORTED_RATE, range.min_frames_per_second);

        fbl::AllocChecker ac;
        supported_formats_.push_back(range, &ac);
        if (!ac.check()) {
            zxlogf(ERROR, "Out of memory attempting to construct supported format list.\n");
            return ZX_ERR_NO_MEMORY;
        }
    }

    return ZX_OK;
}

void Vim2SpdifAudioStream::Enable() {
    const auto& regs = *regs_;

    regs.Write32(AIU_RS_958_FAST_DOMAIN, AIU_RST_SOFT);   // reset

    // Force the next sample fetched from the FIFO to be the start of a
    // frame by writing *any* value to the FORCE_LEFT register.
    //
    // Note: In the AmLogic documentation I have access to,  this register is
    // actually missing from the documentation (but mentioned briefly in the
    // discussion of bit 13 of AIU_958_MISC).  Notes left by the AM Logic driver
    // author in other codebases seem to say that when the SPDIF serializer has
    // been reset, that whether or not the next payload is supposed to be a left
    // or right sample does not actually get reset.  In order to get a proper
    // sequence of marker bits transmitted, we are supposed to use the
    // FORCE_LEFT register to reset this state as well any time we reset the
    // SPDIF TX unit.
    regs.Write32(0x00, AIU_958_FORCE_LEFT);

    regs.SetBits32(AIU_958_MCTRL_FILL_ENB | AIU_958_MCTRL_EMPTY_ENB,
                   AIU_MEM_IEC958_CONTROL);   // Enable the DMA
    regs.SetBits32(AIU_958_DCU_FF_CTRL_ENB, AIU_958_DCU_FF_CTRL);       // Enable the fifo
}

void Vim2SpdifAudioStream::SetupBuffer() {
    ZX_DEBUG_ASSERT((regs_ != nullptr));
    const auto& regs = *regs_;

    // Set up the DMA addresses.
    ZX_DEBUG_ASSERT(pinned_ring_buffer_.region_count() == 1);
    ZX_DEBUG_ASSERT(pinned_ring_buffer_.region(0).size >= 8);
    ZX_DEBUG_ASSERT((pinned_ring_buffer_.region(0).phys_addr +
                     pinned_ring_buffer_.region(0).size - 1)
                    <= std::numeric_limits<uint32_t>::max());

    const auto& r = pinned_ring_buffer_.region(0);
    ZX_DEBUG_ASSERT(usable_buffer_size_ >= AIU_958_BYTES_PER_FRAME);
    ZX_DEBUG_ASSERT(usable_buffer_size_ <= r.size);
    regs.Write32(static_cast<uint32_t>(r.phys_addr), AIU_MEM_IEC958_START_PTR);
    regs.Write32(static_cast<uint32_t>(r.phys_addr), AIU_MEM_IEC958_RD_PTR);
    regs.Write32(static_cast<uint32_t>(r.phys_addr + usable_buffer_size_ - 8), AIU_MEM_IEC958_END_PTR);

    // Set the masks register to all channels present, and to read from all
    // channels.  Apparently, this is the thing to do when we are operating in
    // "split mode"
    regs.Write32(0xFFFF, AIU_MEM_IEC958_MASKS);

    // Now that the buffer has been set up, perform some register writes to the
    // CONTROL and BUF_CONTROL registers in order complete the setup.
    //
    // Exactly what this is accomplishing is something of a mystery.
    // Documentation for bit 0 of the MEM_CONTROL register consists of "bit 0:
    // cntl_init".  Documentation for the low 16 bits of the BUF_CNTL register
    // consists of "bits [0:15]: level_hold".  Why we need to follow this
    // sequence, or what it is accomplishing, is not documented.
    //
    // This sequence is here right now because it is done by the driver written
    // by AmLogic's engineer(s) in other code bases.  They provide no
    // real explanation for what is going on here either; so for now, this
    // remains nothing but cargo-cult garbage.
    regs.SetBits32(AIU_958_MCTRL_INIT, AIU_MEM_IEC958_CONTROL);
    regs.ClearBits32(AIU_958_MCTRL_INIT, AIU_MEM_IEC958_CONTROL);
    regs.Write32(1, AIU_MEM_IEC958_BUF_CNTL);
    regs.Write32(0, AIU_MEM_IEC958_BUF_CNTL);
}

void Vim2SpdifAudioStream::SetMode(uint32_t frame_rate, audio_sample_format_t fmt) {
    ZX_DEBUG_ASSERT((regs_ != nullptr));
    const auto& regs = *regs_;

    // Look up our frame rate to figure out our clock divider and channel status
    // bit.  Note: clock divider values are based on a reference frame rate of
    // 192KHz
    static const struct {
        uint32_t frame_rate;
        uint32_t div_bits;
        uint32_t ch_status_bits;
    } RATE_LUT[] = {
        { .frame_rate = 32000,
          .div_bits = SHIFTED_VAL(AIU_CLK_CTRL_958_DIV, 2u) | AIU_CLK_CTRL_958_DIV_MORE,
          .ch_status_bits = SPDIF_CS_SAMP_FREQ_32K
        },
        { .frame_rate = 48000,
          .div_bits = SHIFTED_VAL(AIU_CLK_CTRL_958_DIV, 3u),
          .ch_status_bits = SPDIF_CS_SAMP_FREQ_48K
        },
        { .frame_rate = 96000,
          .div_bits = SHIFTED_VAL(AIU_CLK_CTRL_958_DIV, 1u),
          .ch_status_bits = SPDIF_CS_SAMP_FREQ_96K
        },
        { .frame_rate = 192000,
          .div_bits = SHIFTED_VAL(AIU_CLK_CTRL_958_DIV, 0u),
          .ch_status_bits = SPDIF_CS_SAMP_FREQ_192K
        },
    };

    uint32_t rate_ndx;
    for (rate_ndx = 0; rate_ndx < fbl::count_of(RATE_LUT); ++rate_ndx) {
        if (RATE_LUT[rate_ndx].frame_rate == frame_rate) {
            break;
        }
    }

    // The requested frame rate should already have been validated by the code
    // before us.  If something has gone terribly wrong, log a warning and
    // default to 48K.
    if (rate_ndx >= fbl::count_of(RATE_LUT)) {
        constexpr uint32_t DEFAULT_RATE_NDX = 1;
        zxlogf(WARN, "Failed to find requested frame rate (%u) in LUT!  Defaulting to 48000\n",
               frame_rate);
        static_assert(DEFAULT_RATE_NDX < fbl::count_of(RATE_LUT), "Invalid default rate index!");
        rate_ndx = DEFAULT_RATE_NDX;
    }

    const auto& RATE = RATE_LUT[rate_ndx];

    // Now go ahead and set up the clock divider.
    constexpr uint32_t DIV_MASK = SHIFTED_MASK(AIU_CLK_CTRL_958_DIV) | AIU_CLK_CTRL_958_DIV_MORE;
    regs.ModifyBits32(RATE.div_bits, DIV_MASK, AIU_CLK_CTRL);

    // Send a 0 for the V bit in each frame.  This indicates that the audio is
    // "valid", at least from a PCM perspective.  When packing compressed audio
    // into a SPDIF transport, apparently the thing to do is set the V bit to 1
    // in order to prevent older SPDIF receivers from treating the data like PCM
    // and breaking your ears.
    regs.Write32(AIU_958_VCTRL_SEND_VBIT, AIU_958_VALID_CTRL);

    // TODO(johngro): Should the bytes per frame vary based on the size of an
    // audio frame?  In particular, should the bytes per frame be an integer
    // multiple of the audio frame size?
    regs.Write32(AIU_958_BYTES_PER_FRAME, AIU_958_BPF);

    // TODO(johngro): Provide some way to change the category code.  Shipping
    // products should not be sending "experimental" as their category code.
    constexpr uint32_t CH_STATUS_BASE = SPDIF_CS_SPDIF_CONSUMER
                                      | SPDIF_CS_AUD_DATA_PCM
                                      | SPDIF_CS_COPY_PERMITTED
                                      | SPDIF_CS_NO_PRE_EMPHASIS
                                      | SPDIF_CS_CCODE_EXPERIMENTAL
                                      | SPDIF_CS_CLK_ACC_100PPM;
    constexpr uint32_t MISC_BASE = AIU_958_MISC_FORCE_LR;
    constexpr uint32_t MCTRL_BASE = AIU_958_MCTRL_LINEAR_RAW
                                  | SHIFTED_VAL(AIU_958_MCTRL_ENDIAN, 0u);

    uint32_t ch_status = CH_STATUS_BASE | RATE.ch_status_bits;
    uint32_t misc = MISC_BASE;
    uint32_t mctrl = MCTRL_BASE;

    // TODO(johngro): Figure out how to get to bits >= 32 in the channel status
    // word.  In theory, we can use bits [32, 35] to signal the number of
    // significant bits in the encoding, as well as to indicate that the
    // auxiliary bits are carrying audio data instead of aux signalling.
    switch (fmt) {
    case AUDIO_SAMPLE_FORMAT_24BIT_PACKED:
        break;

    // Notes about the 32bit shift field.
    // The 958_MISC register has a 3-bit field in it whose documentation reads...
    //
    // "shift number for 32 bit mode"
    //
    // Experimentally, it has been determined that the SPDIF encoder expects
    // audio to be right justified when sending data from 32 bit containers.
    // IOW, if a user puts 24 bit samples into a 32 bit container, the SPDIF
    // encoder expects the samples to be in bits [0, 23].
    //
    // If audio is left justified instead (think 32 bit samples with the low
    // bits zeroed out), the "shift number" bits can be used.  The 32 bit words
    // will be right shifted by this number of bits for values [0, 6], or 8 bits
    // to the left when set to the 7.
    //
    // TL;DR?  When sending left justified audio in a 32 bit container, set this
    // field to 7.
    case AUDIO_SAMPLE_FORMAT_24BIT_IN32:
        misc |= AIU_958_MISC_32BIT_MODE | SHIFTED_VAL(AIU_958_MISC_32BIT_SHIFT, 7u);
        break;

    default:
        zxlogf(WARN, "Unsupported format (0x%08x), defaulting to PCM16\n", fmt);
        __FALLTHROUGH;
    case AUDIO_SAMPLE_FORMAT_16BIT:
        mctrl |= AIU_958_MCTRL_16BIT_MODE;
        misc  |= AIU_958_MISC_16BIT | SHIFTED_VAL(AIU_958_MISC_16BIT_ALIGN,
                                                  AIU_958_MISC_16BIT_ALIGN_LEFT);
        break;
    }

    regs.Write32((ch_status & 0xFFFF), AIU_958_CHSTAT_L0);
    regs.Write32((ch_status & 0xFFFF), AIU_958_CHSTAT_R0);
    regs.Write32((ch_status >> 16), AIU_958_CHSTAT_L1);
    regs.Write32((ch_status >> 16), AIU_958_CHSTAT_R1);
    regs.Write32(misc, AIU_958_MISC);
    regs.Write32(mctrl, AIU_MEM_IEC958_CONTROL);

    // Set the "level hold" to zero.  I have no idea why.
    regs.ClearBits32(SHIFTED_MASK(AIU_958_BCTRL_LEVEL_HOLD), AIU_MEM_IEC958_BUF_CNTL);
}

void Vim2SpdifAudioStream::Mute(bool muted) {
    constexpr uint32_t MUTE_BITS = AIU_958_CTRL_MUTE_LEFT
                                 | AIU_958_CTRL_MUTE_RIGHT
                                 | AIU_958_CTRL_FUB_ZERO;
    const auto& regs = *regs_;

    regs.Write32(muted ? MUTE_BITS : 0u, AIU_958_CTRL);
}

}  // namespace vim2
}  // namespace audio
