static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)

{

    HDAAudioState *a = HDA_AUDIO(hda);

    HDAAudioStream *st;

    const desc_node *node = NULL;

    const desc_param *param;

    uint32_t verb, payload, response, count, shift;



    if ((data & 0x70000) == 0x70000) {

        /* 12/8 id/payload */

        verb = (data >> 8) & 0xfff;

        payload = data & 0x00ff;

    } else {

        /* 4/16 id/payload */

        verb = (data >> 8) & 0xf00;

        payload = data & 0xffff;

    }



    node = hda_codec_find_node(a->desc, nid);

    if (node == NULL) {

        goto fail;

    }

    dprint(a, 2, "%s: nid %d (%s), verb 0x%x, payload 0x%x\n",

           __FUNCTION__, nid, node->name, verb, payload);



    switch (verb) {

    /* all nodes */

    case AC_VERB_PARAMETERS:

        param = hda_codec_find_param(node, payload);

        if (param == NULL) {

            goto fail;

        }

        hda_codec_response(hda, true, param->val);

        break;

    case AC_VERB_GET_SUBSYSTEM_ID:

        hda_codec_response(hda, true, a->desc->iid);

        break;



    /* all functions */

    case AC_VERB_GET_CONNECT_LIST:

        param = hda_codec_find_param(node, AC_PAR_CONNLIST_LEN);

        count = param ? param->val : 0;

        response = 0;

        shift = 0;

        while (payload < count && shift < 32) {

            response |= node->conn[payload] << shift;

            payload++;

            shift += 8;

        }

        hda_codec_response(hda, true, response);

        break;



    /* pin widget */

    case AC_VERB_GET_CONFIG_DEFAULT:

        hda_codec_response(hda, true, node->config);

        break;

    case AC_VERB_GET_PIN_WIDGET_CONTROL:

        hda_codec_response(hda, true, node->pinctl);

        break;

    case AC_VERB_SET_PIN_WIDGET_CONTROL:

        if (node->pinctl != payload) {

            dprint(a, 1, "unhandled pin control bit\n");

        }

        hda_codec_response(hda, true, 0);

        break;



    /* audio in/out widget */

    case AC_VERB_SET_CHANNEL_STREAMID:

        st = a->st + node->stindex;

        if (st->node == NULL) {

            goto fail;

        }

        hda_audio_set_running(st, false);

        st->stream = (payload >> 4) & 0x0f;

        st->channel = payload & 0x0f;

        dprint(a, 2, "%s: stream %d, channel %d\n",

               st->node->name, st->stream, st->channel);

        hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);

        hda_codec_response(hda, true, 0);

        break;

    case AC_VERB_GET_CONV:

        st = a->st + node->stindex;

        if (st->node == NULL) {

            goto fail;

        }

        response = st->stream << 4 | st->channel;

        hda_codec_response(hda, true, response);

        break;

    case AC_VERB_SET_STREAM_FORMAT:

        st = a->st + node->stindex;

        if (st->node == NULL) {

            goto fail;

        }

        st->format = payload;

        hda_codec_parse_fmt(st->format, &st->as);

        hda_audio_setup(st);

        hda_codec_response(hda, true, 0);

        break;

    case AC_VERB_GET_STREAM_FORMAT:

        st = a->st + node->stindex;

        if (st->node == NULL) {

            goto fail;

        }

        hda_codec_response(hda, true, st->format);

        break;

    case AC_VERB_GET_AMP_GAIN_MUTE:

        st = a->st + node->stindex;

        if (st->node == NULL) {

            goto fail;

        }

        if (payload & AC_AMP_GET_LEFT) {

            response = st->gain_left | (st->mute_left ? AC_AMP_MUTE : 0);

        } else {

            response = st->gain_right | (st->mute_right ? AC_AMP_MUTE : 0);

        }

        hda_codec_response(hda, true, response);

        break;

    case AC_VERB_SET_AMP_GAIN_MUTE:

        st = a->st + node->stindex;

        if (st->node == NULL) {

            goto fail;

        }

        dprint(a, 1, "amp (%s): %s%s%s%s index %d  gain %3d %s\n",

               st->node->name,

               (payload & AC_AMP_SET_OUTPUT) ? "o" : "-",

               (payload & AC_AMP_SET_INPUT)  ? "i" : "-",

               (payload & AC_AMP_SET_LEFT)   ? "l" : "-",

               (payload & AC_AMP_SET_RIGHT)  ? "r" : "-",

               (payload & AC_AMP_SET_INDEX) >> AC_AMP_SET_INDEX_SHIFT,

               (payload & AC_AMP_GAIN),

               (payload & AC_AMP_MUTE) ? "muted" : "");

        if (payload & AC_AMP_SET_LEFT) {

            st->gain_left = payload & AC_AMP_GAIN;

            st->mute_left = payload & AC_AMP_MUTE;

        }

        if (payload & AC_AMP_SET_RIGHT) {

            st->gain_right = payload & AC_AMP_GAIN;

            st->mute_right = payload & AC_AMP_MUTE;

        }

        hda_audio_set_amp(st);

        hda_codec_response(hda, true, 0);

        break;



    /* not supported */

    case AC_VERB_SET_POWER_STATE:

    case AC_VERB_GET_POWER_STATE:

    case AC_VERB_GET_SDI_SELECT:

        hda_codec_response(hda, true, 0);

        break;

    default:

        goto fail;

    }

    return;



