socsvn commit: r304163 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve
iateaca at FreeBSD.org
iateaca at FreeBSD.org
Sun May 29 17:08:37 UTC 2016
Author: iateaca
Date: Sun May 29 17:08:35 2016
New Revision: 304163
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=304163
Log:
implement the send_command in controller and .command handler in codec
implement the .response handler in controller (RIRB); used by to codec to send responses
M bhyve/hda_codec.c
M bhyve/pci_hda.c
M bhyve/pci_hda.h
Modified:
soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c
soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c
soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.h
Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c
==============================================================================
--- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sun May 29 16:39:28 2016 (r304162)
+++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sun May 29 17:08:35 2016 (r304163)
@@ -1,10 +1,25 @@
#include "pci_hda.h"
+/*
+ * HDA Codec defines
+ */
+#define HDA_CODEC_RESPONSE_EX_UNSOL 0x10
+#define HDA_CODEC_RESPONSE_EX_SOL 0x00
+
+/*
+ * HDA Codec module function declarations
+ */
static int
hda_codec_init(struct hda_codec_inst *hci, const char *opts);
static int
hda_codec_reset(struct hda_codec_inst *hci);
+static int
+hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data);
+
+/*
+ * HDA Codec module function definitions
+ */
static int
hda_codec_init(struct hda_codec_inst *hci, const char *opts)
@@ -26,15 +41,48 @@
DPRINTF("cad: 0x%x\n", hci->cad);
- hops->signal(hci);
+ if (!hops->signal) {
+ DPRINTF("The controller ops does not implement the signal function\n");
+ return -1;
+ }
- return 0;
+ return hops->signal(hci);
+}
+
+static int
+hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data)
+{
+ struct hda_ops *hops = NULL;
+ uint8_t cad = 0, nid = 0;
+ uint16_t verb = 0, payload = 0;
+
+ // TODO find if the cmd is 12bit or 4bit
+ cad = (cmd_data >> HDA_CMD_CAD_SHIFT) & 0x0f; // 4 bits
+ nid = (cmd_data >> HDA_CMD_NID_SHIFT) & 0xff; // 8 bits
+ verb = (cmd_data >> HDA_CMD_VERB_12BIT_SHIFT) & 0x0fff; // 12 bits
+ payload = cmd_data & 0xff; // 8 bits
+
+ assert(cad == hci->cad);
+ assert(hci);
+
+ hops = hci->hops;
+ assert(hops);
+
+ DPRINTF("cad: 0x%x nid: 0x%x verb: 0x%x payload: 0x%x\n", cad, nid, verb, payload);
+
+ 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);
}
struct hda_codec_class hda_codec = {
- .name = "hda_codec",
- .init = hda_codec_init,
- .reset = hda_codec_reset,
+ .name = "hda_codec",
+ .init = hda_codec_init,
+ .reset = hda_codec_reset,
+ .command = hda_codec_command,
};
HDA_EMUL_SET(hda_codec);
Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c
==============================================================================
--- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sun May 29 16:39:28 2016 (r304162)
+++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sun May 29 17:08:35 2016 (r304163)
@@ -61,6 +61,8 @@
static struct hda_codec_class *
hda_find_codec_class(const char *name);
+static int
+hda_send_command(struct hda_softc *sc, uint32_t verb);
static void
hda_reset(struct hda_softc *sc);
static void
@@ -102,6 +104,8 @@
static int
hda_signal_state_change(struct hda_codec_inst *hci);
+static int
+hda_response(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol);
/*
* PCI HDA function declarations
@@ -159,6 +163,7 @@
static struct hda_ops hops = {
.signal = hda_signal_state_change,
+ .response = hda_response,
};
struct pci_devemu pci_de_hda = {
@@ -246,7 +251,6 @@
hda_codec_constructor(struct hda_softc *sc, struct hda_codec_class *codec)
{
struct hda_codec_inst *hci = NULL;
- int err;
if (sc->codecs_no >= HDA_CODEC_MAX)
return -1;
@@ -262,10 +266,12 @@
sc->codecs[sc->codecs_no++] = hci;
- err = codec->init(hci, NULL);
- assert(!err);
+ if (!codec->init) {
+ DPRINTF("This codec does not implement the init function\n");
+ return -1;
+ }
- return 0;
+ return codec->init(hci, NULL);
}
static struct hda_codec_class *
@@ -283,6 +289,30 @@
return NULL;
}
+static int
+hda_send_command(struct hda_softc *sc, uint32_t verb)
+{
+ struct hda_codec_inst *hci = NULL;
+ struct hda_codec_class *codec = NULL;
+ uint8_t cad = (verb >> HDA_CMD_CAD_SHIFT) & 0x0f;
+
+ hci = sc->codecs[cad];
+ if (!hci)
+ return -1;
+
+ DPRINTF("cad: 0x%x verb: 0x%x\n", cad, verb);
+
+ codec = hci->codec;
+ assert(codec);
+
+ if (!codec->command) {
+ DPRINTF("This codec does not implement the command function\n");
+ return -1;
+ }
+
+ return codec->command(hci, verb);
+}
+
static void
hda_reset(struct hda_softc *sc)
{
@@ -300,7 +330,8 @@
codec = hci->codec;
assert(codec);
- codec->reset(hci);
+ if (codec->reset)
+ codec->reset(hci);
}
return;
@@ -493,6 +524,7 @@
struct hda_codec_cmd_ctl *corb = &sc->corb;
uint32_t value = sc->regs[offset];
uint32_t verb = 0;
+ int err;
corb->wp = value;
@@ -503,10 +535,8 @@
corb->rp++;
verb = hda_dma_ld_dword(corb->dma_vaddr + HDA_CORB_ENTRY_LEN * corb->rp);
- /*
- * TODO get cad from verb and send command to codec[cad]
- */
- DPRINTF("VERB: 0x%x\n", verb);
+ err = hda_send_command(sc, verb);
+ assert(!err);
}
hda_set_reg_by_offset(sc, HDAC_CORBRP, corb->rp);
@@ -579,6 +609,36 @@
return 0;
}
+static int
+hda_response(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol)
+{
+ struct hda_softc *sc = NULL;
+ struct hda_codec_cmd_ctl *rirb = NULL;
+ uint32_t response_ex = 0;
+
+ assert(hci);
+ assert(hci->cad <= HDA_CODEC_MAX);
+
+ response_ex = hci->cad | unsol;
+
+ sc = hci->hda;
+ assert(sc);
+
+ rirb = &sc->rirb;
+
+ if (rirb->run) {
+ rirb->wp++;
+ rirb->wp %= rirb->size;
+
+ hda_dma_st_dword(rirb->dma_vaddr + HDA_RIRB_ENTRY_LEN * rirb->wp, response);
+ hda_dma_st_dword(rirb->dma_vaddr + HDA_RIRB_ENTRY_LEN * rirb->wp + 0x04, response_ex);
+
+ hda_set_reg_by_offset(sc, HDAC_RIRBWP, rirb->wp);
+ }
+
+ return 0;
+}
+
/*
* PCI HDA function definitions
*/
Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.h
==============================================================================
--- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.h Sun May 29 16:39:28 2016 (r304162)
+++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.h Sun May 29 17:08:35 2016 (r304163)
@@ -12,6 +12,8 @@
#include <sys/queue.h>
#include <sys/kernel.h>
+#include "hda_reg.h"
+
/*
* HDA Debug Log
*/
@@ -40,10 +42,12 @@
char *name;
int (*init)(struct hda_codec_inst *hci, const char *opts);
int (*reset)(struct hda_codec_inst *hci);
+ int (*command)(struct hda_codec_inst *hci, uint32_t cmd_data);
};
struct hda_ops {
int (*signal)(struct hda_codec_inst *hci);
+ int (*response)(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol);
};
#define HDA_EMUL_SET(x) DATA_SET(hda_codec_class_set, x);
More information about the svn-soc-all
mailing list