gus.c 95 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561
  1. /* $OpenBSD: gus.c,v 1.43 2015/06/25 20:05:11 ratchov Exp $ */
  2. /* $NetBSD: gus.c,v 1.51 1998/01/25 23:48:06 mycroft Exp $ */
  3. /*-
  4. * Copyright (c) 1996 The NetBSD Foundation, Inc.
  5. * All rights reserved.
  6. *
  7. * This code is derived from software contributed to The NetBSD Foundation
  8. * by Ken Hornstein and John Kohl.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  21. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  22. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  23. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29. * POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. /*
  32. *
  33. * TODO:
  34. * . figure out why mixer activity while sound is playing causes problems
  35. * (phantom interrupts?)
  36. * . figure out a better deinterleave strategy that avoids sucking up
  37. * CPU, memory and cache bandwidth. (Maybe a special encoding?
  38. * Maybe use the double-speed sampling/hardware deinterleave trick
  39. * from the GUS SDK?) A 486/33 isn't quite fast enough to keep
  40. * up with 44.1kHz 16-bit stereo output without some drop-outs.
  41. * . use CS4231 for 16-bit sampling, for a-law and mu-law playback.
  42. * . actually test full-duplex sampling(recording) and playback.
  43. */
  44. /*
  45. * Gravis UltraSound driver
  46. *
  47. * For more detailed information, see the GUS developers' kit
  48. * available on the net at:
  49. *
  50. * http://www.gravis.com/Public/sdk/GUSDK222.ZIP
  51. *
  52. * See ultrawrd.doc inside--it's MS Word (ick), but it's the bible
  53. *
  54. */
  55. /*
  56. * The GUS Max has a slightly strange set of connections between the CS4231
  57. * and the GF1 and the DMA interconnects. It's set up so that the CS4231 can
  58. * be playing while the GF1 is loading patches from the system.
  59. *
  60. * Here's a recreation of the DMA interconnect diagram:
  61. *
  62. * GF1
  63. * +---------+ digital
  64. * | | record ASIC
  65. * | |--------------+
  66. * | | | +--------+
  67. * | | play (dram) | +----+ | |
  68. * | |--------------(------|-\ | | +-+ |
  69. * +---------+ | | >-|----|---|C|--|------ dma chan 1
  70. * | +---|-/ | | +-+ |
  71. * | | +----+ | | |
  72. * | | +----+ | | |
  73. * +---------+ +-+ +--(---|-\ | | | |
  74. * | | play |8| | | >-|----|----+---|------ dma chan 2
  75. * | ---C----|--------|/|------(---|-/ | | |
  76. * | ^ |record |1| | +----+ | |
  77. * | | | /----|6|------+ +--------+
  78. * | ---+----|--/ +-+
  79. * +---------+
  80. * CS4231 8-to-16 bit bus conversion, if needed
  81. *
  82. *
  83. * "C" is an optional combiner.
  84. *
  85. */
  86. #include <sys/param.h>
  87. #include <sys/systm.h>
  88. #include <sys/errno.h>
  89. #include <sys/ioctl.h>
  90. #include <sys/syslog.h>
  91. #include <sys/device.h>
  92. #include <sys/buf.h>
  93. #include <sys/fcntl.h>
  94. #include <sys/malloc.h>
  95. #include <sys/kernel.h>
  96. #include <sys/timeout.h>
  97. #include <machine/cpu.h>
  98. #include <machine/intr.h>
  99. #include <machine/bus.h>
  100. #include <machine/cpufunc.h>
  101. #include <sys/audioio.h>
  102. #include <dev/audio_if.h>
  103. #include <dev/isa/isavar.h>
  104. #include <dev/isa/isadmavar.h>
  105. #include <dev/ic/ics2101reg.h>
  106. #include <dev/ic/cs4231reg.h>
  107. #include <dev/ic/ad1848reg.h>
  108. #include <dev/isa/ics2101var.h>
  109. #include <dev/isa/ad1848var.h>
  110. #include <dev/isa/cs4231var.h>
  111. #include "gusreg.h"
  112. #include "gusvar.h"
  113. #ifdef AUDIO_DEBUG
  114. #define GUSPLAYDEBUG /*XXX*/
  115. #define DPRINTF(x) if (gusdebug) printf x
  116. #define DMAPRINTF(x) if (gusdmadebug) printf x
  117. int gusdebug = 0;
  118. int gusdmadebug = 0;
  119. #else
  120. #define DPRINTF(x)
  121. #define DMAPRINTF(x)
  122. #endif
  123. int gus_dostereo = 1;
  124. #define NDMARECS 2048
  125. #ifdef GUSPLAYDEBUG
  126. int gusstats = 0;
  127. struct dma_record dmarecords[NDMARECS];
  128. int dmarecord_index = 0;
  129. #endif
  130. struct cfdriver gus_cd = {
  131. NULL, "gus", DV_DULL
  132. };
  133. /*
  134. * A mapping from IRQ/DRQ values to the values used in the GUS's internal
  135. * registers. A zero means that the referenced IRQ/DRQ is invalid
  136. */
  137. const int gus_irq_map[] = {
  138. IRQUNK, IRQUNK, 1, 3, IRQUNK, 2, IRQUNK, 4, IRQUNK, 1, IRQUNK, 5, 6,
  139. IRQUNK, IRQUNK, 7
  140. };
  141. const int gus_drq_map[] = {
  142. DRQUNK, 1, DRQUNK, 2, DRQUNK, 3, 4, 5
  143. };
  144. /*
  145. * A list of valid base addresses for the GUS
  146. */
  147. const int gus_base_addrs[] = {
  148. 0x210, 0x220, 0x230, 0x240, 0x250, 0x260
  149. };
  150. const int gus_addrs = sizeof(gus_base_addrs) / sizeof(gus_base_addrs[0]);
  151. /*
  152. * Maximum frequency values of the GUS based on the number of currently active
  153. * voices. Since the GUS samples a voice every 1.6 us, the maximum frequency
  154. * is dependent on the number of active voices. Yes, it is pretty weird.
  155. */
  156. static const int gus_max_frequency[] = {
  157. 44100, /* 14 voices */
  158. 41160, /* 15 voices */
  159. 38587, /* 16 voices */
  160. 36317, /* 17 voices */
  161. 34300, /* 18 voices */
  162. 32494, /* 19 voices */
  163. 30870, /* 20 voices */
  164. 29400, /* 21 voices */
  165. 28063, /* 22 voices */
  166. 26843, /* 23 voices */
  167. 25725, /* 24 voices */
  168. 24696, /* 25 voices */
  169. 23746, /* 26 voices */
  170. 22866, /* 27 voices */
  171. 22050, /* 28 voices */
  172. 21289, /* 29 voices */
  173. 20580, /* 30 voices */
  174. 19916, /* 31 voices */
  175. 19293 /* 32 voices */
  176. };
  177. /*
  178. * A mapping of linear volume levels to the logarithmic volume values used
  179. * by the GF1 chip on the GUS. From GUS SDK vol1.c.
  180. */
  181. static const unsigned short gus_log_volumes[512] = {
  182. 0x0000,
  183. 0x0700, 0x07ff, 0x0880, 0x08ff, 0x0940, 0x0980, 0x09c0, 0x09ff, 0x0a20,
  184. 0x0a40, 0x0a60, 0x0a80, 0x0aa0, 0x0ac0, 0x0ae0, 0x0aff, 0x0b10, 0x0b20,
  185. 0x0b30, 0x0b40, 0x0b50, 0x0b60, 0x0b70, 0x0b80, 0x0b90, 0x0ba0, 0x0bb0,
  186. 0x0bc0, 0x0bd0, 0x0be0, 0x0bf0, 0x0bff, 0x0c08, 0x0c10, 0x0c18, 0x0c20,
  187. 0x0c28, 0x0c30, 0x0c38, 0x0c40, 0x0c48, 0x0c50, 0x0c58, 0x0c60, 0x0c68,
  188. 0x0c70, 0x0c78, 0x0c80, 0x0c88, 0x0c90, 0x0c98, 0x0ca0, 0x0ca8, 0x0cb0,
  189. 0x0cb8, 0x0cc0, 0x0cc8, 0x0cd0, 0x0cd8, 0x0ce0, 0x0ce8, 0x0cf0, 0x0cf8,
  190. 0x0cff, 0x0d04, 0x0d08, 0x0d0c, 0x0d10, 0x0d14, 0x0d18, 0x0d1c, 0x0d20,
  191. 0x0d24, 0x0d28, 0x0d2c, 0x0d30, 0x0d34, 0x0d38, 0x0d3c, 0x0d40, 0x0d44,
  192. 0x0d48, 0x0d4c, 0x0d50, 0x0d54, 0x0d58, 0x0d5c, 0x0d60, 0x0d64, 0x0d68,
  193. 0x0d6c, 0x0d70, 0x0d74, 0x0d78, 0x0d7c, 0x0d80, 0x0d84, 0x0d88, 0x0d8c,
  194. 0x0d90, 0x0d94, 0x0d98, 0x0d9c, 0x0da0, 0x0da4, 0x0da8, 0x0dac, 0x0db0,
  195. 0x0db4, 0x0db8, 0x0dbc, 0x0dc0, 0x0dc4, 0x0dc8, 0x0dcc, 0x0dd0, 0x0dd4,
  196. 0x0dd8, 0x0ddc, 0x0de0, 0x0de4, 0x0de8, 0x0dec, 0x0df0, 0x0df4, 0x0df8,
  197. 0x0dfc, 0x0dff, 0x0e02, 0x0e04, 0x0e06, 0x0e08, 0x0e0a, 0x0e0c, 0x0e0e,
  198. 0x0e10, 0x0e12, 0x0e14, 0x0e16, 0x0e18, 0x0e1a, 0x0e1c, 0x0e1e, 0x0e20,
  199. 0x0e22, 0x0e24, 0x0e26, 0x0e28, 0x0e2a, 0x0e2c, 0x0e2e, 0x0e30, 0x0e32,
  200. 0x0e34, 0x0e36, 0x0e38, 0x0e3a, 0x0e3c, 0x0e3e, 0x0e40, 0x0e42, 0x0e44,
  201. 0x0e46, 0x0e48, 0x0e4a, 0x0e4c, 0x0e4e, 0x0e50, 0x0e52, 0x0e54, 0x0e56,
  202. 0x0e58, 0x0e5a, 0x0e5c, 0x0e5e, 0x0e60, 0x0e62, 0x0e64, 0x0e66, 0x0e68,
  203. 0x0e6a, 0x0e6c, 0x0e6e, 0x0e70, 0x0e72, 0x0e74, 0x0e76, 0x0e78, 0x0e7a,
  204. 0x0e7c, 0x0e7e, 0x0e80, 0x0e82, 0x0e84, 0x0e86, 0x0e88, 0x0e8a, 0x0e8c,
  205. 0x0e8e, 0x0e90, 0x0e92, 0x0e94, 0x0e96, 0x0e98, 0x0e9a, 0x0e9c, 0x0e9e,
  206. 0x0ea0, 0x0ea2, 0x0ea4, 0x0ea6, 0x0ea8, 0x0eaa, 0x0eac, 0x0eae, 0x0eb0,
  207. 0x0eb2, 0x0eb4, 0x0eb6, 0x0eb8, 0x0eba, 0x0ebc, 0x0ebe, 0x0ec0, 0x0ec2,
  208. 0x0ec4, 0x0ec6, 0x0ec8, 0x0eca, 0x0ecc, 0x0ece, 0x0ed0, 0x0ed2, 0x0ed4,
  209. 0x0ed6, 0x0ed8, 0x0eda, 0x0edc, 0x0ede, 0x0ee0, 0x0ee2, 0x0ee4, 0x0ee6,
  210. 0x0ee8, 0x0eea, 0x0eec, 0x0eee, 0x0ef0, 0x0ef2, 0x0ef4, 0x0ef6, 0x0ef8,
  211. 0x0efa, 0x0efc, 0x0efe, 0x0eff, 0x0f01, 0x0f02, 0x0f03, 0x0f04, 0x0f05,
  212. 0x0f06, 0x0f07, 0x0f08, 0x0f09, 0x0f0a, 0x0f0b, 0x0f0c, 0x0f0d, 0x0f0e,
  213. 0x0f0f, 0x0f10, 0x0f11, 0x0f12, 0x0f13, 0x0f14, 0x0f15, 0x0f16, 0x0f17,
  214. 0x0f18, 0x0f19, 0x0f1a, 0x0f1b, 0x0f1c, 0x0f1d, 0x0f1e, 0x0f1f, 0x0f20,
  215. 0x0f21, 0x0f22, 0x0f23, 0x0f24, 0x0f25, 0x0f26, 0x0f27, 0x0f28, 0x0f29,
  216. 0x0f2a, 0x0f2b, 0x0f2c, 0x0f2d, 0x0f2e, 0x0f2f, 0x0f30, 0x0f31, 0x0f32,
  217. 0x0f33, 0x0f34, 0x0f35, 0x0f36, 0x0f37, 0x0f38, 0x0f39, 0x0f3a, 0x0f3b,
  218. 0x0f3c, 0x0f3d, 0x0f3e, 0x0f3f, 0x0f40, 0x0f41, 0x0f42, 0x0f43, 0x0f44,
  219. 0x0f45, 0x0f46, 0x0f47, 0x0f48, 0x0f49, 0x0f4a, 0x0f4b, 0x0f4c, 0x0f4d,
  220. 0x0f4e, 0x0f4f, 0x0f50, 0x0f51, 0x0f52, 0x0f53, 0x0f54, 0x0f55, 0x0f56,
  221. 0x0f57, 0x0f58, 0x0f59, 0x0f5a, 0x0f5b, 0x0f5c, 0x0f5d, 0x0f5e, 0x0f5f,
  222. 0x0f60, 0x0f61, 0x0f62, 0x0f63, 0x0f64, 0x0f65, 0x0f66, 0x0f67, 0x0f68,
  223. 0x0f69, 0x0f6a, 0x0f6b, 0x0f6c, 0x0f6d, 0x0f6e, 0x0f6f, 0x0f70, 0x0f71,
  224. 0x0f72, 0x0f73, 0x0f74, 0x0f75, 0x0f76, 0x0f77, 0x0f78, 0x0f79, 0x0f7a,
  225. 0x0f7b, 0x0f7c, 0x0f7d, 0x0f7e, 0x0f7f, 0x0f80, 0x0f81, 0x0f82, 0x0f83,
  226. 0x0f84, 0x0f85, 0x0f86, 0x0f87, 0x0f88, 0x0f89, 0x0f8a, 0x0f8b, 0x0f8c,
  227. 0x0f8d, 0x0f8e, 0x0f8f, 0x0f90, 0x0f91, 0x0f92, 0x0f93, 0x0f94, 0x0f95,
  228. 0x0f96, 0x0f97, 0x0f98, 0x0f99, 0x0f9a, 0x0f9b, 0x0f9c, 0x0f9d, 0x0f9e,
  229. 0x0f9f, 0x0fa0, 0x0fa1, 0x0fa2, 0x0fa3, 0x0fa4, 0x0fa5, 0x0fa6, 0x0fa7,
  230. 0x0fa8, 0x0fa9, 0x0faa, 0x0fab, 0x0fac, 0x0fad, 0x0fae, 0x0faf, 0x0fb0,
  231. 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7, 0x0fb8, 0x0fb9,
  232. 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf, 0x0fc0, 0x0fc1, 0x0fc2,
  233. 0x0fc3, 0x0fc4, 0x0fc5, 0x0fc6, 0x0fc7, 0x0fc8, 0x0fc9, 0x0fca, 0x0fcb,
  234. 0x0fcc, 0x0fcd, 0x0fce, 0x0fcf, 0x0fd0, 0x0fd1, 0x0fd2, 0x0fd3, 0x0fd4,
  235. 0x0fd5, 0x0fd6, 0x0fd7, 0x0fd8, 0x0fd9, 0x0fda, 0x0fdb, 0x0fdc, 0x0fdd,
  236. 0x0fde, 0x0fdf, 0x0fe0, 0x0fe1, 0x0fe2, 0x0fe3, 0x0fe4, 0x0fe5, 0x0fe6,
  237. 0x0fe7, 0x0fe8, 0x0fe9, 0x0fea, 0x0feb, 0x0fec, 0x0fed, 0x0fee, 0x0fef,
  238. 0x0ff0, 0x0ff1, 0x0ff2, 0x0ff3, 0x0ff4, 0x0ff5, 0x0ff6, 0x0ff7, 0x0ff8,
  239. 0x0ff9, 0x0ffa, 0x0ffb, 0x0ffc, 0x0ffd, 0x0ffe, 0x0fff};
  240. /*
  241. * Interface to higher level audio driver
  242. */
  243. struct audio_hw_if gus_hw_if = {
  244. gusopen,
  245. gusclose,
  246. NULL, /* drain */
  247. gus_query_encoding,
  248. gus_set_params,
  249. gus_round_blocksize,
  250. gus_commit_settings,
  251. NULL,
  252. NULL,
  253. gus_dma_output,
  254. gus_dma_input,
  255. gus_halt_out_dma,
  256. gus_halt_in_dma,
  257. gus_speaker_ctl,
  258. gus_getdev,
  259. NULL,
  260. gus_mixer_set_port,
  261. gus_mixer_get_port,
  262. gus_mixer_query_devinfo,
  263. gus_malloc,
  264. gus_free,
  265. gus_round,
  266. gus_mappage,
  267. gus_get_props,
  268. NULL,
  269. NULL,
  270. NULL
  271. };
  272. static struct audio_hw_if gusmax_hw_if = {
  273. gusmaxopen,
  274. gusmax_close,
  275. NULL, /* drain */
  276. gus_query_encoding, /* query encoding */
  277. gusmax_set_params,
  278. gusmax_round_blocksize,
  279. gusmax_commit_settings,
  280. NULL,
  281. NULL,
  282. gusmax_dma_output,
  283. gusmax_dma_input,
  284. gusmax_halt_out_dma,
  285. gusmax_halt_in_dma,
  286. gusmax_speaker_ctl,
  287. gus_getdev,
  288. NULL,
  289. gusmax_mixer_set_port,
  290. gusmax_mixer_get_port,
  291. gusmax_mixer_query_devinfo,
  292. ad1848_malloc,
  293. ad1848_free,
  294. ad1848_round,
  295. ad1848_mappage,
  296. gusmax_get_props,
  297. NULL,
  298. NULL,
  299. NULL
  300. };
  301. /*
  302. * Some info about the current audio device
  303. */
  304. struct audio_device gus_device = {
  305. "UltraSound",
  306. "",
  307. "gus",
  308. };
  309. int
  310. gusopen(void *addr, int flags)
  311. {
  312. struct gus_softc *sc = addr;
  313. DPRINTF(("gusopen() called\n"));
  314. if (sc->sc_flags & GUS_OPEN)
  315. return EBUSY;
  316. /*
  317. * Some initialization
  318. */
  319. sc->sc_flags |= GUS_OPEN;
  320. sc->sc_dmabuf = 0;
  321. sc->sc_playbuf = -1;
  322. sc->sc_bufcnt = 0;
  323. sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
  324. sc->sc_voc[GUS_VOICE_LEFT].current_addr = GUS_MEM_OFFSET;
  325. if (HAS_CODEC(sc)) {
  326. ad1848_open(&sc->sc_codec, flags);
  327. sc->sc_codec.mute[AD1848_AUX1_CHANNEL] = 0;
  328. ad1848_mute_channel(&sc->sc_codec, AD1848_AUX1_CHANNEL, 0); /* turn on DAC output */
  329. if (flags & FREAD) {
  330. sc->sc_codec.mute[AD1848_MONO_CHANNEL] = 0;
  331. ad1848_mute_channel(&sc->sc_codec, AD1848_MONO_CHANNEL, 0);
  332. }
  333. } else if (flags & FREAD) {
  334. /* enable/unmute the microphone */
  335. if (HAS_MIXER(sc)) {
  336. gusics_mic_mute(&sc->sc_mixer, 0);
  337. } else
  338. gus_mic_ctl(sc, SPKR_ON);
  339. }
  340. if (sc->sc_nbufs == 0)
  341. gus_round_blocksize(sc, GUS_BUFFER_MULTIPLE); /* default blksiz */
  342. return 0;
  343. }
  344. int
  345. gusmaxopen(void *addr, int flags)
  346. {
  347. struct ad1848_softc *ac = addr;
  348. return gusopen(ac->parent, flags);
  349. }
  350. void
  351. gus_deinterleave(struct gus_softc *sc, void *buf, int size)
  352. {
  353. /* deinterleave the stereo data. We can use sc->sc_deintr_buf
  354. for scratch space. */
  355. int i;
  356. if (size > sc->sc_blocksize) {
  357. printf("gus: deinterleave %d > %d\n", size, sc->sc_blocksize);
  358. return;
  359. } else if (size < sc->sc_blocksize) {
  360. DPRINTF(("gus: deinterleave %d < %d\n", size, sc->sc_blocksize));
  361. }
  362. /*
  363. * size is in bytes.
  364. */
  365. if (sc->sc_precision == 16) {
  366. u_short *dei = sc->sc_deintr_buf;
  367. u_short *sbuf = buf;
  368. size >>= 1; /* bytecnt to shortcnt */
  369. /* copy 2nd of each pair of samples to the staging area, while
  370. compacting the 1st of each pair into the original area. */
  371. for (i = 0; i < size/2-1; i++) {
  372. dei[i] = sbuf[i*2+1];
  373. sbuf[i+1] = sbuf[i*2+2];
  374. }
  375. /*
  376. * this has copied one less sample than half of the
  377. * buffer. The first sample of the 1st stream was
  378. * already in place and didn't need copying.
  379. * Therefore, we've moved all of the 1st stream's
  380. * samples into place. We have one sample from 2nd
  381. * stream in the last slot of original area, not
  382. * copied to the staging area (But we don't need to!).
  383. * Copy the remainder of the original stream into place.
  384. */
  385. bcopy(dei, &sbuf[size/2], i * sizeof(short));
  386. } else {
  387. u_char *dei = sc->sc_deintr_buf;
  388. u_char *sbuf = buf;
  389. for (i = 0; i < size/2-1; i++) {
  390. dei[i] = sbuf[i*2+1];
  391. sbuf[i+1] = sbuf[i*2+2];
  392. }
  393. bcopy(dei, &sbuf[size/2], i);
  394. }
  395. }
  396. /*
  397. * Actually output a buffer to the DSP chip
  398. */
  399. int
  400. gusmax_dma_output(void *addr, void *buf, int size, void (*intr)(void *),
  401. void *arg)
  402. {
  403. struct ad1848_softc *ac = addr;
  404. return gus_dma_output(ac->parent, buf, size, intr, arg);
  405. }
  406. /*
  407. * called at splaudio() from interrupt handler.
  408. */
  409. void
  410. stereo_dmaintr(void *arg)
  411. {
  412. struct gus_softc *sc = arg;
  413. struct stereo_dma_intr *sa = &sc->sc_stereo;
  414. DMAPRINTF(("stereo_dmaintr"));
  415. /*
  416. * Put other half in its place, then call the real interrupt routine :)
  417. */
  418. sc->sc_dmaoutintr = sa->intr;
  419. sc->sc_outarg = sa->arg;
  420. #ifdef GUSPLAYDEBUG
  421. if (gusstats) {
  422. microtime(&dmarecords[dmarecord_index].tv);
  423. dmarecords[dmarecord_index].gusaddr = sa->dmabuf;
  424. dmarecords[dmarecord_index].bsdaddr = sa->buffer;
  425. dmarecords[dmarecord_index].count = sa->size;
  426. dmarecords[dmarecord_index].channel = 1;
  427. dmarecords[dmarecord_index++].direction = 1;
  428. dmarecord_index = dmarecord_index % NDMARECS;
  429. }
  430. #endif
  431. gusdmaout(sc, sa->flags, sa->dmabuf, (caddr_t) sa->buffer, sa->size);
  432. sa->flags = 0;
  433. sa->dmabuf = 0;
  434. sa->buffer = 0;
  435. sa->size = 0;
  436. sa->intr = 0;
  437. sa->arg = 0;
  438. }
  439. /*
  440. * Start up DMA output to the card.
  441. * Called at splaudio(), either from intr handler or from
  442. * generic audio code.
  443. */
  444. int
  445. gus_dma_output(void *addr, void *buf, int size, void (*intr)(void *), void *arg)
  446. {
  447. struct gus_softc *sc = addr;
  448. u_char *buffer = buf;
  449. u_long boarddma;
  450. int flags;
  451. DMAPRINTF(("gus_dma_output %d @ %p\n", size, buf));
  452. if (size != sc->sc_blocksize) {
  453. DPRINTF(("gus_dma_output reqsize %d not sc_blocksize %d\n",
  454. size, sc->sc_blocksize));
  455. return EINVAL;
  456. }
  457. flags = GUSMASK_DMA_WRITE;
  458. if (sc->sc_precision == 16)
  459. flags |= GUSMASK_DMA_DATA_SIZE;
  460. if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
  461. sc->sc_encoding == AUDIO_ENCODING_ALAW ||
  462. sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE ||
  463. sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE)
  464. flags |= GUSMASK_DMA_INVBIT;
  465. if (sc->sc_channels == 2) {
  466. if (sc->sc_precision == 16) {
  467. if (size & 3) {
  468. DPRINTF(("gus_dma_output: unpaired 16bit samples"));
  469. size &= 3;
  470. }
  471. } else if (size & 1) {
  472. DPRINTF(("gus_dma_output: unpaired samples"));
  473. size &= 1;
  474. }
  475. if (size == 0) {
  476. return 0;
  477. }
  478. gus_deinterleave(sc, (void *)buffer, size);
  479. size >>= 1;
  480. boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
  481. sc->sc_stereo.intr = intr;
  482. sc->sc_stereo.arg = arg;
  483. sc->sc_stereo.size = size;
  484. sc->sc_stereo.dmabuf = boarddma + GUS_LEFT_RIGHT_OFFSET;
  485. sc->sc_stereo.buffer = buffer + size;
  486. sc->sc_stereo.flags = flags;
  487. if (gus_dostereo) {
  488. intr = stereo_dmaintr;
  489. arg = sc;
  490. }
  491. } else
  492. boarddma = size * sc->sc_dmabuf + GUS_MEM_OFFSET;
  493. sc->sc_flags |= GUS_LOCKED;
  494. sc->sc_dmaoutintr = intr;
  495. sc->sc_outarg = arg;
  496. #ifdef GUSPLAYDEBUG
  497. if (gusstats) {
  498. microtime(&dmarecords[dmarecord_index].tv);
  499. dmarecords[dmarecord_index].gusaddr = boarddma;
  500. dmarecords[dmarecord_index].bsdaddr = buffer;
  501. dmarecords[dmarecord_index].count = size;
  502. dmarecords[dmarecord_index].channel = 0;
  503. dmarecords[dmarecord_index++].direction = 1;
  504. dmarecord_index = dmarecord_index % NDMARECS;
  505. }
  506. #endif
  507. gusdmaout(sc, flags, boarddma, (caddr_t) buffer, size);
  508. return 0;
  509. }
  510. void
  511. gusmax_close(void *addr)
  512. {
  513. struct ad1848_softc *ac = addr;
  514. struct gus_softc *sc = ac->parent;
  515. #if 0
  516. ac->mute[AD1848_AUX1_CHANNEL] = MUTE_ALL;
  517. ad1848_mute_channel(ac, MUTE_ALL); /* turn off DAC output */
  518. #endif
  519. ad1848_close(ac);
  520. gusclose(sc);
  521. }
  522. /*
  523. * Close out device stuff. Called at splaudio() from generic audio layer.
  524. */
  525. void
  526. gusclose(void *addr)
  527. {
  528. struct gus_softc *sc = addr;
  529. DPRINTF(("gus_close: sc=%p\n", sc));
  530. /* if (sc->sc_flags & GUS_DMAOUT_ACTIVE) */ {
  531. gus_halt_out_dma(sc);
  532. }
  533. /* if (sc->sc_flags & GUS_DMAIN_ACTIVE) */ {
  534. gus_halt_in_dma(sc);
  535. }
  536. sc->sc_flags &= ~(GUS_OPEN|GUS_LOCKED|GUS_DMAOUT_ACTIVE|GUS_DMAIN_ACTIVE);
  537. if (sc->sc_deintr_buf) {
  538. free(sc->sc_deintr_buf, M_DEVBUF, 0);
  539. sc->sc_deintr_buf = NULL;
  540. }
  541. /* turn off speaker, etc. */
  542. /* make sure the voices shut up: */
  543. gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
  544. gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
  545. }
  546. /*
  547. * Service interrupts. Farm them off to helper routines if we are using the
  548. * GUS for simple playback/record
  549. */
  550. #ifdef AUDIO_DEBUG
  551. int gusintrcnt;
  552. int gusdmaintrcnt;
  553. int gusvocintrcnt;
  554. #endif
  555. int
  556. gusintr(void *arg)
  557. {
  558. struct gus_softc *sc = arg;
  559. bus_space_tag_t iot = sc->sc_iot;
  560. bus_space_handle_t ioh1 = sc->sc_ioh1;
  561. bus_space_handle_t ioh2 = sc->sc_ioh2;
  562. unsigned char intr;
  563. int retval = 0;
  564. DPRINTF(("gusintr\n"));
  565. #ifdef AUDIO_DEBUG
  566. gusintrcnt++;
  567. #endif
  568. if (HAS_CODEC(sc))
  569. retval = ad1848_intr(&sc->sc_codec);
  570. mtx_enter(&audio_lock);
  571. if ((intr = bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS)) & GUSMASK_IRQ_DMATC) {
  572. DMAPRINTF(("gusintr dma flags=%x\n", sc->sc_flags));
  573. #ifdef AUDIO_DEBUG
  574. gusdmaintrcnt++;
  575. #endif
  576. retval += gus_dmaout_intr(sc);
  577. if (sc->sc_flags & GUS_DMAIN_ACTIVE) {
  578. SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
  579. intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
  580. if (intr & GUSMASK_SAMPLE_DMATC) {
  581. retval += gus_dmain_intr(sc);
  582. }
  583. }
  584. }
  585. if (intr & (GUSMASK_IRQ_VOICE | GUSMASK_IRQ_VOLUME)) {
  586. DMAPRINTF(("gusintr voice flags=%x\n", sc->sc_flags));
  587. #ifdef AUDIO_DEBUG
  588. gusvocintrcnt++;
  589. #endif
  590. retval += gus_voice_intr(sc);
  591. }
  592. if (retval) {
  593. mtx_leave(&audio_lock);
  594. return 1;
  595. }
  596. mtx_leave(&audio_lock);
  597. return retval;
  598. }
  599. int gus_bufcnt[GUS_MEM_FOR_BUFFERS / GUS_BUFFER_MULTIPLE];
  600. int gus_restart; /* how many restarts? */
  601. int gus_stops; /* how many times did voice stop? */
  602. int gus_falsestops; /* stopped but not done? */
  603. int gus_continues;
  604. struct playcont {
  605. struct timeval tv;
  606. u_int playbuf;
  607. u_int dmabuf;
  608. u_char bufcnt;
  609. u_char vaction;
  610. u_char voccntl;
  611. u_char volcntl;
  612. u_long curaddr;
  613. u_long endaddr;
  614. } playstats[NDMARECS];
  615. int playcntr;
  616. void
  617. gus_dmaout_timeout(void *arg)
  618. {
  619. struct gus_softc *sc = arg;
  620. bus_space_tag_t iot = sc->sc_iot;
  621. bus_space_handle_t ioh2 = sc->sc_ioh2;
  622. printf("%s: dmaout timeout\n", sc->sc_dev.dv_xname);
  623. /*
  624. * Stop any DMA.
  625. */
  626. mtx_enter(&audio_lock);
  627. SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
  628. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
  629. #if 0
  630. /* XXX we will dmadone below? */
  631. isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
  632. #endif
  633. gus_dmaout_dointr(sc);
  634. mtx_leave(&audio_lock);
  635. }
  636. /*
  637. * Service DMA interrupts. This routine will only get called if we're doing
  638. * a DMA transfer for playback/record requests from the audio layer.
  639. */
  640. int
  641. gus_dmaout_intr(struct gus_softc *sc)
  642. {
  643. bus_space_tag_t iot = sc->sc_iot;
  644. bus_space_handle_t ioh2 = sc->sc_ioh2;
  645. /*
  646. * If we got a DMA transfer complete from the GUS DRAM, then deal
  647. * with it.
  648. */
  649. SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
  650. if (bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & GUSMASK_DMA_IRQPEND) {
  651. timeout_del(&sc->sc_dma_tmo);
  652. gus_dmaout_dointr(sc);
  653. return 1;
  654. }
  655. return 0;
  656. }
  657. void
  658. gus_dmaout_dointr(struct gus_softc *sc)
  659. {
  660. bus_space_tag_t iot = sc->sc_iot;
  661. bus_space_handle_t ioh2 = sc->sc_ioh2;
  662. /* sc->sc_dmaoutcnt - 1 because DMA controller counts from zero?. */
  663. isa_dmadone(sc->sc_dev.dv_parent, sc->sc_drq);
  664. sc->sc_flags &= ~GUS_DMAOUT_ACTIVE; /* pending DMA is done */
  665. DMAPRINTF(("gus_dmaout_dointr %d @ %p\n", sc->sc_dmaoutcnt,
  666. sc->sc_dmaoutaddr));
  667. /*
  668. * to prevent clicking, we need to copy last sample
  669. * from last buffer to scratch area just before beginning of
  670. * buffer. However, if we're doing formats that are converted by
  671. * the card during the DMA process, we need to pick up the converted
  672. * byte rather than the one we have in memory.
  673. */
  674. if (sc->sc_dmabuf == sc->sc_nbufs - 1) {
  675. int i;
  676. switch (sc->sc_encoding) {
  677. case AUDIO_ENCODING_SLINEAR_LE:
  678. case AUDIO_ENCODING_SLINEAR_BE:
  679. if (sc->sc_precision == 8)
  680. goto byte;
  681. /* we have the native format */
  682. for (i = 1; i <= 2; i++)
  683. guspoke(iot, ioh2, sc->sc_gusaddr -
  684. (sc->sc_nbufs - 1) * sc->sc_chanblocksize - i,
  685. sc->sc_dmaoutaddr[sc->sc_dmaoutcnt-i]);
  686. break;
  687. case AUDIO_ENCODING_ULINEAR_LE:
  688. case AUDIO_ENCODING_ULINEAR_BE:
  689. guspoke(iot, ioh2, sc->sc_gusaddr -
  690. (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 2,
  691. guspeek(iot, ioh2,
  692. sc->sc_gusaddr + sc->sc_chanblocksize - 2));
  693. case AUDIO_ENCODING_ALAW:
  694. case AUDIO_ENCODING_ULAW:
  695. byte:
  696. /* we need to fetch the translated byte, then stuff it. */
  697. guspoke(iot, ioh2, sc->sc_gusaddr -
  698. (sc->sc_nbufs - 1) * sc->sc_chanblocksize - 1,
  699. guspeek(iot, ioh2,
  700. sc->sc_gusaddr + sc->sc_chanblocksize - 1));
  701. break;
  702. }
  703. }
  704. /*
  705. * If this is the first half of stereo, "ignore" this one
  706. * and copy out the second half.
  707. */
  708. if (sc->sc_dmaoutintr == stereo_dmaintr) {
  709. (*sc->sc_dmaoutintr)(sc->sc_outarg);
  710. return;
  711. }
  712. /*
  713. * If the voice is stopped, then start it. Reset the loop
  714. * and roll bits. Call the audio layer routine, since if
  715. * we're starting a stopped voice, that means that the next
  716. * buffer can be filled
  717. */
  718. sc->sc_flags &= ~GUS_LOCKED;
  719. if (sc->sc_voc[GUS_VOICE_LEFT].voccntl &
  720. GUSMASK_VOICE_STOPPED) {
  721. if (sc->sc_flags & GUS_PLAYING) {
  722. printf("%s: playing yet stopped?\n", sc->sc_dev.dv_xname);
  723. }
  724. sc->sc_bufcnt++; /* another yet to be played */
  725. gus_start_playing(sc, sc->sc_dmabuf);
  726. gus_restart++;
  727. } else {
  728. /*
  729. * set the sound action based on which buffer we
  730. * just transferred. If we just transferred buffer 0
  731. * we want the sound to loop when it gets to the nth
  732. * buffer; if we just transferred
  733. * any other buffer, we want the sound to roll over
  734. * at least one more time. The voice interrupt
  735. * handlers will take care of accounting &
  736. * setting control bits if it's not caught up to us
  737. * yet.
  738. */
  739. if (++sc->sc_bufcnt == 2) {
  740. /*
  741. * XXX
  742. * If we're too slow in reaction here,
  743. * the voice could be just approaching the
  744. * end of its run. It should be set to stop,
  745. * so these adjustments might not DTRT.
  746. */
  747. if (sc->sc_dmabuf == 0 &&
  748. sc->sc_playbuf == sc->sc_nbufs - 1) {
  749. /* player is just at the last buf, we're at the
  750. first. Turn on looping, turn off rolling. */
  751. sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
  752. sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~GUSMASK_VOICE_ROLL;
  753. playstats[playcntr].vaction = 3;
  754. } else {
  755. /* player is at previous buf:
  756. turn on rolling, turn off looping */
  757. sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
  758. sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
  759. playstats[playcntr].vaction = 4;
  760. }
  761. #ifdef GUSPLAYDEBUG
  762. if (gusstats) {
  763. microtime(&playstats[playcntr].tv);
  764. playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
  765. playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
  766. playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
  767. playstats[playcntr].playbuf = sc->sc_playbuf;
  768. playstats[playcntr].dmabuf = sc->sc_dmabuf;
  769. playstats[playcntr].bufcnt = sc->sc_bufcnt;
  770. playstats[playcntr++].curaddr = gus_get_curaddr(sc, GUS_VOICE_LEFT);
  771. playcntr = playcntr % NDMARECS;
  772. }
  773. #endif
  774. bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
  775. SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
  776. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
  777. SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
  778. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
  779. }
  780. }
  781. gus_bufcnt[sc->sc_bufcnt-1]++;
  782. /*
  783. * flip to the next DMA buffer
  784. */
  785. sc->sc_dmabuf = ++sc->sc_dmabuf % sc->sc_nbufs;
  786. /*
  787. * See comments below about DMA admission control strategy.
  788. * We can call the upper level here if we have an
  789. * idle buffer (not currently playing) to DMA into.
  790. */
  791. if (sc->sc_dmaoutintr && sc->sc_bufcnt < sc->sc_nbufs) {
  792. /* clean out to prevent double calls */
  793. void (*pfunc)(void *) = sc->sc_dmaoutintr;
  794. void *arg = sc->sc_outarg;
  795. sc->sc_outarg = 0;
  796. sc->sc_dmaoutintr = 0;
  797. (*pfunc)(arg);
  798. }
  799. }
  800. /*
  801. * Service voice interrupts
  802. */
  803. int
  804. gus_voice_intr(struct gus_softc *sc)
  805. {
  806. bus_space_tag_t iot = sc->sc_iot;
  807. bus_space_handle_t ioh2 = sc->sc_ioh2;
  808. int ignore = 0, voice, rval = 0;
  809. unsigned char intr, status;
  810. /*
  811. * The point of this may not be obvious at first. A voice can
  812. * interrupt more than once; according to the GUS SDK we are supposed
  813. * to ignore multiple interrupts for the same voice.
  814. */
  815. while(1) {
  816. SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
  817. intr = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
  818. if ((intr & (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
  819. == (GUSMASK_WIRQ_VOLUME | GUSMASK_WIRQ_VOICE))
  820. /*
  821. * No more interrupts, time to return
  822. */
  823. return rval;
  824. if ((intr & GUSMASK_WIRQ_VOICE) == 0) {
  825. /*
  826. * We've got a voice interrupt. Ignore previous
  827. * interrupts by the same voice.
  828. */
  829. rval = 1;
  830. voice = intr & GUSMASK_WIRQ_VOICEMASK;
  831. if ((1 << voice) & ignore)
  832. break;
  833. ignore |= 1 << voice;
  834. /*
  835. * If the voice is stopped, then force it to stop
  836. * (this stops it from continuously generating IRQs)
  837. */
  838. SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL+0x80);
  839. status = bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
  840. if (status & GUSMASK_VOICE_STOPPED) {
  841. if (voice != GUS_VOICE_LEFT) {
  842. DMAPRINTF(("%s: spurious voice %d stop?\n",
  843. sc->sc_dev.dv_xname, voice));
  844. gus_stop_voice(sc, voice, 0);
  845. continue;
  846. }
  847. gus_stop_voice(sc, voice, 1);
  848. /* also kill right voice */
  849. gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
  850. sc->sc_bufcnt--; /* it finished a buffer */
  851. if (sc->sc_bufcnt > 0) {
  852. /*
  853. * probably a race to get here: the voice
  854. * stopped while the DMA code was just trying to
  855. * get the next buffer in place.
  856. * Start the voice again.
  857. */
  858. printf("%s: stopped voice not drained? (%x)\n",
  859. sc->sc_dev.dv_xname, sc->sc_bufcnt);
  860. gus_falsestops++;
  861. sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs;
  862. gus_start_playing(sc, sc->sc_playbuf);
  863. } else if (sc->sc_bufcnt < 0) {
  864. panic("%s: negative bufcnt in stopped voice",
  865. sc->sc_dev.dv_xname);
  866. } else {
  867. sc->sc_playbuf = -1; /* none are active */
  868. gus_stops++;
  869. }
  870. /* fall through to callback and admit another
  871. buffer.... */
  872. } else if (sc->sc_bufcnt != 0) {
  873. /*
  874. * This should always be taken if the voice
  875. * is not stopped.
  876. */
  877. gus_continues++;
  878. if (gus_continue_playing(sc, voice)) {
  879. /*
  880. * we shouldn't have continued--active DMA
  881. * is in the way in the ring, for
  882. * some as-yet undebugged reason.
  883. */
  884. gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
  885. /* also kill right voice */
  886. gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
  887. sc->sc_playbuf = -1;
  888. gus_stops++;
  889. }
  890. }
  891. /*
  892. * call the upper level to send on down another
  893. * block. We do admission rate control as follows:
  894. *
  895. * When starting up output (in the first N
  896. * blocks), call the upper layer after the DMA is
  897. * complete (see above in gus_dmaout_intr()).
  898. *
  899. * When output is already in progress and we have
  900. * no more GUS buffers to use for DMA, the DMA
  901. * output routines do not call the upper layer.
  902. * Instead, we call the DMA completion routine
  903. * here, after the voice interrupts indicating
  904. * that it's finished with a buffer.
  905. *
  906. * However, don't call anything here if the DMA
  907. * output flag is set, (which shouldn't happen)
  908. * because we'll squish somebody else's DMA if
  909. * that's the case. When DMA is done, it will
  910. * call back if there is a spare buffer.
  911. */
  912. if (sc->sc_dmaoutintr && !(sc->sc_flags & GUS_LOCKED)) {
  913. if (sc->sc_dmaoutintr == stereo_dmaintr)
  914. printf("gusdmaout botch?\n");
  915. else {
  916. /* clean out to avoid double calls */
  917. void (*pfunc)(void *) = sc->sc_dmaoutintr;
  918. void *arg = sc->sc_outarg;
  919. sc->sc_outarg = 0;
  920. sc->sc_dmaoutintr = 0;
  921. (*pfunc)(arg);
  922. }
  923. }
  924. }
  925. /*
  926. * Ignore other interrupts for now
  927. */
  928. }
  929. return 0;
  930. }
  931. void
  932. gus_start_playing(struct gus_softc *sc, int bufno)
  933. {
  934. bus_space_tag_t iot = sc->sc_iot;
  935. bus_space_handle_t ioh2 = sc->sc_ioh2;
  936. /*
  937. * Start the voices playing, with buffer BUFNO.
  938. */
  939. /*
  940. * Loop or roll if we have buffers ready.
  941. */
  942. if (sc->sc_bufcnt == 1) {
  943. sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~(GUSMASK_LOOP_ENABLE);
  944. sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
  945. } else {
  946. if (bufno == sc->sc_nbufs - 1) {
  947. sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_LOOP_ENABLE;
  948. sc->sc_voc[GUS_VOICE_LEFT].volcntl &= ~(GUSMASK_VOICE_ROLL);
  949. } else {
  950. sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_LOOP_ENABLE;
  951. sc->sc_voc[GUS_VOICE_LEFT].volcntl |= GUSMASK_VOICE_ROLL;
  952. }
  953. }
  954. bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_LEFT);
  955. SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
  956. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].voccntl);
  957. SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
  958. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_LEFT].volcntl);
  959. sc->sc_voc[GUS_VOICE_LEFT].current_addr =
  960. GUS_MEM_OFFSET + sc->sc_chanblocksize * bufno;
  961. sc->sc_voc[GUS_VOICE_LEFT].end_addr =
  962. sc->sc_voc[GUS_VOICE_LEFT].current_addr + sc->sc_chanblocksize - 1;
  963. sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
  964. sc->sc_voc[GUS_VOICE_LEFT].current_addr +
  965. (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0);
  966. /*
  967. * set up right channel to just loop forever, no interrupts,
  968. * starting at the buffer we just filled. We'll feed it data
  969. * at the same time as left channel.
  970. */
  971. sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_LOOP_ENABLE;
  972. sc->sc_voc[GUS_VOICE_RIGHT].volcntl &= ~(GUSMASK_VOICE_ROLL);
  973. #ifdef GUSPLAYDEBUG
  974. if (gusstats) {
  975. microtime(&playstats[playcntr].tv);
  976. playstats[playcntr].curaddr = sc->sc_voc[GUS_VOICE_LEFT].current_addr;
  977. playstats[playcntr].voccntl = sc->sc_voc[GUS_VOICE_LEFT].voccntl;
  978. playstats[playcntr].volcntl = sc->sc_voc[GUS_VOICE_LEFT].volcntl;
  979. playstats[playcntr].endaddr = sc->sc_voc[GUS_VOICE_LEFT].end_addr;
  980. playstats[playcntr].playbuf = bufno;
  981. playstats[playcntr].dmabuf = sc->sc_dmabuf;
  982. playstats[playcntr].bufcnt = sc->sc_bufcnt;
  983. playstats[playcntr++].vaction = 5;
  984. playcntr = playcntr % NDMARECS;
  985. }
  986. #endif
  987. bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, GUS_VOICE_RIGHT);
  988. SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
  989. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].voccntl);
  990. SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
  991. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[GUS_VOICE_RIGHT].volcntl);
  992. gus_start_voice(sc, GUS_VOICE_RIGHT, 0);
  993. gus_start_voice(sc, GUS_VOICE_LEFT, 1);
  994. if (sc->sc_playbuf == -1)
  995. /* mark start of playing */
  996. sc->sc_playbuf = bufno;
  997. }
  998. int
  999. gus_continue_playing(struct gus_softc *sc, int voice)
  1000. {
  1001. bus_space_tag_t iot = sc->sc_iot;
  1002. bus_space_handle_t ioh2 = sc->sc_ioh2;
  1003. /*
  1004. * stop this voice from interrupting while we work.
  1005. */
  1006. SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
  1007. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl & ~(GUSMASK_VOICE_IRQ));
  1008. /*
  1009. * update playbuf to point to the buffer the hardware just started
  1010. * playing
  1011. */
  1012. sc->sc_playbuf = ++sc->sc_playbuf % sc->sc_nbufs;
  1013. /*
  1014. * account for buffer just finished
  1015. */
  1016. if (--sc->sc_bufcnt == 0) {
  1017. DPRINTF(("gus: bufcnt 0 on continuing voice?\n"));
  1018. }
  1019. if (sc->sc_playbuf == sc->sc_dmabuf && (sc->sc_flags & GUS_LOCKED)) {
  1020. printf("%s: continue into active dmabuf?\n", sc->sc_dev.dv_xname);
  1021. return 1;
  1022. }
  1023. /*
  1024. * Select the end of the buffer based on the currently active
  1025. * buffer, [plus extra contiguous buffers (if ready)].
  1026. */
  1027. /*
  1028. * set endpoint at end of buffer we just started playing.
  1029. *
  1030. * The total gets -1 because end addrs are one less than you might
  1031. * think (the end_addr is the address of the last sample to play)
  1032. */
  1033. gus_set_endaddr(sc, voice, GUS_MEM_OFFSET +
  1034. sc->sc_chanblocksize * (sc->sc_playbuf + 1) - 1);
  1035. if (sc->sc_bufcnt < 2) {
  1036. /*
  1037. * Clear out the loop and roll flags, and rotate the currently
  1038. * playing buffer. That way, if we don't manage to get more
  1039. * data before this buffer finishes, we'll just stop.
  1040. */
  1041. sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
  1042. sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
  1043. playstats[playcntr].vaction = 0;
  1044. } else {
  1045. /*
  1046. * We have some buffers to play. set LOOP if we're on the
  1047. * last buffer in the ring, otherwise set ROLL.
  1048. */
  1049. if (sc->sc_playbuf == sc->sc_nbufs - 1) {
  1050. sc->sc_voc[voice].voccntl |= GUSMASK_LOOP_ENABLE;
  1051. sc->sc_voc[voice].volcntl &= ~GUSMASK_VOICE_ROLL;
  1052. playstats[playcntr].vaction = 1;
  1053. } else {
  1054. sc->sc_voc[voice].voccntl &= ~GUSMASK_LOOP_ENABLE;
  1055. sc->sc_voc[voice].volcntl |= GUSMASK_VOICE_ROLL;
  1056. playstats[playcntr].vaction = 2;
  1057. }
  1058. }
  1059. #ifdef GUSPLAYDEBUG
  1060. if (gusstats) {
  1061. microtime(&playstats[playcntr].tv);
  1062. playstats[playcntr].curaddr = gus_get_curaddr(sc, voice);
  1063. playstats[playcntr].voccntl = sc->sc_voc[voice].voccntl;
  1064. playstats[playcntr].volcntl = sc->sc_voc[voice].volcntl;
  1065. playstats[playcntr].endaddr = sc->sc_voc[voice].end_addr;
  1066. playstats[playcntr].playbuf = sc->sc_playbuf;
  1067. playstats[playcntr].dmabuf = sc->sc_dmabuf;
  1068. playstats[playcntr++].bufcnt = sc->sc_bufcnt;
  1069. playcntr = playcntr % NDMARECS;
  1070. }
  1071. #endif
  1072. /*
  1073. * (re-)set voice parameters. This will reenable interrupts from this
  1074. * voice.
  1075. */
  1076. SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
  1077. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
  1078. SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
  1079. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].volcntl);
  1080. return 0;
  1081. }
  1082. /*
  1083. * Send/receive data into GUS's DRAM using DMA. Called at splaudio()
  1084. */
  1085. void
  1086. gusdmaout(struct gus_softc *sc, int flags, u_long gusaddr, caddr_t buffaddr,
  1087. int length)
  1088. {
  1089. unsigned char c = (unsigned char) flags;
  1090. bus_space_tag_t iot = sc->sc_iot;
  1091. bus_space_handle_t ioh2 = sc->sc_ioh2;
  1092. DMAPRINTF(("gusdmaout flags=%x scflags=%x\n", flags, sc->sc_flags));
  1093. sc->sc_gusaddr = gusaddr;
  1094. /*
  1095. * If we're using a 16 bit DMA channel, we have to jump through some
  1096. * extra hoops; this includes translating the DRAM address a bit
  1097. */
  1098. if (sc->sc_drq >= 4) {
  1099. c |= GUSMASK_DMA_WIDTH;
  1100. gusaddr = convert_to_16bit(gusaddr);
  1101. }
  1102. /*
  1103. * Add flag bits that we always set - fast DMA, enable IRQ
  1104. */
  1105. c |= GUSMASK_DMA_ENABLE | GUSMASK_DMA_R0 | GUSMASK_DMA_IRQ;
  1106. /*
  1107. * Make sure the GUS _isn't_ setup for DMA
  1108. */
  1109. SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
  1110. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
  1111. /*
  1112. * Tell the PC DMA controller to start doing DMA
  1113. */
  1114. sc->sc_dmaoutaddr = (u_char *) buffaddr;
  1115. sc->sc_dmaoutcnt = length;
  1116. isa_dmastart(sc->sc_dev.dv_parent, sc->sc_drq, buffaddr, length,
  1117. NULL, DMAMODE_WRITE, BUS_DMA_NOWAIT);
  1118. /*
  1119. * Set up DMA address - use the upper 16 bits ONLY
  1120. */
  1121. sc->sc_flags |= GUS_DMAOUT_ACTIVE;
  1122. SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_START);
  1123. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (int) (gusaddr >> 4));
  1124. /*
  1125. * Tell the GUS to start doing DMA
  1126. */
  1127. SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
  1128. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, c);
  1129. /*
  1130. * XXX If we don't finish in one second, give up...
  1131. */
  1132. timeout_add_sec(&sc->sc_dma_tmo, 1);
  1133. }
  1134. /*
  1135. * Start a voice playing on the GUS. Called from interrupt handler at
  1136. * splaudio().
  1137. */
  1138. void
  1139. gus_start_voice(struct gus_softc *sc, int voice, int intrs)
  1140. {
  1141. bus_space_tag_t iot = sc->sc_iot;
  1142. bus_space_handle_t ioh2 = sc->sc_ioh2;
  1143. u_long start;
  1144. u_long current;
  1145. u_long end;
  1146. /*
  1147. * Pick all the values for the voice out of the gus_voice struct
  1148. * and use those to program the voice
  1149. */
  1150. start = sc->sc_voc[voice].start_addr;
  1151. current = sc->sc_voc[voice].current_addr;
  1152. end = sc->sc_voc[voice].end_addr;
  1153. /*
  1154. * If we're using 16 bit data, mangle the addresses a bit
  1155. */
  1156. if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16) {
  1157. /* -1 on start so that we get onto sample boundary--other
  1158. code always sets it for 1-byte rollover protection */
  1159. start = convert_to_16bit(start-1);
  1160. current = convert_to_16bit(current);
  1161. end = convert_to_16bit(end);
  1162. }
  1163. /*
  1164. * Select the voice we want to use, and program the data addresses
  1165. */
  1166. bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
  1167. SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
  1168. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(start));
  1169. SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
  1170. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(start));
  1171. SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
  1172. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(current));
  1173. SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
  1174. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(current));
  1175. SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
  1176. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(end));
  1177. SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
  1178. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(end));
  1179. /*
  1180. * (maybe) enable interrupts, disable voice stopping
  1181. */
  1182. if (intrs) {
  1183. sc->sc_flags |= GUS_PLAYING; /* playing is about to start */
  1184. sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_IRQ;
  1185. DMAPRINTF(("gus voice playing=%x\n", sc->sc_flags));
  1186. } else
  1187. sc->sc_voc[voice].voccntl &= ~GUSMASK_VOICE_IRQ;
  1188. sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_STOPPED |
  1189. GUSMASK_STOP_VOICE);
  1190. /*
  1191. * Tell the GUS about it. Note that we're doing volume ramping here
  1192. * from 0 up to the set volume to help reduce clicks.
  1193. */
  1194. SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
  1195. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
  1196. SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
  1197. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].current_volume >> 4);
  1198. SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
  1199. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x00);
  1200. SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
  1201. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 63);
  1202. SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
  1203. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
  1204. SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
  1205. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
  1206. delay(50);
  1207. SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
  1208. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
  1209. SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
  1210. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
  1211. }
  1212. /*
  1213. * Stop a given voice. Called at splaudio().
  1214. */
  1215. void
  1216. gus_stop_voice(struct gus_softc *sc, int voice, int intrs_too)
  1217. {
  1218. bus_space_tag_t iot = sc->sc_iot;
  1219. bus_space_handle_t ioh2 = sc->sc_ioh2;
  1220. sc->sc_voc[voice].voccntl |= GUSMASK_VOICE_STOPPED |
  1221. GUSMASK_STOP_VOICE;
  1222. if (intrs_too) {
  1223. sc->sc_voc[voice].voccntl &= ~(GUSMASK_VOICE_IRQ);
  1224. /* no more DMA to do */
  1225. sc->sc_flags &= ~GUS_PLAYING;
  1226. }
  1227. DMAPRINTF(("gusintr voice notplaying=%x\n", sc->sc_flags));
  1228. guspoke(iot, ioh2, 0L, 0);
  1229. bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
  1230. SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
  1231. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
  1232. SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
  1233. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
  1234. delay(100);
  1235. SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
  1236. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
  1237. SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
  1238. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[voice].voccntl);
  1239. SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
  1240. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
  1241. SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
  1242. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
  1243. }
  1244. /*
  1245. * Set the volume of a given voice. Called at splaudio().
  1246. */
  1247. void
  1248. gus_set_volume(struct gus_softc *sc, int voice, int volume)
  1249. {
  1250. bus_space_tag_t iot = sc->sc_iot;
  1251. bus_space_handle_t ioh2 = sc->sc_ioh2;
  1252. unsigned int gusvol;
  1253. gusvol = gus_log_volumes[volume < 512 ? volume : 511];
  1254. sc->sc_voc[voice].current_volume = gusvol;
  1255. bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
  1256. SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
  1257. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
  1258. SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
  1259. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) (gusvol >> 4));
  1260. SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
  1261. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
  1262. delay(500);
  1263. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, gusvol << 4);
  1264. }
  1265. /*
  1266. * Interface to the audio layer.
  1267. */
  1268. int
  1269. gusmax_set_params(void *addr, int setmode, int usemode, struct audio_params *p,
  1270. struct audio_params *r)
  1271. {
  1272. struct ad1848_softc *ac = addr;
  1273. struct gus_softc *sc = ac->parent;
  1274. int error;
  1275. error = ad1848_set_params(ac, setmode, usemode, p, r);
  1276. if (error)
  1277. return error;
  1278. error = gus_set_params(sc, setmode, usemode, p, r);
  1279. return error;
  1280. }
  1281. int
  1282. gus_set_params(void *addr, int setmode, int usemode, struct audio_params *p,
  1283. struct audio_params *r)
  1284. {
  1285. struct gus_softc *sc = addr;
  1286. switch (p->encoding) {
  1287. case AUDIO_ENCODING_SLINEAR_LE:
  1288. case AUDIO_ENCODING_ULINEAR_LE:
  1289. break;
  1290. default:
  1291. return (EINVAL);
  1292. }
  1293. /* XXX: why?! this is called with interrupts disabled */
  1294. mtx_enter(&audio_lock);
  1295. if (p->precision == 8) {
  1296. sc->sc_voc[GUS_VOICE_LEFT].voccntl &= ~GUSMASK_DATA_SIZE16;
  1297. sc->sc_voc[GUS_VOICE_RIGHT].voccntl &= ~GUSMASK_DATA_SIZE16;
  1298. } else {
  1299. sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
  1300. sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
  1301. }
  1302. sc->sc_encoding = p->encoding;
  1303. sc->sc_precision = p->precision;
  1304. sc->sc_channels = p->channels;
  1305. mtx_leave(&audio_lock);
  1306. if (p->sample_rate > gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES])
  1307. p->sample_rate = gus_max_frequency[sc->sc_voices - GUS_MIN_VOICES];
  1308. if (setmode & AUMODE_RECORD)
  1309. sc->sc_irate = p->sample_rate;
  1310. if (setmode & AUMODE_PLAY)
  1311. sc->sc_orate = p->sample_rate;
  1312. p->bps = AUDIO_BPS(p->precision);
  1313. r->bps = AUDIO_BPS(r->precision);
  1314. p->msb = r->msb = 1;
  1315. return 0;
  1316. }
  1317. /*
  1318. * Interface to the audio layer - set the blocksize to the correct number
  1319. * of units
  1320. */
  1321. int
  1322. gusmax_round_blocksize(void *addr, int blocksize)
  1323. {
  1324. struct ad1848_softc *ac = addr;
  1325. struct gus_softc *sc = ac->parent;
  1326. /* blocksize = ad1848_round_blocksize(ac, blocksize);*/
  1327. return gus_round_blocksize(sc, blocksize);
  1328. }
  1329. int
  1330. gus_round_blocksize(addr, blocksize)
  1331. void * addr;
  1332. int blocksize;
  1333. {
  1334. struct gus_softc *sc = addr;
  1335. DPRINTF(("gus_round_blocksize called\n"));
  1336. if ((sc->sc_encoding == AUDIO_ENCODING_ULAW ||
  1337. sc->sc_encoding == AUDIO_ENCODING_ALAW) && blocksize > 32768)
  1338. blocksize = 32768;
  1339. else if (blocksize > 65536)
  1340. blocksize = 65536;
  1341. if ((blocksize % GUS_BUFFER_MULTIPLE) != 0)
  1342. blocksize = (blocksize / GUS_BUFFER_MULTIPLE + 1) *
  1343. GUS_BUFFER_MULTIPLE;
  1344. /* set up temporary buffer to hold the deinterleave, if necessary
  1345. for stereo output */
  1346. if (sc->sc_deintr_buf) {
  1347. free(sc->sc_deintr_buf, M_DEVBUF, 0);
  1348. sc->sc_deintr_buf = NULL;
  1349. }
  1350. sc->sc_deintr_buf = malloc(blocksize/2, M_DEVBUF, M_WAITOK);
  1351. sc->sc_blocksize = blocksize;
  1352. /* multi-buffering not quite working yet. */
  1353. sc->sc_nbufs = /*GUS_MEM_FOR_BUFFERS / blocksize*/ 2;
  1354. gus_set_chan_addrs(sc);
  1355. return blocksize;
  1356. }
  1357. int
  1358. gus_get_out_gain(caddr_t addr)
  1359. {
  1360. struct gus_softc *sc = (struct gus_softc *) addr;
  1361. DPRINTF(("gus_get_out_gain called\n"));
  1362. return sc->sc_ogain / 2;
  1363. }
  1364. inline void
  1365. gus_set_voices(struct gus_softc *sc, int voices)
  1366. {
  1367. bus_space_tag_t iot = sc->sc_iot;
  1368. bus_space_handle_t ioh2 = sc->sc_ioh2;
  1369. /*
  1370. * Select the active number of voices
  1371. */
  1372. SELECT_GUS_REG(iot, ioh2, GUSREG_ACTIVE_VOICES);
  1373. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (voices-1) | 0xc0);
  1374. sc->sc_voices = voices;
  1375. }
  1376. /*
  1377. * Actually set the settings of various values on the card
  1378. */
  1379. int
  1380. gusmax_commit_settings(void *addr)
  1381. {
  1382. struct ad1848_softc *ac = addr;
  1383. struct gus_softc *sc = ac->parent;
  1384. int error;
  1385. error = ad1848_commit_settings(ac);
  1386. if (error)
  1387. return error;
  1388. return gus_commit_settings(sc);
  1389. }
  1390. /*
  1391. * Commit the settings. Called at normal IPL.
  1392. */
  1393. int
  1394. gus_commit_settings(void *addr)
  1395. {
  1396. struct gus_softc *sc = addr;
  1397. DPRINTF(("gus_commit_settings called (gain = %d)\n",sc->sc_ogain));
  1398. /* XXX: why?! this is called with interrupts disabled */
  1399. mtx_enter(&audio_lock);
  1400. gus_set_recrate(sc, sc->sc_irate);
  1401. gus_set_volume(sc, GUS_VOICE_LEFT, sc->sc_ogain);
  1402. gus_set_volume(sc, GUS_VOICE_RIGHT, sc->sc_ogain);
  1403. gus_set_samprate(sc, GUS_VOICE_LEFT, sc->sc_orate);
  1404. gus_set_samprate(sc, GUS_VOICE_RIGHT, sc->sc_orate);
  1405. mtx_leave(&audio_lock);
  1406. gus_set_chan_addrs(sc);
  1407. return 0;
  1408. }
  1409. void
  1410. gus_set_chan_addrs(struct gus_softc *sc)
  1411. {
  1412. /*
  1413. * We use sc_nbufs * blocksize bytes of storage in the on-board GUS
  1414. * ram.
  1415. * For mono, each of the sc_nbufs buffers is DMA'd to in one chunk,
  1416. * and both left & right channels play the same buffer.
  1417. *
  1418. * For stereo, each channel gets a contiguous half of the memory,
  1419. * and each has sc_nbufs buffers of size blocksize/2.
  1420. * Stereo data are deinterleaved in main memory before the DMA out
  1421. * routines are called to queue the output.
  1422. *
  1423. * The blocksize per channel is kept in sc_chanblocksize.
  1424. */
  1425. if (sc->sc_channels == 2)
  1426. sc->sc_chanblocksize = sc->sc_blocksize/2;
  1427. else
  1428. sc->sc_chanblocksize = sc->sc_blocksize;
  1429. sc->sc_voc[GUS_VOICE_LEFT].start_addr = GUS_MEM_OFFSET - 1;
  1430. sc->sc_voc[GUS_VOICE_RIGHT].start_addr =
  1431. (gus_dostereo && sc->sc_channels == 2 ? GUS_LEFT_RIGHT_OFFSET : 0)
  1432. + GUS_MEM_OFFSET - 1;
  1433. sc->sc_voc[GUS_VOICE_RIGHT].current_addr =
  1434. sc->sc_voc[GUS_VOICE_RIGHT].start_addr + 1;
  1435. sc->sc_voc[GUS_VOICE_RIGHT].end_addr =
  1436. sc->sc_voc[GUS_VOICE_RIGHT].start_addr +
  1437. sc->sc_nbufs * sc->sc_chanblocksize;
  1438. }
  1439. /*
  1440. * Set the sample rate of the given voice. Called at splaudio().
  1441. */
  1442. void
  1443. gus_set_samprate(struct gus_softc *sc, int voice, int freq)
  1444. {
  1445. bus_space_tag_t iot = sc->sc_iot;
  1446. bus_space_handle_t ioh2 = sc->sc_ioh2;
  1447. unsigned int fc;
  1448. u_long temp, f = (u_long) freq;
  1449. /*
  1450. * calculate fc based on the number of active voices;
  1451. * we need to use longs to preserve enough bits
  1452. */
  1453. temp = (u_long) gus_max_frequency[sc->sc_voices-GUS_MIN_VOICES];
  1454. fc = (unsigned int)(((f << 9L) + (temp >> 1L)) / temp);
  1455. fc <<= 1;
  1456. /*
  1457. * Program the voice frequency, and set it in the voice data record
  1458. */
  1459. bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
  1460. SELECT_GUS_REG(iot, ioh2, GUSREG_FREQ_CONTROL);
  1461. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, fc);
  1462. sc->sc_voc[voice].rate = freq;
  1463. }
  1464. /*
  1465. * Set the sample rate of the recording frequency. Formula is from the GUS
  1466. * SDK. Called at splaudio().
  1467. */
  1468. void
  1469. gus_set_recrate(struct gus_softc *sc, u_long rate)
  1470. {
  1471. bus_space_tag_t iot = sc->sc_iot;
  1472. bus_space_handle_t ioh2 = sc->sc_ioh2;
  1473. u_char realrate;
  1474. DPRINTF(("gus_set_recrate %lu\n", rate));
  1475. #if 0
  1476. realrate = 9878400/(16*(rate+2)); /* formula from GUS docs */
  1477. #endif
  1478. realrate = (9878400 >> 4)/rate - 2; /* formula from code, sigh. */
  1479. SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_FREQ);
  1480. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, realrate);
  1481. }
  1482. /*
  1483. * Interface to the audio layer - turn the output on or off. Note that some
  1484. * of these bits are flipped in the register
  1485. */
  1486. int
  1487. gusmax_speaker_ctl(void *addr, int newstate)
  1488. {
  1489. struct ad1848_softc *sc = addr;
  1490. return gus_speaker_ctl(sc->parent, newstate);
  1491. }
  1492. int
  1493. gus_speaker_ctl(void *addr, int newstate)
  1494. {
  1495. struct gus_softc *sc = (struct gus_softc *) addr;
  1496. bus_space_tag_t iot = sc->sc_iot;
  1497. bus_space_handle_t ioh1 = sc->sc_ioh1;
  1498. /* Line out bit is flipped: 0 enables, 1 disables */
  1499. if ((newstate == SPKR_ON) &&
  1500. (sc->sc_mixcontrol & GUSMASK_LINE_OUT)) {
  1501. sc->sc_mixcontrol &= ~GUSMASK_LINE_OUT;
  1502. bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
  1503. }
  1504. if ((newstate == SPKR_OFF) &&
  1505. (sc->sc_mixcontrol & GUSMASK_LINE_OUT) == 0) {
  1506. sc->sc_mixcontrol |= GUSMASK_LINE_OUT;
  1507. bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
  1508. }
  1509. return 0;
  1510. }
  1511. int
  1512. gus_linein_ctl(void *addr, int newstate)
  1513. {
  1514. struct gus_softc *sc = (struct gus_softc *) addr;
  1515. bus_space_tag_t iot = sc->sc_iot;
  1516. bus_space_handle_t ioh1 = sc->sc_ioh1;
  1517. /* Line in bit is flipped: 0 enables, 1 disables */
  1518. if ((newstate == SPKR_ON) &&
  1519. (sc->sc_mixcontrol & GUSMASK_LINE_IN)) {
  1520. sc->sc_mixcontrol &= ~GUSMASK_LINE_IN;
  1521. bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
  1522. }
  1523. if ((newstate == SPKR_OFF) &&
  1524. (sc->sc_mixcontrol & GUSMASK_LINE_IN) == 0) {
  1525. sc->sc_mixcontrol |= GUSMASK_LINE_IN;
  1526. bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
  1527. }
  1528. return 0;
  1529. }
  1530. int
  1531. gus_mic_ctl(void *addr, int newstate)
  1532. {
  1533. struct gus_softc *sc = (struct gus_softc *) addr;
  1534. bus_space_tag_t iot = sc->sc_iot;
  1535. bus_space_handle_t ioh1 = sc->sc_ioh1;
  1536. /* Mic bit is normal: 1 enables, 0 disables */
  1537. if ((newstate == SPKR_ON) &&
  1538. (sc->sc_mixcontrol & GUSMASK_MIC_IN) == 0) {
  1539. sc->sc_mixcontrol |= GUSMASK_MIC_IN;
  1540. bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
  1541. }
  1542. if ((newstate == SPKR_OFF) &&
  1543. (sc->sc_mixcontrol & GUSMASK_MIC_IN)) {
  1544. sc->sc_mixcontrol &= ~GUSMASK_MIC_IN;
  1545. bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
  1546. }
  1547. return 0;
  1548. }
  1549. /*
  1550. * Set the end address of a give voice. Called at splaudio().
  1551. */
  1552. void
  1553. gus_set_endaddr(struct gus_softc *sc, int voice, u_long addr)
  1554. {
  1555. bus_space_tag_t iot = sc->sc_iot;
  1556. bus_space_handle_t ioh2 = sc->sc_ioh2;
  1557. sc->sc_voc[voice].end_addr = addr;
  1558. if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
  1559. addr = convert_to_16bit(addr);
  1560. SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
  1561. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
  1562. SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
  1563. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
  1564. }
  1565. #ifdef GUSPLAYDEBUG
  1566. /*
  1567. * Set current address. Called at splaudio().
  1568. */
  1569. void
  1570. gus_set_curaddr(struct gus_softc *sc, int voice, u_long addr)
  1571. {
  1572. bus_space_tag_t iot = sc->sc_iot;
  1573. bus_space_handle_t ioh2 = sc->sc_ioh2;
  1574. sc->sc_voc[voice].current_addr = addr;
  1575. if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
  1576. addr = convert_to_16bit(addr);
  1577. bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
  1578. SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
  1579. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_HIGH(addr));
  1580. SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
  1581. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, ADDR_LOW(addr));
  1582. }
  1583. /*
  1584. * Get current GUS playback address. Called at splaudio().
  1585. */
  1586. u_long
  1587. gus_get_curaddr(struct gus_softc *sc, int voice)
  1588. {
  1589. bus_space_tag_t iot = sc->sc_iot;
  1590. bus_space_handle_t ioh2 = sc->sc_ioh2;
  1591. u_long addr;
  1592. bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) voice);
  1593. SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH|GUSREG_READ);
  1594. addr = (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) & 0x1fff) << 7;
  1595. SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW|GUSREG_READ);
  1596. addr |= (bus_space_read_2(iot, ioh2, GUS_DATA_LOW) >> 9L) & 0x7f;
  1597. if (sc->sc_voc[voice].voccntl & GUSMASK_DATA_SIZE16)
  1598. addr = (addr & 0xc0000) | ((addr & 0x1ffff) << 1); /* undo 16-bit change */
  1599. DPRINTF(("gus voice %d curaddr %ld end_addr %ld\n",
  1600. voice, addr, sc->sc_voc[voice].end_addr));
  1601. /* XXX sanity check the address? */
  1602. return(addr);
  1603. }
  1604. #endif
  1605. /*
  1606. * Convert an address value to a "16 bit" value - why this is necessary I
  1607. * have NO idea
  1608. */
  1609. u_long
  1610. convert_to_16bit(u_long address)
  1611. {
  1612. u_long old_address;
  1613. old_address = address;
  1614. address >>= 1;
  1615. address &= 0x0001ffffL;
  1616. address |= (old_address & 0x000c0000L);
  1617. return (address);
  1618. }
  1619. /*
  1620. * Write a value into the GUS's DRAM
  1621. */
  1622. void
  1623. guspoke(bus_space_tag_t iot, bus_space_handle_t ioh2, long address,
  1624. unsigned char value)
  1625. {
  1626. /*
  1627. * Select the DRAM address
  1628. */
  1629. SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
  1630. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
  1631. SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
  1632. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
  1633. /*
  1634. * Actually write the data
  1635. */
  1636. bus_space_write_1(iot, ioh2, GUS_DRAM_DATA, value);
  1637. }
  1638. /*
  1639. * Read a value from the GUS's DRAM
  1640. */
  1641. unsigned char
  1642. guspeek(bus_space_tag_t iot, bus_space_handle_t ioh2, u_long address)
  1643. {
  1644. /*
  1645. * Select the DRAM address
  1646. */
  1647. SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_LOW);
  1648. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, (unsigned int) (address & 0xffff));
  1649. SELECT_GUS_REG(iot, ioh2, GUSREG_DRAM_ADDR_HIGH);
  1650. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, (unsigned char) ((address >> 16) & 0xff));
  1651. /*
  1652. * Read in the data from the board
  1653. */
  1654. return (unsigned char) bus_space_read_1(iot, ioh2, GUS_DRAM_DATA);
  1655. }
  1656. /*
  1657. * Reset the Gravis UltraSound card, completely
  1658. */
  1659. void
  1660. gusreset(struct gus_softc *sc, int voices)
  1661. {
  1662. bus_space_tag_t iot = sc->sc_iot;
  1663. bus_space_handle_t ioh1 = sc->sc_ioh1;
  1664. bus_space_handle_t ioh2 = sc->sc_ioh2;
  1665. bus_space_handle_t ioh4 = sc->sc_ioh4;
  1666. int i;
  1667. mtx_enter(&audio_lock);
  1668. /*
  1669. * Reset the GF1 chip
  1670. */
  1671. SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
  1672. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
  1673. delay(500);
  1674. /*
  1675. * Release reset
  1676. */
  1677. SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
  1678. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
  1679. delay(500);
  1680. /*
  1681. * Reset MIDI port as well, if applicable
  1682. */
  1683. if (ioh4 != (bus_space_handle_t)NULL) {
  1684. bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, MIDI_RESET);
  1685. delay(500);
  1686. bus_space_write_1(iot, ioh4, GUS_MIDI_CONTROL, 0x00);
  1687. }
  1688. /*
  1689. * Clear interrupts
  1690. */
  1691. SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
  1692. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
  1693. SELECT_GUS_REG(iot, ioh2, GUSREG_TIMER_CONTROL);
  1694. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
  1695. SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
  1696. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
  1697. gus_set_voices(sc, voices);
  1698. bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
  1699. SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
  1700. bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
  1701. SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
  1702. bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
  1703. SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
  1704. bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
  1705. /*
  1706. * Reset voice specific information
  1707. */
  1708. for(i = 0; i < voices; i++) {
  1709. bus_space_write_1(iot, ioh2, GUS_VOICE_SELECT, (unsigned char) i);
  1710. SELECT_GUS_REG(iot, ioh2, GUSREG_VOICE_CNTL);
  1711. sc->sc_voc[i].voccntl = GUSMASK_VOICE_STOPPED |
  1712. GUSMASK_STOP_VOICE;
  1713. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].voccntl);
  1714. sc->sc_voc[i].volcntl = GUSMASK_VOLUME_STOPPED |
  1715. GUSMASK_STOP_VOLUME;
  1716. SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_CONTROL);
  1717. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, sc->sc_voc[i].volcntl);
  1718. delay(100);
  1719. gus_set_samprate(sc, i, 8000);
  1720. SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_HIGH);
  1721. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
  1722. SELECT_GUS_REG(iot, ioh2, GUSREG_START_ADDR_LOW);
  1723. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
  1724. SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_HIGH);
  1725. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
  1726. SELECT_GUS_REG(iot, ioh2, GUSREG_END_ADDR_LOW);
  1727. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
  1728. SELECT_GUS_REG(iot, ioh2, GUSREG_VOLUME_RATE);
  1729. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x01);
  1730. SELECT_GUS_REG(iot, ioh2, GUSREG_START_VOLUME);
  1731. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x10);
  1732. SELECT_GUS_REG(iot, ioh2, GUSREG_END_VOLUME);
  1733. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0xe0);
  1734. SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_VOLUME);
  1735. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
  1736. SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_HIGH);
  1737. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
  1738. SELECT_GUS_REG(iot, ioh2, GUSREG_CUR_ADDR_LOW);
  1739. bus_space_write_2(iot, ioh2, GUS_DATA_LOW, 0x0000);
  1740. SELECT_GUS_REG(iot, ioh2, GUSREG_PAN_POS);
  1741. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x07);
  1742. }
  1743. /*
  1744. * Clear out any pending IRQs
  1745. */
  1746. bus_space_read_1(iot, ioh1, GUS_IRQ_STATUS);
  1747. SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
  1748. bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
  1749. SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
  1750. bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
  1751. SELECT_GUS_REG(iot, ioh2, GUSREG_IRQ_STATUS);
  1752. bus_space_read_1(iot, ioh2, GUS_DATA_HIGH);
  1753. SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
  1754. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET | GUSMASK_DAC_ENABLE |
  1755. GUSMASK_IRQ_ENABLE);
  1756. mtx_leave(&audio_lock);
  1757. }
  1758. int
  1759. gus_init_cs4231(struct gus_softc *sc)
  1760. {
  1761. bus_space_tag_t iot = sc->sc_iot;
  1762. bus_space_handle_t ioh1 = sc->sc_ioh1;
  1763. int port = sc->sc_iobase;
  1764. u_char ctrl;
  1765. ctrl = (port & 0xf0) >> 4; /* set port address middle nibble */
  1766. /*
  1767. * The codec is a bit weird--swapped dma channels.
  1768. */
  1769. ctrl |= GUS_MAX_CODEC_ENABLE;
  1770. if (sc->sc_drq >= 4)
  1771. ctrl |= GUS_MAX_RECCHAN16;
  1772. if (sc->sc_recdrq >= 4)
  1773. ctrl |= GUS_MAX_PLAYCHAN16;
  1774. bus_space_write_1(iot, ioh1, GUS_MAX_CTRL, ctrl);
  1775. sc->sc_codec.sc_iot = sc->sc_iot;
  1776. sc->sc_codec.sc_iobase = port+GUS_MAX_CODEC_BASE;
  1777. if (ad1848_mapprobe(&sc->sc_codec, sc->sc_codec.sc_iobase) == 0) {
  1778. sc->sc_flags &= ~GUS_CODEC_INSTALLED;
  1779. return (0);
  1780. } else {
  1781. struct ad1848_volume vol = {AUDIO_MAX_GAIN, AUDIO_MAX_GAIN};
  1782. sc->sc_flags |= GUS_CODEC_INSTALLED;
  1783. sc->sc_codec.parent = sc;
  1784. sc->sc_codec.sc_drq = sc->sc_recdrq;
  1785. sc->sc_codec.sc_recdrq = sc->sc_drq;
  1786. gus_hw_if = gusmax_hw_if;
  1787. /* enable line in and mic in the GUS mixer; the codec chip
  1788. will do the real mixing for them. */
  1789. sc->sc_mixcontrol &= ~GUSMASK_LINE_IN; /* 0 enables. */
  1790. sc->sc_mixcontrol |= GUSMASK_MIC_IN; /* 1 enables. */
  1791. bus_space_write_1(iot, ioh1, GUS_MIX_CONTROL, sc->sc_mixcontrol);
  1792. ad1848_attach(&sc->sc_codec);
  1793. /* turn on pre-MUX microphone gain. */
  1794. ad1848_set_mic_gain(&sc->sc_codec, &vol);
  1795. return (1);
  1796. }
  1797. }
  1798. /*
  1799. * Return info about the audio device, for the AUDIO_GETINFO ioctl
  1800. */
  1801. int
  1802. gus_getdev(void *addr, struct audio_device *dev)
  1803. {
  1804. *dev = gus_device;
  1805. return 0;
  1806. }
  1807. /*
  1808. * stubs (XXX)
  1809. */
  1810. int
  1811. gus_set_in_gain(caddr_t addr, u_int gain, u_char balance)
  1812. {
  1813. DPRINTF(("gus_set_in_gain called\n"));
  1814. return 0;
  1815. }
  1816. int
  1817. gus_get_in_gain(caddr_t addr)
  1818. {
  1819. DPRINTF(("gus_get_in_gain called\n"));
  1820. return 0;
  1821. }
  1822. int
  1823. gusmax_dma_input(void *addr, void *buf, int size, void (*callback)(void *),
  1824. void *arg)
  1825. {
  1826. struct ad1848_softc *sc = addr;
  1827. return gus_dma_input(sc->parent, buf, size, callback, arg);
  1828. }
  1829. /*
  1830. * Start sampling the input source into the requested DMA buffer.
  1831. * Called at splaudio(), either from top-half or from interrupt handler.
  1832. */
  1833. int
  1834. gus_dma_input(void *addr, void *buf, int size, void (*callback)(void *),
  1835. void *arg)
  1836. {
  1837. struct gus_softc *sc = addr;
  1838. bus_space_tag_t iot = sc->sc_iot;
  1839. bus_space_handle_t ioh2 = sc->sc_ioh2;
  1840. u_char dmac;
  1841. DMAPRINTF(("gus_dma_input called\n"));
  1842. /*
  1843. * Sample SIZE bytes of data from the card, into buffer at BUF.
  1844. */
  1845. if (sc->sc_precision == 16) {
  1846. return EINVAL; /* XXX */
  1847. }
  1848. /* set DMA modes */
  1849. dmac = GUSMASK_SAMPLE_IRQ|GUSMASK_SAMPLE_START;
  1850. if (sc->sc_recdrq >= 4)
  1851. dmac |= GUSMASK_SAMPLE_DATA16;
  1852. if (sc->sc_encoding == AUDIO_ENCODING_ULAW ||
  1853. sc->sc_encoding == AUDIO_ENCODING_ALAW ||
  1854. sc->sc_encoding == AUDIO_ENCODING_ULINEAR_LE ||
  1855. sc->sc_encoding == AUDIO_ENCODING_ULINEAR_BE)
  1856. dmac |= GUSMASK_SAMPLE_INVBIT;
  1857. if (sc->sc_channels == 2)
  1858. dmac |= GUSMASK_SAMPLE_STEREO;
  1859. isa_dmastart(sc->sc_dev.dv_parent, sc->sc_recdrq, buf, size,
  1860. NULL, DMAMODE_READ, BUS_DMA_NOWAIT);
  1861. DMAPRINTF(("gus_dma_input isadma_started\n"));
  1862. sc->sc_flags |= GUS_DMAIN_ACTIVE;
  1863. sc->sc_dmainintr = callback;
  1864. sc->sc_inarg = arg;
  1865. sc->sc_dmaincnt = size;
  1866. sc->sc_dmainaddr = buf;
  1867. SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
  1868. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, dmac); /* Go! */
  1869. DMAPRINTF(("gus_dma_input returning\n"));
  1870. return 0;
  1871. }
  1872. int
  1873. gus_dmain_intr(struct gus_softc *sc)
  1874. {
  1875. void (*callback)(void *);
  1876. void *arg;
  1877. DMAPRINTF(("gus_dmain_intr called\n"));
  1878. if (sc->sc_dmainintr) {
  1879. isa_dmadone(sc->sc_dev.dv_parent, sc->sc_recdrq);
  1880. callback = sc->sc_dmainintr;
  1881. arg = sc->sc_inarg;
  1882. sc->sc_dmainaddr = 0;
  1883. sc->sc_dmaincnt = 0;
  1884. sc->sc_dmainintr = 0;
  1885. sc->sc_inarg = 0;
  1886. sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
  1887. DMAPRINTF(("calling dmain_intr callback %p(%p)\n", callback, arg));
  1888. (*callback)(arg);
  1889. return 1;
  1890. } else {
  1891. DMAPRINTF(("gus_dmain_intr false?\n"));
  1892. return 0; /* XXX ??? */
  1893. }
  1894. }
  1895. int
  1896. gusmax_halt_out_dma(void *addr)
  1897. {
  1898. struct ad1848_softc *sc = addr;
  1899. return gus_halt_out_dma(sc->parent);
  1900. }
  1901. int
  1902. gusmax_halt_in_dma(void *addr)
  1903. {
  1904. struct ad1848_softc *sc = addr;
  1905. return gus_halt_in_dma(sc->parent);
  1906. }
  1907. /*
  1908. * Stop any DMA output. Called at splaudio().
  1909. */
  1910. int
  1911. gus_halt_out_dma(void *addr)
  1912. {
  1913. struct gus_softc *sc = addr;
  1914. bus_space_tag_t iot = sc->sc_iot;
  1915. bus_space_handle_t ioh2 = sc->sc_ioh2;
  1916. mtx_enter(&audio_lock);
  1917. DMAPRINTF(("gus_halt_out_dma called\n"));
  1918. /*
  1919. * Make sure the GUS _isn't_ setup for DMA
  1920. */
  1921. SELECT_GUS_REG(iot, ioh2, GUSREG_DMA_CONTROL);
  1922. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0);
  1923. timeout_del(&sc->sc_dma_tmo);
  1924. isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_drq);
  1925. sc->sc_flags &= ~(GUS_DMAOUT_ACTIVE|GUS_LOCKED);
  1926. sc->sc_dmaoutintr = 0;
  1927. sc->sc_outarg = 0;
  1928. sc->sc_dmaoutaddr = 0;
  1929. sc->sc_dmaoutcnt = 0;
  1930. sc->sc_dmabuf = 0;
  1931. sc->sc_bufcnt = 0;
  1932. sc->sc_playbuf = -1;
  1933. /* also stop playing */
  1934. gus_stop_voice(sc, GUS_VOICE_LEFT, 1);
  1935. gus_stop_voice(sc, GUS_VOICE_RIGHT, 0);
  1936. mtx_leave(&audio_lock);
  1937. return 0;
  1938. }
  1939. /*
  1940. * Stop any DMA output. Called at splaudio().
  1941. */
  1942. int
  1943. gus_halt_in_dma(void *addr)
  1944. {
  1945. struct gus_softc *sc = addr;
  1946. bus_space_tag_t iot = sc->sc_iot;
  1947. bus_space_handle_t ioh2 = sc->sc_ioh2;
  1948. mtx_enter(&audio_lock);
  1949. DMAPRINTF(("gus_halt_in_dma called\n"));
  1950. /*
  1951. * Make sure the GUS _isn't_ setup for DMA
  1952. */
  1953. SELECT_GUS_REG(iot, ioh2, GUSREG_SAMPLE_CONTROL);
  1954. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH,
  1955. bus_space_read_1(iot, ioh2, GUS_DATA_HIGH) & ~(GUSMASK_SAMPLE_START|GUSMASK_SAMPLE_IRQ));
  1956. isa_dmaabort(sc->sc_dev.dv_parent, sc->sc_recdrq);
  1957. sc->sc_flags &= ~GUS_DMAIN_ACTIVE;
  1958. sc->sc_dmainintr = 0;
  1959. sc->sc_inarg = 0;
  1960. sc->sc_dmainaddr = 0;
  1961. sc->sc_dmaincnt = 0;
  1962. mtx_leave(&audio_lock);
  1963. return 0;
  1964. }
  1965. ad1848_devmap_t gusmapping[] = {
  1966. {GUSMAX_DAC_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL},
  1967. {GUSMAX_LINE_IN_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL},
  1968. {GUSMAX_MONO_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL},
  1969. {GUSMAX_CD_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL},
  1970. {GUSMAX_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL},
  1971. {GUSMAX_OUT_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL},
  1972. {GUSMAX_DAC_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL},
  1973. {GUSMAX_LINE_IN_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL},
  1974. {GUSMAX_MONO_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL},
  1975. {GUSMAX_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL},
  1976. {GUSMAX_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL},
  1977. {GUSMAX_REC_LVL, AD1848_KIND_RECORDGAIN, -1},
  1978. {GUSMAX_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1}
  1979. };
  1980. int nummap = sizeof(gusmapping) / sizeof(gusmapping[0]);
  1981. int
  1982. gusmax_mixer_get_port(void *addr, mixer_ctrl_t *cp)
  1983. {
  1984. struct ad1848_softc *ac = addr;
  1985. struct gus_softc *sc = ac->parent;
  1986. struct ad1848_volume vol;
  1987. int error = ad1848_mixer_get_port(ac, gusmapping, nummap, cp);
  1988. if (error != ENXIO)
  1989. return (error);
  1990. error = EINVAL;
  1991. switch (cp->dev) {
  1992. case GUSMAX_SPEAKER_LVL: /* fake speaker for mute naming */
  1993. if (cp->type == AUDIO_MIXER_VALUE) {
  1994. if (sc->sc_mixcontrol & GUSMASK_LINE_OUT)
  1995. vol.left = vol.right = AUDIO_MAX_GAIN;
  1996. else
  1997. vol.left = vol.right = AUDIO_MIN_GAIN;
  1998. error = 0;
  1999. ad1848_from_vol(cp, &vol);
  2000. }
  2001. break;
  2002. case GUSMAX_SPEAKER_MUTE:
  2003. if (cp->type == AUDIO_MIXER_ENUM) {
  2004. cp->un.ord = sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
  2005. error = 0;
  2006. }
  2007. break;
  2008. default:
  2009. error = ENXIO;
  2010. break;
  2011. }
  2012. return(error);
  2013. }
  2014. int
  2015. gus_mixer_get_port(void *addr, mixer_ctrl_t *cp)
  2016. {
  2017. struct gus_softc *sc = addr;
  2018. struct ics2101_softc *ic = &sc->sc_mixer;
  2019. struct ad1848_volume vol;
  2020. int error = EINVAL;
  2021. DPRINTF(("gus_mixer_get_port: dev=%d type=%d\n", cp->dev, cp->type));
  2022. if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
  2023. return ENXIO;
  2024. switch (cp->dev) {
  2025. case GUSICS_MIC_IN_MUTE: /* Microphone */
  2026. if (cp->type == AUDIO_MIXER_ENUM) {
  2027. if (HAS_MIXER(sc))
  2028. cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
  2029. else
  2030. cp->un.ord =
  2031. sc->sc_mixcontrol & GUSMASK_MIC_IN ? 0 : 1;
  2032. error = 0;
  2033. }
  2034. break;
  2035. case GUSICS_LINE_IN_MUTE:
  2036. if (cp->type == AUDIO_MIXER_ENUM) {
  2037. if (HAS_MIXER(sc))
  2038. cp->un.ord = ic->sc_mute[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
  2039. else
  2040. cp->un.ord =
  2041. sc->sc_mixcontrol & GUSMASK_LINE_IN ? 1 : 0;
  2042. error = 0;
  2043. }
  2044. break;
  2045. case GUSICS_MASTER_MUTE:
  2046. if (cp->type == AUDIO_MIXER_ENUM) {
  2047. if (HAS_MIXER(sc))
  2048. cp->un.ord = ic->sc_mute[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
  2049. else
  2050. cp->un.ord =
  2051. sc->sc_mixcontrol & GUSMASK_LINE_OUT ? 1 : 0;
  2052. error = 0;
  2053. }
  2054. break;
  2055. case GUSICS_DAC_MUTE:
  2056. if (cp->type == AUDIO_MIXER_ENUM) {
  2057. cp->un.ord = ic->sc_mute[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
  2058. error = 0;
  2059. }
  2060. break;
  2061. case GUSICS_CD_MUTE:
  2062. if (cp->type == AUDIO_MIXER_ENUM) {
  2063. cp->un.ord = ic->sc_mute[GUSMIX_CHAN_CD][ICSMIX_LEFT];
  2064. error = 0;
  2065. }
  2066. break;
  2067. case GUSICS_MASTER_LVL:
  2068. if (cp->type == AUDIO_MIXER_VALUE) {
  2069. vol.left = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_LEFT];
  2070. vol.right = ic->sc_setting[GUSMIX_CHAN_MASTER][ICSMIX_RIGHT];
  2071. if (ad1848_from_vol(cp, &vol))
  2072. error = 0;
  2073. }
  2074. break;
  2075. case GUSICS_MIC_IN_LVL: /* Microphone */
  2076. if (cp->type == AUDIO_MIXER_VALUE) {
  2077. vol.left = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_LEFT];
  2078. vol.right = ic->sc_setting[GUSMIX_CHAN_MIC][ICSMIX_RIGHT];
  2079. if (ad1848_from_vol(cp, &vol))
  2080. error = 0;
  2081. }
  2082. break;
  2083. case GUSICS_LINE_IN_LVL: /* line in */
  2084. if (cp->type == AUDIO_MIXER_VALUE) {
  2085. vol.left = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_LEFT];
  2086. vol.right = ic->sc_setting[GUSMIX_CHAN_LINE][ICSMIX_RIGHT];
  2087. if (ad1848_from_vol(cp, &vol))
  2088. error = 0;
  2089. }
  2090. break;
  2091. case GUSICS_CD_LVL:
  2092. if (cp->type == AUDIO_MIXER_VALUE) {
  2093. vol.left = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_LEFT];
  2094. vol.right = ic->sc_setting[GUSMIX_CHAN_CD][ICSMIX_RIGHT];
  2095. if (ad1848_from_vol(cp, &vol))
  2096. error = 0;
  2097. }
  2098. break;
  2099. case GUSICS_DAC_LVL: /* dac out */
  2100. if (cp->type == AUDIO_MIXER_VALUE) {
  2101. vol.left = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_LEFT];
  2102. vol.right = ic->sc_setting[GUSMIX_CHAN_DAC][ICSMIX_RIGHT];
  2103. if (ad1848_from_vol(cp, &vol))
  2104. error = 0;
  2105. }
  2106. break;
  2107. case GUSICS_RECORD_SOURCE:
  2108. if (cp->type == AUDIO_MIXER_ENUM) {
  2109. /* Can't set anything else useful, sigh. */
  2110. cp->un.ord = 0;
  2111. }
  2112. break;
  2113. default:
  2114. return ENXIO;
  2115. /*NOTREACHED*/
  2116. }
  2117. return error;
  2118. }
  2119. void
  2120. gusics_master_mute(struct ics2101_softc *ic, int mute)
  2121. {
  2122. ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_LEFT, mute);
  2123. ics2101_mix_mute(ic, GUSMIX_CHAN_MASTER, ICSMIX_RIGHT, mute);
  2124. }
  2125. void
  2126. gusics_mic_mute(struct ics2101_softc *ic, int mute)
  2127. {
  2128. ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_LEFT, mute);
  2129. ics2101_mix_mute(ic, GUSMIX_CHAN_MIC, ICSMIX_RIGHT, mute);
  2130. }
  2131. void
  2132. gusics_linein_mute(struct ics2101_softc *ic, int mute)
  2133. {
  2134. ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_LEFT, mute);
  2135. ics2101_mix_mute(ic, GUSMIX_CHAN_LINE, ICSMIX_RIGHT, mute);
  2136. }
  2137. void
  2138. gusics_cd_mute(struct ics2101_softc *ic, int mute)
  2139. {
  2140. ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_LEFT, mute);
  2141. ics2101_mix_mute(ic, GUSMIX_CHAN_CD, ICSMIX_RIGHT, mute);
  2142. }
  2143. void
  2144. gusics_dac_mute(struct ics2101_softc *ic, int mute)
  2145. {
  2146. ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_LEFT, mute);
  2147. ics2101_mix_mute(ic, GUSMIX_CHAN_DAC, ICSMIX_RIGHT, mute);
  2148. }
  2149. int
  2150. gusmax_mixer_set_port(void *addr, mixer_ctrl_t *cp)
  2151. {
  2152. struct ad1848_softc *ac = addr;
  2153. struct gus_softc *sc = ac->parent;
  2154. struct ad1848_volume vol;
  2155. int error = ad1848_mixer_set_port(ac, gusmapping, nummap, cp);
  2156. if (error != ENXIO)
  2157. return (error);
  2158. DPRINTF(("gusmax_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
  2159. switch (cp->dev) {
  2160. case GUSMAX_SPEAKER_LVL:
  2161. if (cp->type == AUDIO_MIXER_VALUE &&
  2162. cp->un.value.num_channels == 1) {
  2163. if (ad1848_to_vol(cp, &vol)) {
  2164. gus_speaker_ctl(sc, vol.left > AUDIO_MIN_GAIN ?
  2165. SPKR_ON : SPKR_OFF);
  2166. error = 0;
  2167. }
  2168. }
  2169. break;
  2170. case GUSMAX_SPEAKER_MUTE:
  2171. if (cp->type == AUDIO_MIXER_ENUM) {
  2172. gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
  2173. error = 0;
  2174. }
  2175. break;
  2176. default:
  2177. return ENXIO;
  2178. /*NOTREACHED*/
  2179. }
  2180. return error;
  2181. }
  2182. int
  2183. gus_mixer_set_port(void *addr, mixer_ctrl_t *cp)
  2184. {
  2185. struct gus_softc *sc = addr;
  2186. struct ics2101_softc *ic = &sc->sc_mixer;
  2187. struct ad1848_volume vol;
  2188. int error = EINVAL;
  2189. DPRINTF(("gus_mixer_set_port: dev=%d type=%d\n", cp->dev, cp->type));
  2190. if (!HAS_MIXER(sc) && cp->dev > GUSICS_MASTER_MUTE)
  2191. return ENXIO;
  2192. switch (cp->dev) {
  2193. case GUSICS_MIC_IN_MUTE: /* Microphone */
  2194. if (cp->type == AUDIO_MIXER_ENUM) {
  2195. DPRINTF(("mic mute %d\n", cp->un.ord));
  2196. if (HAS_MIXER(sc)) {
  2197. gusics_mic_mute(ic, cp->un.ord);
  2198. }
  2199. gus_mic_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
  2200. error = 0;
  2201. }
  2202. break;
  2203. case GUSICS_LINE_IN_MUTE:
  2204. if (cp->type == AUDIO_MIXER_ENUM) {
  2205. DPRINTF(("linein mute %d\n", cp->un.ord));
  2206. if (HAS_MIXER(sc)) {
  2207. gusics_linein_mute(ic, cp->un.ord);
  2208. }
  2209. gus_linein_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
  2210. error = 0;
  2211. }
  2212. break;
  2213. case GUSICS_MASTER_MUTE:
  2214. if (cp->type == AUDIO_MIXER_ENUM) {
  2215. DPRINTF(("master mute %d\n", cp->un.ord));
  2216. if (HAS_MIXER(sc)) {
  2217. gusics_master_mute(ic, cp->un.ord);
  2218. }
  2219. gus_speaker_ctl(sc, cp->un.ord ? SPKR_OFF : SPKR_ON);
  2220. error = 0;
  2221. }
  2222. break;
  2223. case GUSICS_DAC_MUTE:
  2224. if (cp->type == AUDIO_MIXER_ENUM) {
  2225. gusics_dac_mute(ic, cp->un.ord);
  2226. error = 0;
  2227. }
  2228. break;
  2229. case GUSICS_CD_MUTE:
  2230. if (cp->type == AUDIO_MIXER_ENUM) {
  2231. gusics_cd_mute(ic, cp->un.ord);
  2232. error = 0;
  2233. }
  2234. break;
  2235. case GUSICS_MASTER_LVL:
  2236. if (cp->type == AUDIO_MIXER_VALUE) {
  2237. if (ad1848_to_vol(cp, &vol)) {
  2238. ics2101_mix_attenuate(ic,
  2239. GUSMIX_CHAN_MASTER,
  2240. ICSMIX_LEFT,
  2241. vol.left);
  2242. ics2101_mix_attenuate(ic,
  2243. GUSMIX_CHAN_MASTER,
  2244. ICSMIX_RIGHT,
  2245. vol.right);
  2246. error = 0;
  2247. }
  2248. }
  2249. break;
  2250. case GUSICS_MIC_IN_LVL: /* Microphone */
  2251. if (cp->type == AUDIO_MIXER_VALUE) {
  2252. if (ad1848_to_vol(cp, &vol)) {
  2253. ics2101_mix_attenuate(ic,
  2254. GUSMIX_CHAN_MIC,
  2255. ICSMIX_LEFT,
  2256. vol.left);
  2257. ics2101_mix_attenuate(ic,
  2258. GUSMIX_CHAN_MIC,
  2259. ICSMIX_RIGHT,
  2260. vol.right);
  2261. error = 0;
  2262. }
  2263. }
  2264. break;
  2265. case GUSICS_LINE_IN_LVL: /* line in */
  2266. if (cp->type == AUDIO_MIXER_VALUE) {
  2267. if (ad1848_to_vol(cp, &vol)) {
  2268. ics2101_mix_attenuate(ic,
  2269. GUSMIX_CHAN_LINE,
  2270. ICSMIX_LEFT,
  2271. vol.left);
  2272. ics2101_mix_attenuate(ic,
  2273. GUSMIX_CHAN_LINE,
  2274. ICSMIX_RIGHT,
  2275. vol.right);
  2276. error = 0;
  2277. }
  2278. }
  2279. break;
  2280. case GUSICS_CD_LVL:
  2281. if (cp->type == AUDIO_MIXER_VALUE) {
  2282. if (ad1848_to_vol(cp, &vol)) {
  2283. ics2101_mix_attenuate(ic,
  2284. GUSMIX_CHAN_CD,
  2285. ICSMIX_LEFT,
  2286. vol.left);
  2287. ics2101_mix_attenuate(ic,
  2288. GUSMIX_CHAN_CD,
  2289. ICSMIX_RIGHT,
  2290. vol.right);
  2291. error = 0;
  2292. }
  2293. }
  2294. break;
  2295. case GUSICS_DAC_LVL: /* dac out */
  2296. if (cp->type == AUDIO_MIXER_VALUE) {
  2297. if (ad1848_to_vol(cp, &vol)) {
  2298. ics2101_mix_attenuate(ic,
  2299. GUSMIX_CHAN_DAC,
  2300. ICSMIX_LEFT,
  2301. vol.left);
  2302. ics2101_mix_attenuate(ic,
  2303. GUSMIX_CHAN_DAC,
  2304. ICSMIX_RIGHT,
  2305. vol.right);
  2306. error = 0;
  2307. }
  2308. }
  2309. break;
  2310. case GUSICS_RECORD_SOURCE:
  2311. if (cp->type == AUDIO_MIXER_ENUM && cp->un.ord == 0) {
  2312. /* Can't set anything else useful, sigh. */
  2313. error = 0;
  2314. }
  2315. break;
  2316. default:
  2317. return ENXIO;
  2318. /*NOTREACHED*/
  2319. }
  2320. return error;
  2321. }
  2322. int
  2323. gus_get_props(void *addr)
  2324. {
  2325. struct gus_softc *sc = addr;
  2326. return AUDIO_PROP_MMAP |
  2327. (sc->sc_recdrq == sc->sc_drq ? 0 : AUDIO_PROP_FULLDUPLEX);
  2328. }
  2329. int
  2330. gusmax_get_props(void *addr)
  2331. {
  2332. struct ad1848_softc *ac = addr;
  2333. return gus_get_props(ac->parent);
  2334. }
  2335. int
  2336. gusmax_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip)
  2337. {
  2338. DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
  2339. switch(dip->index) {
  2340. #if 0
  2341. case GUSMAX_MIC_IN_LVL: /* Microphone */
  2342. dip->type = AUDIO_MIXER_VALUE;
  2343. dip->mixer_class = GUSMAX_INPUT_CLASS;
  2344. dip->prev = AUDIO_MIXER_LAST;
  2345. dip->next = GUSMAX_MIC_IN_MUTE;
  2346. strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name);
  2347. dip->un.v.num_channels = 2;
  2348. strlcpy(dip->un.v.units.name, AudioNvolume,
  2349. sizeof dip->un.v.units.name);
  2350. break;
  2351. #endif
  2352. case GUSMAX_MONO_LVL: /* mono/microphone mixer */
  2353. dip->type = AUDIO_MIXER_VALUE;
  2354. dip->mixer_class = GUSMAX_INPUT_CLASS;
  2355. dip->prev = AUDIO_MIXER_LAST;
  2356. dip->next = GUSMAX_MONO_MUTE;
  2357. strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name);
  2358. dip->un.v.num_channels = 1;
  2359. strlcpy(dip->un.v.units.name, AudioNvolume,
  2360. sizeof dip->un.v.units.name);
  2361. break;
  2362. case GUSMAX_DAC_LVL: /* dacout */
  2363. dip->type = AUDIO_MIXER_VALUE;
  2364. dip->mixer_class = GUSMAX_INPUT_CLASS;
  2365. dip->prev = AUDIO_MIXER_LAST;
  2366. dip->next = GUSMAX_DAC_MUTE;
  2367. strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
  2368. dip->un.v.num_channels = 2;
  2369. strlcpy(dip->un.v.units.name, AudioNvolume,
  2370. sizeof dip->un.v.units.name);
  2371. break;
  2372. case GUSMAX_LINE_IN_LVL: /* line */
  2373. dip->type = AUDIO_MIXER_VALUE;
  2374. dip->mixer_class = GUSMAX_INPUT_CLASS;
  2375. dip->prev = AUDIO_MIXER_LAST;
  2376. dip->next = GUSMAX_LINE_IN_MUTE;
  2377. strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
  2378. dip->un.v.num_channels = 2;
  2379. strlcpy(dip->un.v.units.name, AudioNvolume,
  2380. sizeof dip->un.v.units.name);
  2381. break;
  2382. case GUSMAX_CD_LVL: /* cd */
  2383. dip->type = AUDIO_MIXER_VALUE;
  2384. dip->mixer_class = GUSMAX_INPUT_CLASS;
  2385. dip->prev = AUDIO_MIXER_LAST;
  2386. dip->next = GUSMAX_CD_MUTE;
  2387. strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
  2388. dip->un.v.num_channels = 2;
  2389. strlcpy(dip->un.v.units.name, AudioNvolume,
  2390. sizeof dip->un.v.units.name);
  2391. break;
  2392. case GUSMAX_MONITOR_LVL: /* monitor level */
  2393. dip->type = AUDIO_MIXER_VALUE;
  2394. dip->mixer_class = GUSMAX_MONITOR_CLASS;
  2395. dip->next = GUSMAX_MONITOR_MUTE;
  2396. dip->prev = AUDIO_MIXER_LAST;
  2397. strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name);
  2398. dip->un.v.num_channels = 1;
  2399. strlcpy(dip->un.v.units.name, AudioNvolume,
  2400. sizeof dip->un.v.units.name);
  2401. break;
  2402. case GUSMAX_OUT_LVL: /* cs4231 output volume: not useful? */
  2403. dip->type = AUDIO_MIXER_VALUE;
  2404. dip->mixer_class = GUSMAX_MONITOR_CLASS;
  2405. dip->prev = dip->next = AUDIO_MIXER_LAST;
  2406. strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name);
  2407. dip->un.v.num_channels = 2;
  2408. strlcpy(dip->un.v.units.name, AudioNvolume,
  2409. sizeof dip->un.v.units.name);
  2410. break;
  2411. case GUSMAX_SPEAKER_LVL: /* fake speaker volume */
  2412. dip->type = AUDIO_MIXER_VALUE;
  2413. dip->mixer_class = GUSMAX_MONITOR_CLASS;
  2414. dip->prev = AUDIO_MIXER_LAST;
  2415. dip->next = GUSMAX_SPEAKER_MUTE;
  2416. strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
  2417. dip->un.v.num_channels = 2;
  2418. strlcpy(dip->un.v.units.name, AudioNvolume,
  2419. sizeof dip->un.v.units.name);
  2420. break;
  2421. case GUSMAX_LINE_IN_MUTE:
  2422. dip->mixer_class = GUSMAX_INPUT_CLASS;
  2423. dip->type = AUDIO_MIXER_ENUM;
  2424. dip->prev = GUSMAX_LINE_IN_LVL;
  2425. dip->next = AUDIO_MIXER_LAST;
  2426. goto mute;
  2427. case GUSMAX_DAC_MUTE:
  2428. dip->mixer_class = GUSMAX_INPUT_CLASS;
  2429. dip->type = AUDIO_MIXER_ENUM;
  2430. dip->prev = GUSMAX_DAC_LVL;
  2431. dip->next = AUDIO_MIXER_LAST;
  2432. goto mute;
  2433. case GUSMAX_CD_MUTE:
  2434. dip->mixer_class = GUSMAX_INPUT_CLASS;
  2435. dip->type = AUDIO_MIXER_ENUM;
  2436. dip->prev = GUSMAX_CD_LVL;
  2437. dip->next = AUDIO_MIXER_LAST;
  2438. goto mute;
  2439. case GUSMAX_MONO_MUTE:
  2440. dip->mixer_class = GUSMAX_INPUT_CLASS;
  2441. dip->type = AUDIO_MIXER_ENUM;
  2442. dip->prev = GUSMAX_MONO_LVL;
  2443. dip->next = AUDIO_MIXER_LAST;
  2444. goto mute;
  2445. case GUSMAX_MONITOR_MUTE:
  2446. dip->mixer_class = GUSMAX_OUTPUT_CLASS;
  2447. dip->type = AUDIO_MIXER_ENUM;
  2448. dip->prev = GUSMAX_MONITOR_LVL;
  2449. dip->next = AUDIO_MIXER_LAST;
  2450. goto mute;
  2451. case GUSMAX_SPEAKER_MUTE:
  2452. dip->mixer_class = GUSMAX_OUTPUT_CLASS;
  2453. dip->type = AUDIO_MIXER_ENUM;
  2454. dip->prev = GUSMAX_SPEAKER_LVL;
  2455. dip->next = AUDIO_MIXER_LAST;
  2456. mute:
  2457. strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
  2458. dip->un.e.num_mem = 2;
  2459. strlcpy(dip->un.e.member[0].label.name, AudioNoff,
  2460. sizeof dip->un.e.member[0].label.name);
  2461. dip->un.e.member[0].ord = 0;
  2462. strlcpy(dip->un.e.member[1].label.name, AudioNon,
  2463. sizeof dip->un.e.member[1].label.name);
  2464. dip->un.e.member[1].ord = 1;
  2465. break;
  2466. case GUSMAX_REC_LVL: /* record level */
  2467. dip->type = AUDIO_MIXER_VALUE;
  2468. dip->mixer_class = GUSMAX_RECORD_CLASS;
  2469. dip->prev = AUDIO_MIXER_LAST;
  2470. dip->next = GUSMAX_RECORD_SOURCE;
  2471. strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name);
  2472. dip->un.v.num_channels = 2;
  2473. strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name);
  2474. break;
  2475. case GUSMAX_RECORD_SOURCE:
  2476. dip->mixer_class = GUSMAX_RECORD_CLASS;
  2477. dip->type = AUDIO_MIXER_ENUM;
  2478. dip->prev = GUSMAX_REC_LVL;
  2479. dip->next = AUDIO_MIXER_LAST;
  2480. strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
  2481. dip->un.e.num_mem = 4;
  2482. strlcpy(dip->un.e.member[0].label.name, AudioNoutput,
  2483. sizeof dip->un.e.member[0].label.name);
  2484. dip->un.e.member[0].ord = DAC_IN_PORT;
  2485. strlcpy(dip->un.e.member[1].label.name, AudioNmicrophone,
  2486. sizeof dip->un.e.member[1].label.name);
  2487. dip->un.e.member[1].ord = MIC_IN_PORT;
  2488. strlcpy(dip->un.e.member[2].label.name, AudioNdac,
  2489. sizeof dip->un.e.member[2].label.name);
  2490. dip->un.e.member[2].ord = AUX1_IN_PORT;
  2491. strlcpy(dip->un.e.member[3].label.name, AudioNline,
  2492. sizeof dip->un.e.member[3].label.name);
  2493. dip->un.e.member[3].ord = LINE_IN_PORT;
  2494. break;
  2495. case GUSMAX_INPUT_CLASS: /* input class descriptor */
  2496. dip->type = AUDIO_MIXER_CLASS;
  2497. dip->mixer_class = GUSMAX_INPUT_CLASS;
  2498. dip->next = dip->prev = AUDIO_MIXER_LAST;
  2499. strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
  2500. break;
  2501. case GUSMAX_OUTPUT_CLASS: /* output class descriptor */
  2502. dip->type = AUDIO_MIXER_CLASS;
  2503. dip->mixer_class = GUSMAX_OUTPUT_CLASS;
  2504. dip->next = dip->prev = AUDIO_MIXER_LAST;
  2505. strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
  2506. break;
  2507. case GUSMAX_MONITOR_CLASS: /* monitor class descriptor */
  2508. dip->type = AUDIO_MIXER_CLASS;
  2509. dip->mixer_class = GUSMAX_MONITOR_CLASS;
  2510. dip->next = dip->prev = AUDIO_MIXER_LAST;
  2511. strlcpy(dip->label.name, AudioCmonitor, sizeof dip->label.name);
  2512. break;
  2513. case GUSMAX_RECORD_CLASS: /* record source class */
  2514. dip->type = AUDIO_MIXER_CLASS;
  2515. dip->mixer_class = GUSMAX_RECORD_CLASS;
  2516. dip->next = dip->prev = AUDIO_MIXER_LAST;
  2517. strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
  2518. break;
  2519. default:
  2520. return ENXIO;
  2521. /*NOTREACHED*/
  2522. }
  2523. DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
  2524. return 0;
  2525. }
  2526. int
  2527. gus_mixer_query_devinfo(void *addr, mixer_devinfo_t *dip)
  2528. {
  2529. struct gus_softc *sc = addr;
  2530. DPRINTF(("gusmax_query_devinfo: index=%d\n", dip->index));
  2531. if (!HAS_MIXER(sc) && dip->index > GUSICS_MASTER_MUTE)
  2532. return ENXIO;
  2533. switch(dip->index) {
  2534. case GUSICS_MIC_IN_LVL: /* Microphone */
  2535. dip->type = AUDIO_MIXER_VALUE;
  2536. dip->mixer_class = GUSICS_INPUT_CLASS;
  2537. dip->prev = AUDIO_MIXER_LAST;
  2538. dip->next = GUSICS_MIC_IN_MUTE;
  2539. strlcpy(dip->label.name, AudioNmicrophone,
  2540. sizeof dip->label.name);
  2541. dip->un.v.num_channels = 2;
  2542. strlcpy(dip->un.v.units.name, AudioNvolume,
  2543. sizeof dip->un.v.units.name);
  2544. break;
  2545. case GUSICS_LINE_IN_LVL: /* line */
  2546. dip->type = AUDIO_MIXER_VALUE;
  2547. dip->mixer_class = GUSICS_INPUT_CLASS;
  2548. dip->prev = AUDIO_MIXER_LAST;
  2549. dip->next = GUSICS_LINE_IN_MUTE;
  2550. strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
  2551. dip->un.v.num_channels = 2;
  2552. strlcpy(dip->un.v.units.name, AudioNvolume,
  2553. sizeof dip->un.v.units.name);
  2554. break;
  2555. case GUSICS_CD_LVL: /* cd */
  2556. dip->type = AUDIO_MIXER_VALUE;
  2557. dip->mixer_class = GUSICS_INPUT_CLASS;
  2558. dip->prev = AUDIO_MIXER_LAST;
  2559. dip->next = GUSICS_CD_MUTE;
  2560. strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
  2561. dip->un.v.num_channels = 2;
  2562. strlcpy(dip->un.v.units.name, AudioNvolume,
  2563. sizeof dip->un.v.units.name);
  2564. break;
  2565. case GUSICS_DAC_LVL: /* dacout */
  2566. dip->type = AUDIO_MIXER_VALUE;
  2567. dip->mixer_class = GUSICS_INPUT_CLASS;
  2568. dip->prev = AUDIO_MIXER_LAST;
  2569. dip->next = GUSICS_DAC_MUTE;
  2570. strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
  2571. dip->un.v.num_channels = 2;
  2572. strlcpy(dip->un.v.units.name, AudioNvolume,
  2573. sizeof dip->un.v.units.name);
  2574. break;
  2575. case GUSICS_MASTER_LVL: /* master output */
  2576. dip->type = AUDIO_MIXER_VALUE;
  2577. dip->mixer_class = GUSICS_OUTPUT_CLASS;
  2578. dip->prev = AUDIO_MIXER_LAST;
  2579. dip->next = GUSICS_MASTER_MUTE;
  2580. strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
  2581. dip->un.v.num_channels = 2;
  2582. strlcpy(dip->un.v.units.name, AudioNvolume,
  2583. sizeof dip->un.v.units.name);
  2584. break;
  2585. case GUSICS_LINE_IN_MUTE:
  2586. dip->mixer_class = GUSICS_INPUT_CLASS;
  2587. dip->type = AUDIO_MIXER_ENUM;
  2588. dip->prev = GUSICS_LINE_IN_LVL;
  2589. dip->next = AUDIO_MIXER_LAST;
  2590. goto mute;
  2591. case GUSICS_DAC_MUTE:
  2592. dip->mixer_class = GUSICS_INPUT_CLASS;
  2593. dip->type = AUDIO_MIXER_ENUM;
  2594. dip->prev = GUSICS_DAC_LVL;
  2595. dip->next = AUDIO_MIXER_LAST;
  2596. goto mute;
  2597. case GUSICS_CD_MUTE:
  2598. dip->mixer_class = GUSICS_INPUT_CLASS;
  2599. dip->type = AUDIO_MIXER_ENUM;
  2600. dip->prev = GUSICS_CD_LVL;
  2601. dip->next = AUDIO_MIXER_LAST;
  2602. goto mute;
  2603. case GUSICS_MIC_IN_MUTE:
  2604. dip->mixer_class = GUSICS_INPUT_CLASS;
  2605. dip->type = AUDIO_MIXER_ENUM;
  2606. dip->prev = GUSICS_MIC_IN_LVL;
  2607. dip->next = AUDIO_MIXER_LAST;
  2608. goto mute;
  2609. case GUSICS_MASTER_MUTE:
  2610. dip->mixer_class = GUSICS_OUTPUT_CLASS;
  2611. dip->type = AUDIO_MIXER_ENUM;
  2612. dip->prev = GUSICS_MASTER_LVL;
  2613. dip->next = AUDIO_MIXER_LAST;
  2614. mute:
  2615. strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
  2616. dip->un.e.num_mem = 2;
  2617. strlcpy(dip->un.e.member[0].label.name, AudioNoff,
  2618. sizeof dip->un.e.member[0].label.name);
  2619. dip->un.e.member[0].ord = 0;
  2620. strlcpy(dip->un.e.member[1].label.name, AudioNon,
  2621. sizeof dip->un.e.member[1].label.name);
  2622. dip->un.e.member[1].ord = 1;
  2623. break;
  2624. case GUSICS_RECORD_SOURCE:
  2625. dip->mixer_class = GUSICS_RECORD_CLASS;
  2626. dip->type = AUDIO_MIXER_ENUM;
  2627. dip->prev = dip->next = AUDIO_MIXER_LAST;
  2628. strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
  2629. dip->un.e.num_mem = 1;
  2630. strlcpy(dip->un.e.member[0].label.name, AudioNoutput,
  2631. sizeof dip->un.e.member[0].label.name);
  2632. dip->un.e.member[0].ord = GUSICS_MASTER_LVL;
  2633. break;
  2634. case GUSICS_INPUT_CLASS:
  2635. dip->type = AUDIO_MIXER_CLASS;
  2636. dip->mixer_class = GUSICS_INPUT_CLASS;
  2637. dip->next = dip->prev = AUDIO_MIXER_LAST;
  2638. strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
  2639. break;
  2640. case GUSICS_OUTPUT_CLASS:
  2641. dip->type = AUDIO_MIXER_CLASS;
  2642. dip->mixer_class = GUSICS_OUTPUT_CLASS;
  2643. dip->next = dip->prev = AUDIO_MIXER_LAST;
  2644. strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
  2645. break;
  2646. case GUSICS_RECORD_CLASS:
  2647. dip->type = AUDIO_MIXER_CLASS;
  2648. dip->mixer_class = GUSICS_RECORD_CLASS;
  2649. dip->next = dip->prev = AUDIO_MIXER_LAST;
  2650. strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
  2651. break;
  2652. default:
  2653. return ENXIO;
  2654. /*NOTREACHED*/
  2655. }
  2656. DPRINTF(("AUDIO_MIXER_DEVINFO: name=%s\n", dip->label.name));
  2657. return 0;
  2658. }
  2659. int
  2660. gus_query_encoding(void *addr, struct audio_encoding *fp)
  2661. {
  2662. switch (fp->index) {
  2663. case 0:
  2664. strlcpy(fp->name, AudioEslinear, sizeof fp->name);
  2665. fp->encoding = AUDIO_ENCODING_SLINEAR;
  2666. fp->precision = 8;
  2667. fp->flags = 0;
  2668. break;
  2669. case 1:
  2670. strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
  2671. fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
  2672. fp->precision = 16;
  2673. fp->flags = 0;
  2674. break;
  2675. case 2:
  2676. strlcpy(fp->name, AudioEulinear, sizeof fp->name);
  2677. fp->encoding = AUDIO_ENCODING_ULINEAR;
  2678. fp->precision = 8;
  2679. fp->flags = 0;
  2680. break;
  2681. case 3:
  2682. strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
  2683. fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
  2684. fp->precision = 16;
  2685. fp->flags = 0;
  2686. break;
  2687. default:
  2688. return(EINVAL);
  2689. /*NOTREACHED*/
  2690. }
  2691. fp->bps = AUDIO_BPS(fp->precision);
  2692. fp->msb = 1;
  2693. return (0);
  2694. }
  2695. void *
  2696. gus_malloc(void *addr, int direction, size_t size, int pool, int flags)
  2697. {
  2698. struct gus_softc *sc = addr;
  2699. int drq;
  2700. if (direction == AUMODE_PLAY)
  2701. drq = sc->sc_drq;
  2702. else
  2703. drq = sc->sc_recdrq;
  2704. return isa_malloc(sc->sc_isa, drq, size, pool, flags);
  2705. }
  2706. void
  2707. gus_free(void *addr, void *ptr, int pool)
  2708. {
  2709. isa_free(ptr, pool);
  2710. }
  2711. size_t
  2712. gus_round(void *addr, int direction, size_t size)
  2713. {
  2714. if (size > MAX_ISADMA)
  2715. size = MAX_ISADMA;
  2716. return size;
  2717. }
  2718. paddr_t
  2719. gus_mappage(void *addr, void *mem, off_t off, int prot)
  2720. {
  2721. return isa_mappage(mem, off, prot);
  2722. }
  2723. /*
  2724. * Setup the ICS mixer in "transparent" mode: reset everything to a sensible
  2725. * level. Levels as suggested by GUS SDK code.
  2726. */
  2727. void
  2728. gus_init_ics2101(struct gus_softc *sc)
  2729. {
  2730. struct ics2101_softc *ic = &sc->sc_mixer;
  2731. sc->sc_mixer.sc_iot = sc->sc_iot;
  2732. sc->sc_mixer.sc_selio = GUS_MIXER_SELECT;
  2733. sc->sc_mixer.sc_selio_ioh = sc->sc_ioh3;
  2734. sc->sc_mixer.sc_dataio = GUS_MIXER_DATA;
  2735. sc->sc_mixer.sc_dataio_ioh = sc->sc_ioh2;
  2736. sc->sc_mixer.sc_flags = (sc->sc_revision == 5) ? ICS_FLIP : 0;
  2737. ics2101_mix_attenuate(ic,
  2738. GUSMIX_CHAN_MIC,
  2739. ICSMIX_LEFT,
  2740. ICSMIX_MIN_ATTN);
  2741. ics2101_mix_attenuate(ic,
  2742. GUSMIX_CHAN_MIC,
  2743. ICSMIX_RIGHT,
  2744. ICSMIX_MIN_ATTN);
  2745. /*
  2746. * Start with microphone muted by the mixer...
  2747. */
  2748. gusics_mic_mute(ic, 1);
  2749. /* ... and enabled by the GUS master mix control */
  2750. gus_mic_ctl(sc, SPKR_ON);
  2751. ics2101_mix_attenuate(ic,
  2752. GUSMIX_CHAN_LINE,
  2753. ICSMIX_LEFT,
  2754. ICSMIX_MIN_ATTN);
  2755. ics2101_mix_attenuate(ic,
  2756. GUSMIX_CHAN_LINE,
  2757. ICSMIX_RIGHT,
  2758. ICSMIX_MIN_ATTN);
  2759. ics2101_mix_attenuate(ic,
  2760. GUSMIX_CHAN_CD,
  2761. ICSMIX_LEFT,
  2762. ICSMIX_MIN_ATTN);
  2763. ics2101_mix_attenuate(ic,
  2764. GUSMIX_CHAN_CD,
  2765. ICSMIX_RIGHT,
  2766. ICSMIX_MIN_ATTN);
  2767. ics2101_mix_attenuate(ic,
  2768. GUSMIX_CHAN_DAC,
  2769. ICSMIX_LEFT,
  2770. ICSMIX_MIN_ATTN);
  2771. ics2101_mix_attenuate(ic,
  2772. GUSMIX_CHAN_DAC,
  2773. ICSMIX_RIGHT,
  2774. ICSMIX_MIN_ATTN);
  2775. ics2101_mix_attenuate(ic,
  2776. ICSMIX_CHAN_4,
  2777. ICSMIX_LEFT,
  2778. ICSMIX_MAX_ATTN);
  2779. ics2101_mix_attenuate(ic,
  2780. ICSMIX_CHAN_4,
  2781. ICSMIX_RIGHT,
  2782. ICSMIX_MAX_ATTN);
  2783. ics2101_mix_attenuate(ic,
  2784. GUSMIX_CHAN_MASTER,
  2785. ICSMIX_LEFT,
  2786. ICSMIX_MIN_ATTN);
  2787. ics2101_mix_attenuate(ic,
  2788. GUSMIX_CHAN_MASTER,
  2789. ICSMIX_RIGHT,
  2790. ICSMIX_MIN_ATTN);
  2791. /* unmute other stuff: */
  2792. gusics_cd_mute(ic, 0);
  2793. gusics_dac_mute(ic, 0);
  2794. gusics_linein_mute(ic, 0);
  2795. return;
  2796. }
  2797. void
  2798. gus_subattach(struct gus_softc *sc, struct isa_attach_args *ia)
  2799. {
  2800. int i;
  2801. bus_space_tag_t iot;
  2802. unsigned char c,d,m;
  2803. iot = sc->sc_iot;
  2804. /*
  2805. * Figure out our board rev, and see if we need to initialize the
  2806. * mixer
  2807. */
  2808. c = bus_space_read_1(iot, sc->sc_ioh3, GUS_BOARD_REV);
  2809. if (c != 0xff)
  2810. sc->sc_revision = c;
  2811. else
  2812. sc->sc_revision = 0;
  2813. SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET);
  2814. bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, 0x00);
  2815. gusreset(sc, GUS_MAX_VOICES); /* initialize all voices */
  2816. gusreset(sc, GUS_MIN_VOICES); /* then set to just the ones we use */
  2817. /*
  2818. * Setup the IRQ and DRQ lines in software, using values from
  2819. * config file
  2820. */
  2821. m = GUSMASK_LINE_IN|GUSMASK_LINE_OUT; /* disable all */
  2822. c = ((unsigned char) gus_irq_map[ia->ia_irq]) | GUSMASK_BOTH_RQ;
  2823. if (sc->sc_recdrq == sc->sc_drq)
  2824. d = (unsigned char) (gus_drq_map[sc->sc_drq] |
  2825. GUSMASK_BOTH_RQ);
  2826. else
  2827. d = (unsigned char) (gus_drq_map[sc->sc_drq] |
  2828. gus_drq_map[sc->sc_recdrq] << 3);
  2829. /*
  2830. * Program the IRQ and DMA channels on the GUS. Note that we hardwire
  2831. * the GUS to only use one IRQ channel, but we give the user the
  2832. * option of using two DMA channels (the other one given by the drq2
  2833. * option in the config file). Two DMA channels are needed for full-
  2834. * duplex operation.
  2835. *
  2836. * The order of these operations is very magical.
  2837. */
  2838. disable_intr(); /* XXX needed? */
  2839. bus_space_write_1(iot, sc->sc_ioh1, GUS_REG_CONTROL, GUS_REG_IRQCTL);
  2840. bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m);
  2841. bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQCTL_CONTROL, 0x00);
  2842. bus_space_write_1(iot, sc->sc_ioh1, 0x0f, 0x00);
  2843. bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m);
  2844. /* magic reset? */
  2845. bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d | 0x80);
  2846. bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL,
  2847. m | GUSMASK_CONTROL_SEL);
  2848. bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c);
  2849. bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL, m);
  2850. bus_space_write_1(iot, sc->sc_ioh1, GUS_DMA_CONTROL, d);
  2851. bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL,
  2852. m | GUSMASK_CONTROL_SEL);
  2853. bus_space_write_1(iot, sc->sc_ioh1, GUS_IRQ_CONTROL, c);
  2854. bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00);
  2855. /* enable line in, line out. leave mic disabled. */
  2856. bus_space_write_1(iot, sc->sc_ioh1, GUS_MIX_CONTROL,
  2857. (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN));
  2858. bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT, 0x00);
  2859. enable_intr();
  2860. sc->sc_mixcontrol =
  2861. (m | GUSMASK_LATCHES) & ~(GUSMASK_LINE_OUT|GUSMASK_LINE_IN);
  2862. sc->sc_codec.sc_isa = sc->sc_isa;
  2863. if (sc->sc_revision >= 5 && sc->sc_revision <= 9) {
  2864. sc->sc_flags |= GUS_MIXER_INSTALLED;
  2865. gus_init_ics2101(sc);
  2866. }
  2867. if (sc->sc_revision < 10 || !gus_init_cs4231(sc)) {
  2868. /* Not using the CS4231, so create our DMA maps. */
  2869. if (sc->sc_drq != -1) {
  2870. if (isa_dmamap_create(sc->sc_isa, sc->sc_drq,
  2871. MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
  2872. printf("%s: can't create map for drq %d\n",
  2873. sc->sc_dev.dv_xname, sc->sc_drq);
  2874. return;
  2875. }
  2876. }
  2877. if (sc->sc_recdrq != -1 && sc->sc_recdrq != sc->sc_drq) {
  2878. if (isa_dmamap_create(sc->sc_isa, sc->sc_recdrq,
  2879. MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
  2880. printf("%s: can't create map for drq %d\n",
  2881. sc->sc_dev.dv_xname, sc->sc_recdrq);
  2882. return;
  2883. }
  2884. }
  2885. }
  2886. timeout_set(&sc->sc_dma_tmo, gus_dmaout_timeout, sc);
  2887. SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_RESET);
  2888. /*
  2889. * Check to see how much memory we have on this card; see if any
  2890. * "mirroring" occurs. We're assuming at least 256K already exists
  2891. * on the card; otherwise the initial probe would have failed
  2892. */
  2893. guspoke(iot, sc->sc_ioh2, 0L, 0x00);
  2894. for(i = 1; i < 1024; i++) {
  2895. u_long loc;
  2896. /*
  2897. * See if we've run into mirroring yet
  2898. */
  2899. if (guspeek(iot, sc->sc_ioh2, 0L) != 0)
  2900. break;
  2901. loc = i << 10;
  2902. guspoke(iot, sc->sc_ioh2, loc, 0xaa);
  2903. if (guspeek(iot, sc->sc_ioh2, loc) != 0xaa)
  2904. break;
  2905. }
  2906. sc->sc_dsize = i;
  2907. /*
  2908. * The "official" (3.x) version number cannot easily be obtained.
  2909. * The revision register does not correspond to the minor number
  2910. * of the board version. Simply use the revision register as
  2911. * identification.
  2912. */
  2913. snprintf(gus_device.version, sizeof gus_device.version, "%d",
  2914. sc->sc_revision);
  2915. printf(": ver %d", sc->sc_revision);
  2916. if (sc->sc_revision >= 10)
  2917. printf(", MAX");
  2918. else {
  2919. if (HAS_MIXER(sc))
  2920. printf(", ICS2101 mixer");
  2921. if (HAS_CODEC(sc))
  2922. printf(", %s codec/mixer", sc->sc_codec.chip_name);
  2923. }
  2924. printf(", %dKB DRAM, ", sc->sc_dsize);
  2925. if (sc->sc_recdrq == sc->sc_drq) {
  2926. printf("half-duplex");
  2927. } else {
  2928. printf("full-duplex, record drq %d", sc->sc_recdrq);
  2929. }
  2930. printf("\n");
  2931. /*
  2932. * Setup a default interrupt handler
  2933. */
  2934. sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq,
  2935. IST_EDGE, IPL_AUDIO | IPL_MPSAFE,
  2936. gusintr, sc /* sc->sc_gusdsp */, sc->sc_dev.dv_xname);
  2937. /*
  2938. * Set some default values
  2939. * XXX others start with 8kHz mono mulaw
  2940. */
  2941. sc->sc_irate = sc->sc_orate = 44100;
  2942. sc->sc_encoding = AUDIO_ENCODING_SLINEAR_LE;
  2943. sc->sc_precision = 16;
  2944. sc->sc_voc[GUS_VOICE_LEFT].voccntl |= GUSMASK_DATA_SIZE16;
  2945. sc->sc_voc[GUS_VOICE_RIGHT].voccntl |= GUSMASK_DATA_SIZE16;
  2946. sc->sc_channels = 1;
  2947. sc->sc_ogain = 340;
  2948. gus_commit_settings(sc);
  2949. /*
  2950. * We always put the left channel full left & right channel
  2951. * full right.
  2952. * For mono playback, we set up both voices playing the same buffer.
  2953. */
  2954. bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT,
  2955. (u_char)GUS_VOICE_LEFT);
  2956. SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS);
  2957. bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_LEFT);
  2958. bus_space_write_1(iot, sc->sc_ioh2, GUS_VOICE_SELECT,
  2959. (u_char)GUS_VOICE_RIGHT);
  2960. SELECT_GUS_REG(iot, sc->sc_ioh2, GUSREG_PAN_POS);
  2961. bus_space_write_1(iot, sc->sc_ioh2, GUS_DATA_HIGH, GUS_PAN_FULL_RIGHT);
  2962. /*
  2963. * Attach to the generic audio layer
  2964. */
  2965. audio_attach_mi(&gus_hw_if, HAS_CODEC(sc) ? (void *)&sc->sc_codec :
  2966. (void *)sc, &sc->sc_dev);
  2967. }
  2968. /*
  2969. * Test to see if a particular I/O base is valid for the GUS. Return true
  2970. * if it is.
  2971. */
  2972. int
  2973. gus_test_iobase (bus_space_tag_t iot, int iobase)
  2974. {
  2975. bus_space_handle_t ioh1, ioh2, ioh3, ioh4;
  2976. u_char s1, s2;
  2977. int rv = 0;
  2978. /* Map i/o space */
  2979. if (bus_space_map(iot, iobase, GUS_NPORT1, 0, &ioh1))
  2980. return 0;
  2981. if (bus_space_map(iot, iobase+GUS_IOH2_OFFSET, GUS_NPORT2, 0, &ioh2))
  2982. goto bad1;
  2983. /* XXX Maybe we shouldn't fail on mapping this, but just assume
  2984. * the card is of revision 0? */
  2985. if (bus_space_map(iot, iobase+GUS_IOH3_OFFSET, GUS_NPORT3, 0, &ioh3))
  2986. goto bad2;
  2987. if (bus_space_map(iot, iobase+GUS_IOH4_OFFSET, GUS_NPORT4, 0, &ioh4))
  2988. goto bad3;
  2989. /*
  2990. * Reset GUS to an initial state before we do anything.
  2991. */
  2992. mtx_enter(&audio_lock);
  2993. delay(500);
  2994. SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
  2995. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, 0x00);
  2996. delay(500);
  2997. SELECT_GUS_REG(iot, ioh2, GUSREG_RESET);
  2998. bus_space_write_1(iot, ioh2, GUS_DATA_HIGH, GUSMASK_MASTER_RESET);
  2999. delay(500);
  3000. mtx_leave(&audio_lock);
  3001. /*
  3002. * See if we can write to the board's memory
  3003. */
  3004. s1 = guspeek(iot, ioh2, 0L);
  3005. s2 = guspeek(iot, ioh2, 1L);
  3006. guspoke(iot, ioh2, 0L, 0xaa);
  3007. guspoke(iot, ioh2, 1L, 0x55);
  3008. if (guspeek(iot, ioh2, 0L) != 0xaa)
  3009. goto bad;
  3010. guspoke(iot, ioh2, 0L, s1);
  3011. guspoke(iot, ioh2, 1L, s2);
  3012. rv = 1;
  3013. bad:
  3014. bus_space_unmap(iot, ioh4, GUS_NPORT4);
  3015. bad3:
  3016. bus_space_unmap(iot, ioh3, GUS_NPORT3);
  3017. bad2:
  3018. bus_space_unmap(iot, ioh2, GUS_NPORT2);
  3019. bad1:
  3020. bus_space_unmap(iot, ioh1, GUS_NPORT1);
  3021. return rv;
  3022. }