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