Lines Matching +full:4 +full:- +full:ch
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
40 /* -------------------------------------------------------------------- */
54 #define TR_MAXPLAYCH 4
57 * Though, it's not clearly documented in the 4DWAVE datasheet, the
60 * is 32-bit, but the two MSBs are used for other purposes.
62 #define TR_MAXADDR ((1U << 30) - 1)
63 #define ALI_MAXADDR ((1U << 31) - 1)
112 /* -------------------------------------------------------------------- */
140 /* -------------------------------------------------------------------- */
149 return bus_space_read_1(tr->st, tr->sh, regno); in tr_rd()
151 return bus_space_read_2(tr->st, tr->sh, regno); in tr_rd()
152 case 4: in tr_rd()
153 return bus_space_read_4(tr->st, tr->sh, regno); in tr_rd()
164 bus_space_write_1(tr->st, tr->sh, regno, data); in tr_wr()
167 bus_space_write_2(tr->st, tr->sh, regno, data); in tr_wr()
169 case 4: in tr_wr()
170 bus_space_write_4(tr->st, tr->sh, regno, data); in tr_wr()
175 /* -------------------------------------------------------------------- */
184 switch (tr->type) { in tr_rdcd()
190 if (tr->rev > 0x01) in tr_rdcd()
206 return -1; in tr_rdcd()
212 snd_mtxlock(tr->lock); in tr_rdcd()
213 if (tr->type == ALI_PCI_ID) { in tr_rdcd()
216 for (i = TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--) in tr_rdcd()
217 j = tr_rd(tr, treg, 4); in tr_rdcd()
219 chk1 = tr_rd(tr, 0xc8, 4); in tr_rdcd()
220 chk2 = tr_rd(tr, 0xc8, 4); in tr_rdcd()
222 i--) in tr_rdcd()
223 chk2 = tr_rd(tr, 0xc8, 4); in tr_rdcd()
226 if (tr->type != ALI_PCI_ID || i > 0) { in tr_rdcd()
227 tr_wr(tr, treg, regno | trw, 4); in tr_rdcd()
229 for (i=TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--) in tr_rdcd()
230 j=tr_rd(tr, treg, 4); in tr_rdcd()
232 snd_mtxunlock(tr->lock); in tr_rdcd()
243 switch (tr->type) { in tr_wrcd()
259 return -1; in tr_wrcd()
269 snd_mtxlock(tr->lock); in tr_wrcd()
270 if (tr->type == ALI_PCI_ID) { in tr_wrcd()
272 for (i = TR_TIMEOUT_CDC; (i > 0) && (j & trw); i--) in tr_wrcd()
273 j = tr_rd(tr, treg, 4); in tr_wrcd()
276 chk1 = tr_rd(tr, 0xc8, 4); in tr_wrcd()
277 chk2 = tr_rd(tr, 0xc8, 4); in tr_wrcd()
279 i--) in tr_wrcd()
280 chk2 = tr_rd(tr, 0xc8, 4); in tr_wrcd()
283 if (tr->type != ALI_PCI_ID || i > 0) { in tr_wrcd()
284 for (i=TR_TIMEOUT_CDC; (i>0) && (j & trw); i--) in tr_wrcd()
285 j=tr_rd(tr, treg, 4); in tr_wrcd()
286 if (tr->type == ALI_PCI_ID && tr->rev > 0x01) in tr_wrcd()
288 tr_wr(tr, treg, (data << TR_CDC_DATA) | regno | trw, 4); in tr_wrcd()
291 printf(" - wrote %x, now %x\n", data, tr_rdcd(devinfo, regno)); in tr_wrcd()
293 snd_mtxunlock(tr->lock); in tr_wrcd()
295 return (i > 0)? 0 : -1; in tr_wrcd()
305 /* -------------------------------------------------------------------- */
310 tr_testint(struct tr_chinfo *ch)
312 struct tr_info *tr = ch->parent;
315 bank = (ch->index & 0x20) ? 1 : 0;
316 chan = ch->index & 0x1f;
317 return tr_rd(tr, bank? TR_REG_ADDRINTB : TR_REG_ADDRINTA, 4) & (1 << chan);
322 tr_clrint(struct tr_chinfo *ch) in tr_clrint() argument
324 struct tr_info *tr = ch->parent; in tr_clrint()
327 bank = (ch->index & 0x20) ? 1 : 0; in tr_clrint()
328 chan = ch->index & 0x1f; in tr_clrint()
329 tr_wr(tr, bank? TR_REG_ADDRINTB : TR_REG_ADDRINTA, 1 << chan, 4); in tr_clrint()
333 tr_enaint(struct tr_chinfo *ch, int enable) in tr_enaint() argument
335 struct tr_info *tr = ch->parent; in tr_enaint()
339 snd_mtxlock(tr->lock); in tr_enaint()
340 bank = (ch->index & 0x20) ? 1 : 0; in tr_enaint()
341 chan = ch->index & 0x1f; in tr_enaint()
344 i = tr_rd(tr, reg, 4); in tr_enaint()
348 tr_clrint(ch); in tr_enaint()
349 tr_wr(tr, reg, i, 4); in tr_enaint()
350 snd_mtxunlock(tr->lock); in tr_enaint()
356 tr_selch(struct tr_chinfo *ch) in tr_selch() argument
358 struct tr_info *tr = ch->parent; in tr_selch()
361 i = tr_rd(tr, TR_REG_CIR, 4); in tr_selch()
363 i |= ch->index & 0x3f; in tr_selch()
364 tr_wr(tr, TR_REG_CIR, i, 4); in tr_selch()
368 tr_startch(struct tr_chinfo *ch) in tr_startch() argument
370 struct tr_info *tr = ch->parent; in tr_startch()
373 bank = (ch->index & 0x20) ? 1 : 0; in tr_startch()
374 chan = ch->index & 0x1f; in tr_startch()
375 tr_wr(tr, bank? TR_REG_STARTB : TR_REG_STARTA, 1 << chan, 4); in tr_startch()
379 tr_stopch(struct tr_chinfo *ch) in tr_stopch() argument
381 struct tr_info *tr = ch->parent; in tr_stopch()
384 bank = (ch->index & 0x20) ? 1 : 0; in tr_stopch()
385 chan = ch->index & 0x1f; in tr_stopch()
386 tr_wr(tr, bank? TR_REG_STOPB : TR_REG_STOPA, 1 << chan, 4); in tr_stopch()
390 tr_wrch(struct tr_chinfo *ch) in tr_wrch() argument
392 struct tr_info *tr = ch->parent; in tr_wrch()
395 ch->gvsel &= 0x00000001; in tr_wrch()
396 ch->fmc &= 0x00000003; in tr_wrch()
397 ch->fms &= 0x0000000f; in tr_wrch()
398 ch->ctrl &= 0x0000000f; in tr_wrch()
399 ch->pan &= 0x0000007f; in tr_wrch()
400 ch->rvol &= 0x0000007f; in tr_wrch()
401 ch->cvol &= 0x0000007f; in tr_wrch()
402 ch->vol &= 0x000000ff; in tr_wrch()
403 ch->ec &= 0x00000fff; in tr_wrch()
404 ch->alpha &= 0x00000fff; in tr_wrch()
405 ch->delta &= 0x0000ffff; in tr_wrch()
406 if (tr->type == ALI_PCI_ID) in tr_wrch()
407 ch->lba &= ALI_MAXADDR; in tr_wrch()
409 ch->lba &= TR_MAXADDR; in tr_wrch()
411 cr[1]=ch->lba; in tr_wrch()
412 cr[3]=(ch->fmc<<14) | (ch->rvol<<7) | (ch->cvol); in tr_wrch()
413 cr[4]=(ch->gvsel<<31) | (ch->pan<<24) | (ch->vol<<16) | (ch->ctrl<<12) | (ch->ec); in tr_wrch()
415 switch (tr->type) { in tr_wrch()
419 ch->cso &= 0x0000ffff; in tr_wrch()
420 ch->eso &= 0x0000ffff; in tr_wrch()
421 cr[0]=(ch->cso<<16) | (ch->alpha<<4) | (ch->fms); in tr_wrch()
422 cr[2]=(ch->eso<<16) | (ch->delta); in tr_wrch()
425 ch->cso &= 0x00ffffff; in tr_wrch()
426 ch->eso &= 0x00ffffff; in tr_wrch()
427 cr[0]=((ch->delta & 0xff)<<24) | (ch->cso); in tr_wrch()
428 cr[2]=((ch->delta>>8)<<24) | (ch->eso); in tr_wrch()
429 cr[3]|=(ch->alpha<<20) | (ch->fms<<16) | (ch->fmc<<14); in tr_wrch()
432 snd_mtxlock(tr->lock); in tr_wrch()
433 tr_selch(ch); in tr_wrch()
435 tr_wr(tr, TR_REG_CHNBASE+(i<<2), cr[i], 4); in tr_wrch()
436 snd_mtxunlock(tr->lock); in tr_wrch()
440 tr_rdch(struct tr_chinfo *ch) in tr_rdch() argument
442 struct tr_info *tr = ch->parent; in tr_rdch()
445 snd_mtxlock(tr->lock); in tr_rdch()
446 tr_selch(ch); in tr_rdch()
448 cr[i]=tr_rd(tr, TR_REG_CHNBASE+(i<<2), 4); in tr_rdch()
449 snd_mtxunlock(tr->lock); in tr_rdch()
451 if (tr->type == ALI_PCI_ID) in tr_rdch()
452 ch->lba=(cr[1] & ALI_MAXADDR); in tr_rdch()
454 ch->lba=(cr[1] & TR_MAXADDR); in tr_rdch()
455 ch->fmc= (cr[3] & 0x0000c000) >> 14; in tr_rdch()
456 ch->rvol= (cr[3] & 0x00003f80) >> 7; in tr_rdch()
457 ch->cvol= (cr[3] & 0x0000007f); in tr_rdch()
458 ch->gvsel= (cr[4] & 0x80000000) >> 31; in tr_rdch()
459 ch->pan= (cr[4] & 0x7f000000) >> 24; in tr_rdch()
460 ch->vol= (cr[4] & 0x00ff0000) >> 16; in tr_rdch()
461 ch->ctrl= (cr[4] & 0x0000f000) >> 12; in tr_rdch()
462 ch->ec= (cr[4] & 0x00000fff); in tr_rdch()
463 switch(tr->type) { in tr_rdch()
467 ch->cso= (cr[0] & 0xffff0000) >> 16; in tr_rdch()
468 ch->alpha= (cr[0] & 0x0000fff0) >> 4; in tr_rdch()
469 ch->fms= (cr[0] & 0x0000000f); in tr_rdch()
470 ch->eso= (cr[2] & 0xffff0000) >> 16; in tr_rdch()
471 ch->delta= (cr[2] & 0x0000ffff); in tr_rdch()
474 ch->cso= (cr[0] & 0x00ffffff); in tr_rdch()
475 ch->eso= (cr[2] & 0x00ffffff); in tr_rdch()
476 ch->delta= ((cr[2] & 0xff000000) >> 16) | ((cr[0] & 0xff000000) >> 24); in tr_rdch()
477 ch->alpha= (cr[3] & 0xfff00000) >> 20; in tr_rdch()
478 ch->fms= (cr[3] & 0x000f0000) >> 16; in tr_rdch()
496 /* -------------------------------------------------------------------- */
503 struct tr_chinfo *ch; in trpchan_init() local
506 ch = &tr->chinfo[tr->playchns]; in trpchan_init()
507 ch->index = tr->playchns++; in trpchan_init()
508 ch->buffer = b; in trpchan_init()
509 ch->parent = tr; in trpchan_init()
510 ch->channel = c; in trpchan_init()
511 if (sndbuf_alloc(ch->buffer, tr->parent_dmat, 0, tr->bufsz) != 0) in trpchan_init()
514 return ch; in trpchan_init()
520 struct tr_chinfo *ch = data; in trpchan_setformat() local
522 ch->ctrl = tr_fmttobits(format) | 0x01; in trpchan_setformat()
530 struct tr_chinfo *ch = data; in trpchan_setspeed() local
532 ch->delta = (speed << 12) / 48000; in trpchan_setspeed()
533 return (ch->delta * 48000) >> 12; in trpchan_setspeed()
539 struct tr_chinfo *ch = data; in trpchan_setblocksize() local
541 sndbuf_resize(ch->buffer, 2, blocksize); in trpchan_setblocksize()
548 struct tr_chinfo *ch = data; in trpchan_trigger() local
554 ch->fmc = 3; in trpchan_trigger()
555 ch->fms = 0; in trpchan_trigger()
556 ch->ec = 0; in trpchan_trigger()
557 ch->alpha = 0; in trpchan_trigger()
558 ch->lba = sndbuf_getbufaddr(ch->buffer); in trpchan_trigger()
559 ch->cso = 0; in trpchan_trigger()
560 ch->eso = (sndbuf_getsize(ch->buffer) / sndbuf_getalign(ch->buffer)) - 1; in trpchan_trigger()
561 ch->rvol = ch->cvol = 0x7f; in trpchan_trigger()
562 ch->gvsel = 0; in trpchan_trigger()
563 ch->pan = 0; in trpchan_trigger()
564 ch->vol = 0; in trpchan_trigger()
565 ch->bufhalf = 0; in trpchan_trigger()
566 tr_wrch(ch); in trpchan_trigger()
567 tr_enaint(ch, 1); in trpchan_trigger()
568 tr_startch(ch); in trpchan_trigger()
569 ch->active = 1; in trpchan_trigger()
571 tr_stopch(ch); in trpchan_trigger()
572 ch->active = 0; in trpchan_trigger()
581 struct tr_chinfo *ch = data; in trpchan_getptr() local
583 tr_rdch(ch); in trpchan_getptr()
584 return ch->cso * sndbuf_getalign(ch->buffer); in trpchan_getptr()
605 /* -------------------------------------------------------------------- */
612 struct tr_rchinfo *ch; in trrchan_init() local
615 ch = &tr->recchinfo; in trrchan_init()
616 ch->buffer = b; in trrchan_init()
617 ch->parent = tr; in trrchan_init()
618 ch->channel = c; in trrchan_init()
619 if (sndbuf_alloc(ch->buffer, tr->parent_dmat, 0, tr->bufsz) != 0) in trrchan_init()
622 return ch; in trrchan_init()
628 struct tr_rchinfo *ch = data; in trrchan_setformat() local
629 struct tr_info *tr = ch->parent; in trrchan_setformat()
634 i = (sndbuf_runsz(ch->buffer) >> ((bits & 0x08)? 1 : 0)) - 1; in trrchan_setformat()
635 tr_wr(tr, TR_REG_SBBL, i | (i << 16), 4); in trrchan_setformat()
637 i = 0x18 | (bits << 4); in trrchan_setformat()
646 struct tr_rchinfo *ch = data; in trrchan_setspeed() local
647 struct tr_info *tr = ch->parent; in trrchan_setspeed()
650 ch->delta = (48000 << 12) / speed; in trrchan_setspeed()
651 tr_wr(tr, TR_REG_SBDELTA, ch->delta, 2); in trrchan_setspeed()
654 return (48000 << 12) / ch->delta; in trrchan_setspeed()
660 struct tr_rchinfo *ch = data; in trrchan_setblocksize() local
662 sndbuf_resize(ch->buffer, 2, blocksize); in trrchan_setblocksize()
670 struct tr_rchinfo *ch = data; in trrchan_trigger() local
671 struct tr_info *tr = ch->parent; in trrchan_trigger()
683 tr_wr(tr, TR_REG_DMAR0, sndbuf_getbufaddr(ch->buffer), 4); in trrchan_trigger()
685 i = tr_rd(tr, TR_REG_DMAR4, 4) & ~0x00ffffff; in trrchan_trigger()
686 tr_wr(tr, TR_REG_DMAR4, i | (sndbuf_runsz(ch->buffer) - 1), 4); in trrchan_trigger()
689 ch->active = 1; in trrchan_trigger()
692 ch->active = 0; in trrchan_trigger()
702 struct tr_rchinfo *ch = data; in trrchan_getptr() local
703 struct tr_info *tr = ch->parent; in trrchan_getptr()
706 return tr_rd(tr, TR_REG_DMAR0, 4) - sndbuf_getbufaddr(ch->buffer); in trrchan_getptr()
727 /* -------------------------------------------------------------------- */
734 struct tr_chinfo *ch; in tr_intr() local
738 intsrc = tr_rd(tr, TR_REG_MISCINT, 4); in tr_intr()
741 while (chnum < tr->hwchns) { in tr_intr()
743 active = tr_rd(tr, (chnum < 32)? TR_REG_ADDRINTA : TR_REG_ADDRINTB, 4); in tr_intr()
744 bufhalf = tr_rd(tr, (chnum < 32)? TR_REG_CSPF_A : TR_REG_CSPF_B, 4); in tr_intr()
749 if (chnum < tr->playchns) { in tr_intr()
750 ch = &tr->chinfo[chnum]; in tr_intr()
751 /* printf("%d @ %d, ", chnum, trpchan_getptr(NULL, ch)); */ in tr_intr()
752 if (ch->bufhalf != tmp) { in tr_intr()
753 chn_intr(ch->channel); in tr_intr()
754 ch->bufhalf = tmp; in tr_intr()
764 tr_wr(tr, (chnum <= 32)? TR_REG_ADDRINTA : TR_REG_ADDRINTB, active, 4); in tr_intr()
768 chn_intr(tr->recchinfo.channel); in tr_intr()
774 /* -------------------------------------------------------------------- */
783 switch (tr->type) { in tr_init()
785 tr_wr(tr, SPA_REG_GPIO, 0, 4); in tr_init()
786 tr_wr(tr, SPA_REG_CODECST, SPA_RST_OFF, 4); in tr_init()
789 tr_wr(tr, TDX_REG_CODECST, TDX_CDC_ON, 4); in tr_init()
792 tr_wr(tr, TNX_REG_CODECST, TNX_CDC_ON, 4); in tr_init()
796 tr_wr(tr, TR_REG_CIR, TR_CIR_MIDENA | TR_CIR_ADDRENA, 4); in tr_init()
811 device_set_desc(dev, "Trident 4DWave DX"); in tr_pci_probe()
814 device_set_desc(dev, "Trident 4DWave NX"); in tr_pci_probe()
831 tr->type = pci_get_devid(dev); in tr_pci_attach()
832 tr->rev = pci_get_revid(dev); in tr_pci_attach()
833 tr->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_t4dwave softc"); in tr_pci_attach()
844 switch (tr->type) { in tr_pci_attach()
856 tr->regid = PCIR_BAR(0); in tr_pci_attach()
857 tr->regtype = SYS_RES_IOPORT; in tr_pci_attach()
858 tr->reg = bus_alloc_resource_any(dev, tr->regtype, &tr->regid, in tr_pci_attach()
860 if (tr->reg) { in tr_pci_attach()
861 tr->st = rman_get_bustag(tr->reg); in tr_pci_attach()
862 tr->sh = rman_get_bushandle(tr->reg); in tr_pci_attach()
868 if (tr_init(tr) == -1) { in tr_pci_attach()
872 tr->playchns = 0; in tr_pci_attach()
876 if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad; in tr_pci_attach()
878 tr->irqid = 0; in tr_pci_attach()
879 tr->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &tr->irqid, in tr_pci_attach()
881 if (!tr->irq || snd_setup_intr(dev, tr->irq, 0, tr_intr, tr, &tr->ih)) { in tr_pci_attach()
886 if (tr->type == ALI_PCI_ID) { in tr_pci_attach()
889 * 32-bit DMA, the 31st bit can be set via its accompanying in tr_pci_attach()
891 * will actually supply us with a 32-bit buffer and even when in tr_pci_attach()
893 * we might end up with the play buffer being in the 32-bit in tr_pci_attach()
898 tr->hwchns = ALI_MAXHWCH; in tr_pci_attach()
899 tr->bufsz = ALI_BUFSZ; in tr_pci_attach()
902 tr->hwchns = TR_MAXHWCH; in tr_pci_attach()
903 tr->bufsz = pcm_getbuffersize(dev, 4096, TR_DEFAULT_BUFSZ, in tr_pci_attach()
913 /*maxsize*/tr->bufsz, /*nsegments*/1, /*maxsegz*/tr->bufsz, in tr_pci_attach()
915 &tr->parent_dmat) != 0) { in tr_pci_attach()
921 rman_get_start(tr->reg), rman_get_start(tr->irq), in tr_pci_attach()
935 if (tr->reg) bus_release_resource(dev, tr->regtype, tr->regid, tr->reg); in tr_pci_attach()
936 if (tr->ih) bus_teardown_intr(dev, tr->irq, tr->ih); in tr_pci_attach()
937 if (tr->irq) bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq); in tr_pci_attach()
938 if (tr->parent_dmat) bus_dma_tag_destroy(tr->parent_dmat); in tr_pci_attach()
939 if (tr->lock) snd_mtxfree(tr->lock); in tr_pci_attach()
955 bus_release_resource(dev, tr->regtype, tr->regid, tr->reg); in tr_pci_detach()
956 bus_teardown_intr(dev, tr->irq, tr->ih); in tr_pci_detach()
957 bus_release_resource(dev, SYS_RES_IRQ, tr->irqid, tr->irq); in tr_pci_detach()
958 bus_dma_tag_destroy(tr->parent_dmat); in tr_pci_detach()
959 snd_mtxfree(tr->lock); in tr_pci_detach()
973 for (i = 0; i < tr->playchns; i++) { in tr_pci_suspend()
974 tr->chinfo[i].was_active = tr->chinfo[i].active; in tr_pci_suspend()
975 if (tr->chinfo[i].active) { in tr_pci_suspend()
976 trpchan_trigger(NULL, &tr->chinfo[i], PCMTRIG_STOP); in tr_pci_suspend()
980 tr->recchinfo.was_active = tr->recchinfo.active; in tr_pci_suspend()
981 if (tr->recchinfo.active) { in tr_pci_suspend()
982 trrchan_trigger(NULL, &tr->recchinfo, PCMTRIG_STOP); in tr_pci_suspend()
996 if (tr_init(tr) == -1) { in tr_pci_resume()
1001 if (mixer_reinit(dev) == -1) { in tr_pci_resume()
1006 for (i = 0; i < tr->playchns; i++) { in tr_pci_resume()
1007 if (tr->chinfo[i].was_active) { in tr_pci_resume()
1008 trpchan_trigger(NULL, &tr->chinfo[i], PCMTRIG_START); in tr_pci_resume()
1012 if (tr->recchinfo.was_active) { in tr_pci_resume()
1013 trrchan_trigger(NULL, &tr->recchinfo, PCMTRIG_START); in tr_pci_resume()