Date: Sun, 5 Jun 2016 19:41:38 GMT From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r304715 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve Message-ID: <201606051941.u55JfcS2055324@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: iateaca Date: Sun Jun 5 19:41:38 2016 New Revision: 304715 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=304715 Log: design the hda codec data structure describe the hda codec parameters for each node (ROOT, FG and AUDIO OUTPUT) implement the GET_PARAMETER verb M bhyve/hda_codec.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sun Jun 5 18:16:33 2016 (r304714) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sun Jun 5 19:41:38 2016 (r304715) @@ -4,9 +4,44 @@ /* * HDA Codec defines */ +#define INTEL_VENDORID 0x8086 + +#define HDA_CODEC_SUBSYSTEM_ID ((INTEL_VENDORID << 16) | 0x01) +#define HDA_CODEC_ROOT_NID 0x00 +#define HDA_CODEC_FG_NID 0x01 +#define HDA_CODEC_AUDIO_OUTPUT_NID 0x02 + +#define HDA_CODEC_PARAMS_COUNT 0x14 #define HDA_CODEC_RESPONSE_EX_UNSOL 0x10 #define HDA_CODEC_RESPONSE_EX_SOL 0x00 +#define HDA_CODEC_SUPP_STREAM_FORMATS_PCM (1 << HDA_PARAM_SUPP_STREAM_FORMATS_PCM_SHIFT) + +#define HDA_CODEC_AUDIO_WCAP_OUTPUT (0x00 << HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT) +#define HDA_CODEC_AUDIO_WCAP_FORMAT_OVR (1 << HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR_SHIFT) +#define HDA_CODEC_AUDIO_WCAP_AMP_OVR (1 << HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR_SHIFT) +#define HDA_CODEC_AUDIO_WCAP_OUT_AMP (1 << HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP_SHIFT) +#define HDA_CODEC_AUDIO_WCAP_STEREO (1 << HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_SHIFT) + +#define HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP (1 << HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP_SHIFT) +#define HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE (0x03 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) +#define HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS (0x1f << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) +#define HDA_CODEC_OUTPUT_AMP_CAP_OFFSET (0x00 << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT) + + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +/* + * HDA Codec data structures + */ + + +struct hda_codec_softc { + uint32_t subsystem_id; + uint32_t no_nodes; + const uint32_t (*get_parameters)[HDA_CODEC_PARAMS_COUNT]; +}; + /* * HDA Codec module function declarations */ @@ -18,14 +53,63 @@ hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data); /* + * HDA Codec global data + */ + +static const uint32_t hda_codec_parameters[][HDA_CODEC_PARAMS_COUNT] = { + [HDA_CODEC_ROOT_NID] = { + [HDA_PARAM_VENDOR_ID] = INTEL_VENDORID, + [HDA_PARAM_REVISION_ID] = 0xffff, + [HDA_PARAM_SUB_NODE_COUNT] = 0x00010001, /* 1 Subnode, StartNid = 1 */ + }, + [HDA_CODEC_FG_NID] = { + [HDA_PARAM_SUB_NODE_COUNT] = 0x00020001, /* 1 Subnode, StartNid = 2 */ + [HDA_PARAM_FCT_GRP_TYPE] = HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO, + [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x1f << 16) | 0x7ff, /* B8 - B32, 8.0 - 192.0kHz */ + [HDA_PARAM_SUPP_STREAM_FORMATS] = HDA_CODEC_SUPP_STREAM_FORMATS_PCM, + [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ + [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ + [HDA_PARAM_GPIO_COUNT] = 0x00, + }, + [HDA_CODEC_AUDIO_OUTPUT_NID] = { + [HDA_PARAM_AUDIO_WIDGET_CAP] = HDA_CODEC_AUDIO_WCAP_OUTPUT | + HDA_CODEC_AUDIO_WCAP_FORMAT_OVR | + HDA_CODEC_AUDIO_WCAP_AMP_OVR | + HDA_CODEC_AUDIO_WCAP_OUT_AMP | + HDA_CODEC_AUDIO_WCAP_STEREO, + [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x1f << 16) | 0x7ff, /* B8 - B32, 8.0 - 192.0kHz */ + [HDA_PARAM_SUPP_STREAM_FORMATS] = HDA_CODEC_SUPP_STREAM_FORMATS_PCM, + [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ + [HDA_PARAM_CONN_LIST_LENGTH] = 0x00, + [HDA_PARAM_OUTPUT_AMP_CAP] = HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP | + HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE | + HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS | + HDA_CODEC_OUTPUT_AMP_CAP_OFFSET, + }, +}; + +/* * HDA Codec module function definitions */ static int hda_codec_init(struct hda_codec_inst *hci, const char *opts) { + struct hda_codec_softc *sc = NULL; + DPRINTF("cad: 0x%x opts: %s\n", hci->cad, opts); + sc = calloc(1, sizeof(*sc)); + if (!sc) + return -1; + + sc->subsystem_id = HDA_CODEC_SUBSYSTEM_ID; + sc->no_nodes = ARRAY_SIZE(hda_codec_parameters); + sc->get_parameters = hda_codec_parameters; + DPRINTF("HDA Codec nodes: %d\n", sc->no_nodes); + + hci->priv = sc; + return 0; } @@ -52,9 +136,11 @@ static int hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data) { + struct hda_codec_softc *sc = NULL; struct hda_ops *hops = NULL; uint8_t cad = 0, nid = 0; uint16_t verb = 0, payload = 0; + uint32_t res = 0; cad = (cmd_data >> HDA_CMD_CAD_SHIFT) & 0x0f; // 4 bits nid = (cmd_data >> HDA_CMD_NID_SHIFT) & 0xff; // 8 bits @@ -73,14 +159,36 @@ hops = hci->hops; assert(hops); - DPRINTF("cad: 0x%x nid: 0x%x verb: 0x%x payload: 0x%x\n", cad, nid, verb, payload); + sc = (struct hda_codec_softc *)hci->priv; + assert(sc); if (!hops->response) { DPRINTF("The controller ops does not implement the response function\n"); return -1; } - return hops->response(hci, 0, HDA_CODEC_RESPONSE_EX_SOL); + switch (verb) { + case HDA_CMD_VERB_GET_PARAMETER: + if (nid < sc->no_nodes) + res = sc->get_parameters[nid][payload]; + else + DPRINTF("GET_PARAMETER(nid: %d) not described\n", nid); + break; + case HDA_CMD_VERB_GET_SUBSYSTEM_ID: + res = sc->subsystem_id; + break; + case HDA_CMD_VERB_SET_AMP_GAIN_MUTE: + /* TODO - handle this command */ + break; + default: + /* TODO - call a specific handler per node */ + break; + } + + DPRINTF("cad: 0x%x nid: 0x%x verb: 0x%x payload: 0x%x response: 0x%x\n", + cad, nid, verb, payload, res); + + return hops->response(hci, res, HDA_CODEC_RESPONSE_EX_SOL); } struct hda_codec_class hda_codec = {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201606051941.u55JfcS2055324>