From owner-svn-soc-all@freebsd.org Sun Jun 5 19:41:39 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 65805B6BA0A for ; Sun, 5 Jun 2016 19:41:39 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4B9E7146F for ; Sun, 5 Jun 2016 19:41:39 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u55JfdGt055327 for ; Sun, 5 Jun 2016 19:41:39 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u55JfcS2055324 for svn-soc-all@FreeBSD.org; Sun, 5 Jun 2016 19:41:38 GMT (envelope-from iateaca@FreeBSD.org) Date: Sun, 5 Jun 2016 19:41:38 GMT Message-Id: <201606051941.u55JfcS2055324@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to iateaca@FreeBSD.org using -f From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r304715 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 05 Jun 2016 19:41:39 -0000 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 = {