fail:

    dprint(a, 1, "%s: not handled: nid %d (%s), verb 0x%x, payload 0x%x\n",

           __FUNCTION__, nid, node ? node->name : "?", verb, payload);

    hda_codec_response(hda, true, 0);

}

static void hda_audio_command(HDACodecDevice *hda, uint32_t nid, uint32_t data)

{

    HDAAudioState *a = HDA_AUDIO(hda);

    HDAAudioStream *st;

    const desc_node *node = NULL;

    const desc_param *param;

    uint32_t verb, payload, response, count, shift;



    if ((data & 0x70000) == 0x70000) {

        

        verb = (data >> 8) & 0xfff;

        payload = data & 0x00ff;

    } else {

        

        verb = (data >> 8) & 0xf00;

        payload = data & 0xffff;

    }



    node = hda_codec_find_node(a->desc, nid);

    if (node == NULL) {

        goto fail;

    }

    dprint(a, 2, "%s: nid %d (%s), verb 0x%x, payload 0x%x\n",

           __FUNCTION__, nid, node->name, verb, payload);



    switch (verb) {

    

    case AC_VERB_PARAMETERS:

        param = hda_codec_find_param(node, payload);

        if (param == NULL) {

            goto fail;

        }

        hda_codec_response(hda, true, param->val);

        break;

    case AC_VERB_GET_SUBSYSTEM_ID:

        hda_codec_response(hda, true, a->desc->iid);

        break;



    

    case AC_VERB_GET_CONNECT_LIST:

        param = hda_codec_find_param(node, AC_PAR_CONNLIST_LEN);

        count = param ? param->val : 0;

        response = 0;

        shift = 0;

        while (payload < count && shift < 32) {

            response |= node->conn[payload] << shift;

            payload++;

            shift += 8;

        }

        hda_codec_response(hda, true, response);

        break;



    

    case AC_VERB_GET_CONFIG_DEFAULT:

        hda_codec_response(hda, true, node->config);

        break;

    case AC_VERB_GET_PIN_WIDGET_CONTROL:

        hda_codec_response(hda, true, node->pinctl);

        break;

    case AC_VERB_SET_PIN_WIDGET_CONTROL:

        if (node->pinctl != payload) {

            dprint(a, 1, "unhandled pin control bit\n");

        }

        hda_codec_response(hda, true, 0);

        break;



    

    case AC_VERB_SET_CHANNEL_STREAMID:

        st = a->st + node->stindex;

        if (st->node == NULL) {

            goto fail;

        }

        hda_audio_set_running(st, false);

        st->stream = (payload >> 4) & 0x0f;

        st->channel = payload & 0x0f;

        dprint(a, 2, "%s: stream %d, channel %d\n",

               st->node->name, st->stream, st->channel);

        hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);

        hda_codec_response(hda, true, 0);

        break;

    case AC_VERB_GET_CONV:

        st = a->st + node->stindex;

        if (st->node == NULL) {

            goto fail;

        }

        response = st->stream << 4 | st->channel;

        hda_codec_response(hda, true, response);

        break;

    case AC_VERB_SET_STREAM_FORMAT:

        st = a->st + node->stindex;

        if (st->node == NULL) {

            goto fail;

        }

        st->format = payload;

        hda_codec_parse_fmt(st->format, &st->as);

        hda_audio_setup(st);

        hda_codec_response(hda, true, 0);

        break;

    case AC_VERB_GET_STREAM_FORMAT:

        st = a->st + node->stindex;

        if (st->node == NULL) {

            goto fail;

        }

        hda_codec_response(hda, true, st->format);

        break;

    case AC_VERB_GET_AMP_GAIN_MUTE:

        st = a->st + node->stindex;

        if (st->node == NULL) {

            goto fail;

        }

        if (payload & AC_AMP_GET_LEFT) {

            response = st->gain_left | (st->mute_left ? AC_AMP_MUTE : 0);

        } else {

            response = st->gain_right | (st->mute_right ? AC_AMP_MUTE : 0);

        }

        hda_codec_response(hda, true, response);

        break;

    case AC_VERB_SET_AMP_GAIN_MUTE:

        st = a->st + node->stindex;

        if (st->node == NULL) {

            goto fail;

        }

        dprint(a, 1, "amp (%s): %s%s%s%s index %d  gain %3d %s\n",

               st->node->name,

               (payload & AC_AMP_SET_OUTPUT) ? "o" : "-",

               (payload & AC_AMP_SET_INPUT)  ? "i" : "-",

               (payload & AC_AMP_SET_LEFT)   ? "l" : "-",

               (payload & AC_AMP_SET_RIGHT)  ? "r" : "-",

               (payload & AC_AMP_SET_INDEX) >> AC_AMP_SET_INDEX_SHIFT,

               (payload & AC_AMP_GAIN),

               (payload & AC_AMP_MUTE) ? "muted" : "");

        if (payload & AC_AMP_SET_LEFT) {

            st->gain_left = payload & AC_AMP_GAIN;

            st->mute_left = payload & AC_AMP_MUTE;

        }

        if (payload & AC_AMP_SET_RIGHT) {

            st->gain_right = payload & AC_AMP_GAIN;

            st->mute_right = payload & AC_AMP_MUTE;

        }

        hda_audio_set_amp(st);

        hda_codec_response(hda, true, 0);

        break;



    

    case AC_VERB_SET_POWER_STATE:

    case AC_VERB_GET_POWER_STATE:

    case AC_VERB_GET_SDI_SELECT:

        hda_codec_response(hda, true, 0);

        break;

    default:

        goto fail;

    }

    return;



