Lines Matching +full:adc +full:- +full:dev
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
34 #include <dev/sound/pcm/sound.h>
35 #include <dev/sound/pcm/ac97.h>
36 #include <dev/sound/pci/spicds.h>
37 #include <dev/sound/pci/envy24.h>
39 #include <dev/pci/pcireg.h>
40 #include <dev/pci/pcivar.h>
46 /* -------------------------------------------------------------------- */
97 void *(*create)(device_t dev, void *devinfo, int dir, int num);
118 device_t dev;
151 /* ADC/DAC number and info */
153 void *adc[4], *dac[4];
179 /* -------------------------------------------------------------------- */
208 /* M-Audio Delta series AK4524 access interface */
215 /* -------------------------------------------------------------------- */
221 /* API -> hardware channel map */
236 /* mixer -> API channel map. see above */
238 -1, /* Master output level. It is depend on codec support */
239 -1, /* Treble level of all output channels */
240 -1, /* Bass level of all output channels */
241 -1, /* Volume of synthesier input */
243 -1, /* Output level for the PC speaker */
245 -1, /* microphone jack */
246 -1, /* CD audio input */
247 -1, /* Recording monitor */
249 -1, /* global recording level */
250 -1, /* Input gain */
251 -1, /* Output gain */
256 -1, /* Digital (input) 2 */
257 -1, /* Digital (input) 3 */
258 -1, /* Phone input */
259 -1, /* Phone output */
260 -1, /* Video/TV (audio) in */
261 -1, /* Radio in */
262 -1, /* Monitor volume */
400 /* -------------------------------------------------------------------- */
408 return bus_space_read_1(sc->cst, sc->csh, regno);
410 return bus_space_read_2(sc->cst, sc->csh, regno);
412 return bus_space_read_4(sc->cst, sc->csh, regno);
423 bus_space_write_1(sc->cst, sc->csh, regno, data);
426 bus_space_write_2(sc->cst, sc->csh, regno, data);
429 bus_space_write_4(sc->cst, sc->csh, regno, data);
439 return bus_space_read_1(sc->mtt, sc->mth, regno);
441 return bus_space_read_2(sc->mtt, sc->mth, regno);
443 return bus_space_read_4(sc->mtt, sc->mth, regno);
454 bus_space_write_1(sc->mtt, sc->mth, regno, data);
457 bus_space_write_2(sc->mtt, sc->mth, regno, data);
460 bus_space_write_4(sc->mtt, sc->mth, regno, data);
479 /* -------------------------------------------------------------------- */
484 envy24_rdi2c(struct sc_info *sc, u_int32_t dev, u_int32_t addr)
490 device_printf(sc->dev, "envy24_rdi2c(sc, 0x%02x, 0x%02x)\n", dev, addr);
499 return -1;
503 (dev & ENVY24_CCS_I2CDEV_ADDR) | ENVY24_CCS_I2CDEV_RD, 1);
511 return -1;
516 device_printf(sc->dev, "envy24_rdi2c(): return 0x%x\n", data);
523 envy24_wri2c(struct sc_info *sc, u_int32_t dev, u_int32_t addr, u_int32_t data)
529 device_printf(sc->dev, "envy24_rdi2c(sc, 0x%02x, 0x%02x)\n", dev, addr);
538 return -1;
543 (dev & ENVY24_CCS_I2CDEV_ADDR) | ENVY24_CCS_I2CDEV_WR, 1);
551 return -1;
564 device_printf(sc->dev, "envy24_rdrom(sc, 0x%02x)\n", addr);
569 device_printf(sc->dev, "envy24_rdrom(): E2PROM not presented\n");
571 return -1;
585 device_printf(sc->dev, "envy24_rom2cfg(sc)\n");
590 device_printf(sc->dev, "envy24_rom2cfg(): ENVY24_E2PROM_SIZE-->%d\n", size);
597 device_printf(sc->dev, "envy24_rom2cfg(): malloc()\n");
601 buff->free = 1;
603 buff->subvendor = envy24_rdrom(sc, ENVY24_E2PROM_SUBVENDOR) << 8;
604 buff->subvendor += envy24_rdrom(sc, ENVY24_E2PROM_SUBVENDOR + 1);
605 buff->subdevice = envy24_rdrom(sc, ENVY24_E2PROM_SUBDEVICE) << 8;
606 buff->subdevice += envy24_rdrom(sc, ENVY24_E2PROM_SUBDEVICE + 1);
607 buff->scfg = envy24_rdrom(sc, ENVY24_E2PROM_SCFG);
608 buff->acl = envy24_rdrom(sc, ENVY24_E2PROM_ACL);
609 buff->i2s = envy24_rdrom(sc, ENVY24_E2PROM_I2S);
610 buff->spdif = envy24_rdrom(sc, ENVY24_E2PROM_SPDIF);
611 buff->gpiomask = envy24_rdrom(sc, ENVY24_E2PROM_GPIOMASK);
612 buff->gpiostate = envy24_rdrom(sc, ENVY24_E2PROM_GPIOSTATE);
613 buff->gpiodir = envy24_rdrom(sc, ENVY24_E2PROM_GPIODIR);
616 if (cfg_table[i].subvendor == buff->subvendor &&
617 cfg_table[i].subdevice == buff->subdevice)
619 buff->name = cfg_table[i].name;
620 buff->codec = cfg_table[i].codec;
629 if (cfg->free)
634 /* -------------------------------------------------------------------- */
646 device_printf(sc->dev, "envy24_coldcd()\n");
659 return -1;
670 device_printf(sc->dev, "envy24_slavecd()\n");
684 return -1;
696 device_printf(sc->dev, "envy24_rdcd(obj, sc, 0x%02x)\n", regno);
708 device_printf(sc->dev, "envy24_rdcd(): return 0x%x\n", data);
721 device_printf(sc->dev, "envy24_wrcd(obj, sc, 0x%02x, 0x%04x)\n", regno, data);
743 /* -------------------------------------------------------------------- */
757 device_printf(sc->dev, "envy24_gpiowr(sc, 0x%02x)\n", data & 0xff);
794 /* -------------------------------------------------------------------- */
796 /* Envy24 I2C through GPIO bit-banging */
812 device_printf(ptr->parent->dev, "--> %d, %d\n", scl, sda);
814 data = envy24_gpiord(ptr->parent);
818 envy24_gpiowr(ptr->parent, data);
882 i2c_wr(void *codec, void (*ctrl)(void*, unsigned int, unsigned int), u_int32_t dev, int reg, u_int8_t val)
890 i2c_wrbit(ptr, ctrl, dev & mask);
906 /* -------------------------------------------------------------------- */
908 /* M-Audio Delta series AK4524 access interface routine */
917 device_printf(ptr->parent->dev, "--> %d, %d, %d\n", cs, cclk, cdti);
919 data = envy24_gpiord(ptr->parent);
920 data &= ~(ptr->cs | ptr->cclk | ptr->cdti);
921 if (cs) data += ptr->cs;
922 if (cclk) data += ptr->cclk;
923 if (cdti) data += ptr->cdti;
924 envy24_gpiowr(ptr->parent, data);
929 envy24_delta_ak4524_create(device_t dev, void *info, int dir, int num)
935 device_printf(sc->dev, "envy24_delta_ak4524_create(dev, sc, %d, %d)\n", dir, num);
942 if (dir == PCMDIR_REC && sc->adc[num] != NULL)
943 buff->info = ((struct envy24_delta_ak4524_codec *)sc->adc[num])->info;
944 else if (dir == PCMDIR_PLAY && sc->dac[num] != NULL)
945 buff->info = ((struct envy24_delta_ak4524_codec *)sc->dac[num])->info;
947 buff->info = spicds_create(dev, buff, num, envy24_delta_ak4524_ctl);
948 if (buff->info == NULL) {
953 buff->parent = sc;
954 buff->dir = dir;
955 buff->num = num;
967 device_printf(ptr->parent->dev, "envy24_delta_ak4524_destroy()\n");
970 if (ptr->dir == PCMDIR_PLAY) {
971 if (ptr->parent->dac[ptr->num] != NULL)
972 spicds_destroy(ptr->info);
975 if (ptr->parent->adc[ptr->num] != NULL)
976 spicds_destroy(ptr->info);
992 device_printf(ptr->parent->dev, "envy24_delta_ak4524_init()\n");
996 gpiomask = envy24_gpiogetmask(ptr->parent);
998 envy24_gpiosetmask(ptr->parent, gpiomask);
999 gpiodir = envy24_gpiogetdir(ptr->parent);
1001 envy24_gpiosetdir(ptr->parent, gpiodir);
1003 ptr->cs = ptr->parent->cfg->cs;
1005 envy24_gpiosetmask(ptr->parent, ENVY24_GPIO_CS8414_STATUS);
1006 envy24_gpiosetdir(ptr->parent, ~ENVY24_GPIO_CS8414_STATUS);
1007 if (ptr->num == 0)
1008 ptr->cs = ENVY24_GPIO_AK4524_CS0;
1010 ptr->cs = ENVY24_GPIO_AK4524_CS1;
1011 ptr->cclk = ENVY24_GPIO_AK4524_CCLK;
1013 ptr->cclk = ptr->parent->cfg->cclk;
1014 ptr->cdti = ptr->parent->cfg->cdti;
1015 spicds_settype(ptr->info, ptr->parent->cfg->type);
1016 spicds_setcif(ptr->info, ptr->parent->cfg->cif);
1017 spicds_setformat(ptr->info,
1019 spicds_setdvc(ptr->info, AK452X_DVC_DEMOFF);
1021 if (ptr->num == 0)
1022 spicds_init(ptr->info);
1024 /* 6fire rear input init test, set ptr->num to 1 for test */
1025 if (ptr->parent->cfg->subvendor == 0x153b && \
1026 ptr->parent->cfg->subdevice == 0x1138 && ptr->num == 100) {
1027 ptr->cs = 0x02;
1028 spicds_init(ptr->info);
1029 device_printf(ptr->parent->dev, "6fire rear input init\n");
1044 device_printf(ptr->parent->dev, "envy24_delta_ak4524_reinit()\n");
1047 spicds_reinit(ptr->info);
1057 device_printf(ptr->parent->dev, "envy24_delta_ak4524_set()\n");
1060 spicds_set(ptr->info, dir, left, right);
1071 /* -------------------------------------------------------------------- */
1101 device_printf(sc->dev, "envy24_setspeed(sc, %d)\n", speed);
1115 device_printf(sc->dev, "envy24_setspeed(): speed %d/code 0x%04x\n", envy24_speedtab[i].speed, code);
1131 device_printf(sc->dev, "envy24_setspeed(): return %d\n", speed);
1140 device_printf(sc->dev, "envy24_setvolume(sc, %d)\n", ch);
1142 if (sc->cfg->subvendor==0x153b && sc->cfg->subdevice==0x1138 ) {
1150 envy24_wrmt(sc, ENVY24_MT_VOLUME, 0x7f00 | sc->left[ch], 2);
1152 envy24_wrmt(sc, ENVY24_MT_VOLUME, (sc->right[ch] << 8) | 0x7f, 2);
1161 device_printf(sc->dev, "envy24_mutevolume(sc, %d)\n", ch);
1177 device_printf(sc->dev, "envy24_gethwptr(sc, %d)\n", dir);
1180 rtn = sc->psize / 4;
1185 rtn = sc->rsize / 4;
1191 rtn -= (ptr + 1);
1195 device_printf(sc->dev, "envy24_gethwptr(): return %d\n", rtn);
1209 device_printf(sc->dev, "envy24_updintr(sc, %d)\n", dir);
1212 blk = sc->blk[0];
1217 blk = sc->blk[1];
1222 cnt = blk - 1;
1224 device_printf(sc->dev, "envy24_updintr():blk = %d, cnt = %d\n", blk, cnt);
1229 device_printf(sc->dev, "envy24_updintr():intr = 0x%02x, mask = 0x%02x\n", intr, mask);
1233 device_printf(sc->dev, "envy24_updintr():INT-->0x%02x\n",
1247 device_printf(sc->dev, "envy24_maskintr(sc, %d)\n", dir);
1266 device_printf(sc->dev, "envy24_checkintr(sc, %d)\n", dir);
1293 device_printf(sc->dev, "envy24_start(sc, %d)\n", dir);
1304 device_printf(sc->dev, "PADDR:0x%08x\n", envy24_rdmt(sc, ENVY24_MT_PADDR, 4));
1305 device_printf(sc->dev, "PCNT:%ld\n", envy24_rdmt(sc, ENVY24_MT_PCNT, 2));
1317 device_printf(sc->dev, "envy24_stop(sc, %d)\n", dir);
1331 envy24_route(struct sc_info *sc, int dac, int class, int adc, int rev)
1337 device_printf(sc->dev, "envy24_route(sc, %d, %d, %d, %d)\n",
1338 dac, class, adc, rev);
1342 return -1;
1345 return -1;
1357 ((adc << 1 | left) | left << 3) << 8 |
1358 ((adc << 1 | right) | right << 3) << 12;
1360 device_printf(sc->dev, "envy24_route(): MT_SPDOUT-->0x%04x\n", reg);
1369 device_printf(sc->dev, "envy24_route(): MT_PSDOUT-->0x%04x\n", reg);
1375 (((adc << 1 | left) | left << 3) |
1376 ((adc << 1 | right) | right << 3) << 4) << dac * 8;
1378 device_printf(sc->dev, "envy24_route(): MT_RECORD-->0x%08x\n", reg);
1389 /* -------------------------------------------------------------------- */
1401 length = sndbuf_getready(ch->buffer) / 8;
1402 dmabuf = ch->parent->pbuf;
1403 data = (u_int32_t *)ch->data;
1404 src = sndbuf_getreadyptr(ch->buffer) / 4;
1405 dst = src / 2 + ch->offset;
1406 ssize = ch->size / 4;
1407 dsize = ch->size / 8;
1408 slot = ch->num * 2;
1432 device_printf(ch->parent->dev, "envy24_p16sl()\n");
1434 length = sndbuf_getready(ch->buffer) / 4;
1435 dmabuf = ch->parent->pbuf;
1436 data = (u_int16_t *)ch->data;
1437 src = sndbuf_getreadyptr(ch->buffer) / 2;
1438 dst = src / 2 + ch->offset;
1439 ssize = ch->size / 2;
1440 dsize = ch->size / 4;
1441 slot = ch->num * 2;
1443 device_printf(ch->parent->dev, "envy24_p16sl():%lu-->%lu(%lu)\n", src, dst, length);
1476 length = sndbuf_getready(ch->buffer) / 2;
1477 dmabuf = ch->parent->pbuf;
1478 data = (u_int8_t *)ch->data;
1479 src = sndbuf_getreadyptr(ch->buffer);
1480 dst = src / 2 + ch->offset;
1481 ssize = ch->size;
1482 dsize = ch->size / 4;
1483 slot = ch->num * 2;
1506 length = sndbuf_getfree(ch->buffer) / 8;
1507 dmabuf = ch->parent->rbuf;
1508 data = (u_int32_t *)ch->data;
1509 dst = sndbuf_getfreeptr(ch->buffer) / 4;
1510 src = dst / 2 + ch->offset;
1511 dsize = ch->size / 4;
1512 ssize = ch->size / 8;
1513 slot = (ch->num - ENVY24_CHAN_REC_ADC1) * 2;
1536 length = sndbuf_getfree(ch->buffer) / 4;
1537 dmabuf = ch->parent->rbuf;
1538 data = (u_int16_t *)ch->data;
1539 dst = sndbuf_getfreeptr(ch->buffer) / 2;
1540 src = dst / 2 + ch->offset;
1541 dsize = ch->size / 2;
1542 ssize = ch->size / 8;
1543 slot = (ch->num - ENVY24_CHAN_REC_ADC1) * 2;
1557 /* -------------------------------------------------------------------- */
1568 device_printf(sc->dev, "envy24chan_init(obj, devinfo, b, c, %d)\n", dir);
1570 snd_mtxlock(sc->lock);
1571 if ((sc->chnum > ENVY24_CHAN_PLAY_SPDIF && dir != PCMDIR_REC) ||
1572 (sc->chnum < ENVY24_CHAN_REC_ADC1 && dir != PCMDIR_PLAY)) {
1573 snd_mtxunlock(sc->lock);
1576 num = sc->chnum;
1578 ch = &sc->chan[num];
1579 ch->size = 8 * ENVY24_SAMPLE_NUM;
1580 ch->data = malloc(ch->size, M_ENVY24, M_NOWAIT);
1581 if (ch->data == NULL) {
1582 ch->size = 0;
1586 ch->buffer = b;
1587 ch->channel = c;
1588 ch->parent = sc;
1589 ch->dir = dir;
1591 ch->num = envy24_chanmap[num];
1592 snd_mtxunlock(sc->lock);
1593 sndbuf_setup(ch->buffer, ch->data, ch->size);
1594 snd_mtxlock(sc->lock);
1596 ch->unit = 4;
1597 ch->blk = 10240;
1599 snd_mtxunlock(sc->lock);
1608 struct sc_info *sc = ch->parent;
1611 device_printf(sc->dev, "envy24chan_free()\n");
1613 snd_mtxlock(sc->lock);
1614 if (ch->data != NULL) {
1615 free(ch->data, M_ENVY24);
1616 ch->data = NULL;
1618 snd_mtxunlock(sc->lock);
1627 struct sc_info *sc = ch->parent;
1633 device_printf(sc->dev, "envy24chan_setformat(obj, data, 0x%08x)\n", format);
1635 snd_mtxlock(sc->lock);
1637 if (ch->dir == PCMDIR_PLAY)
1642 snd_mtxunlock(sc->lock);
1643 return -1;
1649 snd_mtxunlock(sc->lock);
1650 return -1;
1654 ch->format = format;
1655 ch->emldma = emltab[i].emldma;
1656 if (ch->unit > emltab[i].unit)
1657 ch->blk *= ch->unit / emltab[i].unit;
1659 ch->blk /= emltab[i].unit / ch->unit;
1660 ch->unit = emltab[i].unit;
1663 ch->size = ch->unit * ENVY24_SAMPLE_NUM;
1665 if (ch->dir == PCMDIR_PLAY)
1666 bsize = ch->blk * 4 / ENVY24_PLAY_BUFUNIT;
1668 bsize = ch->blk * 4 / ENVY24_REC_BUFUNIT;
1669 bsize *= ch->unit;
1670 bcnt = ch->size / bsize;
1671 sndbuf_resize(ch->buffer, bcnt, bsize);
1673 snd_mtxunlock(sc->lock);
1676 device_printf(sc->dev, "envy24chan_setformat(): return 0x%08x\n", 0);
1697 device_printf(ch->parent->dev, "envy24chan_setspeed(obj, data, %d)\n", speed);
1701 if (abs(val - speed) < abs(prev - speed))
1706 ch->speed = prev;
1709 device_printf(ch->parent->dev, "envy24chan_setspeed(): return %d\n", ch->speed);
1711 return ch->speed;
1718 /* struct sc_info *sc = ch->parent; */
1723 device_printf(sc->dev, "envy24chan_setblocksize(obj, data, %d)\n", blocksize);
1726 /* snd_mtxlock(sc->lock); */
1727 for (size = ch->size / 2; size > 0; size /= 2) {
1728 if (abs(size - blocksize) < abs(prev - blocksize))
1734 ch->blk = prev / ch->unit;
1735 if (ch->dir == PCMDIR_PLAY)
1736 ch->blk *= ENVY24_PLAY_BUFUNIT / 4;
1738 ch->blk *= ENVY24_REC_BUFUNIT / 4;
1740 /* ch->size = ch->unit * ENVY24_SAMPLE_NUM; */
1741 if (ch->dir == PCMDIR_PLAY)
1742 bsize = ch->blk * 4 / ENVY24_PLAY_BUFUNIT;
1744 bsize = ch->blk * 4 / ENVY24_REC_BUFUNIT;
1745 bsize *= ch->unit;
1746 bcnt = ch->size / bsize;
1747 sndbuf_resize(ch->buffer, bcnt, bsize);
1748 /* snd_mtxunlock(sc->lock); */
1751 device_printf(sc->dev, "envy24chan_setblocksize(): return %d\n", prev);
1761 struct sc_info *sc = ch->parent;
1768 device_printf(sc->dev, "envy24chan_trigger(obj, data, %d)\n", go);
1770 snd_mtxlock(sc->lock);
1771 if (ch->dir == PCMDIR_PLAY)
1778 device_printf(sc->dev, "envy24chan_trigger(): start\n");
1781 if (sc->run[0] == 0 && sc->run[1] == 0) {
1782 sc->speed = envy24_setspeed(sc, ch->speed);
1783 sc->caps[0].minspeed = sc->caps[0].maxspeed = sc->speed;
1784 sc->caps[1].minspeed = sc->caps[1].maxspeed = sc->speed;
1786 else if (ch->speed != 0 && ch->speed != sc->speed) {
1787 error = -1;
1790 if (ch->speed == 0)
1791 ch->channel->speed = sc->speed;
1793 sc->run[slot]++;
1794 if (sc->run[slot] == 1) {
1796 ch->offset = 0;
1797 sc->blk[slot] = ch->blk;
1800 ptr = envy24_gethwptr(sc, ch->dir);
1801 ch->offset = ((ptr / ch->blk + 1) * ch->blk %
1802 (ch->size / 4)) * 4 / ch->unit;
1803 if (ch->blk < sc->blk[slot])
1804 sc->blk[slot] = ch->blk;
1806 if (ch->dir == PCMDIR_PLAY) {
1807 ch->emldma(ch);
1808 envy24_setvolume(sc, ch->num);
1810 envy24_updintr(sc, ch->dir);
1811 if (sc->run[slot] == 1)
1812 envy24_start(sc, ch->dir);
1813 ch->run = 1;
1817 device_printf(sc->dev, "envy24chan_trigger(): emldmawr\n");
1819 if (ch->run != 1) {
1820 error = -1;
1823 ch->emldma(ch);
1827 device_printf(sc->dev, "envy24chan_trigger(): emldmard\n");
1829 if (ch->run != 1) {
1830 error = -1;
1833 ch->emldma(ch);
1836 if (ch->run) {
1838 device_printf(sc->dev, "envy24chan_trigger(): abort\n");
1840 ch->run = 0;
1841 sc->run[slot]--;
1842 if (ch->dir == PCMDIR_PLAY)
1843 envy24_mutevolume(sc, ch->num);
1844 if (sc->run[slot] == 0) {
1845 envy24_stop(sc, ch->dir);
1846 sc->intr[slot] = 0;
1849 else if (ch->blk == sc->blk[slot]) {
1850 sc->blk[slot] = ENVY24_SAMPLE_NUM / 2;
1852 if (sc->chan[i].dir == ch->dir &&
1853 sc->chan[i].run == 1 &&
1854 sc->chan[i].blk < sc->blk[slot])
1855 sc->blk[slot] = sc->chan[i].blk;
1857 if (ch->blk != sc->blk[slot])
1858 envy24_updintr(sc, ch->dir);
1865 snd_mtxunlock(sc->lock);
1873 struct sc_info *sc = ch->parent;
1877 device_printf(sc->dev, "envy24chan_getptr()\n");
1879 snd_mtxlock(sc->lock);
1880 ptr = envy24_gethwptr(sc, ch->dir);
1881 rtn = ptr * ch->unit;
1882 snd_mtxunlock(sc->lock);
1885 device_printf(sc->dev, "envy24chan_getptr(): return %d\n",
1895 struct sc_info *sc = ch->parent;
1899 device_printf(sc->dev, "envy24chan_getcaps()\n");
1901 snd_mtxlock(sc->lock);
1902 if (ch->dir == PCMDIR_PLAY) {
1903 if (sc->run[0] == 0)
1906 rtn = &sc->caps[0];
1909 if (sc->run[1] == 0)
1912 rtn = &sc->caps[1];
1914 snd_mtxunlock(sc->lock);
1932 /* -------------------------------------------------------------------- */
1942 device_printf(sc->dev, "envy24mixer_init()\n");
1945 return -1;
1948 snd_mtxlock(sc->lock);
1953 snd_mtxunlock(sc->lock);
1964 return -1;
1966 device_printf(sc->dev, "envy24mixer_reinit()\n");
1978 return -1;
1980 device_printf(sc->dev, "envy24mixer_uninit()\n");
1987 envy24mixer_set(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right)
1990 int ch = envy24_mixmap[dev];
1995 return -1;
1996 if (dev == 0 && sc->cfg->codec->setvolume == NULL)
1997 return -1;
1998 if (dev != 0 && ch == -1)
1999 return -1;
2002 device_printf(sc->dev, "envy24mixer_set(m, %d, %d, %d)\n",
2003 dev, left, right);
2006 snd_mtxlock(sc->lock);
2007 if (dev == 0) {
2008 for (i = 0; i < sc->dacn; i++) {
2009 sc->cfg->codec->setvolume(sc->dac[i], PCMDIR_PLAY, left, right);
2014 if ((sc->left[hwch] = 100 - left) > ENVY24_VOL_MIN)
2015 sc->left[hwch] = ENVY24_VOL_MUTE;
2016 if ((sc->right[hwch] = 100 - right) > ENVY24_VOL_MIN)
2017 sc->right[hwch] = ENVY24_VOL_MUTE;
2020 if (hwch > ENVY24_CHAN_PLAY_SPDIF || sc->chan[ch].run)
2023 snd_mtxunlock(sc->lock);
2034 device_printf(sc->dev, "envy24mixer_setrecsrc(m, %d)\n", src);
2038 sc->src = ch;
2052 /* -------------------------------------------------------------------- */
2064 device_printf(sc->dev, "envy24_intr()\n");
2066 snd_mtxlock(sc->lock);
2069 device_printf(sc->dev, "envy24_intr(): play\n");
2071 dsize = sc->psize / 4;
2072 ptr = dsize - envy24_rdmt(sc, ENVY24_MT_PCNT, 2) - 1;
2074 device_printf(sc->dev, "envy24_intr(): ptr = %d-->", ptr);
2076 ptr -= ptr % sc->blk[0];
2077 feed = (ptr + dsize - sc->intr[0]) % dsize;
2079 printf("%d intr = %d feed = %d\n", ptr, sc->intr[0], feed);
2082 ch = &sc->chan[i];
2084 if (ch->run)
2085 device_printf(sc->dev, "envy24_intr(): chan[%d].blk = %d\n", i, ch->blk);
2087 if (ch->run && ch->blk <= feed) {
2088 snd_mtxunlock(sc->lock);
2089 chn_intr(ch->channel);
2090 snd_mtxlock(sc->lock);
2093 sc->intr[0] = ptr;
2098 device_printf(sc->dev, "envy24_intr(): rec\n");
2100 dsize = sc->rsize / 4;
2101 ptr = dsize - envy24_rdmt(sc, ENVY24_MT_RCNT, 2) - 1;
2102 ptr -= ptr % sc->blk[1];
2103 feed = (ptr + dsize - sc->intr[1]) % dsize;
2105 ch = &sc->chan[i];
2106 if (ch->run && ch->blk <= feed) {
2107 snd_mtxunlock(sc->lock);
2108 chn_intr(ch->channel);
2109 snd_mtxlock(sc->lock);
2112 sc->intr[1] = ptr;
2115 snd_mtxunlock(sc->lock);
2125 envy24_pci_probe(device_t dev)
2133 if (pci_get_device(dev) == PCID_ENVY24 &&
2134 pci_get_vendor(dev) == PCIV_ENVY24) {
2135 sv = pci_get_subvendor(dev);
2136 sd = pci_get_subdevice(dev);
2143 device_set_desc(dev, cfg_table[i].name);
2162 sc->paddr = segs->ds_addr;
2164 device_printf(sc->dev, "envy24_dmapsetmap()\n");
2167 (unsigned long)segs->ds_addr,
2168 (unsigned long)segs->ds_len);
2169 printf("%p -> %lx\n", sc->pmap, sc->paddr);
2179 sc->raddr = segs->ds_addr;
2181 device_printf(sc->dev, "envy24_dmarsetmap()\n");
2184 (unsigned long)segs->ds_addr,
2185 (unsigned long)segs->ds_len);
2186 printf("%p -> %lx\n", sc->rmap, sc->raddr);
2195 device_printf(sc->dev, "envy24_dmafree():");
2196 printf(" sc->raddr(0x%08x)", (u_int32_t)sc->raddr);
2197 printf(" sc->paddr(0x%08x)", (u_int32_t)sc->paddr);
2198 if (sc->rbuf) printf(" sc->rbuf(0x%08x)", (u_int32_t)sc->rbuf);
2199 else printf(" sc->rbuf(null)");
2200 if (sc->pbuf) printf(" sc->pbuf(0x%08x)\n", (u_int32_t)sc->pbuf);
2201 else printf(" sc->pbuf(null)\n");
2204 if (sc->raddr)
2205 bus_dmamap_unload(sc->dmat, sc->rmap);
2206 if (sc->paddr)
2207 bus_dmamap_unload(sc->dmat, sc->pmap);
2208 if (sc->rbuf)
2209 bus_dmamem_free(sc->dmat, sc->rbuf, sc->rmap);
2210 if (sc->pbuf)
2211 bus_dmamem_free(sc->dmat, sc->pbuf, sc->pmap);
2213 bus_dmamap_unload(sc->dmat, sc->rmap);
2214 bus_dmamap_unload(sc->dmat, sc->pmap);
2215 bus_dmamem_free(sc->dmat, sc->rbuf, sc->rmap);
2216 bus_dmamem_free(sc->dmat, sc->pbuf, sc->pmap);
2219 sc->raddr = sc->paddr = 0;
2220 sc->pbuf = NULL;
2221 sc->rbuf = NULL;
2231 device_printf(sc->dev, "envy24_dmainit()\n");
2234 sc->psize = ENVY24_PLAY_BUFUNIT * ENVY24_SAMPLE_NUM;
2235 sc->rsize = ENVY24_REC_BUFUNIT * ENVY24_SAMPLE_NUM;
2236 sc->pbuf = NULL;
2237 sc->rbuf = NULL;
2238 sc->paddr = sc->raddr = 0;
2239 sc->blk[0] = sc->blk[1] = 0;
2243 device_printf(sc->dev, "envy24_dmainit(): bus_dmamem_alloc(): sc->pbuf\n");
2245 if (bus_dmamem_alloc(sc->dmat, (void **)&sc->pbuf, BUS_DMA_NOWAIT, &sc->pmap))
2248 device_printf(sc->dev, "envy24_dmainit(): bus_dmamem_alloc(): sc->rbuf\n");
2250 if (bus_dmamem_alloc(sc->dmat, (void **)&sc->rbuf, BUS_DMA_NOWAIT, &sc->rmap))
2253 device_printf(sc->dev, "envy24_dmainit(): bus_dmamem_load(): sc->pmap\n");
2255 if (bus_dmamap_load(sc->dmat, sc->pmap, sc->pbuf, sc->psize,
2259 device_printf(sc->dev, "envy24_dmainit(): bus_dmamem_load(): sc->rmap\n");
2261 if (bus_dmamap_load(sc->dmat, sc->rmap, sc->rbuf, sc->rsize,
2264 bzero(sc->pbuf, sc->psize);
2265 bzero(sc->rbuf, sc->rsize);
2269 device_printf(sc->dev, "paddr(0x%08x)\n", sc->paddr);
2271 envy24_wrmt(sc, ENVY24_MT_PADDR, sc->paddr, 4);
2273 device_printf(sc->dev, "PADDR-->(0x%08x)\n", envy24_rdmt(sc, ENVY24_MT_PADDR, 4));
2274 device_printf(sc->dev, "psize(%ld)\n", sc->psize / 4 - 1);
2276 envy24_wrmt(sc, ENVY24_MT_PCNT, sc->psize / 4 - 1, 2);
2278 device_printf(sc->dev, "PCNT-->(%ld)\n", envy24_rdmt(sc, ENVY24_MT_PCNT, 2));
2280 envy24_wrmt(sc, ENVY24_MT_RADDR, sc->raddr, 4);
2281 envy24_wrmt(sc, ENVY24_MT_RCNT, sc->rsize / 4 - 1, 2);
2292 device_printf(sc->dev, "system configuration\n");
2294 sc->cfg->subvendor, sc->cfg->subdevice);
2296 switch (sc->cfg->scfg & PCIM_SCFG_XIN2) {
2309 printf(" MPU-401 UART(s) #: ");
2310 if (sc->cfg->scfg & PCIM_SCFG_MPU)
2315 if (sc->cfg->scfg & PCIM_SCFG_AC97)
2319 printf(" ADC #: ");
2320 printf("%d\n", sc->adcn);
2322 printf("%d\n", sc->dacn);
2323 printf(" Multi-track converter type: ");
2324 if ((sc->cfg->acl & PCIM_ACL_MTC) == 0) {
2326 if (sc->cfg->acl & PCIM_ACL_OMODE)
2331 if (sc->cfg->acl & PCIM_ACL_IMODE)
2339 if (sc->cfg->i2s & PCIM_I2S_VOL)
2341 if (sc->cfg->i2s & PCIM_I2S_96KHZ)
2343 switch (sc->cfg->i2s & PCIM_I2S_RES) {
2357 printf("ID#0x%x)\n", sc->cfg->i2s & PCIM_I2S_ID);
2360 if (sc->cfg->spdif & PCIM_SPDIF_IN)
2364 if (sc->cfg->spdif & PCIM_SPDIF_OUT)
2368 if (sc->cfg->spdif & (PCIM_SPDIF_IN | PCIM_SPDIF_OUT))
2369 printf("ID# 0x%02x\n", (sc->cfg->spdif & PCIM_SPDIF_ID) >> 2);
2371 sc->cfg->gpiomask, sc->cfg->gpiodir, sc->cfg->gpiostate);
2385 device_printf(sc->dev, "envy24_init()\n");
2395 data = pci_read_config(sc->dev, PCIR_LAC, 2);
2397 pci_write_config(sc->dev, PCIR_LAC, data, 2);
2400 sc->cfg = NULL;
2403 sv = pci_get_subvendor(sc->dev);
2404 sd = pci_get_subdevice(sc->dev);
2407 device_printf(sc->dev, "Set configuration from table\n");
2409 sc->cfg = &cfg_table[i];
2413 if (sc->cfg == NULL) {
2415 sc->cfg = envy24_rom2cfg(sc);
2417 sc->adcn = ((sc->cfg->scfg & PCIM_SCFG_ADC) >> 2) + 1;
2418 sc->dacn = (sc->cfg->scfg & PCIM_SCFG_DAC) + 1;
2425 pci_write_config(sc->dev, PCIR_SCFG, sc->cfg->scfg, 1);
2426 pci_write_config(sc->dev, PCIR_ACL, sc->cfg->acl, 1);
2427 pci_write_config(sc->dev, PCIR_I2S, sc->cfg->i2s, 1);
2428 pci_write_config(sc->dev, PCIR_SPDIF, sc->cfg->spdif, 1);
2429 envy24_gpiosetmask(sc, sc->cfg->gpiomask);
2430 envy24_gpiosetdir(sc, sc->cfg->gpiodir);
2431 envy24_gpiowr(sc, sc->cfg->gpiostate);
2432 for (i = 0; i < sc->adcn; i++) {
2433 sc->adc[i] = sc->cfg->codec->create(sc->dev, sc, PCMDIR_REC, i);
2434 sc->cfg->codec->init(sc->adc[i]);
2436 for (i = 0; i < sc->dacn; i++) {
2437 sc->dac[i] = sc->cfg->codec->create(sc->dev, sc, PCMDIR_PLAY, i);
2438 sc->cfg->codec->init(sc->dac[i]);
2443 device_printf(sc->dev, "envy24_init(): initialize DMA buffer\n");
2449 sc->run[0] = sc->run[1] = 0;
2450 sc->intr[0] = sc->intr[1] = 0;
2451 sc->speed = 0;
2452 sc->caps[0].fmtlist = envy24_playfmt;
2453 sc->caps[1].fmtlist = envy24_recfmt;
2465 device_printf(sc->dev, "envy24_init(): CCS_IMASK-->0x%02x\n", data);
2475 sc->csid = PCIR_CCS;
2476 sc->cs = bus_alloc_resource_any(sc->dev, SYS_RES_IOPORT,
2477 &sc->csid, RF_ACTIVE);
2478 sc->ddmaid = PCIR_DDMA;
2479 sc->ddma = bus_alloc_resource_any(sc->dev, SYS_RES_IOPORT,
2480 &sc->ddmaid, RF_ACTIVE);
2481 sc->dsid = PCIR_DS;
2482 sc->ds = bus_alloc_resource_any(sc->dev, SYS_RES_IOPORT,
2483 &sc->dsid, RF_ACTIVE);
2484 sc->mtid = PCIR_MT;
2485 sc->mt = bus_alloc_resource_any(sc->dev, SYS_RES_IOPORT,
2486 &sc->mtid, RF_ACTIVE);
2487 if (!sc->cs || !sc->ddma || !sc->ds || !sc->mt) {
2488 device_printf(sc->dev, "unable to map IO port space\n");
2491 sc->cst = rman_get_bustag(sc->cs);
2492 sc->csh = rman_get_bushandle(sc->cs);
2493 sc->ddmat = rman_get_bustag(sc->ddma);
2494 sc->ddmah = rman_get_bushandle(sc->ddma);
2495 sc->dst = rman_get_bustag(sc->ds);
2496 sc->dsh = rman_get_bushandle(sc->ds);
2497 sc->mtt = rman_get_bustag(sc->mt);
2498 sc->mth = rman_get_bushandle(sc->mt);
2500 device_printf(sc->dev,
2502 pci_read_config(sc->dev, PCIR_CCS, 4),
2503 pci_read_config(sc->dev, PCIR_DDMA, 4),
2504 pci_read_config(sc->dev, PCIR_DS, 4),
2505 pci_read_config(sc->dev, PCIR_MT, 4));
2509 sc->irqid = 0;
2510 sc->irq = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, &sc->irqid,
2512 if (!sc->irq ||
2513 snd_setup_intr(sc->dev, sc->irq, INTR_MPSAFE, envy24_intr, sc, &sc->ih)) {
2514 device_printf(sc->dev, "unable to map interrupt\n");
2519 if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(sc->dev),
2528 &sc->dmat) != 0) {
2529 device_printf(sc->dev, "unable to create dma tag\n");
2537 envy24_pci_attach(device_t dev)
2545 device_printf(dev, "envy24_pci_attach()\n");
2549 device_printf(dev, "cannot allocate softc\n");
2554 sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_envy24 softc");
2555 sc->dev = dev;
2558 pci_enable_busmaster(dev);
2563 device_printf(dev, "unable to allocate system resources\n");
2570 device_printf(dev, "unable to initialize the card\n");
2575 mixer_init(dev, &envy24mixer_class, sc);
2578 pcm_init(dev, sc);
2579 sc->chnum = 0;
2581 pcm_addchan(dev, PCMDIR_PLAY, &envy24chan_class, sc);
2582 sc->chnum++;
2584 for (i = 0; i < 2 + sc->adcn; i++) {
2585 pcm_addchan(dev, PCMDIR_REC, &envy24chan_class, sc);
2586 sc->chnum++;
2592 rman_get_start(sc->cs),
2593 rman_get_end(sc->cs) - rman_get_start(sc->cs) + 1,
2594 rman_get_start(sc->ddma),
2595 rman_get_end(sc->ddma) - rman_get_start(sc->ddma) + 1,
2596 rman_get_start(sc->ds),
2597 rman_get_end(sc->ds) - rman_get_start(sc->ds) + 1,
2598 rman_get_start(sc->mt),
2599 rman_get_end(sc->mt) - rman_get_start(sc->mt) + 1,
2600 rman_get_start(sc->irq),
2601 device_get_nameunit(device_get_parent(dev)));
2602 if (pcm_register(dev, status))
2608 if (sc->ih)
2609 bus_teardown_intr(dev, sc->irq, sc->ih);
2610 if (sc->irq)
2611 bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
2613 if (sc->dmat)
2614 bus_dma_tag_destroy(sc->dmat);
2615 if (sc->cfg->codec->destroy != NULL) {
2616 for (i = 0; i < sc->adcn; i++)
2617 sc->cfg->codec->destroy(sc->adc[i]);
2618 for (i = 0; i < sc->dacn; i++)
2619 sc->cfg->codec->destroy(sc->dac[i]);
2621 envy24_cfgfree(sc->cfg);
2622 if (sc->cs)
2623 bus_release_resource(dev, SYS_RES_IOPORT, sc->csid, sc->cs);
2624 if (sc->ddma)
2625 bus_release_resource(dev, SYS_RES_IOPORT, sc->ddmaid, sc->ddma);
2626 if (sc->ds)
2627 bus_release_resource(dev, SYS_RES_IOPORT, sc->dsid, sc->ds);
2628 if (sc->mt)
2629 bus_release_resource(dev, SYS_RES_IOPORT, sc->mtid, sc->mt);
2630 if (sc->lock)
2631 snd_mtxfree(sc->lock);
2637 envy24_pci_detach(device_t dev)
2644 device_printf(dev, "envy24_pci_detach()\n");
2646 sc = pcm_getdevinfo(dev);
2649 r = pcm_unregister(dev);
2654 if (sc->cfg->codec->destroy != NULL) {
2655 for (i = 0; i < sc->adcn; i++)
2656 sc->cfg->codec->destroy(sc->adc[i]);
2657 for (i = 0; i < sc->dacn; i++)
2658 sc->cfg->codec->destroy(sc->dac[i]);
2660 envy24_cfgfree(sc->cfg);
2661 bus_dma_tag_destroy(sc->dmat);
2662 bus_teardown_intr(dev, sc->irq, sc->ih);
2663 bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq);
2664 bus_release_resource(dev, SYS_RES_IOPORT, sc->csid, sc->cs);
2665 bus_release_resource(dev, SYS_RES_IOPORT, sc->ddmaid, sc->ddma);
2666 bus_release_resource(dev, SYS_RES_IOPORT, sc->dsid, sc->ds);
2667 bus_release_resource(dev, SYS_RES_IOPORT, sc->mtid, sc->mt);
2668 snd_mtxfree(sc->lock);