Page MenuHomeFreeBSD

D58372.1793802762.diff
No OneTemporary

Authored By
Unknown
Size
11 KB
Referenced Files
None
Subscribers
None

D58372.1793802762.diff

diff --git a/sys/dev/sound/pci/hdspe-pcm.c b/sys/dev/sound/pci/hdspe-pcm.c
--- a/sys/dev/sound/pci/hdspe-pcm.c
+++ b/sys/dev/sound/pci/hdspe-pcm.c
@@ -108,21 +108,14 @@
return (ports & (~(ports - 1))); /* Extract first bit set. */
}
-static uint32_t
-hdspe_port_first_row(uint32_t ports)
+/* AIO ADAT channels use strided slots at double and quad speed. */
+static unsigned int
+hdspe_port_slot_stride(struct sc_info *sc, uint32_t port)
{
- uint32_t ends;
-
- /* Restrict ports to one set with contiguous slots. */
- if (ports & HDSPE_CHAN_AIO_ALL)
- ports &= HDSPE_CHAN_AIO_ALL; /* All AIO slots. */
- else if (ports & HDSPE_CHAN_RAY_ALL)
- ports &= HDSPE_CHAN_RAY_ALL; /* All RayDAT slots. */
-
- /* Ends of port rows are followed by a port which is not in the set. */
- ends = ports & (~(ports >> 1));
- /* First row of contiguous ports ends in the first row end. */
- return (ports & (ends ^ (ends - 1)));
+ if (sc->type == HDSPE_AIO &&
+ hdspe_port_first(port) == HDSPE_CHAN_AIO_ADAT)
+ return (8 / hdspe_adat_width(sc->speed));
+ return (1);
}
static unsigned int
@@ -184,7 +177,7 @@
static unsigned int
hdspe_port_slot_offset(uint32_t port, unsigned int adat_width)
{
- /* Exctract the first port (lowest bit) if set of ports. */
+ /* Extract the first port if a set of ports is specified. */
switch (hdspe_port_first(port)) {
/* AIO ports */
case HDSPE_CHAN_AIO_LINE:
@@ -219,13 +212,9 @@
}
static unsigned int
-hdspe_port_slot_width(uint32_t ports, unsigned int adat_width)
+hdspe_port_slot_width(uint32_t port, unsigned int adat_width)
{
- uint32_t row;
-
- /* Count number of contiguous slots from the first physical port. */
- row = hdspe_port_first_row(ports);
- return (hdspe_channel_count(row, adat_width));
+ return (hdspe_channel_count(hdspe_port_first(port), adat_width));
}
static int
@@ -255,7 +244,7 @@
{
struct sc_info *sc;
uint32_t port, ports;
- unsigned int slot, end_slot;
+ unsigned int base, width, stride, i, slot;
unsigned short volume;
sc = ch->parent->sc;
@@ -264,15 +253,14 @@
ports = ch->ports;
port = hdspe_port_first(ports);
while (port != 0) {
- /* Get slot range of the physical port. */
- slot =
- hdspe_port_slot_offset(port, hdspe_adat_width(sc->speed));
- end_slot = slot +
- hdspe_port_slot_width(port, hdspe_adat_width(sc->speed));
+ base = hdspe_port_slot_offset(port, hdspe_adat_width(sc->speed));
+ width = hdspe_port_slot_width(port, hdspe_adat_width(sc->speed));
+ stride = hdspe_port_slot_stride(sc, port);
/* Treat first slot as left channel. */
volume = ch->lvol * HDSPE_MAX_GAIN / 100;
- for (; slot < end_slot; slot++) {
+ for (i = 0; i < width; i++) {
+ slot = base + i * stride;
hdspe_hw_mixer(ch, slot, slot, volume);
/* Subsequent slots all get the right channel volume. */
volume = ch->rvol * HDSPE_MAX_GAIN / 100;
@@ -354,9 +342,9 @@
{
struct sc_pcminfo *scp;
struct sc_info *sc;
- uint32_t row, ports;
+ uint32_t port, ports;
int reg;
- unsigned int slot, end_slot;
+ unsigned int base, width, stride, i, slot;
scp = ch->parent;
sc = scp->sc;
@@ -368,21 +356,20 @@
ch->run = value;
- /* Iterate through rows of ports with contiguous slots. */
ports = ch->ports;
- row = hdspe_port_first_row(ports);
- while (row != 0) {
- slot =
- hdspe_port_slot_offset(row, hdspe_adat_width(sc->speed));
- end_slot = slot +
- hdspe_port_slot_width(row, hdspe_adat_width(sc->speed));
-
- for (; slot < end_slot; slot++) {
+ port = hdspe_port_first(ports);
+ while (port != 0) {
+ base = hdspe_port_slot_offset(port, hdspe_adat_width(sc->speed));
+ width = hdspe_port_slot_width(port, hdspe_adat_width(sc->speed));
+ stride = hdspe_port_slot_stride(sc, port);
+
+ for (i = 0; i < width; i++) {
+ slot = base + i * stride;
hdspe_write_1(sc, reg + (4 * slot), value);
}
- ports &= ~row;
- row = hdspe_port_first_row(ports);
+ ports &= ~port;
+ port = hdspe_port_first(ports);
}
}
@@ -429,96 +416,83 @@
static void
buffer_mux_write(uint32_t *dma, uint32_t *pcm, unsigned int pos,
- unsigned int samples, unsigned int slots, unsigned int channels)
+ unsigned int samples, unsigned int nch, unsigned int channels,
+ unsigned int stride)
{
- int slot;
+ unsigned int i;
for (; samples > 0; samples--) {
- for (slot = 0; slot < slots; slot++) {
- dma[slot * HDSPE_CHANBUF_SAMPLES + pos] =
- pcm[pos * channels + slot];
+ for (i = 0; i < nch; i++) {
+ dma[i * stride * HDSPE_CHANBUF_SAMPLES + pos] =
+ pcm[pos * channels + i];
}
pos = (pos + 1) % HDSPE_CHANBUF_SAMPLES;
}
}
static void
-buffer_mux_port(uint32_t *dma, uint32_t *pcm, uint32_t subset, uint32_t ports,
- unsigned int pos, unsigned int samples, unsigned int adat_width,
- unsigned int pcm_width)
+buffer_mux_port(struct sc_info *sc, uint32_t *dma, uint32_t *pcm,
+ uint32_t port, uint32_t ports, unsigned int pos, unsigned int samples,
+ unsigned int adat_width, unsigned int pcm_width)
{
- unsigned int slot_offset, slots;
+ unsigned int slot_offset, nch, stride;
unsigned int channels, chan_pos;
/* Translate DMA slot offset to DMA buffer offset. */
- slot_offset = hdspe_port_slot_offset(subset, adat_width);
+ slot_offset = hdspe_port_slot_offset(port, adat_width);
dma += slot_offset * HDSPE_CHANBUF_SAMPLES;
- /* Channel position of the port subset and total number of channels. */
- chan_pos = hdspe_channel_offset(subset, ports, pcm_width);
+ /* Channel position of the port and total number of channels. */
+ chan_pos = hdspe_channel_offset(port, ports, pcm_width);
pcm += chan_pos;
channels = hdspe_channel_count(ports, pcm_width);
/* Only copy as much as supported by both hardware and pcm channel. */
- slots = hdspe_port_slot_width(subset, min(adat_width, pcm_width));
-
- /* Let the compiler inline and loop unroll common cases. */
- if (slots == 2)
- buffer_mux_write(dma, pcm, pos, samples, 2, channels);
- else if (slots == 4)
- buffer_mux_write(dma, pcm, pos, samples, 4, channels);
- else if (slots == 8)
- buffer_mux_write(dma, pcm, pos, samples, 8, channels);
- else
- buffer_mux_write(dma, pcm, pos, samples, slots, channels);
+ nch = hdspe_port_slot_width(port, min(adat_width, pcm_width));
+ stride = hdspe_port_slot_stride(sc, port);
+
+ buffer_mux_write(dma, pcm, pos, samples, nch, channels, stride);
}
static void
buffer_demux_read(uint32_t *dma, uint32_t *pcm, unsigned int pos,
- unsigned int samples, unsigned int slots, unsigned int channels)
+ unsigned int samples, unsigned int nch, unsigned int channels,
+ unsigned int stride)
{
- int slot;
+ unsigned int i;
for (; samples > 0; samples--) {
- for (slot = 0; slot < slots; slot++) {
- pcm[pos * channels + slot] =
- dma[slot * HDSPE_CHANBUF_SAMPLES + pos];
+ for (i = 0; i < nch; i++) {
+ pcm[pos * channels + i] =
+ dma[i * stride * HDSPE_CHANBUF_SAMPLES + pos];
}
pos = (pos + 1) % HDSPE_CHANBUF_SAMPLES;
}
}
static void
-buffer_demux_port(uint32_t *dma, uint32_t *pcm, uint32_t subset, uint32_t ports,
- unsigned int pos, unsigned int samples, unsigned int adat_width,
- unsigned int pcm_width)
+buffer_demux_port(struct sc_info *sc, uint32_t *dma, uint32_t *pcm,
+ uint32_t port, uint32_t ports, unsigned int pos, unsigned int samples,
+ unsigned int adat_width, unsigned int pcm_width)
{
- unsigned int slot_offset, slots;
+ unsigned int slot_offset, nch, stride;
unsigned int channels, chan_pos;
/* Translate port slot offset to DMA buffer offset. */
- slot_offset = hdspe_port_slot_offset(subset, adat_width);
+ slot_offset = hdspe_port_slot_offset(port, adat_width);
dma += slot_offset * HDSPE_CHANBUF_SAMPLES;
- /* Channel position of the port subset and total number of channels. */
- chan_pos = hdspe_channel_offset(subset, ports, pcm_width);
+ /* Channel position of the port and total number of channels. */
+ chan_pos = hdspe_channel_offset(port, ports, pcm_width);
pcm += chan_pos;
channels = hdspe_channel_count(ports, pcm_width);
/* Only copy as much as supported by both hardware and pcm channel. */
- slots = hdspe_port_slot_width(subset, min(adat_width, pcm_width));
-
- /* Let the compiler inline and loop unroll common cases. */
- if (slots == 2)
- buffer_demux_read(dma, pcm, pos, samples, 2, channels);
- else if (slots == 4)
- buffer_demux_read(dma, pcm, pos, samples, 4, channels);
- else if (slots == 8)
- buffer_demux_read(dma, pcm, pos, samples, 8, channels);
- else
- buffer_demux_read(dma, pcm, pos, samples, slots, channels);
-}
+ nch = hdspe_port_slot_width(port, min(adat_width, pcm_width));
+ stride = hdspe_port_slot_stride(sc, port);
+ buffer_demux_read(dma, pcm, pos, samples, nch, channels, stride);
+}
/* Copy data between DMA and PCM buffers. */
static void
@@ -526,7 +500,7 @@
{
struct sc_pcminfo *scp;
struct sc_info *sc;
- uint32_t row, ports;
+ uint32_t port, ports;
uint32_t dma_pos;
unsigned int pos, length, offset;
unsigned int n;
@@ -575,26 +549,19 @@
pos /= 4;
length /= 4;
- /* Iterate through rows of ports with contiguous slots. */
+ /* Copy each port separately to preserve strided AIO ADAT slots. */
ports = ch->ports;
- if (pcm_width == adat_width)
- row = hdspe_port_first_row(ports);
- else
- row = hdspe_port_first(ports);
-
- while (row != 0) {
+ port = hdspe_port_first(ports);
+ while (port != 0) {
if (ch->dir == PCMDIR_PLAY)
- buffer_mux_port(sc->pbuf, ch->data, row, ch->ports, pos,
- length, adat_width, pcm_width);
- else
- buffer_demux_port(sc->rbuf, ch->data, row, ch->ports,
+ buffer_mux_port(sc, sc->pbuf, ch->data, port, ch->ports,
pos, length, adat_width, pcm_width);
-
- ports &= ~row;
- if (pcm_width == adat_width)
- row = hdspe_port_first_row(ports);
else
- row = hdspe_port_first(ports);
+ buffer_demux_port(sc, sc->rbuf, ch->data, port,
+ ch->ports, pos, length, adat_width, pcm_width);
+
+ ports &= ~port;
+ port = hdspe_port_first(ports);
}
if (ch->dir == PCMDIR_PLAY && length > 0) {
@@ -612,8 +579,8 @@
struct sc_pcminfo *scp;
struct sc_info *sc;
uint32_t *buf;
- uint32_t row, ports;
- unsigned int offset, slots;
+ uint32_t port, ports;
+ unsigned int base, width, stride, i, slot;
scp = ch->parent;
sc = scp->sc;
@@ -627,19 +594,23 @@
else
bus_dmamap_sync(sc->dmat, sc->rmap, BUS_DMASYNC_POSTREAD);
- /* Iterate through rows of ports with contiguous slots. */
ports = ch->ports;
- row = hdspe_port_first_row(ports);
- while (row != 0) {
- offset = hdspe_port_slot_offset(row,
+ port = hdspe_port_first(ports);
+ while (port != 0) {
+ base = hdspe_port_slot_offset(port,
hdspe_adat_width(sc->speed));
- slots = hdspe_port_slot_width(row, hdspe_adat_width(sc->speed));
+ width = hdspe_port_slot_width(port,
+ hdspe_adat_width(sc->speed));
+ stride = hdspe_port_slot_stride(sc, port);
- bzero(buf + offset * HDSPE_CHANBUF_SAMPLES,
- slots * HDSPE_CHANBUF_SIZE);
+ for (i = 0; i < width; i++) {
+ slot = base + i * stride;
+ bzero(buf + slot * HDSPE_CHANBUF_SAMPLES,
+ HDSPE_CHANBUF_SIZE);
+ }
- ports &= ~row;
- row = hdspe_port_first_row(ports);
+ ports &= ~port;
+ port = hdspe_port_first(ports);
}
if (ch->dir == PCMDIR_PLAY)
diff --git a/sys/dev/sound/pci/hdspe.c b/sys/dev/sound/pci/hdspe.c
--- a/sys/dev/sound/pci/hdspe.c
+++ b/sys/dev/sound/pci/hdspe.c
@@ -957,9 +957,9 @@
if (sc->dmat)
bus_dma_tag_destroy(sc->dmat);
if (sc->irq)
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
+ bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
if (sc->cs)
- bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->cs);
+ bus_release_resource(dev, SYS_RES_MEMORY, sc->csid, sc->cs);
cv_destroy(&sc->pcm_cv);
mtx_destroy(&sc->lock);

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 4, 2:32 PM (12 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41379170
Default Alt Text
D58372.1793802762.diff (11 KB)

Event Timeline