1139749Simp/*- 253553Stanimura * Copyright (c) 1999 Seigo Tanimura 353553Stanimura * All rights reserved. 453553Stanimura * 554377Stanimura * Portions of this source are based on cwcealdr.cpp and dhwiface.cpp in 654377Stanimura * cwcealdr1.zip, the sample sources by Crystal Semiconductor. 754377Stanimura * Copyright (c) 1996-1998 Crystal Semiconductor Corp. 854377Stanimura * 953553Stanimura * Redistribution and use in source and binary forms, with or without 1053553Stanimura * modification, are permitted provided that the following conditions 1153553Stanimura * are met: 1253553Stanimura * 1. Redistributions of source code must retain the above copyright 1353553Stanimura * notice, this list of conditions and the following disclaimer. 1453553Stanimura * 2. Redistributions in binary form must reproduce the above copyright 1553553Stanimura * notice, this list of conditions and the following disclaimer in the 1653553Stanimura * documentation and/or other materials provided with the distribution. 1753553Stanimura * 1853553Stanimura * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1953553Stanimura * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2053553Stanimura * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2153553Stanimura * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2253553Stanimura * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2353553Stanimura * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2453553Stanimura * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2553553Stanimura * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2653553Stanimura * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2753553Stanimura * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2853553Stanimura * SUCH DAMAGE. 2953553Stanimura */ 3053553Stanimura 3153553Stanimura#include <sys/param.h> 3253553Stanimura#include <sys/systm.h> 3353553Stanimura#include <sys/kernel.h> 3453553Stanimura#include <sys/bus.h> 3553553Stanimura#include <sys/malloc.h> 3653553Stanimura#include <sys/module.h> 3753553Stanimura#include <machine/resource.h> 3853553Stanimura#include <machine/bus.h> 3953553Stanimura#include <sys/rman.h> 40193640Sariff 41193640Sariff#ifdef HAVE_KERNEL_OPTION_HEADERS 42193640Sariff#include "opt_snd.h" 43193640Sariff#endif 44193640Sariff 4562483Scg#include <dev/sound/pcm/sound.h> 4653553Stanimura#include <dev/sound/chip.h> 4753553Stanimura#include <dev/sound/pci/csareg.h> 4853553Stanimura#include <dev/sound/pci/csavar.h> 4953553Stanimura 50119287Simp#include <dev/pci/pcireg.h> 51119287Simp#include <dev/pci/pcivar.h> 5253553Stanimura 53231047Spfg#include <dev/sound/pci/cs461x_dsp.h> 5453553Stanimura 5582180ScgSND_DECLARE_FILE("$FreeBSD$"); 5682180Scg 5777504Scg/* This is the pci device id. */ 5877504Scg#define CS4610_PCI_ID 0x60011013 5977504Scg#define CS4614_PCI_ID 0x60031013 6077504Scg#define CS4615_PCI_ID 0x60041013 6177504Scg 6253553Stanimura/* Here is the parameter structure per a device. */ 6353553Stanimurastruct csa_softc { 6453553Stanimura device_t dev; /* device */ 6553553Stanimura csa_res res; /* resources */ 6653553Stanimura 6753553Stanimura device_t pcm; /* pcm device */ 6853553Stanimura driver_intr_t* pcmintr; /* pcm intr */ 6953553Stanimura void *pcmintr_arg; /* pcm intr arg */ 7053553Stanimura device_t midi; /* midi device */ 7153553Stanimura driver_intr_t* midiintr; /* midi intr */ 7253553Stanimura void *midiintr_arg; /* midi intr arg */ 7353553Stanimura void *ih; /* cookie */ 7455320Stanimura 7577504Scg struct csa_card *card; 7655320Stanimura struct csa_bridgeinfo binfo; /* The state of this bridge. */ 7753553Stanimura}; 7853553Stanimura 7953553Stanimuratypedef struct csa_softc *sc_p; 8053553Stanimura 8153553Stanimurastatic int csa_probe(device_t dev); 8253553Stanimurastatic int csa_attach(device_t dev); 8353553Stanimurastatic struct resource *csa_alloc_resource(device_t bus, device_t child, int type, int *rid, 8453553Stanimura u_long start, u_long end, u_long count, u_int flags); 8553553Stanimurastatic int csa_release_resource(device_t bus, device_t child, int type, int rid, 8653553Stanimura struct resource *r); 8755320Stanimurastatic int csa_setup_intr(device_t bus, device_t child, 8855320Stanimura struct resource *irq, int flags, 89166918Sariff#if __FreeBSD_version >= 700031 90166918Sariff driver_filter_t *filter, 91166918Sariff#endif 92166918Sariff driver_intr_t *intr, void *arg, void **cookiep); 9355320Stanimurastatic int csa_teardown_intr(device_t bus, device_t child, 9455320Stanimura struct resource *irq, void *cookie); 9555320Stanimurastatic driver_intr_t csa_intr; 9653553Stanimurastatic int csa_initialize(sc_p scp); 9753553Stanimurastatic int csa_downloadimage(csa_res *resp); 98231047Spfgstatic int csa_transferimage(csa_res *resp, u_int32_t *src, u_long dest, u_long len); 9953553Stanimura 10053553Stanimurastatic devclass_t csa_devclass; 10153553Stanimura 10277504Scgstatic void 10377504Scgamp_none(void) 10477504Scg{ 10577504Scg} 10677504Scg 10777504Scgstatic void 10877504Scgamp_voyetra(void) 10977504Scg{ 11077504Scg} 11177504Scg 11253553Stanimurastatic int 11377504Scgclkrun_hack(int run) 11453553Stanimura{ 11577504Scg#ifdef __i386__ 11677504Scg devclass_t pci_devclass; 11777504Scg device_t *pci_devices, *pci_children, *busp, *childp; 11877504Scg int pci_count = 0, pci_childcount = 0; 11977504Scg int i, j, port; 12077504Scg u_int16_t control; 12177504Scg bus_space_tag_t btag; 12253553Stanimura 12377504Scg if ((pci_devclass = devclass_find("pci")) == NULL) { 12477504Scg return ENXIO; 12553553Stanimura } 12653553Stanimura 12777504Scg devclass_get_devices(pci_devclass, &pci_devices, &pci_count); 12877504Scg 12977504Scg for (i = 0, busp = pci_devices; i < pci_count; i++, busp++) { 13077504Scg pci_childcount = 0; 131182077Simp if (device_get_children(*busp, &pci_children, &pci_childcount)) 132182077Simp continue; 13377504Scg for (j = 0, childp = pci_children; j < pci_childcount; j++, childp++) { 13477504Scg if (pci_get_vendor(*childp) == 0x8086 && pci_get_device(*childp) == 0x7113) { 13577504Scg port = (pci_read_config(*childp, 0x41, 1) << 8) + 0x10; 13677504Scg /* XXX */ 137216592Stijl btag = X86_BUS_SPACE_IO; 13877504Scg 13977504Scg control = bus_space_read_2(btag, 0x0, port); 14077504Scg control &= ~0x2000; 14177504Scg control |= run? 0 : 0x2000; 14277504Scg bus_space_write_2(btag, 0x0, port, control); 14378429Scg free(pci_devices, M_TEMP); 14478429Scg free(pci_children, M_TEMP); 14577504Scg return 0; 14677504Scg } 14777504Scg } 14878429Scg free(pci_children, M_TEMP); 14953553Stanimura } 15053553Stanimura 15177504Scg free(pci_devices, M_TEMP); 15277504Scg return ENXIO; 15377504Scg#else 15477504Scg return 0; 15577504Scg#endif 15653553Stanimura} 15753553Stanimura 15877504Scgstatic struct csa_card cards_4610[] = { 15978673Scg {0, 0, "Unknown/invalid SSID (CS4610)", NULL, NULL, NULL, 0}, 16077504Scg}; 16177504Scg 16277504Scgstatic struct csa_card cards_4614[] = { 16378673Scg {0x1489, 0x7001, "Genius Soundmaker 128 value", amp_none, NULL, NULL, 0}, 16478673Scg {0x5053, 0x3357, "Turtle Beach Santa Cruz", amp_voyetra, NULL, NULL, 1}, 16578673Scg {0x1071, 0x6003, "Mitac MI6020/21", amp_voyetra, NULL, NULL, 0}, 16678673Scg {0x14AF, 0x0050, "Hercules Game Theatre XP", NULL, NULL, NULL, 0}, 16778673Scg {0x1681, 0x0050, "Hercules Game Theatre XP", NULL, NULL, NULL, 0}, 16886409Sasmodai {0x1014, 0x0132, "Thinkpad 570", amp_none, NULL, NULL, 0}, 16978673Scg {0x1014, 0x0153, "Thinkpad 600X/A20/T20", amp_none, NULL, clkrun_hack, 0}, 17078673Scg {0x1014, 0x1010, "Thinkpad 600E (unsupported)", NULL, NULL, NULL, 0}, 17178673Scg {0, 0, "Unknown/invalid SSID (CS4614)", NULL, NULL, NULL, 0}, 17277504Scg}; 17377504Scg 17477504Scgstatic struct csa_card cards_4615[] = { 17578673Scg {0, 0, "Unknown/invalid SSID (CS4615)", NULL, NULL, NULL, 0}, 17677504Scg}; 17777504Scg 17878673Scgstatic struct csa_card nocard = {0, 0, "unknown", NULL, NULL, NULL, 0}; 17977504Scg 18077504Scgstruct card_type { 18177504Scg u_int32_t devid; 18277504Scg char *name; 18377504Scg struct csa_card *cards; 18477504Scg}; 18577504Scg 18677504Scgstatic struct card_type cards[] = { 18777504Scg {CS4610_PCI_ID, "CS4610/CS4611", cards_4610}, 18877504Scg {CS4614_PCI_ID, "CS4280/CS4614/CS4622/CS4624/CS4630", cards_4614}, 18977504Scg {CS4615_PCI_ID, "CS4615", cards_4615}, 19077504Scg {0, NULL, NULL}, 19177504Scg}; 19277504Scg 19377504Scgstatic struct card_type * 19477504Scgcsa_findcard(device_t dev) 19577504Scg{ 19677504Scg int i; 19777504Scg 19877504Scg i = 0; 19977504Scg while (cards[i].devid != 0) { 20077504Scg if (pci_get_devid(dev) == cards[i].devid) 20177504Scg return &cards[i]; 20277504Scg i++; 20377504Scg } 20477504Scg return NULL; 20577504Scg} 20677504Scg 20777504Scgstruct csa_card * 20877504Scgcsa_findsubcard(device_t dev) 20977504Scg{ 21077504Scg int i; 21177504Scg struct card_type *card; 21277504Scg struct csa_card *subcard; 21377504Scg 21477504Scg card = csa_findcard(dev); 21577504Scg if (card == NULL) 21677504Scg return &nocard; 21777504Scg subcard = card->cards; 21877504Scg i = 0; 21977504Scg while (subcard[i].subvendor != 0) { 22077504Scg if (pci_get_subvendor(dev) == subcard[i].subvendor 22177504Scg && pci_get_subdevice(dev) == subcard[i].subdevice) { 22277504Scg return &subcard[i]; 22377504Scg } 22477504Scg i++; 22577504Scg } 22677504Scg return &subcard[i]; 22777504Scg} 22877504Scg 22953553Stanimurastatic int 23077504Scgcsa_probe(device_t dev) 23177504Scg{ 23277504Scg struct card_type *card; 23377504Scg 23477504Scg card = csa_findcard(dev); 23577504Scg if (card) { 23677504Scg device_set_desc(dev, card->name); 237142890Simp return BUS_PROBE_DEFAULT; 23877504Scg } 23977504Scg return ENXIO; 24077504Scg} 24177504Scg 24277504Scgstatic int 24353553Stanimuracsa_attach(device_t dev) 24453553Stanimura{ 24553553Stanimura sc_p scp; 24653553Stanimura csa_res *resp; 24755320Stanimura struct sndcard_func *func; 24878421Stmm int error = ENXIO; 24953553Stanimura 25053553Stanimura scp = device_get_softc(dev); 25153553Stanimura 25253553Stanimura /* Fill in the softc. */ 25353553Stanimura bzero(scp, sizeof(*scp)); 25453553Stanimura scp->dev = dev; 25553553Stanimura 256254306Sscottl pci_enable_busmaster(dev); 25753553Stanimura 25853553Stanimura /* Allocate the resources. */ 25953553Stanimura resp = &scp->res; 26077504Scg scp->card = csa_findsubcard(dev); 26177504Scg scp->binfo.card = scp->card; 26277504Scg printf("csa: card is %s\n", scp->card->name); 263119690Sjhb resp->io_rid = PCIR_BAR(0); 264127135Snjl resp->io = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 265127135Snjl &resp->io_rid, RF_ACTIVE); 26653553Stanimura if (resp->io == NULL) 26753553Stanimura return (ENXIO); 268119690Sjhb resp->mem_rid = PCIR_BAR(1); 269127135Snjl resp->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 270127135Snjl &resp->mem_rid, RF_ACTIVE); 27178421Stmm if (resp->mem == NULL) 27278421Stmm goto err_io; 27353553Stanimura resp->irq_rid = 0; 274127135Snjl resp->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, 275127135Snjl &resp->irq_rid, RF_ACTIVE | RF_SHAREABLE); 27678421Stmm if (resp->irq == NULL) 27778421Stmm goto err_mem; 27853553Stanimura 27955320Stanimura /* Enable interrupt. */ 280128232Sgreen if (snd_setup_intr(dev, resp->irq, 0, csa_intr, scp, &scp->ih)) 28178421Stmm goto err_intr; 28277504Scg#if 0 28355320Stanimura if ((csa_readio(resp, BA0_HISR) & HISR_INTENA) == 0) 28455320Stanimura csa_writeio(resp, BA0_HICR, HICR_IEV | HICR_CHGM); 28577504Scg#endif 28655320Stanimura 28753553Stanimura /* Initialize the chip. */ 28878421Stmm if (csa_initialize(scp)) 28978421Stmm goto err_teardown; 29053553Stanimura 29153553Stanimura /* Reset the Processor. */ 29253553Stanimura csa_resetdsp(resp); 29353553Stanimura 29453553Stanimura /* Download the Processor Image to the processor. */ 29578421Stmm if (csa_downloadimage(resp)) 29678421Stmm goto err_teardown; 29753553Stanimura 29855320Stanimura /* Attach the children. */ 29955320Stanimura 30055320Stanimura /* PCM Audio */ 30178564Sgreid func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO); 30278421Stmm if (func == NULL) { 30378421Stmm error = ENOMEM; 30478421Stmm goto err_teardown; 30578421Stmm } 30655320Stanimura func->varinfo = &scp->binfo; 30755320Stanimura func->func = SCF_PCM; 30855320Stanimura scp->pcm = device_add_child(dev, "pcm", -1); 30955320Stanimura device_set_ivars(scp->pcm, func); 31055320Stanimura 31155320Stanimura /* Midi Interface */ 31278564Sgreid func = malloc(sizeof(struct sndcard_func), M_DEVBUF, M_NOWAIT | M_ZERO); 31378421Stmm if (func == NULL) { 31478421Stmm error = ENOMEM; 31578421Stmm goto err_teardown; 31678421Stmm } 31755320Stanimura func->varinfo = &scp->binfo; 31855320Stanimura func->func = SCF_MIDI; 31955320Stanimura scp->midi = device_add_child(dev, "midi", -1); 32055320Stanimura device_set_ivars(scp->midi, func); 32155320Stanimura 32253553Stanimura bus_generic_attach(dev); 32353553Stanimura 32453553Stanimura return (0); 32578421Stmm 32678421Stmmerr_teardown: 32778421Stmm bus_teardown_intr(dev, resp->irq, scp->ih); 32878421Stmmerr_intr: 32978421Stmm bus_release_resource(dev, SYS_RES_IRQ, resp->irq_rid, resp->irq); 33078421Stmmerr_mem: 33178421Stmm bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem); 33278421Stmmerr_io: 33378421Stmm bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); 33478421Stmm return (error); 33553553Stanimura} 33653553Stanimura 33777504Scgstatic int 33877504Scgcsa_detach(device_t dev) 33977504Scg{ 34082379Scg csa_res *resp; 34177504Scg sc_p scp; 342167667Sariff struct sndcard_func *func; 34382379Scg int err; 34477504Scg 34577504Scg scp = device_get_softc(dev); 34682379Scg resp = &scp->res; 34782379Scg 348167667Sariff if (scp->midi != NULL) { 349167667Sariff func = device_get_ivars(scp->midi); 35082379Scg err = device_delete_child(dev, scp->midi); 351167667Sariff if (err != 0) 352167667Sariff return err; 353167667Sariff if (func != NULL) 354167667Sariff free(func, M_DEVBUF); 355167667Sariff scp->midi = NULL; 356167667Sariff } 35782379Scg 358167667Sariff if (scp->pcm != NULL) { 359167667Sariff func = device_get_ivars(scp->pcm); 36082379Scg err = device_delete_child(dev, scp->pcm); 361167667Sariff if (err != 0) 362167667Sariff return err; 363167667Sariff if (func != NULL) 364167667Sariff free(func, M_DEVBUF); 365167667Sariff scp->pcm = NULL; 366167667Sariff } 36782379Scg 36882379Scg bus_teardown_intr(dev, resp->irq, scp->ih); 36982379Scg bus_release_resource(dev, SYS_RES_IRQ, resp->irq_rid, resp->irq); 37082379Scg bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem); 37182379Scg bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); 37282379Scg 37377504Scg return bus_generic_detach(dev); 37477504Scg} 37577504Scg 376100634Sambriskostatic int 377100634Sambriskocsa_resume(device_t dev) 378100634Sambrisko{ 379147626Sglebius csa_res *resp; 380147626Sglebius sc_p scp; 381147626Sglebius 382147626Sglebius scp = device_get_softc(dev); 383147626Sglebius resp = &scp->res; 384147626Sglebius 385147626Sglebius /* Initialize the chip. */ 386147626Sglebius if (csa_initialize(scp)) 387147626Sglebius return (ENXIO); 388147626Sglebius 389147626Sglebius /* Reset the Processor. */ 390147626Sglebius csa_resetdsp(resp); 391147626Sglebius 392147626Sglebius /* Download the Processor Image to the processor. */ 393147626Sglebius if (csa_downloadimage(resp)) 394147626Sglebius return (ENXIO); 395147626Sglebius 396147626Sglebius return (bus_generic_resume(dev)); 397100634Sambrisko} 398100634Sambrisko 39953553Stanimurastatic struct resource * 40053553Stanimuracsa_alloc_resource(device_t bus, device_t child, int type, int *rid, 40153553Stanimura u_long start, u_long end, u_long count, u_int flags) 40253553Stanimura{ 40353553Stanimura sc_p scp; 40453553Stanimura csa_res *resp; 40553553Stanimura struct resource *res; 40653553Stanimura 40753553Stanimura scp = device_get_softc(bus); 40853553Stanimura resp = &scp->res; 40953553Stanimura switch (type) { 41053553Stanimura case SYS_RES_IRQ: 41153553Stanimura if (*rid != 0) 41253553Stanimura return (NULL); 41353553Stanimura res = resp->irq; 41453553Stanimura break; 41553553Stanimura case SYS_RES_MEMORY: 41653553Stanimura switch (*rid) { 417119690Sjhb case PCIR_BAR(0): 41853553Stanimura res = resp->io; 41953553Stanimura break; 420119690Sjhb case PCIR_BAR(1): 42153553Stanimura res = resp->mem; 42253553Stanimura break; 42353553Stanimura default: 42453553Stanimura return (NULL); 42553553Stanimura } 42653553Stanimura break; 42753553Stanimura default: 42853553Stanimura return (NULL); 42953553Stanimura } 43053553Stanimura 43153553Stanimura return res; 43253553Stanimura} 43353553Stanimura 43453553Stanimurastatic int 43553553Stanimuracsa_release_resource(device_t bus, device_t child, int type, int rid, 43653553Stanimura struct resource *r) 43753553Stanimura{ 43853553Stanimura return (0); 43953553Stanimura} 44053553Stanimura 44155320Stanimura/* 44255320Stanimura * The following three functions deal with interrupt handling. 44355320Stanimura * An interrupt is primarily handled by the bridge driver. 44455320Stanimura * The bridge driver then determines the child devices to pass 44555320Stanimura * the interrupt. Certain information of the device can be read 44655320Stanimura * only once(eg the value of HISR). The bridge driver is responsible 44755320Stanimura * to pass such the information to the children. 44855320Stanimura */ 44955320Stanimura 45053553Stanimurastatic int 45155320Stanimuracsa_setup_intr(device_t bus, device_t child, 45255320Stanimura struct resource *irq, int flags, 453166918Sariff#if __FreeBSD_version >= 700031 454166918Sariff driver_filter_t *filter, 455166918Sariff#endif 456166918Sariff driver_intr_t *intr, void *arg, void **cookiep) 45755320Stanimura{ 45855320Stanimura sc_p scp; 45955320Stanimura csa_res *resp; 46055320Stanimura struct sndcard_func *func; 46155320Stanimura 462166918Sariff#if __FreeBSD_version >= 700031 463166901Spiso if (filter != NULL) { 464166901Spiso printf("ata-csa.c: we cannot use a filter here\n"); 465166901Spiso return (EINVAL); 466166901Spiso } 467166918Sariff#endif 46855320Stanimura scp = device_get_softc(bus); 46955320Stanimura resp = &scp->res; 47055320Stanimura 47155320Stanimura /* 47255320Stanimura * Look at the function code of the child to determine 47355320Stanimura * the appropriate hander for it. 47455320Stanimura */ 47555320Stanimura func = device_get_ivars(child); 47655320Stanimura if (func == NULL || irq != resp->irq) 47755320Stanimura return (EINVAL); 47855320Stanimura 47955320Stanimura switch (func->func) { 48055320Stanimura case SCF_PCM: 48155320Stanimura scp->pcmintr = intr; 48255320Stanimura scp->pcmintr_arg = arg; 48355320Stanimura break; 48455320Stanimura 48555320Stanimura case SCF_MIDI: 48655320Stanimura scp->midiintr = intr; 48755320Stanimura scp->midiintr_arg = arg; 48855320Stanimura break; 48955320Stanimura 49055320Stanimura default: 49155320Stanimura return (EINVAL); 49255320Stanimura } 49355320Stanimura *cookiep = scp; 49455320Stanimura if ((csa_readio(resp, BA0_HISR) & HISR_INTENA) == 0) 49555320Stanimura csa_writeio(resp, BA0_HICR, HICR_IEV | HICR_CHGM); 49655320Stanimura 49755320Stanimura return (0); 49855320Stanimura} 49955320Stanimura 50055320Stanimurastatic int 50155320Stanimuracsa_teardown_intr(device_t bus, device_t child, 50255320Stanimura struct resource *irq, void *cookie) 50355320Stanimura{ 50455320Stanimura sc_p scp; 50555320Stanimura csa_res *resp; 50655320Stanimura struct sndcard_func *func; 50755320Stanimura 50855320Stanimura scp = device_get_softc(bus); 50955320Stanimura resp = &scp->res; 51055320Stanimura 51155320Stanimura /* 51255320Stanimura * Look at the function code of the child to determine 51355320Stanimura * the appropriate hander for it. 51455320Stanimura */ 51555320Stanimura func = device_get_ivars(child); 51655320Stanimura if (func == NULL || irq != resp->irq || cookie != scp) 51755320Stanimura return (EINVAL); 51855320Stanimura 51955320Stanimura switch (func->func) { 52055320Stanimura case SCF_PCM: 52155320Stanimura scp->pcmintr = NULL; 52255320Stanimura scp->pcmintr_arg = NULL; 52355320Stanimura break; 52455320Stanimura 52555320Stanimura case SCF_MIDI: 52655320Stanimura scp->midiintr = NULL; 52755320Stanimura scp->midiintr_arg = NULL; 52855320Stanimura break; 52955320Stanimura 53055320Stanimura default: 53155320Stanimura return (EINVAL); 53255320Stanimura } 53355320Stanimura 53455320Stanimura return (0); 53555320Stanimura} 53655320Stanimura 53755320Stanimura/* The interrupt handler */ 53855320Stanimurastatic void 53955320Stanimuracsa_intr(void *arg) 54055320Stanimura{ 54155320Stanimura sc_p scp = arg; 54255320Stanimura csa_res *resp; 54355320Stanimura u_int32_t hisr; 54455320Stanimura 54555320Stanimura resp = &scp->res; 54655320Stanimura 54755320Stanimura /* Is this interrupt for us? */ 54855320Stanimura hisr = csa_readio(resp, BA0_HISR); 54977504Scg if ((hisr & 0x7fffffff) == 0) { 55055320Stanimura /* Throw an eoi. */ 55155320Stanimura csa_writeio(resp, BA0_HICR, HICR_IEV | HICR_CHGM); 55255320Stanimura return; 55355320Stanimura } 55455320Stanimura 55555320Stanimura /* 55655320Stanimura * Pass the value of HISR via struct csa_bridgeinfo. 55755320Stanimura * The children get access through their ivars. 55855320Stanimura */ 55955320Stanimura scp->binfo.hisr = hisr; 56055320Stanimura 56155320Stanimura /* Invoke the handlers of the children. */ 56277504Scg if ((hisr & (HISR_VC0 | HISR_VC1)) != 0 && scp->pcmintr != NULL) { 56355320Stanimura scp->pcmintr(scp->pcmintr_arg); 56477504Scg hisr &= ~(HISR_VC0 | HISR_VC1); 56577504Scg } 56677504Scg if ((hisr & HISR_MIDI) != 0 && scp->midiintr != NULL) { 56755320Stanimura scp->midiintr(scp->midiintr_arg); 56877504Scg hisr &= ~HISR_MIDI; 56977504Scg } 57055320Stanimura 57155320Stanimura /* Throw an eoi. */ 57255320Stanimura csa_writeio(resp, BA0_HICR, HICR_IEV | HICR_CHGM); 57355320Stanimura} 57455320Stanimura 57555320Stanimurastatic int 57653553Stanimuracsa_initialize(sc_p scp) 57753553Stanimura{ 57853553Stanimura int i; 57953553Stanimura u_int32_t acsts, acisv; 58053553Stanimura csa_res *resp; 58153553Stanimura 58253553Stanimura resp = &scp->res; 58353553Stanimura 58453553Stanimura /* 58553553Stanimura * First, blast the clock control register to zero so that the PLL starts 58653553Stanimura * out in a known state, and blast the master serial port control register 58753553Stanimura * to zero so that the serial ports also start out in a known state. 58853553Stanimura */ 58953553Stanimura csa_writeio(resp, BA0_CLKCR1, 0); 59053553Stanimura csa_writeio(resp, BA0_SERMC1, 0); 59153553Stanimura 59253553Stanimura /* 59353553Stanimura * If we are in AC97 mode, then we must set the part to a host controlled 59453553Stanimura * AC-link. Otherwise, we won't be able to bring up the link. 59553553Stanimura */ 59653553Stanimura#if 1 59753553Stanimura csa_writeio(resp, BA0_SERACC, SERACC_HSP | SERACC_CODEC_TYPE_1_03); /* 1.03 codec */ 59853553Stanimura#else 59953553Stanimura csa_writeio(resp, BA0_SERACC, SERACC_HSP | SERACC_CODEC_TYPE_2_0); /* 2.0 codec */ 60053553Stanimura#endif /* 1 */ 60153553Stanimura 60253553Stanimura /* 60353553Stanimura * Drive the ARST# pin low for a minimum of 1uS (as defined in the AC97 60453553Stanimura * spec) and then drive it high. This is done for non AC97 modes since 60553553Stanimura * there might be logic external to the CS461x that uses the ARST# line 60653553Stanimura * for a reset. 60753553Stanimura */ 60877504Scg csa_writeio(resp, BA0_ACCTL, 1); 60977504Scg DELAY(50); 61053553Stanimura csa_writeio(resp, BA0_ACCTL, 0); 61177504Scg DELAY(50); 61253553Stanimura csa_writeio(resp, BA0_ACCTL, ACCTL_RSTN); 61353553Stanimura 61453553Stanimura /* 61553553Stanimura * The first thing we do here is to enable sync generation. As soon 61653553Stanimura * as we start receiving bit clock, we'll start producing the SYNC 61753553Stanimura * signal. 61853553Stanimura */ 61953553Stanimura csa_writeio(resp, BA0_ACCTL, ACCTL_ESYN | ACCTL_RSTN); 62053553Stanimura 62153553Stanimura /* 62253553Stanimura * Now wait for a short while to allow the AC97 part to start 62353553Stanimura * generating bit clock (so we don't try to start the PLL without an 62453553Stanimura * input clock). 62553553Stanimura */ 62653553Stanimura DELAY(50000); 62753553Stanimura 62853553Stanimura /* 62953553Stanimura * Set the serial port timing configuration, so that 63053553Stanimura * the clock control circuit gets its clock from the correct place. 63153553Stanimura */ 63253553Stanimura csa_writeio(resp, BA0_SERMC1, SERMC1_PTC_AC97); 63377504Scg DELAY(700000); 63453553Stanimura 63553553Stanimura /* 63653553Stanimura * Write the selected clock control setup to the hardware. Do not turn on 63753553Stanimura * SWCE yet (if requested), so that the devices clocked by the output of 63853553Stanimura * PLL are not clocked until the PLL is stable. 63953553Stanimura */ 64053553Stanimura csa_writeio(resp, BA0_PLLCC, PLLCC_LPF_1050_2780_KHZ | PLLCC_CDR_73_104_MHZ); 64153553Stanimura csa_writeio(resp, BA0_PLLM, 0x3a); 64253553Stanimura csa_writeio(resp, BA0_CLKCR2, CLKCR2_PDIVS_8); 64353553Stanimura 64453553Stanimura /* 64553553Stanimura * Power up the PLL. 64653553Stanimura */ 64753553Stanimura csa_writeio(resp, BA0_CLKCR1, CLKCR1_PLLP); 64853553Stanimura 64953553Stanimura /* 65053553Stanimura * Wait until the PLL has stabilized. 65153553Stanimura */ 65277504Scg DELAY(5000); 65353553Stanimura 65453553Stanimura /* 65553553Stanimura * Turn on clocking of the core so that we can setup the serial ports. 65653553Stanimura */ 65753553Stanimura csa_writeio(resp, BA0_CLKCR1, csa_readio(resp, BA0_CLKCR1) | CLKCR1_SWCE); 65853553Stanimura 65953553Stanimura /* 66053553Stanimura * Fill the serial port FIFOs with silence. 66153553Stanimura */ 66253553Stanimura csa_clearserialfifos(resp); 66353553Stanimura 66453553Stanimura /* 66553553Stanimura * Set the serial port FIFO pointer to the first sample in the FIFO. 66653553Stanimura */ 667153084Sru#ifdef notdef 66853553Stanimura csa_writeio(resp, BA0_SERBSP, 0); 66953553Stanimura#endif /* notdef */ 67053553Stanimura 67153553Stanimura /* 67253553Stanimura * Write the serial port configuration to the part. The master 67353553Stanimura * enable bit is not set until all other values have been written. 67453553Stanimura */ 67553553Stanimura csa_writeio(resp, BA0_SERC1, SERC1_SO1F_AC97 | SERC1_SO1EN); 67653553Stanimura csa_writeio(resp, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN); 67753553Stanimura csa_writeio(resp, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE); 67853553Stanimura 67953553Stanimura /* 68053553Stanimura * Wait for the codec ready signal from the AC97 codec. 68153553Stanimura */ 68253553Stanimura acsts = 0; 68353553Stanimura for (i = 0 ; i < 1000 ; i++) { 68453553Stanimura /* 68553553Stanimura * First, lets wait a short while to let things settle out a bit, 68653553Stanimura * and to prevent retrying the read too quickly. 68753553Stanimura */ 68855288Stanimura DELAY(125); 68953553Stanimura 69053553Stanimura /* 69153553Stanimura * Read the AC97 status register to see if we've seen a CODEC READY 69253553Stanimura * signal from the AC97 codec. 69353553Stanimura */ 69453553Stanimura acsts = csa_readio(resp, BA0_ACSTS); 69553553Stanimura if ((acsts & ACSTS_CRDY) != 0) 69653553Stanimura break; 69753553Stanimura } 69853553Stanimura 69953553Stanimura /* 70053553Stanimura * Make sure we sampled CODEC READY. 70153553Stanimura */ 70253553Stanimura if ((acsts & ACSTS_CRDY) == 0) 70353553Stanimura return (ENXIO); 70453553Stanimura 70553553Stanimura /* 70653553Stanimura * Assert the vaid frame signal so that we can start sending commands 70753553Stanimura * to the AC97 codec. 70853553Stanimura */ 70953553Stanimura csa_writeio(resp, BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); 71053553Stanimura 71153553Stanimura /* 71253553Stanimura * Wait until we've sampled input slots 3 and 4 as valid, meaning that 71353553Stanimura * the codec is pumping ADC data across the AC-link. 71453553Stanimura */ 71553553Stanimura acisv = 0; 71653553Stanimura for (i = 0 ; i < 1000 ; i++) { 71753553Stanimura /* 71853553Stanimura * First, lets wait a short while to let things settle out a bit, 71953553Stanimura * and to prevent retrying the read too quickly. 72053553Stanimura */ 721153084Sru#ifdef notdef 72253553Stanimura DELAY(10000000L); /* clw */ 72353553Stanimura#else 72455288Stanimura DELAY(1000); 72553553Stanimura#endif /* notdef */ 72653553Stanimura /* 72753553Stanimura * Read the input slot valid register and see if input slots 3 and 72853553Stanimura * 4 are valid yet. 72953553Stanimura */ 73053553Stanimura acisv = csa_readio(resp, BA0_ACISV); 73153553Stanimura if ((acisv & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4)) 73253553Stanimura break; 73353553Stanimura } 73453553Stanimura /* 73553553Stanimura * Make sure we sampled valid input slots 3 and 4. If not, then return 73653553Stanimura * an error. 73753553Stanimura */ 73853553Stanimura if ((acisv & (ACISV_ISV3 | ACISV_ISV4)) != (ACISV_ISV3 | ACISV_ISV4)) 73953553Stanimura return (ENXIO); 74053553Stanimura 74153553Stanimura /* 74253553Stanimura * Now, assert valid frame and the slot 3 and 4 valid bits. This will 74353553Stanimura * commense the transfer of digital audio data to the AC97 codec. 74453553Stanimura */ 74553553Stanimura csa_writeio(resp, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4); 74653553Stanimura 74753553Stanimura /* 74853553Stanimura * Power down the DAC and ADC. We will power them up (if) when we need 74953553Stanimura * them. 75053553Stanimura */ 751153084Sru#ifdef notdef 75253553Stanimura csa_writeio(resp, BA0_AC97_POWERDOWN, 0x300); 75353553Stanimura#endif /* notdef */ 75453553Stanimura 75553553Stanimura /* 75661347Scg * Turn off the Processor by turning off the software clock enable flag in 75753553Stanimura * the clock control register. 75853553Stanimura */ 759153084Sru#ifdef notdef 76053553Stanimura clkcr1 = csa_readio(resp, BA0_CLKCR1) & ~CLKCR1_SWCE; 76153553Stanimura csa_writeio(resp, BA0_CLKCR1, clkcr1); 76253553Stanimura#endif /* notdef */ 76353553Stanimura 76453553Stanimura /* 76553553Stanimura * Enable interrupts on the part. 76653553Stanimura */ 76777504Scg#if 0 76853553Stanimura csa_writeio(resp, BA0_HICR, HICR_IEV | HICR_CHGM); 76953553Stanimura#endif /* notdef */ 77053553Stanimura 77153553Stanimura return (0); 77253553Stanimura} 77353553Stanimura 77455320Stanimuravoid 77553553Stanimuracsa_clearserialfifos(csa_res *resp) 77653553Stanimura{ 77753553Stanimura int i, j, pwr; 77853553Stanimura u_int8_t clkcr1, serbst; 77953553Stanimura 78053553Stanimura /* 78153553Stanimura * See if the devices are powered down. If so, we must power them up first 78253553Stanimura * or they will not respond. 78353553Stanimura */ 78453553Stanimura pwr = 1; 78553553Stanimura clkcr1 = csa_readio(resp, BA0_CLKCR1); 78653553Stanimura if ((clkcr1 & CLKCR1_SWCE) == 0) { 78753553Stanimura csa_writeio(resp, BA0_CLKCR1, clkcr1 | CLKCR1_SWCE); 78853553Stanimura pwr = 0; 78953553Stanimura } 79053553Stanimura 79153553Stanimura /* 79253553Stanimura * We want to clear out the serial port FIFOs so we don't end up playing 79353553Stanimura * whatever random garbage happens to be in them. We fill the sample FIFOs 79453553Stanimura * with zero (silence). 79553553Stanimura */ 79653553Stanimura csa_writeio(resp, BA0_SERBWP, 0); 79753553Stanimura 79853553Stanimura /* Fill all 256 sample FIFO locations. */ 79953553Stanimura serbst = 0; 80053553Stanimura for (i = 0 ; i < 256 ; i++) { 80153553Stanimura /* Make sure the previous FIFO write operation has completed. */ 80253553Stanimura for (j = 0 ; j < 5 ; j++) { 80355288Stanimura DELAY(100); 80453553Stanimura serbst = csa_readio(resp, BA0_SERBST); 80553553Stanimura if ((serbst & SERBST_WBSY) == 0) 80653553Stanimura break; 80753553Stanimura } 80853553Stanimura if ((serbst & SERBST_WBSY) != 0) { 80953553Stanimura if (!pwr) 81053553Stanimura csa_writeio(resp, BA0_CLKCR1, clkcr1); 81153553Stanimura } 81253553Stanimura /* Write the serial port FIFO index. */ 81353553Stanimura csa_writeio(resp, BA0_SERBAD, i); 81453553Stanimura /* Tell the serial port to load the new value into the FIFO location. */ 81553553Stanimura csa_writeio(resp, BA0_SERBCM, SERBCM_WRC); 81653553Stanimura } 81753553Stanimura /* 81853553Stanimura * Now, if we powered up the devices, then power them back down again. 81953553Stanimura * This is kinda ugly, but should never happen. 82053553Stanimura */ 82153553Stanimura if (!pwr) 82253553Stanimura csa_writeio(resp, BA0_CLKCR1, clkcr1); 82353553Stanimura} 82453553Stanimura 825147626Sglebiusvoid 82653553Stanimuracsa_resetdsp(csa_res *resp) 82753553Stanimura{ 82853553Stanimura int i; 82953553Stanimura 83053553Stanimura /* 83153553Stanimura * Write the reset bit of the SP control register. 83253553Stanimura */ 83353553Stanimura csa_writemem(resp, BA1_SPCR, SPCR_RSTSP); 83453553Stanimura 83553553Stanimura /* 83653553Stanimura * Write the control register. 83753553Stanimura */ 83853553Stanimura csa_writemem(resp, BA1_SPCR, SPCR_DRQEN); 83953553Stanimura 84053553Stanimura /* 84153553Stanimura * Clear the trap registers. 84253553Stanimura */ 84353553Stanimura for (i = 0 ; i < 8 ; i++) { 84453553Stanimura csa_writemem(resp, BA1_DREG, DREG_REGID_TRAP_SELECT + i); 84553553Stanimura csa_writemem(resp, BA1_TWPR, 0xffff); 84653553Stanimura } 84753553Stanimura csa_writemem(resp, BA1_DREG, 0); 84853553Stanimura 84953553Stanimura /* 85053553Stanimura * Set the frame timer to reflect the number of cycles per frame. 85153553Stanimura */ 85253553Stanimura csa_writemem(resp, BA1_FRMT, 0xadf); 85353553Stanimura} 85453553Stanimura 85553553Stanimurastatic int 85653553Stanimuracsa_downloadimage(csa_res *resp) 85753553Stanimura{ 858231047Spfg int ret; 859231047Spfg u_long ul, offset; 86053553Stanimura 861231047Spfg for (ul = 0, offset = 0 ; ul < INKY_MEMORY_COUNT ; ul++) { 862231047Spfg /* 863231047Spfg * DMA this block from host memory to the appropriate 864231047Spfg * memory on the CSDevice. 865231047Spfg */ 866231047Spfg ret = csa_transferimage(resp, 867231047Spfg cs461x_firmware.BA1Array + offset, 868231047Spfg cs461x_firmware.MemoryStat[ul].ulDestAddr, 869231047Spfg cs461x_firmware.MemoryStat[ul].ulSourceSize); 870231047Spfg if (ret) 871231047Spfg return (ret); 872231047Spfg offset += cs461x_firmware.MemoryStat[ul].ulSourceSize >> 2; 87353553Stanimura } 874231047Spfg return (0); 875231047Spfg} 87653553Stanimura 877231047Spfgstatic int 878231047Spfgcsa_transferimage(csa_res *resp, u_int32_t *src, u_long dest, u_long len) 879231047Spfg{ 880231047Spfg u_long ul; 881231047Spfg 882231047Spfg /* 883231047Spfg * We do not allow DMAs from host memory to host memory (although the DMA 884231047Spfg * can do it) and we do not allow DMAs which are not a multiple of 4 bytes 885231047Spfg * in size (because that DMA can not do that). Return an error if either 886231047Spfg * of these conditions exist. 887231047Spfg */ 888231047Spfg if ((len & 0x3) != 0) 889231047Spfg return (EINVAL); 89053553Stanimura 891231047Spfg /* Check the destination address that it is a multiple of 4 */ 892231047Spfg if ((dest & 0x3) != 0) 893231047Spfg return (EINVAL); 894231047Spfg 895231047Spfg /* Write the buffer out. */ 896231047Spfg for (ul = 0 ; ul < len ; ul += 4) 897231047Spfg csa_writemem(resp, dest + ul, src[ul >> 2]); 89853553Stanimura return (0); 89953553Stanimura} 90053553Stanimura 90153553Stanimuraint 90253553Stanimuracsa_readcodec(csa_res *resp, u_long offset, u_int32_t *data) 90353553Stanimura{ 90453553Stanimura int i; 905193640Sariff u_int32_t acctl, acsts; 90653553Stanimura 90753553Stanimura /* 90853553Stanimura * Make sure that there is not data sitting around from a previous 90953553Stanimura * uncompleted access. ACSDA = Status Data Register = 47Ch 91053553Stanimura */ 911193640Sariff csa_readio(resp, BA0_ACSDA); 91253553Stanimura 91353553Stanimura /* 91453553Stanimura * Setup the AC97 control registers on the CS461x to send the 91553553Stanimura * appropriate command to the AC97 to perform the read. 91653553Stanimura * ACCAD = Command Address Register = 46Ch 91753553Stanimura * ACCDA = Command Data Register = 470h 91853553Stanimura * ACCTL = Control Register = 460h 91953553Stanimura * set DCV - will clear when process completed 92053553Stanimura * set CRW - Read command 92153553Stanimura * set VFRM - valid frame enabled 92253553Stanimura * set ESYN - ASYNC generation enabled 92353553Stanimura * set RSTN - ARST# inactive, AC97 codec not reset 92453553Stanimura */ 92553553Stanimura 92653553Stanimura /* 92753553Stanimura * Get the actual AC97 register from the offset 92853553Stanimura */ 92953553Stanimura csa_writeio(resp, BA0_ACCAD, offset - BA0_AC97_RESET); 93053553Stanimura csa_writeio(resp, BA0_ACCDA, 0); 93153553Stanimura csa_writeio(resp, BA0_ACCTL, ACCTL_DCV | ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); 93253553Stanimura 93353553Stanimura /* 93453553Stanimura * Wait for the read to occur. 93553553Stanimura */ 93653553Stanimura acctl = 0; 93753553Stanimura for (i = 0 ; i < 10 ; i++) { 93853553Stanimura /* 93953553Stanimura * First, we want to wait for a short time. 94053553Stanimura */ 94153553Stanimura DELAY(25); 94253553Stanimura 94353553Stanimura /* 94453553Stanimura * Now, check to see if the read has completed. 94553553Stanimura * ACCTL = 460h, DCV should be reset by now and 460h = 17h 94653553Stanimura */ 94753553Stanimura acctl = csa_readio(resp, BA0_ACCTL); 94853553Stanimura if ((acctl & ACCTL_DCV) == 0) 94953553Stanimura break; 95053553Stanimura } 95153553Stanimura 95253553Stanimura /* 95353553Stanimura * Make sure the read completed. 95453553Stanimura */ 95553553Stanimura if ((acctl & ACCTL_DCV) != 0) 95653553Stanimura return (EAGAIN); 95753553Stanimura 95853553Stanimura /* 95953553Stanimura * Wait for the valid status bit to go active. 96053553Stanimura */ 96153553Stanimura acsts = 0; 96253553Stanimura for (i = 0 ; i < 10 ; i++) { 96353553Stanimura /* 96453553Stanimura * Read the AC97 status register. 96553553Stanimura * ACSTS = Status Register = 464h 96653553Stanimura */ 96753553Stanimura acsts = csa_readio(resp, BA0_ACSTS); 96853553Stanimura /* 96953553Stanimura * See if we have valid status. 97053553Stanimura * VSTS - Valid Status 97153553Stanimura */ 97253553Stanimura if ((acsts & ACSTS_VSTS) != 0) 97353553Stanimura break; 97453553Stanimura /* 97553553Stanimura * Wait for a short while. 97653553Stanimura */ 97753553Stanimura DELAY(25); 97853553Stanimura } 97953553Stanimura 98053553Stanimura /* 98153553Stanimura * Make sure we got valid status. 98253553Stanimura */ 98353553Stanimura if ((acsts & ACSTS_VSTS) == 0) 98453553Stanimura return (EAGAIN); 98553553Stanimura 98653553Stanimura /* 98753553Stanimura * Read the data returned from the AC97 register. 98862483Scg * ACSDA = Status Data Register = 474h 98953553Stanimura */ 99062483Scg *data = csa_readio(resp, BA0_ACSDA); 99153553Stanimura 99253553Stanimura return (0); 99353553Stanimura} 99453553Stanimura 99553553Stanimuraint 99653553Stanimuracsa_writecodec(csa_res *resp, u_long offset, u_int32_t data) 99753553Stanimura{ 99853553Stanimura int i; 99953553Stanimura u_int32_t acctl; 100053553Stanimura 100153553Stanimura /* 100253553Stanimura * Setup the AC97 control registers on the CS461x to send the 100353553Stanimura * appropriate command to the AC97 to perform the write. 100453553Stanimura * ACCAD = Command Address Register = 46Ch 100553553Stanimura * ACCDA = Command Data Register = 470h 100653553Stanimura * ACCTL = Control Register = 460h 100753553Stanimura * set DCV - will clear when process completed 100853553Stanimura * set VFRM - valid frame enabled 100953553Stanimura * set ESYN - ASYNC generation enabled 101053553Stanimura * set RSTN - ARST# inactive, AC97 codec not reset 101153553Stanimura */ 101253553Stanimura 101353553Stanimura /* 101453553Stanimura * Get the actual AC97 register from the offset 101553553Stanimura */ 101653553Stanimura csa_writeio(resp, BA0_ACCAD, offset - BA0_AC97_RESET); 101753553Stanimura csa_writeio(resp, BA0_ACCDA, data); 101853553Stanimura csa_writeio(resp, BA0_ACCTL, ACCTL_DCV | ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN); 101953553Stanimura 102053553Stanimura /* 102153553Stanimura * Wait for the write to occur. 102253553Stanimura */ 102353553Stanimura acctl = 0; 102453553Stanimura for (i = 0 ; i < 10 ; i++) { 102553553Stanimura /* 102653553Stanimura * First, we want to wait for a short time. 102753553Stanimura */ 102853553Stanimura DELAY(25); 102953553Stanimura 103053553Stanimura /* 103153553Stanimura * Now, check to see if the read has completed. 103253553Stanimura * ACCTL = 460h, DCV should be reset by now and 460h = 17h 103353553Stanimura */ 103453553Stanimura acctl = csa_readio(resp, BA0_ACCTL); 103553553Stanimura if ((acctl & ACCTL_DCV) == 0) 103653553Stanimura break; 103753553Stanimura } 103853553Stanimura 103953553Stanimura /* 104053553Stanimura * Make sure the write completed. 104153553Stanimura */ 104253553Stanimura if ((acctl & ACCTL_DCV) != 0) 104353553Stanimura return (EAGAIN); 104453553Stanimura 104553553Stanimura return (0); 104653553Stanimura} 104753553Stanimura 104853553Stanimurau_int32_t 104953553Stanimuracsa_readio(csa_res *resp, u_long offset) 105053553Stanimura{ 105153553Stanimura u_int32_t ul; 105253553Stanimura 105353553Stanimura if (offset < BA0_AC97_RESET) 105453553Stanimura return bus_space_read_4(rman_get_bustag(resp->io), rman_get_bushandle(resp->io), offset) & 0xffffffff; 105553553Stanimura else { 105653553Stanimura if (csa_readcodec(resp, offset, &ul)) 105753553Stanimura ul = 0; 105853553Stanimura return (ul); 105953553Stanimura } 106053553Stanimura} 106153553Stanimura 106253553Stanimuravoid 106353553Stanimuracsa_writeio(csa_res *resp, u_long offset, u_int32_t data) 106453553Stanimura{ 106553553Stanimura if (offset < BA0_AC97_RESET) 106653553Stanimura bus_space_write_4(rman_get_bustag(resp->io), rman_get_bushandle(resp->io), offset, data); 106753553Stanimura else 106853553Stanimura csa_writecodec(resp, offset, data); 106953553Stanimura} 107053553Stanimura 107153553Stanimurau_int32_t 107253553Stanimuracsa_readmem(csa_res *resp, u_long offset) 107353553Stanimura{ 107477504Scg return bus_space_read_4(rman_get_bustag(resp->mem), rman_get_bushandle(resp->mem), offset); 107553553Stanimura} 107653553Stanimura 107753553Stanimuravoid 107853553Stanimuracsa_writemem(csa_res *resp, u_long offset, u_int32_t data) 107953553Stanimura{ 108053553Stanimura bus_space_write_4(rman_get_bustag(resp->mem), rman_get_bushandle(resp->mem), offset, data); 108153553Stanimura} 108253553Stanimura 108353553Stanimurastatic device_method_t csa_methods[] = { 108453553Stanimura /* Device interface */ 108553553Stanimura DEVMETHOD(device_probe, csa_probe), 108653553Stanimura DEVMETHOD(device_attach, csa_attach), 108777504Scg DEVMETHOD(device_detach, csa_detach), 108853553Stanimura DEVMETHOD(device_shutdown, bus_generic_shutdown), 108953553Stanimura DEVMETHOD(device_suspend, bus_generic_suspend), 1090100634Sambrisko DEVMETHOD(device_resume, csa_resume), 109153553Stanimura 109253553Stanimura /* Bus interface */ 109353553Stanimura DEVMETHOD(bus_alloc_resource, csa_alloc_resource), 109453553Stanimura DEVMETHOD(bus_release_resource, csa_release_resource), 109553553Stanimura DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 109653553Stanimura DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 109755320Stanimura DEVMETHOD(bus_setup_intr, csa_setup_intr), 109855320Stanimura DEVMETHOD(bus_teardown_intr, csa_teardown_intr), 109953553Stanimura 1100229093Shselasky DEVMETHOD_END 110153553Stanimura}; 110253553Stanimura 110353553Stanimurastatic driver_t csa_driver = { 110453553Stanimura "csa", 110553553Stanimura csa_methods, 110653553Stanimura sizeof(struct csa_softc), 110753553Stanimura}; 110853553Stanimura 110953553Stanimura/* 111053553Stanimura * csa can be attached to a pci bus. 111153553Stanimura */ 111262483ScgDRIVER_MODULE(snd_csa, pci, csa_driver, csa_devclass, 0, 0); 1113132236StanimuraMODULE_DEPEND(snd_csa, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 111462483ScgMODULE_VERSION(snd_csa, 1); 1115