ess.c 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610
  1. /* $OpenBSD: ess.c,v 1.22 2015/06/25 06:43:46 ratchov Exp $ */
  2. /* $NetBSD: ess.c,v 1.44.4.1 1999/06/21 01:18:00 thorpej Exp $ */
  3. /*
  4. * Copyright 1997
  5. * Digital Equipment Corporation. All rights reserved.
  6. *
  7. * This software is furnished under license and may be used and
  8. * copied only in accordance with the following terms and conditions.
  9. * Subject to these conditions, you may download, copy, install,
  10. * use, modify and distribute this software in source and/or binary
  11. * form. No title or ownership is transferred hereby.
  12. *
  13. * 1) Any source code used, modified or distributed must reproduce
  14. * and retain this copyright notice and list of conditions as
  15. * they appear in the source file.
  16. *
  17. * 2) No right is granted to use any trade name, trademark, or logo of
  18. * Digital Equipment Corporation. Neither the "Digital Equipment
  19. * Corporation" name nor any trademark or logo of Digital Equipment
  20. * Corporation may be used to endorse or promote products derived
  21. * from this software without the prior written permission of
  22. * Digital Equipment Corporation.
  23. *
  24. * 3) This software is provided "AS-IS" and any express or implied
  25. * warranties, including but not limited to, any implied warranties
  26. * of merchantability, fitness for a particular purpose, or
  27. * non-infringement are disclaimed. In no event shall DIGITAL be
  28. * liable for any damages whatsoever, and in particular, DIGITAL
  29. * shall not be liable for special, indirect, consequential, or
  30. * incidental damages or damages for lost profits, loss of
  31. * revenue or loss of use, whether such damages arise in contract,
  32. * negligence, tort, under statute, in equity, at law or otherwise,
  33. * even if advised of the possibility of such damage.
  34. */
  35. /*
  36. **++
  37. **
  38. ** ess.c
  39. **
  40. ** FACILITY:
  41. **
  42. ** DIGITAL Network Appliance Reference Design (DNARD)
  43. **
  44. ** MODULE DESCRIPTION:
  45. **
  46. ** This module contains the device driver for the ESS
  47. ** Technologies 1888/1887/888 sound chip. The code in sbdsp.c was
  48. ** used as a reference point when implementing this driver.
  49. **
  50. ** AUTHORS:
  51. **
  52. ** Blair Fidler Software Engineering Australia
  53. ** Gold Coast, Australia.
  54. **
  55. ** CREATION DATE:
  56. **
  57. ** March 10, 1997.
  58. **
  59. ** MODIFICATION HISTORY:
  60. **
  61. ** Heavily modified by Lennart Augustsson and Charles M. Hannum for
  62. ** bus_dma, changes to audio interface, and many bug fixes.
  63. ** ESS1788 support by Nathan J. Williams and Charles M. Hannum.
  64. **--
  65. */
  66. #include <sys/param.h>
  67. #include <sys/systm.h>
  68. #include <sys/errno.h>
  69. #include <sys/ioctl.h>
  70. #include <sys/syslog.h>
  71. #include <sys/device.h>
  72. #include <sys/kernel.h>
  73. #include <sys/timeout.h>
  74. #include <machine/cpu.h>
  75. #include <machine/intr.h>
  76. #include <machine/bus.h>
  77. #include <sys/audioio.h>
  78. #include <dev/audio_if.h>
  79. #include <dev/isa/isavar.h>
  80. #include <dev/isa/isadmavar.h>
  81. #include <dev/isa/essvar.h>
  82. #include <dev/isa/essreg.h>
  83. #ifdef AUDIO_DEBUG
  84. #define DPRINTF(x) if (essdebug) printf x
  85. #define DPRINTFN(n,x) if (essdebug>(n)) printf x
  86. int essdebug = 0;
  87. #else
  88. #define DPRINTF(x)
  89. #define DPRINTFN(n,x)
  90. #endif
  91. #if 0
  92. unsigned uuu;
  93. #define EREAD1(t, h, a) (uuu=bus_space_read_1(t, h, a),printf("EREAD %02x=%02x\n", ((int)h&0xfff)+a, uuu),uuu)
  94. #define EWRITE1(t, h, a, d) (printf("EWRITE %02x=%02x\n", ((int)h & 0xfff)+a, d), bus_space_write_1(t, h, a, d))
  95. #else
  96. #define EREAD1(t, h, a) bus_space_read_1(t, h, a)
  97. #define EWRITE1(t, h, a, d) bus_space_write_1(t, h, a, d)
  98. #endif
  99. struct cfdriver ess_cd = {
  100. NULL, "ess", DV_DULL
  101. };
  102. struct audio_params ess_audio_default =
  103. {44100, AUDIO_ENCODING_SLINEAR_LE, 16, 2, 1, 2};
  104. int ess_setup_sc(struct ess_softc *, int);
  105. int ess_open(void *, int);
  106. void ess_1788_close(void *);
  107. void ess_1888_close(void *);
  108. int ess_getdev(void *, struct audio_device *);
  109. int ess_drain(void *);
  110. int ess_query_encoding(void *, struct audio_encoding *);
  111. int ess_set_params(void *, int, int, struct audio_params *,
  112. struct audio_params *);
  113. int ess_round_blocksize(void *, int);
  114. int ess_audio1_trigger_output(void *, void *, void *, int,
  115. void (*)(void *), void *, struct audio_params *);
  116. int ess_audio2_trigger_output(void *, void *, void *, int,
  117. void (*)(void *), void *, struct audio_params *);
  118. int ess_audio1_trigger_input(void *, void *, void *, int,
  119. void (*)(void *), void *, struct audio_params *);
  120. int ess_audio1_halt(void *);
  121. int ess_audio2_halt(void *);
  122. int ess_audio1_intr(void *);
  123. int ess_audio2_intr(void *);
  124. void ess_audio1_poll(void *);
  125. void ess_audio2_poll(void *);
  126. int ess_speaker_ctl(void *, int);
  127. int ess_getdev(void *, struct audio_device *);
  128. int ess_set_port(void *, mixer_ctrl_t *);
  129. int ess_get_port(void *, mixer_ctrl_t *);
  130. void *ess_malloc(void *, int, size_t, int, int);
  131. void ess_free(void *, void *, int);
  132. size_t ess_round_buffersize(void *, int, size_t);
  133. paddr_t ess_mappage(void *, void *, off_t, int);
  134. int ess_query_devinfo(void *, mixer_devinfo_t *);
  135. int ess_1788_get_props(void *);
  136. int ess_1888_get_props(void *);
  137. void ess_speaker_on(struct ess_softc *);
  138. void ess_speaker_off(struct ess_softc *);
  139. int ess_config_addr(struct ess_softc *);
  140. void ess_config_irq(struct ess_softc *);
  141. void ess_config_drq(struct ess_softc *);
  142. void ess_setup(struct ess_softc *);
  143. int ess_identify(struct ess_softc *);
  144. int ess_reset(struct ess_softc *);
  145. void ess_set_gain(struct ess_softc *, int, int);
  146. int ess_set_in_port(struct ess_softc *, int);
  147. int ess_set_in_ports(struct ess_softc *, int);
  148. u_int ess_srtotc(u_int);
  149. u_int ess_srtofc(u_int);
  150. u_char ess_get_dsp_status(struct ess_softc *);
  151. u_char ess_dsp_read_ready(struct ess_softc *);
  152. u_char ess_dsp_write_ready(struct ess_softc *);
  153. int ess_rdsp(struct ess_softc *);
  154. int ess_wdsp(struct ess_softc *, u_char);
  155. u_char ess_read_x_reg(struct ess_softc *, u_char);
  156. int ess_write_x_reg(struct ess_softc *, u_char, u_char);
  157. void ess_clear_xreg_bits(struct ess_softc *, u_char, u_char);
  158. void ess_set_xreg_bits(struct ess_softc *, u_char, u_char);
  159. u_char ess_read_mix_reg(struct ess_softc *, u_char);
  160. void ess_write_mix_reg(struct ess_softc *, u_char, u_char);
  161. void ess_clear_mreg_bits(struct ess_softc *, u_char, u_char);
  162. void ess_set_mreg_bits(struct ess_softc *, u_char, u_char);
  163. void ess_read_multi_mix_reg(struct ess_softc *, u_char, u_int8_t *, bus_size_t);
  164. static char *essmodel[] = {
  165. "unsupported",
  166. "1888",
  167. "1887",
  168. "888",
  169. "1788",
  170. "1869",
  171. "1879",
  172. "1868",
  173. "1878",
  174. };
  175. struct audio_device ess_device = {
  176. "ESS Technology",
  177. "x",
  178. "ess"
  179. };
  180. /*
  181. * Define our interface to the higher level audio driver.
  182. */
  183. struct audio_hw_if ess_1788_hw_if = {
  184. ess_open,
  185. ess_1788_close,
  186. ess_drain,
  187. ess_query_encoding,
  188. ess_set_params,
  189. ess_round_blocksize,
  190. NULL,
  191. NULL,
  192. NULL,
  193. NULL,
  194. NULL,
  195. ess_audio1_halt,
  196. ess_audio1_halt,
  197. ess_speaker_ctl,
  198. ess_getdev,
  199. NULL,
  200. ess_set_port,
  201. ess_get_port,
  202. ess_query_devinfo,
  203. ess_malloc,
  204. ess_free,
  205. ess_round_buffersize,
  206. ess_mappage,
  207. ess_1788_get_props,
  208. ess_audio1_trigger_output,
  209. ess_audio1_trigger_input,
  210. NULL
  211. };
  212. struct audio_hw_if ess_1888_hw_if = {
  213. ess_open,
  214. ess_1888_close,
  215. ess_drain,
  216. ess_query_encoding,
  217. ess_set_params,
  218. ess_round_blocksize,
  219. NULL,
  220. NULL,
  221. NULL,
  222. NULL,
  223. NULL,
  224. ess_audio2_halt,
  225. ess_audio1_halt,
  226. ess_speaker_ctl,
  227. ess_getdev,
  228. NULL,
  229. ess_set_port,
  230. ess_get_port,
  231. ess_query_devinfo,
  232. ess_malloc,
  233. ess_free,
  234. ess_round_buffersize,
  235. ess_mappage,
  236. ess_1888_get_props,
  237. ess_audio2_trigger_output,
  238. ess_audio1_trigger_input,
  239. NULL
  240. };
  241. #ifdef AUDIO_DEBUG
  242. void ess_printsc(struct ess_softc *);
  243. void ess_dump_mixer(struct ess_softc *);
  244. void
  245. ess_printsc(struct ess_softc *sc)
  246. {
  247. int i;
  248. printf("open %d iobase 0x%x outport %u inport %u speaker %s\n",
  249. (int)sc->sc_open, sc->sc_iobase, sc->out_port,
  250. sc->in_port, sc->spkr_state ? "on" : "off");
  251. printf("audio1: dmachan %d irq %d nintr %lu intr %p arg %p\n",
  252. sc->sc_audio1.drq, sc->sc_audio1.irq, sc->sc_audio1.nintr,
  253. sc->sc_audio1.intr, sc->sc_audio1.arg);
  254. if (!ESS_USE_AUDIO1(sc->sc_model)) {
  255. printf("audio2: dmachan %d irq %d nintr %lu intr %p arg %p\n",
  256. sc->sc_audio2.drq, sc->sc_audio2.irq, sc->sc_audio2.nintr,
  257. sc->sc_audio2.intr, sc->sc_audio2.arg);
  258. }
  259. printf("gain:");
  260. for (i = 0; i < sc->ndevs; i++)
  261. printf(" %u,%u", sc->gain[i][ESS_LEFT], sc->gain[i][ESS_RIGHT]);
  262. printf("\n");
  263. }
  264. void
  265. ess_dump_mixer(struct ess_softc *sc)
  266. {
  267. printf("ESS_DAC_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
  268. 0x7C, ess_read_mix_reg(sc, 0x7C));
  269. printf("ESS_MIC_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
  270. 0x1A, ess_read_mix_reg(sc, 0x1A));
  271. printf("ESS_LINE_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
  272. 0x3E, ess_read_mix_reg(sc, 0x3E));
  273. printf("ESS_SYNTH_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
  274. 0x36, ess_read_mix_reg(sc, 0x36));
  275. printf("ESS_CD_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
  276. 0x38, ess_read_mix_reg(sc, 0x38));
  277. printf("ESS_AUXB_PLAY_VOL: mix reg 0x%02x=0x%02x\n",
  278. 0x3A, ess_read_mix_reg(sc, 0x3A));
  279. printf("ESS_MASTER_VOL: mix reg 0x%02x=0x%02x\n",
  280. 0x32, ess_read_mix_reg(sc, 0x32));
  281. printf("ESS_PCSPEAKER_VOL: mix reg 0x%02x=0x%02x\n",
  282. 0x3C, ess_read_mix_reg(sc, 0x3C));
  283. printf("ESS_DAC_REC_VOL: mix reg 0x%02x=0x%02x\n",
  284. 0x69, ess_read_mix_reg(sc, 0x69));
  285. printf("ESS_MIC_REC_VOL: mix reg 0x%02x=0x%02x\n",
  286. 0x68, ess_read_mix_reg(sc, 0x68));
  287. printf("ESS_LINE_REC_VOL: mix reg 0x%02x=0x%02x\n",
  288. 0x6E, ess_read_mix_reg(sc, 0x6E));
  289. printf("ESS_SYNTH_REC_VOL: mix reg 0x%02x=0x%02x\n",
  290. 0x6B, ess_read_mix_reg(sc, 0x6B));
  291. printf("ESS_CD_REC_VOL: mix reg 0x%02x=0x%02x\n",
  292. 0x6A, ess_read_mix_reg(sc, 0x6A));
  293. printf("ESS_AUXB_REC_VOL: mix reg 0x%02x=0x%02x\n",
  294. 0x6C, ess_read_mix_reg(sc, 0x6C));
  295. printf("ESS_RECORD_VOL: x reg 0x%02x=0x%02x\n",
  296. 0xB4, ess_read_x_reg(sc, 0xB4));
  297. printf("Audio 1 play vol (unused): mix reg 0x%02x=0x%02x\n",
  298. 0x14, ess_read_mix_reg(sc, 0x14));
  299. printf("ESS_MIC_PREAMP: x reg 0x%02x=0x%02x\n",
  300. ESS_XCMD_PREAMP_CTRL, ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL));
  301. printf("ESS_RECORD_MONITOR: x reg 0x%02x=0x%02x\n",
  302. ESS_XCMD_AUDIO_CTRL, ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL));
  303. printf("Record source: mix reg 0x%02x=0x%02x, 0x%02x=0x%02x\n",
  304. ESS_MREG_ADC_SOURCE, ess_read_mix_reg(sc, ESS_MREG_ADC_SOURCE),
  305. ESS_MREG_AUDIO2_CTRL2, ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2));
  306. }
  307. #endif
  308. /*
  309. * Configure the ESS chip for the desired audio base address.
  310. */
  311. int
  312. ess_config_addr(struct ess_softc *sc)
  313. {
  314. int iobase = sc->sc_iobase;
  315. bus_space_tag_t iot = sc->sc_iot;
  316. /*
  317. * Configure using the System Control Register method. This
  318. * method is used when the AMODE line is tied high, which is
  319. * the case for the Shark, but not for the evaluation board.
  320. */
  321. bus_space_handle_t scr_access_ioh;
  322. bus_space_handle_t scr_ioh;
  323. u_short scr_value;
  324. /*
  325. * Set the SCR bit to enable audio.
  326. */
  327. scr_value = ESS_SCR_AUDIO_ENABLE;
  328. /*
  329. * Set the SCR bits necessary to select the specified audio
  330. * base address.
  331. */
  332. switch(iobase) {
  333. case 0x220:
  334. scr_value |= ESS_SCR_AUDIO_220;
  335. break;
  336. case 0x230:
  337. scr_value |= ESS_SCR_AUDIO_230;
  338. break;
  339. case 0x240:
  340. scr_value |= ESS_SCR_AUDIO_240;
  341. break;
  342. case 0x250:
  343. scr_value |= ESS_SCR_AUDIO_250;
  344. break;
  345. default:
  346. printf("ess: configured iobase 0x%x invalid\n", iobase);
  347. return (1);
  348. break;
  349. }
  350. /*
  351. * Get a mapping for the System Control Register (SCR) access
  352. * registers and the SCR data registers.
  353. */
  354. if (bus_space_map(iot, ESS_SCR_ACCESS_BASE, ESS_SCR_ACCESS_PORTS,
  355. 0, &scr_access_ioh)) {
  356. printf("ess: can't map SCR access registers\n");
  357. return (1);
  358. }
  359. if (bus_space_map(iot, ESS_SCR_BASE, ESS_SCR_PORTS,
  360. 0, &scr_ioh)) {
  361. printf("ess: can't map SCR registers\n");
  362. bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS);
  363. return (1);
  364. }
  365. /* Unlock the SCR. */
  366. EWRITE1(iot, scr_access_ioh, ESS_SCR_UNLOCK, 0);
  367. /* Write the base address information into SCR[0]. */
  368. EWRITE1(iot, scr_ioh, ESS_SCR_INDEX, 0);
  369. EWRITE1(iot, scr_ioh, ESS_SCR_DATA, scr_value);
  370. /* Lock the SCR. */
  371. EWRITE1(iot, scr_access_ioh, ESS_SCR_LOCK, 0);
  372. /* Unmap the SCR access ports and the SCR data ports. */
  373. bus_space_unmap(iot, scr_access_ioh, ESS_SCR_ACCESS_PORTS);
  374. bus_space_unmap(iot, scr_ioh, ESS_SCR_PORTS);
  375. return 0;
  376. }
  377. /*
  378. * Configure the ESS chip for the desired IRQ and DMA channels.
  379. * ESS ISA
  380. * --------
  381. * IRQA irq9
  382. * IRQB irq5
  383. * IRQC irq7
  384. * IRQD irq10
  385. * IRQE irq15
  386. *
  387. * DRQA drq0
  388. * DRQB drq1
  389. * DRQC drq3
  390. * DRQD drq5
  391. */
  392. void
  393. ess_config_irq(struct ess_softc *sc)
  394. {
  395. int v;
  396. DPRINTFN(2,("ess_config_irq\n"));
  397. if (sc->sc_model == ESS_1887 &&
  398. sc->sc_audio1.irq == sc->sc_audio2.irq &&
  399. sc->sc_audio1.irq != -1) {
  400. /* Use new method, both interrupts are the same. */
  401. v = ESS_IS_SELECT_IRQ; /* enable intrs */
  402. switch (sc->sc_audio1.irq) {
  403. case 5:
  404. v |= ESS_IS_INTRB;
  405. break;
  406. case 7:
  407. v |= ESS_IS_INTRC;
  408. break;
  409. case 9:
  410. v |= ESS_IS_INTRA;
  411. break;
  412. case 10:
  413. v |= ESS_IS_INTRD;
  414. break;
  415. case 15:
  416. v |= ESS_IS_INTRE;
  417. break;
  418. #ifdef DIAGNOSTIC
  419. default:
  420. printf("ess_config_irq: configured irq %d not supported for Audio 1\n",
  421. sc->sc_audio1.irq);
  422. return;
  423. #endif
  424. }
  425. /* Set the IRQ */
  426. ess_write_mix_reg(sc, ESS_MREG_INTR_ST, v);
  427. return;
  428. }
  429. if (sc->sc_model == ESS_1887) {
  430. /* Tell the 1887 to use the old interrupt method. */
  431. ess_write_mix_reg(sc, ESS_MREG_INTR_ST, ESS_IS_ES1888);
  432. }
  433. if (sc->sc_audio1.polled) {
  434. /* Turn off Audio1 interrupts. */
  435. v = 0;
  436. } else {
  437. /* Configure Audio 1 for the appropriate IRQ line. */
  438. v = ESS_IRQ_CTRL_MASK | ESS_IRQ_CTRL_EXT; /* All intrs on */
  439. switch (sc->sc_audio1.irq) {
  440. case 5:
  441. v |= ESS_IRQ_CTRL_INTRB;
  442. break;
  443. case 7:
  444. v |= ESS_IRQ_CTRL_INTRC;
  445. break;
  446. case 9:
  447. v |= ESS_IRQ_CTRL_INTRA;
  448. break;
  449. case 10:
  450. v |= ESS_IRQ_CTRL_INTRD;
  451. break;
  452. #ifdef DIAGNOSTIC
  453. default:
  454. printf("ess: configured irq %d not supported for Audio 1\n",
  455. sc->sc_audio1.irq);
  456. return;
  457. #endif
  458. }
  459. }
  460. ess_write_x_reg(sc, ESS_XCMD_IRQ_CTRL, v);
  461. if (ESS_USE_AUDIO1(sc->sc_model))
  462. return;
  463. if (sc->sc_audio2.polled) {
  464. /* Turn off Audio2 interrupts. */
  465. ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
  466. ESS_AUDIO2_CTRL2_IRQ2_ENABLE);
  467. } else {
  468. /* Audio2 is hardwired to INTRE in this mode. */
  469. ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
  470. ESS_AUDIO2_CTRL2_IRQ2_ENABLE);
  471. }
  472. }
  473. void
  474. ess_config_drq(struct ess_softc *sc)
  475. {
  476. int v;
  477. DPRINTFN(2,("ess_config_drq\n"));
  478. /* Configure Audio 1 (record) for DMA on the appropriate channel. */
  479. v = ESS_DRQ_CTRL_PU | ESS_DRQ_CTRL_EXT;
  480. switch (sc->sc_audio1.drq) {
  481. case 0:
  482. v |= ESS_DRQ_CTRL_DRQA;
  483. break;
  484. case 1:
  485. v |= ESS_DRQ_CTRL_DRQB;
  486. break;
  487. case 3:
  488. v |= ESS_DRQ_CTRL_DRQC;
  489. break;
  490. #ifdef DIAGNOSTIC
  491. default:
  492. printf("ess_config_drq: configured dma chan %d not supported for Audio 1\n",
  493. sc->sc_audio1.drq);
  494. return;
  495. #endif
  496. }
  497. /* Set DRQ1 */
  498. ess_write_x_reg(sc, ESS_XCMD_DRQ_CTRL, v);
  499. if (ESS_USE_AUDIO1(sc->sc_model))
  500. return;
  501. /* Configure DRQ2 */
  502. v = ESS_AUDIO2_CTRL3_DRQ_PD;
  503. switch (sc->sc_audio2.drq) {
  504. case 0:
  505. v |= ESS_AUDIO2_CTRL3_DRQA;
  506. break;
  507. case 1:
  508. v |= ESS_AUDIO2_CTRL3_DRQB;
  509. break;
  510. case 3:
  511. v |= ESS_AUDIO2_CTRL3_DRQC;
  512. break;
  513. case 5:
  514. v |= ESS_AUDIO2_CTRL3_DRQD;
  515. break;
  516. #ifdef DIAGNOSTIC
  517. default:
  518. printf("ess_config_drq: configured dma chan %d not supported for Audio 2\n",
  519. sc->sc_audio2.drq);
  520. return;
  521. #endif
  522. }
  523. ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL3, v);
  524. /* Enable DMA 2 */
  525. ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2,
  526. ESS_AUDIO2_CTRL2_DMA_ENABLE);
  527. }
  528. /*
  529. * Set up registers after a reset.
  530. */
  531. void
  532. ess_setup(struct ess_softc *sc)
  533. {
  534. ess_config_irq(sc);
  535. ess_config_drq(sc);
  536. DPRINTFN(2,("ess_setup: done\n"));
  537. }
  538. /*
  539. * Determine the model of ESS chip we are talking to. Currently we
  540. * only support ES1888, ES1887 and ES888. The method of determining
  541. * the chip is based on the information on page 27 of the ES1887 data
  542. * sheet.
  543. *
  544. * This routine sets the values of sc->sc_model and sc->sc_version.
  545. */
  546. int
  547. ess_identify(struct ess_softc *sc)
  548. {
  549. u_char reg1;
  550. u_char reg2;
  551. u_char reg3;
  552. u_int8_t ident[4];
  553. sc->sc_model = ESS_UNSUPPORTED;
  554. sc->sc_version = 0;
  555. memset(ident, 0, sizeof(ident));
  556. /*
  557. * 1. Check legacy ID bytes. These should be 0x68 0x8n, where
  558. * n >= 8 for an ES1887 or an ES888. Other values indicate
  559. * earlier (unsupported) chips.
  560. */
  561. ess_wdsp(sc, ESS_ACMD_LEGACY_ID);
  562. if ((reg1 = ess_rdsp(sc)) != 0x68) {
  563. printf("ess: First ID byte wrong (0x%02x)\n", reg1);
  564. return 1;
  565. }
  566. reg2 = ess_rdsp(sc);
  567. if (((reg2 & 0xf0) != 0x80) ||
  568. ((reg2 & 0x0f) < 8)) {
  569. printf("ess: Second ID byte wrong (0x%02x)\n", reg2);
  570. return 1;
  571. }
  572. /*
  573. * Store the ID bytes as the version.
  574. */
  575. sc->sc_version = (reg1 << 8) + reg2;
  576. /*
  577. * 2. Verify we can change bit 2 in mixer register 0x64. This
  578. * should be possible on all supported chips.
  579. */
  580. reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL);
  581. reg2 = reg1 ^ 0x04; /* toggle bit 2 */
  582. ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2);
  583. if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) != reg2) {
  584. printf("ess: Hardware error (unable to toggle bit 2 of mixer register 0x64)\n");
  585. return 1;
  586. }
  587. /*
  588. * Restore the original value of mixer register 0x64.
  589. */
  590. ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1);
  591. /*
  592. * 3. Verify we can change the value of mixer register
  593. * ESS_MREG_SAMPLE_RATE.
  594. * This is possible on the 1888/1887/888, but not on the 1788.
  595. * It is not necessary to restore the value of this mixer register.
  596. */
  597. reg1 = ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE);
  598. reg2 = reg1 ^ 0xff; /* toggle all bits */
  599. ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, reg2);
  600. if (ess_read_mix_reg(sc, ESS_MREG_SAMPLE_RATE) != reg2) {
  601. /* If we got this far before failing, it's a 1788. */
  602. sc->sc_model = ESS_1788;
  603. /*
  604. * Identify ESS model for ES18[67]8.
  605. */
  606. ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident));
  607. if(ident[0] == 0x18) {
  608. switch(ident[1]) {
  609. case 0x68:
  610. sc->sc_model = ESS_1868;
  611. break;
  612. case 0x78:
  613. sc->sc_model = ESS_1878;
  614. break;
  615. }
  616. }
  617. } else {
  618. /*
  619. * 4. Determine if we can change bit 5 in mixer register 0x64.
  620. * This determines whether we have an ES1887:
  621. *
  622. * - can change indicates ES1887
  623. * - can't change indicates ES1888 or ES888
  624. */
  625. reg1 = ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL);
  626. reg2 = reg1 ^ 0x20; /* toggle bit 5 */
  627. ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg2);
  628. if (ess_read_mix_reg(sc, ESS_MREG_VOLUME_CTRL) == reg2) {
  629. sc->sc_model = ESS_1887;
  630. /*
  631. * Restore the original value of mixer register 0x64.
  632. */
  633. ess_write_mix_reg(sc, ESS_MREG_VOLUME_CTRL, reg1);
  634. /*
  635. * Identify ESS model for ES18[67]9.
  636. */
  637. ess_read_multi_mix_reg(sc, 0x40, ident, sizeof(ident));
  638. if(ident[0] == 0x18) {
  639. switch(ident[1]) {
  640. case 0x69:
  641. sc->sc_model = ESS_1869;
  642. break;
  643. case 0x79:
  644. sc->sc_model = ESS_1879;
  645. break;
  646. }
  647. }
  648. } else {
  649. /*
  650. * 5. Determine if we can change the value of mixer
  651. * register 0x69 independently of mixer register
  652. * 0x68. This determines which chip we have:
  653. *
  654. * - can modify idependently indicates ES888
  655. * - register 0x69 is an alias of 0x68 indicates ES1888
  656. */
  657. reg1 = ess_read_mix_reg(sc, 0x68);
  658. reg2 = ess_read_mix_reg(sc, 0x69);
  659. reg3 = reg2 ^ 0xff; /* toggle all bits */
  660. /*
  661. * Write different values to each register.
  662. */
  663. ess_write_mix_reg(sc, 0x68, reg2);
  664. ess_write_mix_reg(sc, 0x69, reg3);
  665. if (ess_read_mix_reg(sc, 0x68) == reg2 &&
  666. ess_read_mix_reg(sc, 0x69) == reg3)
  667. sc->sc_model = ESS_888;
  668. else
  669. sc->sc_model = ESS_1888;
  670. /*
  671. * Restore the original value of the registers.
  672. */
  673. ess_write_mix_reg(sc, 0x68, reg1);
  674. ess_write_mix_reg(sc, 0x69, reg2);
  675. }
  676. }
  677. return 0;
  678. }
  679. int
  680. ess_setup_sc(struct ess_softc *sc, int doinit)
  681. {
  682. /* Reset the chip. */
  683. if (ess_reset(sc) != 0) {
  684. DPRINTF(("ess_setup_sc: couldn't reset chip\n"));
  685. return (1);
  686. }
  687. /* Identify the ESS chip, and check that it is supported. */
  688. if (ess_identify(sc)) {
  689. DPRINTF(("ess_setup_sc: couldn't identify\n"));
  690. return (1);
  691. }
  692. return (0);
  693. }
  694. /*
  695. * Probe for the ESS hardware.
  696. */
  697. int
  698. essmatch(struct ess_softc *sc)
  699. {
  700. if (!ESS_BASE_VALID(sc->sc_iobase)) {
  701. printf("ess: configured iobase 0x%x invalid\n", sc->sc_iobase);
  702. return (0);
  703. }
  704. /* Configure the ESS chip for the desired audio base address. */
  705. if (ess_config_addr(sc))
  706. return (0);
  707. if (ess_setup_sc(sc, 1))
  708. return (0);
  709. if (sc->sc_model == ESS_UNSUPPORTED) {
  710. DPRINTF(("ess: Unsupported model\n"));
  711. return (0);
  712. }
  713. /* Check that requested DMA channels are valid and different. */
  714. if (!ESS_DRQ1_VALID(sc->sc_audio1.drq)) {
  715. printf("ess: record drq %d invalid\n", sc->sc_audio1.drq);
  716. return (0);
  717. }
  718. if (!isa_drq_isfree(sc->sc_isa, sc->sc_audio1.drq))
  719. return (0);
  720. if (!ESS_USE_AUDIO1(sc->sc_model)) {
  721. if (!ESS_DRQ2_VALID(sc->sc_audio2.drq)) {
  722. printf("ess: play drq %d invalid\n", sc->sc_audio2.drq);
  723. return (0);
  724. }
  725. if (sc->sc_audio1.drq == sc->sc_audio2.drq) {
  726. printf("ess: play and record drq both %d\n",
  727. sc->sc_audio1.drq);
  728. return (0);
  729. }
  730. if (!isa_drq_isfree(sc->sc_isa, sc->sc_audio2.drq))
  731. return (0);
  732. }
  733. /*
  734. * The 1887 has an additional IRQ mode where both channels are mapped
  735. * to the same IRQ.
  736. */
  737. if (sc->sc_model == ESS_1887 &&
  738. sc->sc_audio1.irq == sc->sc_audio2.irq &&
  739. sc->sc_audio1.irq != -1 &&
  740. ESS_IRQ12_VALID(sc->sc_audio1.irq))
  741. goto irq_not1888;
  742. /* Check that requested IRQ lines are valid and different. */
  743. if (sc->sc_audio1.irq != -1 &&
  744. !ESS_IRQ1_VALID(sc->sc_audio1.irq)) {
  745. printf("ess: record irq %d invalid\n", sc->sc_audio1.irq);
  746. return (0);
  747. }
  748. if (!ESS_USE_AUDIO1(sc->sc_model)) {
  749. if (sc->sc_audio2.irq != -1 &&
  750. !ESS_IRQ2_VALID(sc->sc_audio2.irq)) {
  751. printf("ess: play irq %d invalid\n", sc->sc_audio2.irq);
  752. return (0);
  753. }
  754. if (sc->sc_audio1.irq == sc->sc_audio2.irq &&
  755. sc->sc_audio1.irq != -1) {
  756. printf("ess: play and record irq both %d\n",
  757. sc->sc_audio1.irq);
  758. return (0);
  759. }
  760. }
  761. irq_not1888:
  762. /* XXX should we check IRQs as well? */
  763. return (1);
  764. }
  765. /*
  766. * Attach hardware to driver, attach hardware driver to audio
  767. * pseudo-device driver.
  768. */
  769. void
  770. essattach(struct ess_softc *sc)
  771. {
  772. struct audio_attach_args arg;
  773. struct audio_params pparams, rparams;
  774. int i;
  775. u_int v;
  776. if (ess_setup_sc(sc, 0)) {
  777. printf(": setup failed\n");
  778. return;
  779. }
  780. printf(": ESS Technology ES%s [version 0x%04x]\n",
  781. essmodel[sc->sc_model], sc->sc_version);
  782. sc->sc_audio1.polled = sc->sc_audio1.irq == -1;
  783. if (!sc->sc_audio1.polled) {
  784. sc->sc_audio1.ih = isa_intr_establish(sc->sc_ic,
  785. sc->sc_audio1.irq, sc->sc_audio1.ist,
  786. IPL_AUDIO | IPL_MPSAFE,
  787. ess_audio1_intr, sc, sc->sc_dev.dv_xname);
  788. printf("%s: audio1 interrupting at irq %d\n",
  789. sc->sc_dev.dv_xname, sc->sc_audio1.irq);
  790. } else
  791. printf("%s: audio1 polled\n", sc->sc_dev.dv_xname);
  792. if (isa_dmamap_create(sc->sc_isa, sc->sc_audio1.drq,
  793. MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
  794. printf("%s: can't create map for drq %d\n",
  795. sc->sc_dev.dv_xname, sc->sc_audio1.drq);
  796. return;
  797. }
  798. if (!ESS_USE_AUDIO1(sc->sc_model)) {
  799. sc->sc_audio2.polled = sc->sc_audio2.irq == -1;
  800. if (!sc->sc_audio2.polled) {
  801. sc->sc_audio2.ih = isa_intr_establish(sc->sc_ic,
  802. sc->sc_audio2.irq, sc->sc_audio2.ist,
  803. IPL_AUDIO | IPL_MPSAFE,
  804. ess_audio2_intr, sc, sc->sc_dev.dv_xname);
  805. printf("%s: audio2 interrupting at irq %d\n",
  806. sc->sc_dev.dv_xname, sc->sc_audio2.irq);
  807. } else
  808. printf("%s: audio2 polled\n", sc->sc_dev.dv_xname);
  809. if (isa_dmamap_create(sc->sc_isa, sc->sc_audio2.drq,
  810. MAX_ISADMA, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW)) {
  811. printf("%s: can't create map for drq %d\n",
  812. sc->sc_dev.dv_xname, sc->sc_audio2.drq);
  813. return;
  814. }
  815. }
  816. timeout_set(&sc->sc_tmo1, ess_audio1_poll, sc);
  817. timeout_set(&sc->sc_tmo2, ess_audio2_poll, sc);
  818. /*
  819. * Set record and play parameters to default values defined in
  820. * generic audio driver.
  821. */
  822. pparams = ess_audio_default;
  823. rparams = ess_audio_default;
  824. ess_set_params(sc, AUMODE_RECORD|AUMODE_PLAY, 0, &pparams, &rparams);
  825. /* Do a hardware reset on the mixer. */
  826. ess_write_mix_reg(sc, ESS_MIX_RESET, ESS_MIX_RESET);
  827. /*
  828. * Set volume of Audio 1 to zero and disable Audio 1 DAC input
  829. * to playback mixer, since playback is always through Audio 2.
  830. */
  831. if (!ESS_USE_AUDIO1(sc->sc_model))
  832. ess_write_mix_reg(sc, ESS_MREG_VOLUME_VOICE, 0);
  833. ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
  834. if (ESS_USE_AUDIO1(sc->sc_model)) {
  835. ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIC);
  836. sc->in_port = ESS_SOURCE_MIC;
  837. sc->ndevs = ESS_1788_NDEVS;
  838. } else {
  839. /*
  840. * Set hardware record source to use output of the record
  841. * mixer. We do the selection of record source in software by
  842. * setting the gain of the unused sources to zero. (See
  843. * ess_set_in_ports.)
  844. */
  845. ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ESS_SOURCE_MIXER);
  846. sc->in_mask = 1 << ESS_MIC_REC_VOL;
  847. sc->ndevs = ESS_1888_NDEVS;
  848. ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x10);
  849. ess_set_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL2, 0x08);
  850. }
  851. /*
  852. * Set gain on each mixer device to a sensible value.
  853. * Devices not normally used are turned off, and other devices
  854. * are set to 50% volume.
  855. */
  856. for (i = 0; i < sc->ndevs; i++) {
  857. switch (i) {
  858. case ESS_MIC_PLAY_VOL:
  859. case ESS_LINE_PLAY_VOL:
  860. case ESS_CD_PLAY_VOL:
  861. case ESS_AUXB_PLAY_VOL:
  862. case ESS_DAC_REC_VOL:
  863. case ESS_LINE_REC_VOL:
  864. case ESS_SYNTH_REC_VOL:
  865. case ESS_CD_REC_VOL:
  866. case ESS_AUXB_REC_VOL:
  867. v = 0;
  868. break;
  869. default:
  870. v = ESS_4BIT_GAIN(AUDIO_MAX_GAIN / 2);
  871. break;
  872. }
  873. sc->gain[i][ESS_LEFT] = sc->gain[i][ESS_RIGHT] = v;
  874. ess_set_gain(sc, i, 1);
  875. }
  876. ess_setup(sc);
  877. /* Disable the speaker until the device is opened. */
  878. ess_speaker_off(sc);
  879. sc->spkr_state = SPKR_OFF;
  880. snprintf(ess_device.name, sizeof ess_device.name, "ES%s",
  881. essmodel[sc->sc_model]);
  882. snprintf(ess_device.version, sizeof ess_device.version, "0x%04x",
  883. sc->sc_version);
  884. if (ESS_USE_AUDIO1(sc->sc_model))
  885. audio_attach_mi(&ess_1788_hw_if, sc, &sc->sc_dev);
  886. else
  887. audio_attach_mi(&ess_1888_hw_if, sc, &sc->sc_dev);
  888. arg.type = AUDIODEV_TYPE_OPL;
  889. arg.hwif = 0;
  890. arg.hdl = 0;
  891. (void)config_found(&sc->sc_dev, &arg, audioprint);
  892. #ifdef AUDIO_DEBUG
  893. if (essdebug > 0)
  894. ess_printsc(sc);
  895. #endif
  896. }
  897. /*
  898. * Various routines to interface to higher level audio driver
  899. */
  900. int
  901. ess_open(void *addr, int flags)
  902. {
  903. struct ess_softc *sc = addr;
  904. DPRINTF(("ess_open: sc=%p\n", sc));
  905. if (sc->sc_open != 0 || ess_reset(sc) != 0)
  906. return ENXIO;
  907. ess_setup(sc); /* because we did a reset */
  908. sc->sc_open = 1;
  909. DPRINTF(("ess_open: opened\n"));
  910. return (0);
  911. }
  912. void
  913. ess_1788_close(void *addr)
  914. {
  915. struct ess_softc *sc = addr;
  916. DPRINTF(("ess_1788_close: sc=%p\n", sc));
  917. ess_speaker_off(sc);
  918. sc->spkr_state = SPKR_OFF;
  919. ess_audio1_halt(sc);
  920. sc->sc_open = 0;
  921. DPRINTF(("ess_1788_close: closed\n"));
  922. }
  923. void
  924. ess_1888_close(void *addr)
  925. {
  926. struct ess_softc *sc = addr;
  927. DPRINTF(("ess_1888_close: sc=%p\n", sc));
  928. ess_speaker_off(sc);
  929. sc->spkr_state = SPKR_OFF;
  930. ess_audio1_halt(sc);
  931. ess_audio2_halt(sc);
  932. sc->sc_open = 0;
  933. DPRINTF(("ess_1888_close: closed\n"));
  934. }
  935. /*
  936. * Wait for FIFO to drain, and analog section to settle.
  937. * XXX should check FIFO empty bit.
  938. */
  939. int
  940. ess_drain(void *addr)
  941. {
  942. tsleep(addr, PWAIT | PCATCH, "essdr", hz/20); /* XXX */
  943. return (0);
  944. }
  945. /* XXX should use reference count */
  946. int
  947. ess_speaker_ctl(void *addr, int newstate)
  948. {
  949. struct ess_softc *sc = addr;
  950. if ((newstate == SPKR_ON) && (sc->spkr_state == SPKR_OFF)) {
  951. ess_speaker_on(sc);
  952. sc->spkr_state = SPKR_ON;
  953. }
  954. if ((newstate == SPKR_OFF) && (sc->spkr_state == SPKR_ON)) {
  955. ess_speaker_off(sc);
  956. sc->spkr_state = SPKR_OFF;
  957. }
  958. return (0);
  959. }
  960. int
  961. ess_getdev(void *addr, struct audio_device *retp)
  962. {
  963. *retp = ess_device;
  964. return (0);
  965. }
  966. int
  967. ess_query_encoding(void *addr, struct audio_encoding *fp)
  968. {
  969. /*struct ess_softc *sc = addr;*/
  970. switch (fp->index) {
  971. case 0:
  972. strlcpy(fp->name, AudioEulinear, sizeof fp->name);
  973. fp->encoding = AUDIO_ENCODING_ULINEAR;
  974. fp->precision = 8;
  975. fp->flags = 0;
  976. break;
  977. case 1:
  978. strlcpy(fp->name, AudioEslinear, sizeof fp->name);
  979. fp->encoding = AUDIO_ENCODING_SLINEAR;
  980. fp->precision = 8;
  981. fp->flags = 0;
  982. break;
  983. case 2:
  984. strlcpy(fp->name, AudioEslinear_le, sizeof fp->name);
  985. fp->encoding = AUDIO_ENCODING_SLINEAR_LE;
  986. fp->precision = 16;
  987. fp->flags = 0;
  988. break;
  989. case 3:
  990. strlcpy(fp->name, AudioEulinear_le, sizeof fp->name);
  991. fp->encoding = AUDIO_ENCODING_ULINEAR_LE;
  992. fp->precision = 16;
  993. fp->flags = 0;
  994. break;
  995. default:
  996. return EINVAL;
  997. }
  998. fp->bps = AUDIO_BPS(fp->precision);
  999. fp->msb = 1;
  1000. return (0);
  1001. }
  1002. int
  1003. ess_set_params(void *addr, int setmode, int usemode,
  1004. struct audio_params *play, struct audio_params *rec)
  1005. {
  1006. struct ess_softc *sc = addr;
  1007. struct audio_params *p;
  1008. int mode;
  1009. int rate;
  1010. DPRINTF(("ess_set_params: set=%d use=%d\n", setmode, usemode));
  1011. /*
  1012. * The ES1887 manual (page 39, `Full-Duplex DMA Mode') claims that in
  1013. * full-duplex operation the sample rates must be the same for both
  1014. * channels. This appears to be false; the only bit in common is the
  1015. * clock source selection. However, we'll be conservative here.
  1016. * - mycroft
  1017. */
  1018. if (play->sample_rate != rec->sample_rate &&
  1019. usemode == (AUMODE_PLAY | AUMODE_RECORD)) {
  1020. if (setmode == AUMODE_PLAY) {
  1021. rec->sample_rate = play->sample_rate;
  1022. setmode |= AUMODE_RECORD;
  1023. } else if (setmode == AUMODE_RECORD) {
  1024. play->sample_rate = rec->sample_rate;
  1025. setmode |= AUMODE_PLAY;
  1026. } else
  1027. return (EINVAL);
  1028. }
  1029. for (mode = AUMODE_RECORD; mode != -1;
  1030. mode = mode == AUMODE_RECORD ? AUMODE_PLAY : -1) {
  1031. if ((setmode & mode) == 0)
  1032. continue;
  1033. p = mode == AUMODE_PLAY ? play : rec;
  1034. if (p->sample_rate < ESS_MINRATE)
  1035. p->sample_rate = ESS_MINRATE;
  1036. if (p->sample_rate > ESS_MAXRATE)
  1037. p->sample_rate = ESS_MAXRATE;
  1038. if (p->precision > 16)
  1039. p->precision = 16;
  1040. if (p->channels > 2)
  1041. p->channels = 2;
  1042. switch (p->encoding) {
  1043. case AUDIO_ENCODING_SLINEAR_BE:
  1044. case AUDIO_ENCODING_ULINEAR_BE:
  1045. if (p->precision != 8)
  1046. return EINVAL;
  1047. break;
  1048. case AUDIO_ENCODING_SLINEAR_LE:
  1049. case AUDIO_ENCODING_ULINEAR_LE:
  1050. break;
  1051. default:
  1052. return (EINVAL);
  1053. }
  1054. p->bps = AUDIO_BPS(p->precision);
  1055. p->msb = 1;
  1056. }
  1057. if (usemode == AUMODE_RECORD)
  1058. rate = rec->sample_rate;
  1059. else
  1060. rate = play->sample_rate;
  1061. ess_write_x_reg(sc, ESS_XCMD_SAMPLE_RATE, ess_srtotc(rate));
  1062. ess_write_x_reg(sc, ESS_XCMD_FILTER_CLOCK, ess_srtofc(rate));
  1063. if (!ESS_USE_AUDIO1(sc->sc_model)) {
  1064. ess_write_mix_reg(sc, ESS_MREG_SAMPLE_RATE, ess_srtotc(rate));
  1065. ess_write_mix_reg(sc, ESS_MREG_FILTER_CLOCK, ess_srtofc(rate));
  1066. }
  1067. return (0);
  1068. }
  1069. int
  1070. ess_audio1_trigger_output(void *addr, void *start, void *end, int blksize,
  1071. void (*intr)(void *), void *arg, struct audio_params *param)
  1072. {
  1073. struct ess_softc *sc = addr;
  1074. u_int8_t reg;
  1075. mtx_enter(&audio_lock);
  1076. DPRINTFN(1, ("ess_audio1_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
  1077. addr, start, end, blksize, intr, arg));
  1078. if (sc->sc_audio1.active)
  1079. panic("ess_audio1_trigger_output: already running");
  1080. sc->sc_audio1.active = 1;
  1081. sc->sc_audio1.intr = intr;
  1082. sc->sc_audio1.arg = arg;
  1083. if (sc->sc_audio1.polled) {
  1084. sc->sc_audio1.dmapos = 0;
  1085. sc->sc_audio1.buffersize = (char *)end - (char *)start;
  1086. sc->sc_audio1.dmacount = 0;
  1087. sc->sc_audio1.blksize = blksize;
  1088. timeout_add_msec(&sc->sc_tmo1, 1000/30);
  1089. }
  1090. reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
  1091. if (param->channels == 2) {
  1092. reg &= ~ESS_AUDIO_CTRL_MONO;
  1093. reg |= ESS_AUDIO_CTRL_STEREO;
  1094. } else {
  1095. reg |= ESS_AUDIO_CTRL_MONO;
  1096. reg &= ~ESS_AUDIO_CTRL_STEREO;
  1097. }
  1098. ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
  1099. reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
  1100. if (param->precision == 16)
  1101. reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
  1102. else
  1103. reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
  1104. if (param->channels == 2)
  1105. reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
  1106. else
  1107. reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
  1108. if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
  1109. param->encoding == AUDIO_ENCODING_SLINEAR_LE)
  1110. reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
  1111. else
  1112. reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
  1113. reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
  1114. ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
  1115. isa_dmastart(sc->sc_isa, sc->sc_audio1.drq, start,
  1116. (char *)end - (char *)start, NULL,
  1117. DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT);
  1118. /* Program transfer count registers with 2's complement of count. */
  1119. blksize = -blksize;
  1120. ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
  1121. ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
  1122. /* Use 4 bytes per output DMA. */
  1123. ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
  1124. /* Start auto-init DMA */
  1125. ess_wdsp(sc, ESS_ACMD_ENABLE_SPKR);
  1126. reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
  1127. reg &= ~(ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE);
  1128. reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
  1129. ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
  1130. mtx_leave(&audio_lock);
  1131. return (0);
  1132. }
  1133. int
  1134. ess_audio2_trigger_output(void *addr, void *start, void *end, int blksize,
  1135. void (*intr)(void *), void *arg, struct audio_params *param)
  1136. {
  1137. struct ess_softc *sc = addr;
  1138. u_int8_t reg;
  1139. mtx_enter(&audio_lock);
  1140. DPRINTFN(1, ("ess_audio2_trigger_output: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
  1141. addr, start, end, blksize, intr, arg));
  1142. if (sc->sc_audio2.active)
  1143. panic("ess_audio2_trigger_output: already running");
  1144. sc->sc_audio2.active = 1;
  1145. sc->sc_audio2.intr = intr;
  1146. sc->sc_audio2.arg = arg;
  1147. if (sc->sc_audio2.polled) {
  1148. sc->sc_audio2.dmapos = 0;
  1149. sc->sc_audio2.buffersize = (char *)end - (char *)start;
  1150. sc->sc_audio2.dmacount = 0;
  1151. sc->sc_audio2.blksize = blksize;
  1152. timeout_add_msec(&sc->sc_tmo2, 1000/30);
  1153. }
  1154. reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
  1155. if (param->precision == 16)
  1156. reg |= ESS_AUDIO2_CTRL2_FIFO_SIZE;
  1157. else
  1158. reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIZE;
  1159. if (param->channels == 2)
  1160. reg |= ESS_AUDIO2_CTRL2_CHANNELS;
  1161. else
  1162. reg &= ~ESS_AUDIO2_CTRL2_CHANNELS;
  1163. if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
  1164. param->encoding == AUDIO_ENCODING_SLINEAR_LE)
  1165. reg |= ESS_AUDIO2_CTRL2_FIFO_SIGNED;
  1166. else
  1167. reg &= ~ESS_AUDIO2_CTRL2_FIFO_SIGNED;
  1168. ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
  1169. isa_dmastart(sc->sc_isa, sc->sc_audio2.drq, start,
  1170. (char *)end - (char *)start, NULL,
  1171. DMAMODE_WRITE | DMAMODE_LOOP, BUS_DMA_NOWAIT);
  1172. if (IS16BITDRQ(sc->sc_audio2.drq))
  1173. blksize >>= 1; /* use word count for 16 bit DMA */
  1174. /* Program transfer count registers with 2's complement of count. */
  1175. blksize = -blksize;
  1176. ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTLO, blksize);
  1177. ess_write_mix_reg(sc, ESS_MREG_XFER_COUNTHI, blksize >> 8);
  1178. reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1);
  1179. if (IS16BITDRQ(sc->sc_audio2.drq))
  1180. reg |= ESS_AUDIO2_CTRL1_XFER_SIZE;
  1181. else
  1182. reg &= ~ESS_AUDIO2_CTRL1_XFER_SIZE;
  1183. reg |= ESS_AUDIO2_CTRL1_DEMAND_8;
  1184. reg |= ESS_AUDIO2_CTRL1_DAC_ENABLE | ESS_AUDIO2_CTRL1_FIFO_ENABLE |
  1185. ESS_AUDIO2_CTRL1_AUTO_INIT;
  1186. ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL1, reg);
  1187. mtx_leave(&audio_lock);
  1188. return (0);
  1189. }
  1190. int
  1191. ess_audio1_trigger_input(void *addr, void *start, void *end, int blksize,
  1192. void (*intr)(void *), void *arg, struct audio_params *param)
  1193. {
  1194. struct ess_softc *sc = addr;
  1195. u_int8_t reg;
  1196. mtx_enter(&audio_lock);
  1197. DPRINTFN(1, ("ess_audio1_trigger_input: sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
  1198. addr, start, end, blksize, intr, arg));
  1199. if (sc->sc_audio1.active)
  1200. panic("ess_audio1_trigger_input: already running");
  1201. sc->sc_audio1.active = 1;
  1202. sc->sc_audio1.intr = intr;
  1203. sc->sc_audio1.arg = arg;
  1204. if (sc->sc_audio1.polled) {
  1205. sc->sc_audio1.dmapos = 0;
  1206. sc->sc_audio1.buffersize = (char *)end - (char *)start;
  1207. sc->sc_audio1.dmacount = 0;
  1208. sc->sc_audio1.blksize = blksize;
  1209. timeout_add_msec(&sc->sc_tmo1, 1000/30);
  1210. }
  1211. reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL);
  1212. if (param->channels == 2) {
  1213. reg &= ~ESS_AUDIO_CTRL_MONO;
  1214. reg |= ESS_AUDIO_CTRL_STEREO;
  1215. } else {
  1216. reg |= ESS_AUDIO_CTRL_MONO;
  1217. reg &= ~ESS_AUDIO_CTRL_STEREO;
  1218. }
  1219. ess_write_x_reg(sc, ESS_XCMD_AUDIO_CTRL, reg);
  1220. reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1);
  1221. if (param->precision == 16)
  1222. reg |= ESS_AUDIO1_CTRL1_FIFO_SIZE;
  1223. else
  1224. reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIZE;
  1225. if (param->channels == 2)
  1226. reg |= ESS_AUDIO1_CTRL1_FIFO_STEREO;
  1227. else
  1228. reg &= ~ESS_AUDIO1_CTRL1_FIFO_STEREO;
  1229. if (param->encoding == AUDIO_ENCODING_SLINEAR_BE ||
  1230. param->encoding == AUDIO_ENCODING_SLINEAR_LE)
  1231. reg |= ESS_AUDIO1_CTRL1_FIFO_SIGNED;
  1232. else
  1233. reg &= ~ESS_AUDIO1_CTRL1_FIFO_SIGNED;
  1234. reg |= ESS_AUDIO1_CTRL1_FIFO_CONNECT;
  1235. ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL1, reg);
  1236. isa_dmastart(sc->sc_isa, sc->sc_audio1.drq, start,
  1237. (char *)end - (char *)start, NULL,
  1238. DMAMODE_READ | DMAMODE_LOOP, BUS_DMA_NOWAIT);
  1239. /* Program transfer count registers with 2's complement of count. */
  1240. blksize = -blksize;
  1241. ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTLO, blksize);
  1242. ess_write_x_reg(sc, ESS_XCMD_XFER_COUNTHI, blksize >> 8);
  1243. /* Use 4 bytes per input DMA. */
  1244. ess_set_xreg_bits(sc, ESS_XCMD_DEMAND_CTRL, ESS_DEMAND_CTRL_DEMAND_4);
  1245. /* Start auto-init DMA */
  1246. ess_wdsp(sc, ESS_ACMD_DISABLE_SPKR);
  1247. reg = ess_read_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2);
  1248. reg |= ESS_AUDIO1_CTRL2_DMA_READ | ESS_AUDIO1_CTRL2_ADC_ENABLE;
  1249. reg |= ESS_AUDIO1_CTRL2_FIFO_ENABLE | ESS_AUDIO1_CTRL2_AUTO_INIT;
  1250. ess_write_x_reg(sc, ESS_XCMD_AUDIO1_CTRL2, reg);
  1251. mtx_leave(&audio_lock);
  1252. return (0);
  1253. }
  1254. int
  1255. ess_audio1_halt(void *addr)
  1256. {
  1257. struct ess_softc *sc = addr;
  1258. DPRINTF(("ess_audio1_halt: sc=%p\n", sc));
  1259. mtx_enter(&audio_lock);
  1260. if (sc->sc_audio1.active) {
  1261. ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO1_CTRL2,
  1262. ESS_AUDIO1_CTRL2_FIFO_ENABLE);
  1263. isa_dmaabort(sc->sc_isa, sc->sc_audio1.drq);
  1264. if (sc->sc_audio1.polled)
  1265. timeout_del(&sc->sc_tmo1);
  1266. sc->sc_audio1.active = 0;
  1267. }
  1268. mtx_leave(&audio_lock);
  1269. return (0);
  1270. }
  1271. int
  1272. ess_audio2_halt(void *addr)
  1273. {
  1274. struct ess_softc *sc = addr;
  1275. DPRINTF(("ess_audio2_halt: sc=%p\n", sc));
  1276. mtx_enter(&audio_lock);
  1277. if (sc->sc_audio2.active) {
  1278. ess_clear_mreg_bits(sc, ESS_MREG_AUDIO2_CTRL1,
  1279. ESS_AUDIO2_CTRL1_DAC_ENABLE |
  1280. ESS_AUDIO2_CTRL1_FIFO_ENABLE);
  1281. isa_dmaabort(sc->sc_isa, sc->sc_audio2.drq);
  1282. if (sc->sc_audio2.polled)
  1283. timeout_del(&sc->sc_tmo2);
  1284. sc->sc_audio2.active = 0;
  1285. }
  1286. mtx_leave(&audio_lock);
  1287. return (0);
  1288. }
  1289. int
  1290. ess_audio1_intr(void *arg)
  1291. {
  1292. struct ess_softc *sc = arg;
  1293. u_int8_t reg;
  1294. DPRINTFN(1,("ess_audio1_intr: intr=%p\n", sc->sc_audio1.intr));
  1295. mtx_enter(&audio_lock);
  1296. /* Check and clear interrupt on Audio1. */
  1297. reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS);
  1298. if ((reg & ESS_DSP_READ_OFLOW) == 0) {
  1299. mtx_leave(&audio_lock);
  1300. return (0);
  1301. }
  1302. reg = EREAD1(sc->sc_iot, sc->sc_ioh, ESS_CLEAR_INTR);
  1303. sc->sc_audio1.nintr++;
  1304. if (sc->sc_audio1.active) {
  1305. (*sc->sc_audio1.intr)(sc->sc_audio1.arg);
  1306. mtx_leave(&audio_lock);
  1307. return (1);
  1308. } else {
  1309. mtx_leave(&audio_lock);
  1310. return (0);
  1311. }
  1312. }
  1313. int
  1314. ess_audio2_intr(void *arg)
  1315. {
  1316. struct ess_softc *sc = arg;
  1317. u_int8_t reg;
  1318. DPRINTFN(1,("ess_audio2_intr: intr=%p\n", sc->sc_audio2.intr));
  1319. mtx_enter(&audio_lock);
  1320. /* Check and clear interrupt on Audio2. */
  1321. reg = ess_read_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2);
  1322. if ((reg & ESS_AUDIO2_CTRL2_IRQ_LATCH) == 0) {
  1323. mtx_leave(&audio_lock);
  1324. return (0);
  1325. }
  1326. reg &= ~ESS_AUDIO2_CTRL2_IRQ_LATCH;
  1327. ess_write_mix_reg(sc, ESS_MREG_AUDIO2_CTRL2, reg);
  1328. sc->sc_audio2.nintr++;
  1329. if (sc->sc_audio2.active) {
  1330. (*sc->sc_audio2.intr)(sc->sc_audio2.arg);
  1331. mtx_leave(&audio_lock);
  1332. return (1);
  1333. } else {
  1334. mtx_leave(&audio_lock);
  1335. return (0);
  1336. }
  1337. }
  1338. void
  1339. ess_audio1_poll(void *addr)
  1340. {
  1341. struct ess_softc *sc = addr;
  1342. int dmapos, dmacount;
  1343. if (!sc->sc_audio1.active)
  1344. return;
  1345. mtx_enter(&audio_lock);
  1346. sc->sc_audio1.nintr++;
  1347. dmapos = isa_dmacount(sc->sc_isa, sc->sc_audio1.drq);
  1348. dmacount = sc->sc_audio1.dmapos - dmapos;
  1349. if (dmacount < 0)
  1350. dmacount += sc->sc_audio1.buffersize;
  1351. sc->sc_audio1.dmapos = dmapos;
  1352. #if 1
  1353. dmacount += sc->sc_audio1.dmacount;
  1354. while (dmacount > sc->sc_audio1.blksize) {
  1355. dmacount -= sc->sc_audio1.blksize;
  1356. (*sc->sc_audio1.intr)(sc->sc_audio1.arg);
  1357. }
  1358. sc->sc_audio1.dmacount = dmacount;
  1359. #else
  1360. (*sc->sc_audio1.intr)(sc->sc_audio1.arg, dmacount);
  1361. #endif
  1362. timeout_add_msec(&sc->sc_tmo1, 1000/30);
  1363. mtx_leave(&audio_lock);
  1364. }
  1365. void
  1366. ess_audio2_poll(void *addr)
  1367. {
  1368. struct ess_softc *sc = addr;
  1369. int dmapos, dmacount;
  1370. if (!sc->sc_audio2.active)
  1371. return;
  1372. mtx_enter(&audio_lock);
  1373. sc->sc_audio2.nintr++;
  1374. dmapos = isa_dmacount(sc->sc_isa, sc->sc_audio2.drq);
  1375. dmacount = sc->sc_audio2.dmapos - dmapos;
  1376. if (dmacount < 0)
  1377. dmacount += sc->sc_audio2.buffersize;
  1378. sc->sc_audio2.dmapos = dmapos;
  1379. #if 1
  1380. dmacount += sc->sc_audio2.dmacount;
  1381. while (dmacount > sc->sc_audio2.blksize) {
  1382. dmacount -= sc->sc_audio2.blksize;
  1383. (*sc->sc_audio2.intr)(sc->sc_audio2.arg);
  1384. }
  1385. sc->sc_audio2.dmacount = dmacount;
  1386. #else
  1387. (*sc->sc_audio2.intr)(sc->sc_audio2.arg, dmacount);
  1388. #endif
  1389. timeout_add_msec(&sc->sc_tmo2, 1000/30);
  1390. mtx_leave(&audio_lock);
  1391. }
  1392. int
  1393. ess_round_blocksize(void *addr, int blk)
  1394. {
  1395. return ((blk + 7) & -8); /* round for max DMA size */
  1396. }
  1397. int
  1398. ess_set_port(void *addr, mixer_ctrl_t *cp)
  1399. {
  1400. struct ess_softc *sc = addr;
  1401. int lgain, rgain;
  1402. DPRINTFN(5,("ess_set_port: port=%d num_channels=%d\n",
  1403. cp->dev, cp->un.value.num_channels));
  1404. switch (cp->dev) {
  1405. /*
  1406. * The following mixer ports are all stereo. If we get a
  1407. * single-channel gain value passed in, then we duplicate it
  1408. * to both left and right channels.
  1409. */
  1410. case ESS_MASTER_VOL:
  1411. case ESS_DAC_PLAY_VOL:
  1412. case ESS_MIC_PLAY_VOL:
  1413. case ESS_LINE_PLAY_VOL:
  1414. case ESS_SYNTH_PLAY_VOL:
  1415. case ESS_CD_PLAY_VOL:
  1416. case ESS_AUXB_PLAY_VOL:
  1417. case ESS_RECORD_VOL:
  1418. if (cp->type != AUDIO_MIXER_VALUE)
  1419. return EINVAL;
  1420. switch (cp->un.value.num_channels) {
  1421. case 1:
  1422. lgain = rgain = ESS_4BIT_GAIN(
  1423. cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
  1424. break;
  1425. case 2:
  1426. lgain = ESS_4BIT_GAIN(
  1427. cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
  1428. rgain = ESS_4BIT_GAIN(
  1429. cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
  1430. break;
  1431. default:
  1432. return EINVAL;
  1433. }
  1434. sc->gain[cp->dev][ESS_LEFT] = lgain;
  1435. sc->gain[cp->dev][ESS_RIGHT] = rgain;
  1436. ess_set_gain(sc, cp->dev, 1);
  1437. return (0);
  1438. /*
  1439. * The PC speaker port is mono. If we get a stereo gain value
  1440. * passed in, then we return EINVAL.
  1441. */
  1442. case ESS_PCSPEAKER_VOL:
  1443. if (cp->un.value.num_channels != 1)
  1444. return EINVAL;
  1445. sc->gain[cp->dev][ESS_LEFT] = sc->gain[cp->dev][ESS_RIGHT] =
  1446. ESS_3BIT_GAIN(cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
  1447. ess_set_gain(sc, cp->dev, 1);
  1448. return (0);
  1449. case ESS_RECORD_SOURCE:
  1450. if (ESS_USE_AUDIO1(sc->sc_model)) {
  1451. if (cp->type == AUDIO_MIXER_ENUM)
  1452. return (ess_set_in_port(sc, cp->un.ord));
  1453. else
  1454. return (EINVAL);
  1455. } else {
  1456. if (cp->type == AUDIO_MIXER_SET)
  1457. return (ess_set_in_ports(sc, cp->un.mask));
  1458. else
  1459. return (EINVAL);
  1460. }
  1461. return (0);
  1462. case ESS_RECORD_MONITOR:
  1463. if (cp->type != AUDIO_MIXER_ENUM)
  1464. return EINVAL;
  1465. if (cp->un.ord)
  1466. /* Enable monitor */
  1467. ess_set_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
  1468. ESS_AUDIO_CTRL_MONITOR);
  1469. else
  1470. /* Disable monitor */
  1471. ess_clear_xreg_bits(sc, ESS_XCMD_AUDIO_CTRL,
  1472. ESS_AUDIO_CTRL_MONITOR);
  1473. return (0);
  1474. }
  1475. if (ESS_USE_AUDIO1(sc->sc_model))
  1476. return (EINVAL);
  1477. switch (cp->dev) {
  1478. case ESS_DAC_REC_VOL:
  1479. case ESS_MIC_REC_VOL:
  1480. case ESS_LINE_REC_VOL:
  1481. case ESS_SYNTH_REC_VOL:
  1482. case ESS_CD_REC_VOL:
  1483. case ESS_AUXB_REC_VOL:
  1484. if (cp->type != AUDIO_MIXER_VALUE)
  1485. return EINVAL;
  1486. switch (cp->un.value.num_channels) {
  1487. case 1:
  1488. lgain = rgain = ESS_4BIT_GAIN(
  1489. cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
  1490. break;
  1491. case 2:
  1492. lgain = ESS_4BIT_GAIN(
  1493. cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]);
  1494. rgain = ESS_4BIT_GAIN(
  1495. cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
  1496. break;
  1497. default:
  1498. return EINVAL;
  1499. }
  1500. sc->gain[cp->dev][ESS_LEFT] = lgain;
  1501. sc->gain[cp->dev][ESS_RIGHT] = rgain;
  1502. ess_set_gain(sc, cp->dev, 1);
  1503. return (0);
  1504. case ESS_MIC_PREAMP:
  1505. if (cp->type != AUDIO_MIXER_ENUM)
  1506. return EINVAL;
  1507. if (cp->un.ord)
  1508. /* Enable microphone preamp */
  1509. ess_set_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
  1510. ESS_PREAMP_CTRL_ENABLE);
  1511. else
  1512. /* Disable microphone preamp */
  1513. ess_clear_xreg_bits(sc, ESS_XCMD_PREAMP_CTRL,
  1514. ESS_PREAMP_CTRL_ENABLE);
  1515. return (0);
  1516. }
  1517. return (EINVAL);
  1518. }
  1519. int
  1520. ess_get_port(void *addr, mixer_ctrl_t *cp)
  1521. {
  1522. struct ess_softc *sc = addr;
  1523. DPRINTFN(5,("ess_get_port: port=%d\n", cp->dev));
  1524. switch (cp->dev) {
  1525. case ESS_MASTER_VOL:
  1526. case ESS_DAC_PLAY_VOL:
  1527. case ESS_MIC_PLAY_VOL:
  1528. case ESS_LINE_PLAY_VOL:
  1529. case ESS_SYNTH_PLAY_VOL:
  1530. case ESS_CD_PLAY_VOL:
  1531. case ESS_AUXB_PLAY_VOL:
  1532. case ESS_RECORD_VOL:
  1533. switch (cp->un.value.num_channels) {
  1534. case 1:
  1535. cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
  1536. sc->gain[cp->dev][ESS_LEFT];
  1537. break;
  1538. case 2:
  1539. cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
  1540. sc->gain[cp->dev][ESS_LEFT];
  1541. cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
  1542. sc->gain[cp->dev][ESS_RIGHT];
  1543. break;
  1544. default:
  1545. return EINVAL;
  1546. }
  1547. return (0);
  1548. case ESS_PCSPEAKER_VOL:
  1549. if (cp->un.value.num_channels != 1)
  1550. return EINVAL;
  1551. cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
  1552. sc->gain[cp->dev][ESS_LEFT];
  1553. return (0);
  1554. case ESS_RECORD_SOURCE:
  1555. if (ESS_USE_AUDIO1(sc->sc_model))
  1556. cp->un.ord = sc->in_port;
  1557. else
  1558. cp->un.mask = sc->in_mask;
  1559. return (0);
  1560. case ESS_RECORD_MONITOR:
  1561. cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_AUDIO_CTRL) &
  1562. ESS_AUDIO_CTRL_MONITOR) ? 1 : 0;
  1563. return (0);
  1564. }
  1565. if (ESS_USE_AUDIO1(sc->sc_model))
  1566. return (EINVAL);
  1567. switch (cp->dev) {
  1568. case ESS_DAC_REC_VOL:
  1569. case ESS_MIC_REC_VOL:
  1570. case ESS_LINE_REC_VOL:
  1571. case ESS_SYNTH_REC_VOL:
  1572. case ESS_CD_REC_VOL:
  1573. case ESS_AUXB_REC_VOL:
  1574. switch (cp->un.value.num_channels) {
  1575. case 1:
  1576. cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
  1577. sc->gain[cp->dev][ESS_LEFT];
  1578. break;
  1579. case 2:
  1580. cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
  1581. sc->gain[cp->dev][ESS_LEFT];
  1582. cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
  1583. sc->gain[cp->dev][ESS_RIGHT];
  1584. break;
  1585. default:
  1586. return EINVAL;
  1587. }
  1588. return (0);
  1589. case ESS_MIC_PREAMP:
  1590. cp->un.ord = (ess_read_x_reg(sc, ESS_XCMD_PREAMP_CTRL) &
  1591. ESS_PREAMP_CTRL_ENABLE) ? 1 : 0;
  1592. return (0);
  1593. }
  1594. return (EINVAL);
  1595. }
  1596. int
  1597. ess_query_devinfo(void *addr, mixer_devinfo_t *dip)
  1598. {
  1599. struct ess_softc *sc = addr;
  1600. DPRINTFN(5,("ess_query_devinfo: model=%d index=%d\n",
  1601. sc->sc_model, dip->index));
  1602. /*
  1603. * REVISIT: There are some slight differences between the
  1604. * mixers on the different ESS chips, which can
  1605. * be sorted out using the chip model rather than a
  1606. * separate mixer model.
  1607. * This is currently coded assuming an ES1887; we
  1608. * need to work out which bits are not applicable to
  1609. * the other models (1888 and 888).
  1610. */
  1611. switch (dip->index) {
  1612. case ESS_DAC_PLAY_VOL:
  1613. dip->mixer_class = ESS_INPUT_CLASS;
  1614. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1615. strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
  1616. dip->type = AUDIO_MIXER_VALUE;
  1617. dip->un.v.num_channels = 2;
  1618. strlcpy(dip->un.v.units.name, AudioNvolume,
  1619. sizeof dip->un.v.units.name);
  1620. return (0);
  1621. case ESS_MIC_PLAY_VOL:
  1622. dip->mixer_class = ESS_INPUT_CLASS;
  1623. dip->prev = AUDIO_MIXER_LAST;
  1624. if (ESS_USE_AUDIO1(sc->sc_model))
  1625. dip->next = AUDIO_MIXER_LAST;
  1626. else
  1627. dip->next = ESS_MIC_PREAMP;
  1628. strlcpy(dip->label.name, AudioNmicrophone,
  1629. sizeof dip->label.name);
  1630. dip->type = AUDIO_MIXER_VALUE;
  1631. dip->un.v.num_channels = 2;
  1632. strlcpy(dip->un.v.units.name, AudioNvolume,
  1633. sizeof dip->un.v.units.name);
  1634. return (0);
  1635. case ESS_LINE_PLAY_VOL:
  1636. dip->mixer_class = ESS_INPUT_CLASS;
  1637. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1638. strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
  1639. dip->type = AUDIO_MIXER_VALUE;
  1640. dip->un.v.num_channels = 2;
  1641. strlcpy(dip->un.v.units.name, AudioNvolume,
  1642. sizeof dip->un.v.units.name);
  1643. return (0);
  1644. case ESS_SYNTH_PLAY_VOL:
  1645. dip->mixer_class = ESS_INPUT_CLASS;
  1646. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1647. strlcpy(dip->label.name, AudioNfmsynth,
  1648. sizeof dip->label.name);
  1649. dip->type = AUDIO_MIXER_VALUE;
  1650. dip->un.v.num_channels = 2;
  1651. strlcpy(dip->un.v.units.name, AudioNvolume,
  1652. sizeof dip->un.v.units.name);
  1653. return (0);
  1654. case ESS_CD_PLAY_VOL:
  1655. dip->mixer_class = ESS_INPUT_CLASS;
  1656. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1657. strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
  1658. dip->type = AUDIO_MIXER_VALUE;
  1659. dip->un.v.num_channels = 2;
  1660. strlcpy(dip->un.v.units.name, AudioNvolume,
  1661. sizeof dip->un.v.units.name);
  1662. return (0);
  1663. case ESS_AUXB_PLAY_VOL:
  1664. dip->mixer_class = ESS_INPUT_CLASS;
  1665. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1666. strlcpy(dip->label.name, "auxb", sizeof dip->label.name);
  1667. dip->type = AUDIO_MIXER_VALUE;
  1668. dip->un.v.num_channels = 2;
  1669. strlcpy(dip->un.v.units.name, AudioNvolume,
  1670. sizeof dip->un.v.units.name);
  1671. return (0);
  1672. case ESS_INPUT_CLASS:
  1673. dip->mixer_class = ESS_INPUT_CLASS;
  1674. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1675. strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name);
  1676. dip->type = AUDIO_MIXER_CLASS;
  1677. return (0);
  1678. case ESS_MASTER_VOL:
  1679. dip->mixer_class = ESS_OUTPUT_CLASS;
  1680. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1681. strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
  1682. dip->type = AUDIO_MIXER_VALUE;
  1683. dip->un.v.num_channels = 2;
  1684. strlcpy(dip->un.v.units.name, AudioNvolume,
  1685. sizeof dip->un.v.units.name);
  1686. return (0);
  1687. case ESS_PCSPEAKER_VOL:
  1688. dip->mixer_class = ESS_OUTPUT_CLASS;
  1689. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1690. strlcpy(dip->label.name, "pc_speaker", sizeof dip->label.name);
  1691. dip->type = AUDIO_MIXER_VALUE;
  1692. dip->un.v.num_channels = 1;
  1693. strlcpy(dip->un.v.units.name, AudioNvolume,
  1694. sizeof dip->un.v.units.name);
  1695. return (0);
  1696. case ESS_OUTPUT_CLASS:
  1697. dip->mixer_class = ESS_OUTPUT_CLASS;
  1698. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1699. strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name);
  1700. dip->type = AUDIO_MIXER_CLASS;
  1701. return (0);
  1702. case ESS_RECORD_VOL:
  1703. dip->mixer_class = ESS_RECORD_CLASS;
  1704. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1705. strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name);
  1706. dip->type = AUDIO_MIXER_VALUE;
  1707. dip->un.v.num_channels = 2;
  1708. strlcpy(dip->un.v.units.name, AudioNvolume,
  1709. sizeof dip->un.v.units.name);
  1710. return (0);
  1711. case ESS_RECORD_SOURCE:
  1712. dip->mixer_class = ESS_RECORD_CLASS;
  1713. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1714. strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
  1715. if (ESS_USE_AUDIO1(sc->sc_model)) {
  1716. /*
  1717. * The 1788 doesn't use the input mixer control that
  1718. * the 1888 uses, because it's a pain when you only
  1719. * have one mixer.
  1720. * Perhaps it could be emulated by keeping both sets of
  1721. * gain values, and doing a `context switch' of the
  1722. * mixer registers when shifting from playing to
  1723. * recording.
  1724. */
  1725. dip->type = AUDIO_MIXER_ENUM;
  1726. dip->un.e.num_mem = 4;
  1727. strlcpy(dip->un.e.member[0].label.name,
  1728. AudioNmicrophone,
  1729. sizeof dip->un.e.member[0].label.name);
  1730. dip->un.e.member[0].ord = ESS_SOURCE_MIC;
  1731. strlcpy(dip->un.e.member[1].label.name, AudioNline,
  1732. sizeof dip->un.e.member[1].label.name);
  1733. dip->un.e.member[1].ord = ESS_SOURCE_LINE;
  1734. strlcpy(dip->un.e.member[2].label.name, AudioNcd,
  1735. sizeof dip->un.e.member[2].label.name);
  1736. dip->un.e.member[2].ord = ESS_SOURCE_CD;
  1737. strlcpy(dip->un.e.member[3].label.name, AudioNmixerout,
  1738. sizeof dip->un.e.member[3].label.name);
  1739. dip->un.e.member[3].ord = ESS_SOURCE_MIXER;
  1740. } else {
  1741. dip->type = AUDIO_MIXER_SET;
  1742. dip->un.s.num_mem = 6;
  1743. strlcpy(dip->un.s.member[0].label.name, AudioNdac,
  1744. sizeof dip->un.e.member[0].label.name);
  1745. dip->un.s.member[0].mask = 1 << ESS_DAC_REC_VOL;
  1746. strlcpy(dip->un.s.member[1].label.name,
  1747. AudioNmicrophone,
  1748. sizeof dip->un.e.member[1].label.name);
  1749. dip->un.s.member[1].mask = 1 << ESS_MIC_REC_VOL;
  1750. strlcpy(dip->un.s.member[2].label.name, AudioNline,
  1751. sizeof dip->un.e.member[2].label.name);
  1752. dip->un.s.member[2].mask = 1 << ESS_LINE_REC_VOL;
  1753. strlcpy(dip->un.s.member[3].label.name, AudioNfmsynth,
  1754. sizeof dip->un.e.member[3].label.name);
  1755. dip->un.s.member[3].mask = 1 << ESS_SYNTH_REC_VOL;
  1756. strlcpy(dip->un.s.member[4].label.name, AudioNcd,
  1757. sizeof dip->un.e.member[4].label.name);
  1758. dip->un.s.member[4].mask = 1 << ESS_CD_REC_VOL;
  1759. strlcpy(dip->un.s.member[5].label.name, "auxb",
  1760. sizeof dip->un.e.member[5].label.name);
  1761. dip->un.s.member[5].mask = 1 << ESS_AUXB_REC_VOL;
  1762. }
  1763. return (0);
  1764. case ESS_RECORD_CLASS:
  1765. dip->mixer_class = ESS_RECORD_CLASS;
  1766. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1767. strlcpy(dip->label.name, AudioCrecord, sizeof dip->label.name);
  1768. dip->type = AUDIO_MIXER_CLASS;
  1769. return (0);
  1770. case ESS_RECORD_MONITOR:
  1771. dip->prev = dip->next = AUDIO_MIXER_LAST;
  1772. strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
  1773. dip->type = AUDIO_MIXER_ENUM;
  1774. dip->mixer_class = ESS_MONITOR_CLASS;
  1775. dip->un.e.num_mem = 2;
  1776. strlcpy(dip->un.e.member[0].label.name, AudioNoff,
  1777. sizeof dip->un.e.member[0].label.name);
  1778. dip->un.e.member[0].ord = 0;
  1779. strlcpy(dip->un.e.member[1].label.name, AudioNon,
  1780. sizeof dip->un.e.member[1].label.name);
  1781. dip->un.e.member[1].ord = 1;
  1782. return (0);
  1783. case ESS_MONITOR_CLASS:
  1784. dip->mixer_class = ESS_MONITOR_CLASS;
  1785. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1786. strlcpy(dip->label.name, AudioCmonitor,
  1787. sizeof dip->label.name);
  1788. dip->type = AUDIO_MIXER_CLASS;
  1789. return (0);
  1790. }
  1791. if (ESS_USE_AUDIO1(sc->sc_model))
  1792. return (ENXIO);
  1793. switch (dip->index) {
  1794. case ESS_DAC_REC_VOL:
  1795. dip->mixer_class = ESS_RECORD_CLASS;
  1796. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1797. strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name);
  1798. dip->type = AUDIO_MIXER_VALUE;
  1799. dip->un.v.num_channels = 2;
  1800. strlcpy(dip->un.v.units.name, AudioNvolume,
  1801. sizeof dip->un.v.units.name);
  1802. return (0);
  1803. case ESS_MIC_REC_VOL:
  1804. dip->mixer_class = ESS_RECORD_CLASS;
  1805. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1806. strlcpy(dip->label.name, AudioNmicrophone,
  1807. sizeof dip->label.name);
  1808. dip->type = AUDIO_MIXER_VALUE;
  1809. dip->un.v.num_channels = 2;
  1810. strlcpy(dip->un.v.units.name, AudioNvolume,
  1811. sizeof dip->un.v.units.name);
  1812. return (0);
  1813. case ESS_LINE_REC_VOL:
  1814. dip->mixer_class = ESS_RECORD_CLASS;
  1815. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1816. strlcpy(dip->label.name, AudioNline, sizeof dip->label.name);
  1817. dip->type = AUDIO_MIXER_VALUE;
  1818. dip->un.v.num_channels = 2;
  1819. strlcpy(dip->un.v.units.name, AudioNvolume,
  1820. sizeof dip->un.v.units.name);
  1821. return (0);
  1822. case ESS_SYNTH_REC_VOL:
  1823. dip->mixer_class = ESS_RECORD_CLASS;
  1824. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1825. strlcpy(dip->label.name, AudioNfmsynth,
  1826. sizeof dip->label.name);
  1827. dip->type = AUDIO_MIXER_VALUE;
  1828. dip->un.v.num_channels = 2;
  1829. strlcpy(dip->un.v.units.name, AudioNvolume,
  1830. sizeof dip->un.v.units.name);
  1831. return (0);
  1832. case ESS_CD_REC_VOL:
  1833. dip->mixer_class = ESS_RECORD_CLASS;
  1834. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1835. strlcpy(dip->label.name, AudioNcd, sizeof dip->label.name);
  1836. dip->type = AUDIO_MIXER_VALUE;
  1837. dip->un.v.num_channels = 2;
  1838. strlcpy(dip->un.v.units.name, AudioNvolume,
  1839. sizeof dip->un.v.units.name);
  1840. return (0);
  1841. case ESS_AUXB_REC_VOL:
  1842. dip->mixer_class = ESS_RECORD_CLASS;
  1843. dip->next = dip->prev = AUDIO_MIXER_LAST;
  1844. strlcpy(dip->label.name, "auxb", sizeof dip->label.name);
  1845. dip->type = AUDIO_MIXER_VALUE;
  1846. dip->un.v.num_channels = 2;
  1847. strlcpy(dip->un.v.units.name, AudioNvolume,
  1848. sizeof dip->un.v.units.name);
  1849. return (0);
  1850. case ESS_MIC_PREAMP:
  1851. dip->mixer_class = ESS_INPUT_CLASS;
  1852. dip->prev = ESS_MIC_PLAY_VOL;
  1853. dip->next = AUDIO_MIXER_LAST;
  1854. strlcpy(dip->label.name, AudioNpreamp, sizeof dip->label.name);
  1855. dip->type = AUDIO_MIXER_ENUM;
  1856. dip->un.e.num_mem = 2;
  1857. strlcpy(dip->un.e.member[0].label.name, AudioNoff,
  1858. sizeof dip->un.e.member[0].label.name);
  1859. dip->un.e.member[0].ord = 0;
  1860. strlcpy(dip->un.e.member[1].label.name, AudioNon,
  1861. sizeof dip->un.e.member[1].label.name);
  1862. dip->un.e.member[1].ord = 1;
  1863. return (0);
  1864. }
  1865. return (ENXIO);
  1866. }
  1867. void *
  1868. ess_malloc(void *addr, int direction, size_t size, int pool, int flags)
  1869. {
  1870. struct ess_softc *sc = addr;
  1871. int drq;
  1872. if (!ESS_USE_AUDIO1(sc->sc_model))
  1873. drq = sc->sc_audio2.drq;
  1874. else
  1875. drq = sc->sc_audio1.drq;
  1876. return (isa_malloc(sc->sc_isa, drq, size, pool, flags));
  1877. }
  1878. void
  1879. ess_free(void *addr, void *ptr, int pool)
  1880. {
  1881. isa_free(ptr, pool);
  1882. }
  1883. size_t
  1884. ess_round_buffersize(void *addr, int direction, size_t size)
  1885. {
  1886. if (size > MAX_ISADMA)
  1887. size = MAX_ISADMA;
  1888. return (size);
  1889. }
  1890. paddr_t
  1891. ess_mappage(void *addr, void *mem, off_t off, int prot)
  1892. {
  1893. return (isa_mappage(mem, off, prot));
  1894. }
  1895. int
  1896. ess_1788_get_props(void *addr)
  1897. {
  1898. return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT);
  1899. }
  1900. int
  1901. ess_1888_get_props(void *addr)
  1902. {
  1903. return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT | AUDIO_PROP_FULLDUPLEX);
  1904. }
  1905. /* ============================================
  1906. * Generic functions for ess, not used by audio h/w i/f
  1907. * =============================================
  1908. */
  1909. /*
  1910. * Reset the chip.
  1911. * Return non-zero if the chip isn't detected.
  1912. */
  1913. int
  1914. ess_reset(struct ess_softc *sc)
  1915. {
  1916. bus_space_tag_t iot = sc->sc_iot;
  1917. bus_space_handle_t ioh = sc->sc_ioh;
  1918. sc->sc_audio1.active = 0;
  1919. sc->sc_audio2.active = 0;
  1920. EWRITE1(iot, ioh, ESS_DSP_RESET, ESS_RESET_EXT);
  1921. delay(10000);
  1922. EWRITE1(iot, ioh, ESS_DSP_RESET, 0);
  1923. if (ess_rdsp(sc) != ESS_MAGIC)
  1924. return (1);
  1925. /* Enable access to the ESS extension commands. */
  1926. ess_wdsp(sc, ESS_ACMD_ENABLE_EXT);
  1927. return (0);
  1928. }
  1929. void
  1930. ess_set_gain(sc, port, on)
  1931. struct ess_softc *sc;
  1932. int port;
  1933. int on;
  1934. {
  1935. int gain, left, right;
  1936. int mix;
  1937. int src;
  1938. int stereo;
  1939. /*
  1940. * Most gain controls are found in the mixer registers and
  1941. * are stereo. Any that are not, must set mix and stereo as
  1942. * required.
  1943. */
  1944. mix = 1;
  1945. stereo = 1;
  1946. switch (port) {
  1947. case ESS_MASTER_VOL:
  1948. src = ESS_MREG_VOLUME_MASTER;
  1949. break;
  1950. case ESS_DAC_PLAY_VOL:
  1951. if (ESS_USE_AUDIO1(sc->sc_model))
  1952. src = ESS_MREG_VOLUME_VOICE;
  1953. else
  1954. src = 0x7C;
  1955. break;
  1956. case ESS_MIC_PLAY_VOL:
  1957. src = ESS_MREG_VOLUME_MIC;
  1958. break;
  1959. case ESS_LINE_PLAY_VOL:
  1960. src = ESS_MREG_VOLUME_LINE;
  1961. break;
  1962. case ESS_SYNTH_PLAY_VOL:
  1963. src = ESS_MREG_VOLUME_SYNTH;
  1964. break;
  1965. case ESS_CD_PLAY_VOL:
  1966. src = ESS_MREG_VOLUME_CD;
  1967. break;
  1968. case ESS_AUXB_PLAY_VOL:
  1969. src = ESS_MREG_VOLUME_AUXB;
  1970. break;
  1971. case ESS_PCSPEAKER_VOL:
  1972. src = ESS_MREG_VOLUME_PCSPKR;
  1973. stereo = 0;
  1974. break;
  1975. case ESS_DAC_REC_VOL:
  1976. src = 0x69;
  1977. break;
  1978. case ESS_MIC_REC_VOL:
  1979. src = 0x68;
  1980. break;
  1981. case ESS_LINE_REC_VOL:
  1982. src = 0x6E;
  1983. break;
  1984. case ESS_SYNTH_REC_VOL:
  1985. src = 0x6B;
  1986. break;
  1987. case ESS_CD_REC_VOL:
  1988. src = 0x6A;
  1989. break;
  1990. case ESS_AUXB_REC_VOL:
  1991. src = 0x6C;
  1992. break;
  1993. case ESS_RECORD_VOL:
  1994. src = ESS_XCMD_VOLIN_CTRL;
  1995. mix = 0;
  1996. break;
  1997. default:
  1998. return;
  1999. }
  2000. /* 1788 doesn't have a separate recording mixer */
  2001. if (ESS_USE_AUDIO1(sc->sc_model) && mix && src > 0x62)
  2002. return;
  2003. if (on) {
  2004. left = sc->gain[port][ESS_LEFT];
  2005. right = sc->gain[port][ESS_RIGHT];
  2006. } else {
  2007. left = right = 0;
  2008. }
  2009. if (stereo)
  2010. gain = ESS_STEREO_GAIN(left, right);
  2011. else
  2012. gain = ESS_MONO_GAIN(left);
  2013. if (mix)
  2014. ess_write_mix_reg(sc, src, gain);
  2015. else
  2016. ess_write_x_reg(sc, src, gain);
  2017. }
  2018. /* Set the input device on devices without an input mixer. */
  2019. int
  2020. ess_set_in_port(struct ess_softc *sc, int ord)
  2021. {
  2022. mixer_devinfo_t di;
  2023. int i;
  2024. DPRINTF(("ess_set_in_port: ord=0x%x\n", ord));
  2025. /*
  2026. * Get the device info for the record source control,
  2027. * including the list of available sources.
  2028. */
  2029. di.index = ESS_RECORD_SOURCE;
  2030. if (ess_query_devinfo(sc, &di))
  2031. return EINVAL;
  2032. /* See if the given ord value was anywhere in the list. */
  2033. for (i = 0; i < di.un.e.num_mem; i++) {
  2034. if (ord == di.un.e.member[i].ord)
  2035. break;
  2036. }
  2037. if (i == di.un.e.num_mem)
  2038. return EINVAL;
  2039. ess_write_mix_reg(sc, ESS_MREG_ADC_SOURCE, ord);
  2040. sc->in_port = ord;
  2041. return (0);
  2042. }
  2043. /* Set the input device levels on input-mixer-enabled devices. */
  2044. int
  2045. ess_set_in_ports(struct ess_softc *sc, int mask)
  2046. {
  2047. mixer_devinfo_t di;
  2048. int i, port;
  2049. DPRINTF(("ess_set_in_ports: mask=0x%x\n", mask));
  2050. /*
  2051. * Get the device info for the record source control,
  2052. * including the list of available sources.
  2053. */
  2054. di.index = ESS_RECORD_SOURCE;
  2055. if (ess_query_devinfo(sc, &di))
  2056. return EINVAL;
  2057. /*
  2058. * Set or disable the record volume control for each of the
  2059. * possible sources.
  2060. */
  2061. for (i = 0; i < di.un.s.num_mem; i++) {
  2062. /*
  2063. * Calculate the source port number from its mask.
  2064. */
  2065. port = ffs(di.un.s.member[i].mask);
  2066. /*
  2067. * Set the source gain:
  2068. * to the current value if source is enabled
  2069. * to zero if source is disabled
  2070. */
  2071. ess_set_gain(sc, port, mask & di.un.s.member[i].mask);
  2072. }
  2073. sc->in_mask = mask;
  2074. return (0);
  2075. }
  2076. void
  2077. ess_speaker_on(struct ess_softc *sc)
  2078. {
  2079. /* Unmute the DAC. */
  2080. ess_set_gain(sc, ESS_DAC_PLAY_VOL, 1);
  2081. }
  2082. void
  2083. ess_speaker_off(struct ess_softc *sc)
  2084. {
  2085. /* Mute the DAC. */
  2086. ess_set_gain(sc, ESS_DAC_PLAY_VOL, 0);
  2087. }
  2088. /*
  2089. * Calculate the time constant for the requested sampling rate.
  2090. */
  2091. u_int
  2092. ess_srtotc(u_int rate)
  2093. {
  2094. u_int tc;
  2095. /* The following formulae are from the ESS data sheet. */
  2096. if (rate <= 22050)
  2097. tc = 128 - 397700L / rate;
  2098. else
  2099. tc = 256 - 795500L / rate;
  2100. return (tc);
  2101. }
  2102. /*
  2103. * Calculate the filter constant for the reuqested sampling rate.
  2104. */
  2105. u_int
  2106. ess_srtofc(u_int rate)
  2107. {
  2108. /*
  2109. * The following formula is derived from the information in
  2110. * the ES1887 data sheet, based on a roll-off frequency of
  2111. * 87%.
  2112. */
  2113. return (256 - 200279L / rate);
  2114. }
  2115. /*
  2116. * Return the status of the DSP.
  2117. */
  2118. u_char
  2119. ess_get_dsp_status(struct ess_softc *sc)
  2120. {
  2121. return (EREAD1(sc->sc_iot, sc->sc_ioh, ESS_DSP_RW_STATUS));
  2122. }
  2123. /*
  2124. * Return the read status of the DSP: 1 -> DSP ready for reading
  2125. * 0 -> DSP not ready for reading
  2126. */
  2127. u_char
  2128. ess_dsp_read_ready(struct ess_softc *sc)
  2129. {
  2130. return ((ess_get_dsp_status(sc) & ESS_DSP_READ_READY) ? 1 : 0);
  2131. }
  2132. /*
  2133. * Return the write status of the DSP: 1 -> DSP ready for writing
  2134. * 0 -> DSP not ready for writing
  2135. */
  2136. u_char
  2137. ess_dsp_write_ready(struct ess_softc *sc)
  2138. {
  2139. return ((ess_get_dsp_status(sc) & ESS_DSP_WRITE_BUSY) ? 0 : 1);
  2140. }
  2141. /*
  2142. * Read a byte from the DSP.
  2143. */
  2144. int
  2145. ess_rdsp(struct ess_softc *sc)
  2146. {
  2147. bus_space_tag_t iot = sc->sc_iot;
  2148. bus_space_handle_t ioh = sc->sc_ioh;
  2149. int i;
  2150. for (i = ESS_READ_TIMEOUT; i > 0; --i) {
  2151. if (ess_dsp_read_ready(sc)) {
  2152. i = EREAD1(iot, ioh, ESS_DSP_READ);
  2153. DPRINTFN(8,("ess_rdsp() = 0x%02x\n", i));
  2154. return i;
  2155. } else
  2156. delay(10);
  2157. }
  2158. DPRINTF(("ess_rdsp: timed out\n"));
  2159. return (-1);
  2160. }
  2161. /*
  2162. * Write a byte to the DSP.
  2163. */
  2164. int
  2165. ess_wdsp(struct ess_softc *sc, u_char v)
  2166. {
  2167. bus_space_tag_t iot = sc->sc_iot;
  2168. bus_space_handle_t ioh = sc->sc_ioh;
  2169. int i;
  2170. DPRINTFN(8,("ess_wdsp(0x%02x)\n", v));
  2171. for (i = ESS_WRITE_TIMEOUT; i > 0; --i) {
  2172. if (ess_dsp_write_ready(sc)) {
  2173. EWRITE1(iot, ioh, ESS_DSP_WRITE, v);
  2174. return (0);
  2175. } else
  2176. delay(10);
  2177. }
  2178. DPRINTF(("ess_wdsp(0x%02x): timed out\n", v));
  2179. return (-1);
  2180. }
  2181. /*
  2182. * Write a value to one of the ESS extended registers.
  2183. */
  2184. int
  2185. ess_write_x_reg(struct ess_softc *sc, u_char reg, u_char val)
  2186. {
  2187. int error;
  2188. DPRINTFN(2,("ess_write_x_reg: %02x=%02x\n", reg, val));
  2189. if ((error = ess_wdsp(sc, reg)) == 0)
  2190. error = ess_wdsp(sc, val);
  2191. return error;
  2192. }
  2193. /*
  2194. * Read the value of one of the ESS extended registers.
  2195. */
  2196. u_char
  2197. ess_read_x_reg(struct ess_softc *sc, u_char reg)
  2198. {
  2199. int error;
  2200. int val;
  2201. if ((error = ess_wdsp(sc, 0xC0)) == 0)
  2202. error = ess_wdsp(sc, reg);
  2203. if (error)
  2204. DPRINTF(("Error reading extended register 0x%02x\n", reg));
  2205. /* REVISIT: what if an error is returned above? */
  2206. val = ess_rdsp(sc);
  2207. DPRINTFN(2,("ess_read_x_reg: %02x=%02x\n", reg, val));
  2208. return val;
  2209. }
  2210. void
  2211. ess_clear_xreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
  2212. {
  2213. if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) & ~mask) == -1)
  2214. DPRINTF(("Error clearing bits in extended register 0x%02x\n",
  2215. reg));
  2216. }
  2217. void
  2218. ess_set_xreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
  2219. {
  2220. if (ess_write_x_reg(sc, reg, ess_read_x_reg(sc, reg) | mask) == -1)
  2221. DPRINTF(("Error setting bits in extended register 0x%02x\n",
  2222. reg));
  2223. }
  2224. /*
  2225. * Write a value to one of the ESS mixer registers.
  2226. */
  2227. void
  2228. ess_write_mix_reg(struct ess_softc *sc, u_char reg, u_char val)
  2229. {
  2230. bus_space_tag_t iot = sc->sc_iot;
  2231. bus_space_handle_t ioh = sc->sc_ioh;
  2232. DPRINTFN(2,("ess_write_mix_reg: %x=%x\n", reg, val));
  2233. mtx_enter(&audio_lock);
  2234. EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
  2235. EWRITE1(iot, ioh, ESS_MIX_REG_DATA, val);
  2236. mtx_leave(&audio_lock);
  2237. }
  2238. /*
  2239. * Read the value of one of the ESS mixer registers.
  2240. */
  2241. u_char
  2242. ess_read_mix_reg(struct ess_softc *sc, u_char reg)
  2243. {
  2244. bus_space_tag_t iot = sc->sc_iot;
  2245. bus_space_handle_t ioh = sc->sc_ioh;
  2246. u_char val;
  2247. mtx_enter(&audio_lock);
  2248. EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
  2249. val = EREAD1(iot, ioh, ESS_MIX_REG_DATA);
  2250. mtx_leave(&audio_lock);
  2251. DPRINTFN(2,("ess_read_mix_reg: %x=%x\n", reg, val));
  2252. return val;
  2253. }
  2254. void
  2255. ess_clear_mreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
  2256. {
  2257. ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) & ~mask);
  2258. }
  2259. void
  2260. ess_set_mreg_bits(struct ess_softc *sc, u_char reg, u_char mask)
  2261. {
  2262. ess_write_mix_reg(sc, reg, ess_read_mix_reg(sc, reg) | mask);
  2263. }
  2264. void
  2265. ess_read_multi_mix_reg(struct ess_softc *sc, u_char reg, u_int8_t *datap,
  2266. bus_size_t count)
  2267. {
  2268. bus_space_tag_t iot = sc->sc_iot;
  2269. bus_space_handle_t ioh = sc->sc_ioh;
  2270. mtx_enter(&audio_lock);
  2271. EWRITE1(iot, ioh, ESS_MIX_REG_SELECT, reg);
  2272. bus_space_read_multi_1(iot, ioh, ESS_MIX_REG_DATA, datap, count);
  2273. mtx_leave(&audio_lock);
  2274. }