socsvn commit: r304715 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve

iateaca at FreeBSD.org iateaca at FreeBSD.org
Sun Jun 5 19:41:39 UTC 2016


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  = {


More information about the svn-soc-all mailing list