fail:

    dprint(a, 1, "%s: not handled: nid %d (%s), verb 0x%x, payload 0x%x\n",

           __FUNCTION__, nid, node ? node->name : "?", verb, payload);

    hda_codec_response(hda, true, 0);

}

static void FUNC_0(HDACodecDevice *VAR_0, uint32_t VAR_1, uint32_t VAR_2)

{

    HDAAudioState *a = HDA_AUDIO(VAR_0);

    HDAAudioStream *st;

    const desc_node *VAR_3 = NULL;

    const desc_param *VAR_4;

    uint32_t verb, payload, response, count, shift;



    if ((VAR_2 & 0x70000) == 0x70000) {

        

        verb = (VAR_2 >> 8) & 0xfff;

        payload = VAR_2 & 0x00ff;

    } else {

        

        verb = (VAR_2 >> 8) & 0xf00;

        payload = VAR_2 & 0xffff;

    }



    VAR_3 = hda_codec_find_node(a->desc, VAR_1);

    if (VAR_3 == NULL) {

        goto fail;

    }

    dprint(a, 2, "%s: VAR_1 %d (%s), verb 0x%x, payload 0x%x\n",

           __FUNCTION__, VAR_1, VAR_3->name, verb, payload);



    switch (verb) {

    

    case AC_VERB_PARAMETERS:

        VAR_4 = hda_codec_find_param(VAR_3, payload);

        if (VAR_4 == NULL) {

            goto fail;

        }

        hda_codec_response(VAR_0, true, VAR_4->val);

        break;

    case AC_VERB_GET_SUBSYSTEM_ID:

        hda_codec_response(VAR_0, true, a->desc->iid);

        break;



    

    case AC_VERB_GET_CONNECT_LIST:

        VAR_4 = hda_codec_find_param(VAR_3, AC_PAR_CONNLIST_LEN);

        count = VAR_4 ? VAR_4->val : 0;

        response = 0;

        shift = 0;

        while (payload < count && shift < 32) {

            response |= VAR_3->conn[payload] << shift;

            payload++;

            shift += 8;

        }

        hda_codec_response(VAR_0, true, response);

        break;



    

    case AC_VERB_GET_CONFIG_DEFAULT:

        hda_codec_response(VAR_0, true, VAR_3->config);

        break;

    case AC_VERB_GET_PIN_WIDGET_CONTROL:

        hda_codec_response(VAR_0, true, VAR_3->pinctl);

        break;

    case AC_VERB_SET_PIN_WIDGET_CONTROL:

        if (VAR_3->pinctl != payload) {

            dprint(a, 1, "unhandled pin control bit\n");

        }

        hda_codec_response(VAR_0, true, 0);

        break;



    

    case AC_VERB_SET_CHANNEL_STREAMID:

        st = a->st + VAR_3->stindex;

        if (st->VAR_3 == NULL) {

            goto fail;

        }

        hda_audio_set_running(st, false);

        st->stream = (payload >> 4) & 0x0f;

        st->channel = payload & 0x0f;

        dprint(a, 2, "%s: stream %d, channel %d\n",

               st->VAR_3->name, st->stream, st->channel);

        hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]);

        hda_codec_response(VAR_0, true, 0);

        break;

    case AC_VERB_GET_CONV:

        st = a->st + VAR_3->stindex;

        if (st->VAR_3 == NULL) {

            goto fail;

        }

        response = st->stream << 4 | st->channel;

        hda_codec_response(VAR_0, true, response);

        break;

    case AC_VERB_SET_STREAM_FORMAT:

        st = a->st + VAR_3->stindex;

        if (st->VAR_3 == NULL) {

            goto fail;

        }

        st->format = payload;

        hda_codec_parse_fmt(st->format, &st->as);

        hda_audio_setup(st);

        hda_codec_response(VAR_0, true, 0);

        break;

    case AC_VERB_GET_STREAM_FORMAT:

        st = a->st + VAR_3->stindex;

        if (st->VAR_3 == NULL) {

            goto fail;

        }

        hda_codec_response(VAR_0, true, st->format);

        break;

    case AC_VERB_GET_AMP_GAIN_MUTE:

        st = a->st + VAR_3->stindex;

        if (st->VAR_3 == NULL) {

            goto fail;

        }

        if (payload & AC_AMP_GET_LEFT) {

            response = st->gain_left | (st->mute_left ? AC_AMP_MUTE : 0);

        } else {

            response = st->gain_right | (st->mute_right ? AC_AMP_MUTE : 0);

        }

        hda_codec_response(VAR_0, true, response);

        break;

    case AC_VERB_SET_AMP_GAIN_MUTE:

        st = a->st + VAR_3->stindex;

        if (st->VAR_3 == NULL) {

            goto fail;

        }

        dprint(a, 1, "amp (%s): %s%s%s%s index %d  gain %3d %s\n",

               st->VAR_3->name,

               (payload & AC_AMP_SET_OUTPUT) ? "o" : "-",

               (payload & AC_AMP_SET_INPUT)  ? "i" : "-",

               (payload & AC_AMP_SET_LEFT)   ? "l" : "-",

               (payload & AC_AMP_SET_RIGHT)  ? "r" : "-",

               (payload & AC_AMP_SET_INDEX) >> AC_AMP_SET_INDEX_SHIFT,

               (payload & AC_AMP_GAIN),

               (payload & AC_AMP_MUTE) ? "muted" : "");

        if (payload & AC_AMP_SET_LEFT) {

            st->gain_left = payload & AC_AMP_GAIN;

            st->mute_left = payload & AC_AMP_MUTE;

        }

        if (payload & AC_AMP_SET_RIGHT) {

            st->gain_right = payload & AC_AMP_GAIN;

            st->mute_right = payload & AC_AMP_MUTE;

        }

        hda_audio_set_amp(st);

        hda_codec_response(VAR_0, true, 0);

        break;



    

    case AC_VERB_SET_POWER_STATE:

    case AC_VERB_GET_POWER_STATE:

    case AC_VERB_GET_SDI_SELECT:

        hda_codec_response(VAR_0, true, 0);

        break;

    default:

        goto fail;

    }

    return;



fail:

    dprint(a, 1, "%s: not handled: VAR_1 %d (%s), verb 0x%x, payload 0x%x\n",

           __FUNCTION__, VAR_1, VAR_3 ? VAR_3->name : "?", verb, payload);

    hda_codec_response(VAR_0, true, 0);

}

static void FUNC_0(HDACodecDevice *VAR_0, uint32_t VAR_1, uint32_t VAR_2)
{ HDAAudioState *a = HDA_AUDIO(VAR_0); HDAAudioStream *st; const desc_node *VAR_3 = NULL; const desc_param *VAR_4; uint32_t verb, payload, response, count, shift; if ((VAR_2 & 0x70000) == 0x70000) { verb = (VAR_2 >> 8) & 0xfff; payload = VAR_2 & 0x00ff; } else { verb = (VAR_2 >> 8) & 0xf00; payload = VAR_2 & 0xffff; } VAR_3 = hda_codec_find_node(a->desc, VAR_1); if (VAR_3 == NULL) { goto fail; } dprint(a, 2, "%s: VAR_1 %d (%s), verb 0x%x, payload 0x%x\n",
__FUNCTION__, VAR_1, VAR_3->name, verb, payload); switch (verb) { case AC_VERB_PARAMETERS:
VAR_4 = hda_codec_find_param(VAR_3, payload); if (VAR_4 == NULL) { goto fail; } hda_codec_response(VAR_0, true, VAR_4->val); break; case AC_VERB_GET_SUBSYSTEM_ID:
hda_codec_response(VAR_0, true, a->desc->iid); break; case AC_VERB_GET_CONNECT_LIST:
VAR_4 = hda_codec_find_param(VAR_3, AC_PAR_CONNLIST_LEN); count = VAR_4 ? VAR_4->val : 0; response = 0; shift = 0; while (payload < count && shift < 32) { response |= VAR_3->conn[payload] << shift; payload++; shift += 8; } hda_codec_response(VAR_0, true, response); break; case AC_VERB_GET_CONFIG_DEFAULT:
hda_codec_response(VAR_0, true, VAR_3->config); break; case AC_VERB_GET_PIN_WIDGET_CONTROL:
hda_codec_response(VAR_0, true, VAR_3->pinctl); break; case AC_VERB_SET_PIN_WIDGET_CONTROL:
if (VAR_3->pinctl != payload) { dprint(a, 1, "unhandled pin control bit\n"); } hda_codec_response(VAR_0, true, 0); break; case AC_VERB_SET_CHANNEL_STREAMID:
st = a->st + VAR_3->stindex; if (st->VAR_3 == NULL) { goto fail; } hda_audio_set_running(st, false); st->stream = (payload >> 4) & 0x0f; st->channel = payload & 0x0f; dprint(a, 2, "%s: stream %d, channel %d\n",
st->VAR_3->name, st->stream, st->channel); hda_audio_set_running(st, a->running_real[st->output * 16 + st->stream]); hda_codec_response(VAR_0, true, 0); break; case AC_VERB_GET_CONV:
st = a->st + VAR_3->stindex; if (st->VAR_3 == NULL) { goto fail; } response = st->stream << 4 | st->channel; hda_codec_response(VAR_0, true, response); break; case AC_VERB_SET_STREAM_FORMAT:
st = a->st + VAR_3->stindex; if (st->VAR_3 == NULL) { goto fail; } st->format = payload; hda_codec_parse_fmt(st->format, &st->as); hda_audio_setup(st); hda_codec_response(VAR_0, true, 0); break; case AC_VERB_GET_STREAM_FORMAT:
st = a->st + VAR_3->stindex; if (st->VAR_3 == NULL) { goto fail; } hda_codec_response(VAR_0, true, st->format); break; case AC_VERB_GET_AMP_GAIN_MUTE:
st = a->st + VAR_3->stindex; if (st->VAR_3 == NULL) { goto fail; } if (payload & AC_AMP_GET_LEFT) { response = st->gain_left | (st->mute_left ? AC_AMP_MUTE : 0); } else { response = st->gain_right | (st->mute_right ? AC_AMP_MUTE : 0); } hda_codec_response(VAR_0, true, response); break; case AC_VERB_SET_AMP_GAIN_MUTE:
st = a->st + VAR_3->stindex; if (st->VAR_3 == NULL) { goto fail; } dprint(a, 1, "amp (%s): %s%s%s%s index %d  gain %3d %s\n",
st->VAR_3->name,
(payload & AC_AMP_SET_OUTPUT) ? "o" : "-",
(payload & AC_AMP_SET_INPUT)  ? "i" : "-",
(payload & AC_AMP_SET_LEFT)   ? "l" : "-",
(payload & AC_AMP_SET_RIGHT)  ? "r" : "-",
(payload & AC_AMP_SET_INDEX) >> AC_AMP_SET_INDEX_SHIFT,
(payload & AC_AMP_GAIN),
(payload & AC_AMP_MUTE) ? "muted" : ""); if (payload & AC_AMP_SET_LEFT) { st->gain_left = payload & AC_AMP_GAIN; st->mute_left = payload & AC_AMP_MUTE; } if (payload & AC_AMP_SET_RIGHT) { st->gain_right = payload & AC_AMP_GAIN; st->mute_right = payload & AC_AMP_MUTE; } hda_audio_set_amp(st); hda_codec_response(VAR_0, true, 0); break; case AC_VERB_SET_POWER_STATE:
case AC_VERB_GET_POWER_STATE:
case AC_VERB_GET_SDI_SELECT:
hda_codec_response(VAR_0, true, 0); break; default:
goto fail; } return; fail:
dprint(a, 1, "%s: not handled: VAR_1 %d (%s), verb 0x%x, payload 0x%x\n",
__FUNCTION__, VAR_1, VAR_3 ? VAR_3->name : "?", verb, payload); hda_codec_response(VAR_0, true, 0); }