mavb.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253
  1. /* $OpenBSD: mavb.c,v 1.18 2015/05/11 06:46:21 ratchov Exp $ */
  2. /*
  3. * Copyright (c) 2005 Mark Kettenis
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. #include <sys/param.h>
  18. #include <sys/systm.h>
  19. #include <sys/device.h>
  20. #include <sys/kernel.h>
  21. #include <sys/timeout.h>
  22. #include <machine/bus.h>
  23. #include <machine/intr.h>
  24. #include <sys/audioio.h>
  25. #include <dev/audio_if.h>
  26. #include <sgi/localbus/macebus.h>
  27. #include <sgi/localbus/macebusvar.h>
  28. #include <sgi/dev/mavbreg.h>
  29. #include <dev/ic/ad1843reg.h>
  30. #undef MAVB_DEBUG
  31. #ifdef MAVB_DEBUG
  32. #define DPRINTF(l,x) do { if (mavb_debug & (l)) printf x; } while (0)
  33. #define MAVB_DEBUG_INTR 0x0100
  34. int mavb_debug = ~MAVB_DEBUG_INTR;
  35. #else
  36. #define DPRINTF(l,x) /* nothing */
  37. #endif
  38. /* Repeat delays for volume buttons. */
  39. #define MAVB_VOLUME_BUTTON_REPEAT_DEL1 400 /* 400ms to start repeating */
  40. #define MAVB_VOLUME_BUTTON_REPEAT_DELN 100 /* 100ms between repeats */
  41. /* XXX We need access to some of the MACE ISA registers. */
  42. #define MAVB_ISA_NREGS 0x20
  43. #define MAVB_ISA_RING_SIZE 0x4000 /* Mace ISA DMA ring size. */
  44. #define MAVB_CHAN_RING_SIZE 0x1000 /* DMA buffer size per channel. */
  45. #define MAVB_CHAN_INTR_SIZE 0x0800 /* Interrupt on 50% buffer transfer. */
  46. #define MAVB_CHAN_CHUNK_SIZE 0x0400 /* Move data in 25% buffer chunks. */
  47. /*
  48. * AD1843 Mixer.
  49. */
  50. enum {
  51. AD1843_RECORD_CLASS,
  52. AD1843_ADC_SOURCE, /* ADC Source Select */
  53. AD1843_ADC_GAIN, /* ADC Input Gain */
  54. AD1843_ADC_MIC_GAIN, /* ADC Mic Input Gain */
  55. AD1843_INPUT_CLASS,
  56. AD1843_DAC1_GAIN, /* DAC1 Analog/Digital Gain/Attenuation */
  57. AD1843_DAC1_MUTE, /* DAC1 Analog Mute */
  58. AD1843_DAC2_GAIN, /* DAC2 Mix Gain */
  59. AD1843_AUX1_GAIN, /* Auxilliary 1 Mix Gain */
  60. AD1843_AUX2_GAIN, /* Auxilliary 2 Mix Gain */
  61. AD1843_AUX3_GAIN, /* Auxilliary 3 Mix Gain */
  62. AD1843_MIC_GAIN, /* Microphone Mix Gain */
  63. AD1843_MONO_GAIN, /* Mono Mix Gain */
  64. AD1843_DAC2_MUTE, /* DAC2 Mix Mute */
  65. AD1843_AUX1_MUTE, /* Auxilliary 1 Mix Mute */
  66. AD1843_AUX2_MUTE, /* Auxilliary 2 Mix Mute */
  67. AD1843_AUX3_MUTE, /* Auxilliary 3 Mix Mute */
  68. AD1843_MIC_MUTE, /* Microphone Mix Mute */
  69. AD1843_MONO_MUTE, /* Mono Mix Mute */
  70. AD1843_SUM_MUTE, /* Sum Mute */
  71. AD1843_OUTPUT_CLASS,
  72. AD1843_MNO_MUTE, /* Mono Output Mute */
  73. AD1843_HPO_MUTE /* Headphone Output Mute */
  74. };
  75. /* ADC Source Select. The order matches the hardware bits. */
  76. const char *ad1843_source[] = {
  77. AudioNline,
  78. AudioNmicrophone,
  79. AudioNaux "1",
  80. AudioNaux "2",
  81. AudioNaux "3",
  82. AudioNmono,
  83. AudioNdac "1",
  84. AudioNdac "2"
  85. };
  86. /* Mix Control. The order matches the hardware register numbering. */
  87. const char *ad1843_input[] = {
  88. AudioNdac "2", /* AD1843_DAC2__TO_MIXER */
  89. AudioNaux "1",
  90. AudioNaux "2",
  91. AudioNaux "3",
  92. AudioNmicrophone,
  93. AudioNmono /* AD1843_MISC_SETTINGS */
  94. };
  95. struct mavb_chan {
  96. caddr_t hw_start;
  97. caddr_t sw_start;
  98. caddr_t sw_end;
  99. caddr_t sw_cur;
  100. void (*intr)(void *);
  101. void *intrarg;
  102. u_long rate;
  103. u_int format;
  104. int blksize;
  105. };
  106. struct mavb_softc {
  107. struct device sc_dev;
  108. bus_space_tag_t sc_st;
  109. bus_space_handle_t sc_sh;
  110. bus_dma_tag_t sc_dmat;
  111. bus_dmamap_t sc_dmamap;
  112. /* XXX We need access to some of the MACE ISA registers. */
  113. bus_space_handle_t sc_isash;
  114. caddr_t sc_ring;
  115. struct mavb_chan play;
  116. struct mavb_chan rec;
  117. struct timeout sc_volume_button_to;
  118. };
  119. typedef u_long ad1843_addr_t;
  120. u_int16_t ad1843_reg_read(struct mavb_softc *, ad1843_addr_t);
  121. u_int16_t ad1843_reg_write(struct mavb_softc *, ad1843_addr_t, u_int16_t);
  122. void ad1843_dump_regs(struct mavb_softc *);
  123. int mavb_match(struct device *, void *, void *);
  124. void mavb_attach(struct device *, struct device *, void *);
  125. struct cfattach mavb_ca = {
  126. sizeof(struct mavb_softc), mavb_match, mavb_attach
  127. };
  128. struct cfdriver mavb_cd = {
  129. NULL, "mavb", DV_DULL
  130. };
  131. int mavb_open(void *, int);
  132. void mavb_close(void *);
  133. int mavb_query_encoding(void *, struct audio_encoding *);
  134. int mavb_set_params(void *, int, int, struct audio_params *,
  135. struct audio_params *);
  136. int mavb_round_blocksize(void *hdl, int bs);
  137. int mavb_halt_output(void *);
  138. int mavb_halt_input(void *);
  139. int mavb_getdev(void *, struct audio_device *);
  140. int mavb_set_port(void *, struct mixer_ctrl *);
  141. int mavb_get_port(void *, struct mixer_ctrl *);
  142. int mavb_query_devinfo(void *, struct mixer_devinfo *);
  143. int mavb_get_props(void *);
  144. int mavb_trigger_output(void *, void *, void *, int, void (*)(void *),
  145. void *, struct audio_params *);
  146. int mavb_trigger_input(void *, void *, void *, int, void (*)(void *),
  147. void *, struct audio_params *);
  148. void mavb_get_default_params(void *, int, struct audio_params *);
  149. struct audio_hw_if mavb_sa_hw_if = {
  150. mavb_open,
  151. mavb_close,
  152. 0,
  153. mavb_query_encoding,
  154. mavb_set_params,
  155. mavb_round_blocksize,
  156. 0,
  157. 0,
  158. 0,
  159. 0,
  160. 0,
  161. mavb_halt_output,
  162. mavb_halt_input,
  163. 0,
  164. mavb_getdev,
  165. 0,
  166. mavb_set_port,
  167. mavb_get_port,
  168. mavb_query_devinfo,
  169. 0,
  170. 0,
  171. 0,
  172. 0,
  173. mavb_get_props,
  174. mavb_trigger_output,
  175. mavb_trigger_input,
  176. mavb_get_default_params
  177. };
  178. struct audio_device mavb_device = {
  179. "A3",
  180. "",
  181. "mavb"
  182. };
  183. int
  184. mavb_open(void *hdl, int flags)
  185. {
  186. return (0);
  187. }
  188. void
  189. mavb_close(void *hdl)
  190. {
  191. }
  192. int
  193. mavb_query_encoding(void *hdl, struct audio_encoding *ae)
  194. {
  195. switch (ae->index) {
  196. case 0:
  197. /* 24-bit Signed Linear PCM LSB-aligned. */
  198. strlcpy(ae->name, AudioEslinear_be, sizeof ae->name);
  199. ae->encoding = AUDIO_ENCODING_SLINEAR_BE;
  200. ae->precision = 24;
  201. ae->flags = 0;
  202. break;
  203. default:
  204. return (EINVAL);
  205. }
  206. ae->bps = AUDIO_BPS(ae->precision);
  207. ae->msb = 0;
  208. return (0);
  209. }
  210. void
  211. mavb_get_default_params(void *hdl, int mode, struct audio_params *p)
  212. {
  213. p->sample_rate = 48000;
  214. p->encoding = AUDIO_ENCODING_SLINEAR_BE;
  215. p->precision = 24;
  216. p->bps = 4;
  217. p->msb = 0;
  218. p->channels = 2;
  219. }
  220. static int
  221. mavb_set_play_rate(struct mavb_softc *sc, u_long sample_rate)
  222. {
  223. if (sample_rate < 4000 || sample_rate > 48000)
  224. return (EINVAL);
  225. if (sc->play.rate != sample_rate) {
  226. ad1843_reg_write(sc, AD1843_CLOCK2_SAMPLE_RATE, sample_rate);
  227. sc->play.rate = sample_rate;
  228. }
  229. return (0);
  230. }
  231. static int
  232. mavb_set_rec_rate(struct mavb_softc *sc, u_long sample_rate)
  233. {
  234. if (sample_rate < 4000 || sample_rate > 48000)
  235. return (EINVAL);
  236. if (sc->rec.rate != sample_rate) {
  237. ad1843_reg_write(sc, AD1843_CLOCK1_SAMPLE_RATE, sample_rate);
  238. sc->rec.rate = sample_rate;
  239. }
  240. return (0);
  241. }
  242. static int
  243. mavb_get_format(u_int encoding, u_int *format)
  244. {
  245. switch(encoding) {
  246. case AUDIO_ENCODING_ULINEAR_BE:
  247. *format = AD1843_PCM8;
  248. break;
  249. case AUDIO_ENCODING_SLINEAR_BE:
  250. *format = AD1843_PCM16;
  251. break;
  252. case AUDIO_ENCODING_ULAW:
  253. *format = AD1843_ULAW;
  254. break;
  255. case AUDIO_ENCODING_ALAW:
  256. *format = AD1843_ALAW;
  257. break;
  258. default:
  259. return (EINVAL);
  260. }
  261. return (0);
  262. }
  263. static int
  264. mavb_set_play_format(struct mavb_softc *sc, u_int encoding)
  265. {
  266. u_int16_t value;
  267. u_int format;
  268. int err;
  269. err = mavb_get_format(encoding, &format);
  270. if (err)
  271. return (err);
  272. if (sc->play.format != format) {
  273. value = ad1843_reg_read(sc, AD1843_SERIAL_INTERFACE);
  274. value &= ~AD1843_DA1F_MASK;
  275. value |= (format << AD1843_DA1F_SHIFT);
  276. ad1843_reg_write(sc, AD1843_SERIAL_INTERFACE, value);
  277. sc->play.format = format;
  278. }
  279. return (0);
  280. }
  281. static int
  282. mavb_set_rec_format(struct mavb_softc *sc, u_int encoding)
  283. {
  284. u_int16_t value;
  285. u_int format;
  286. int err;
  287. err = mavb_get_format(encoding, &format);
  288. if (err)
  289. return (err);
  290. if (sc->rec.format != format) {
  291. value = ad1843_reg_read(sc, AD1843_SERIAL_INTERFACE);
  292. value &= ~(AD1843_ADRF_MASK | AD1843_ADLF_MASK);
  293. value |= (format << AD1843_ADRF_SHIFT) |
  294. (format << AD1843_ADLF_SHIFT);
  295. ad1843_reg_write(sc, AD1843_SERIAL_INTERFACE, value);
  296. sc->rec.format = format;
  297. }
  298. return (0);
  299. }
  300. int
  301. mavb_set_params(void *hdl, int setmode, int usemode,
  302. struct audio_params *play, struct audio_params *rec)
  303. {
  304. struct mavb_softc *sc = (struct mavb_softc *)hdl;
  305. int error;
  306. DPRINTF(1, ("%s: mavb_set_params: sample=%ld precision=%d "
  307. "channels=%d\n", sc->sc_dev.dv_xname, play->sample_rate,
  308. play->precision, play->channels));
  309. if (setmode & AUMODE_PLAY) {
  310. play->encoding = AUDIO_ENCODING_SLINEAR_BE;
  311. play->channels = 2;
  312. play->precision = 24;
  313. play->bps = AUDIO_BPS(play->precision);
  314. play->msb = 0;
  315. error = mavb_set_play_rate(sc, play->sample_rate);
  316. if (error)
  317. return (error);
  318. error = mavb_set_play_format(sc, play->encoding);
  319. if (error)
  320. return (error);
  321. }
  322. if (setmode & AUMODE_RECORD) {
  323. rec->encoding = AUDIO_ENCODING_SLINEAR_BE;
  324. rec->channels = 2;
  325. rec->precision = 24;
  326. rec->bps = AUDIO_BPS(rec->precision);
  327. rec->msb = 0;
  328. error = mavb_set_rec_rate(sc, rec->sample_rate);
  329. if (error)
  330. return (error);
  331. error = mavb_set_rec_format(sc, rec->encoding);
  332. if (error)
  333. return (error);
  334. }
  335. return (0);
  336. }
  337. int
  338. mavb_round_blocksize(void *hdl, int bs)
  339. {
  340. if (bs == 0)
  341. bs = MAVB_CHAN_INTR_SIZE;
  342. else
  343. bs = (bs + MAVB_CHAN_INTR_SIZE - 1) &
  344. ~(MAVB_CHAN_INTR_SIZE - 1);
  345. return (bs);
  346. }
  347. int
  348. mavb_halt_output(void *hdl)
  349. {
  350. struct mavb_softc *sc = (struct mavb_softc *)hdl;
  351. DPRINTF(1, ("%s: mavb_halt_output called\n", sc->sc_dev.dv_xname));
  352. mtx_enter(&audio_lock);
  353. bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL, 0);
  354. mtx_leave(&audio_lock);
  355. return (0);
  356. }
  357. int
  358. mavb_halt_input(void *hdl)
  359. {
  360. struct mavb_softc *sc = (struct mavb_softc *)hdl;
  361. DPRINTF(1, ("%s: mavb_halt_input called\n", sc->sc_dev.dv_xname));
  362. mtx_enter(&audio_lock);
  363. bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL1_CONTROL, 0);
  364. mtx_leave(&audio_lock);
  365. return (0);
  366. }
  367. int
  368. mavb_getdev(void *hdl, struct audio_device *ret)
  369. {
  370. *ret = mavb_device;
  371. return (0);
  372. }
  373. int
  374. mavb_set_port(void *hdl, struct mixer_ctrl *mc)
  375. {
  376. struct mavb_softc *sc = (struct mavb_softc *)hdl;
  377. u_char left, right;
  378. ad1843_addr_t reg;
  379. u_int16_t value;
  380. DPRINTF(1, ("%s: mavb_set_port: dev=%d\n", sc->sc_dev.dv_xname,
  381. mc->dev));
  382. switch (mc->dev) {
  383. case AD1843_ADC_SOURCE:
  384. value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
  385. value &= ~(AD1843_LSS_MASK | AD1843_RSS_MASK);
  386. value |= ((mc->un.ord << AD1843_LSS_SHIFT) & AD1843_LSS_MASK);
  387. value |= ((mc->un.ord << AD1843_RSS_SHIFT) & AD1843_RSS_MASK);
  388. ad1843_reg_write(sc, AD1843_ADC_SOURCE_GAIN, value);
  389. break;
  390. case AD1843_ADC_GAIN:
  391. left = mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
  392. right = mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
  393. value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
  394. value &= ~(AD1843_LIG_MASK | AD1843_RIG_MASK);
  395. value |= ((left >> 4) << AD1843_LIG_SHIFT);
  396. value |= ((right >> 4) << AD1843_RIG_SHIFT);
  397. ad1843_reg_write(sc, AD1843_ADC_SOURCE_GAIN, value);
  398. break;
  399. case AD1843_ADC_MIC_GAIN:
  400. value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
  401. if (mc->un.ord == 0)
  402. value &= ~(AD1843_LMGE | AD1843_RMGE);
  403. else
  404. value |= (AD1843_LMGE | AD1843_RMGE);
  405. ad1843_reg_write(sc, AD1843_ADC_SOURCE_GAIN, value);
  406. break;
  407. case AD1843_DAC1_GAIN:
  408. left = AUDIO_MAX_GAIN -
  409. mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
  410. right = AUDIO_MAX_GAIN -
  411. mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
  412. value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
  413. value &= ~(AD1843_LDA1G_MASK | AD1843_RDA1G_MASK);
  414. value |= ((left >> 2) << AD1843_LDA1G_SHIFT);
  415. value |= ((right >> 2) << AD1843_RDA1G_SHIFT);
  416. ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
  417. break;
  418. case AD1843_DAC1_MUTE:
  419. value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
  420. if (mc->un.ord == 0)
  421. value &= ~(AD1843_LDA1GM | AD1843_RDA1GM);
  422. else
  423. value |= (AD1843_LDA1GM | AD1843_RDA1GM);
  424. ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
  425. break;
  426. case AD1843_DAC2_GAIN:
  427. case AD1843_AUX1_GAIN:
  428. case AD1843_AUX2_GAIN:
  429. case AD1843_AUX3_GAIN:
  430. case AD1843_MIC_GAIN:
  431. left = AUDIO_MAX_GAIN -
  432. mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT];
  433. right = AUDIO_MAX_GAIN -
  434. mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT];
  435. reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_GAIN;
  436. value = ad1843_reg_read(sc, reg);
  437. value &= ~(AD1843_LD2M_MASK | AD1843_RD2M_MASK);
  438. value |= ((left >> 3) << AD1843_LD2M_SHIFT);
  439. value |= ((right >> 3) << AD1843_RD2M_SHIFT);
  440. ad1843_reg_write(sc, reg, value);
  441. break;
  442. case AD1843_MONO_GAIN:
  443. left = AUDIO_MAX_GAIN -
  444. mc->un.value.level[AUDIO_MIXER_LEVEL_MONO];
  445. value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
  446. value &= ~AD1843_MNM_MASK;
  447. value |= ((left >> 3) << AD1843_MNM_SHIFT);
  448. ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
  449. break;
  450. case AD1843_DAC2_MUTE:
  451. case AD1843_AUX1_MUTE:
  452. case AD1843_AUX2_MUTE:
  453. case AD1843_AUX3_MUTE:
  454. case AD1843_MIC_MUTE:
  455. case AD1843_MONO_MUTE: /* matches left channel */
  456. reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_MUTE;
  457. value = ad1843_reg_read(sc, reg);
  458. if (mc->un.ord == 0)
  459. value &= ~(AD1843_LD2MM | AD1843_RD2MM);
  460. else
  461. value |= (AD1843_LD2MM | AD1843_RD2MM);
  462. ad1843_reg_write(sc, reg, value);
  463. break;
  464. case AD1843_SUM_MUTE:
  465. value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
  466. if (mc->un.ord == 0)
  467. value &= ~AD1843_SUMM;
  468. else
  469. value |= AD1843_SUMM;
  470. ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
  471. break;
  472. case AD1843_MNO_MUTE:
  473. value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
  474. if (mc->un.ord == 0)
  475. value &= ~AD1843_MNOM;
  476. else
  477. value |= AD1843_MNOM;
  478. ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
  479. break;
  480. case AD1843_HPO_MUTE:
  481. value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
  482. if (mc->un.ord == 0)
  483. value &= ~AD1843_HPOM;
  484. else
  485. value |= AD1843_HPOM;
  486. ad1843_reg_write(sc, AD1843_MISC_SETTINGS, value);
  487. value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
  488. break;
  489. default:
  490. return (EINVAL);
  491. }
  492. return (0);
  493. }
  494. int
  495. mavb_get_port(void *hdl, struct mixer_ctrl *mc)
  496. {
  497. struct mavb_softc *sc = (struct mavb_softc *)hdl;
  498. u_char left, right;
  499. ad1843_addr_t reg;
  500. u_int16_t value;
  501. DPRINTF(1, ("%s: mavb_get_port: dev=%d\n", sc->sc_dev.dv_xname,
  502. mc->dev));
  503. switch (mc->dev) {
  504. case AD1843_ADC_SOURCE:
  505. value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
  506. mc->un.ord = (value & AD1843_LSS_MASK) >> AD1843_LSS_SHIFT;
  507. break;
  508. case AD1843_ADC_GAIN:
  509. value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
  510. left = (value & AD1843_LIG_MASK) >> AD1843_LIG_SHIFT;
  511. right = (value & AD1843_RIG_MASK) >> AD1843_RIG_SHIFT;
  512. mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
  513. (left << 4) | left;
  514. mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
  515. (right << 4) | right;
  516. break;
  517. case AD1843_ADC_MIC_GAIN:
  518. value = ad1843_reg_read(sc, AD1843_ADC_SOURCE_GAIN);
  519. mc->un.ord = (value & AD1843_LMGE) ? 1 : 0;
  520. break;
  521. case AD1843_DAC1_GAIN:
  522. value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
  523. left = (value & AD1843_LDA1G_MASK) >> AD1843_LDA1G_SHIFT;
  524. right = (value & AD1843_RDA1G_MASK) >> AD1843_RDA1G_SHIFT;
  525. mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
  526. AUDIO_MAX_GAIN - (left << 2);
  527. mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
  528. AUDIO_MAX_GAIN - (right << 2);
  529. break;
  530. case AD1843_DAC1_MUTE:
  531. value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
  532. mc->un.ord = (value & AD1843_LDA1GM) ? 1 : 0;
  533. break;
  534. case AD1843_DAC2_GAIN:
  535. case AD1843_AUX1_GAIN:
  536. case AD1843_AUX2_GAIN:
  537. case AD1843_AUX3_GAIN:
  538. case AD1843_MIC_GAIN:
  539. reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_GAIN;
  540. value = ad1843_reg_read(sc, reg);
  541. left = (value & AD1843_LD2M_MASK) >> AD1843_LD2M_SHIFT;
  542. right = (value & AD1843_RD2M_MASK) >> AD1843_RD2M_SHIFT;
  543. mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
  544. AUDIO_MAX_GAIN - (left << 3);
  545. mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
  546. AUDIO_MAX_GAIN - (right << 3);
  547. break;
  548. case AD1843_MONO_GAIN:
  549. if (mc->un.value.num_channels != 1)
  550. return (EINVAL);
  551. value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
  552. left = (value & AD1843_MNM_MASK) >> AD1843_MNM_SHIFT;
  553. mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
  554. AUDIO_MAX_GAIN - (left << 3);
  555. break;
  556. case AD1843_DAC2_MUTE:
  557. case AD1843_AUX1_MUTE:
  558. case AD1843_AUX2_MUTE:
  559. case AD1843_AUX3_MUTE:
  560. case AD1843_MIC_MUTE:
  561. case AD1843_MONO_MUTE: /* matches left channel */
  562. reg = AD1843_DAC2_TO_MIXER + mc->dev - AD1843_DAC2_MUTE;
  563. value = ad1843_reg_read(sc, reg);
  564. mc->un.ord = (value & AD1843_LD2MM) ? 1 : 0;
  565. break;
  566. case AD1843_SUM_MUTE:
  567. value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
  568. mc->un.ord = (value & AD1843_SUMM) ? 1 : 0;
  569. break;
  570. case AD1843_MNO_MUTE:
  571. value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
  572. mc->un.ord = (value & AD1843_MNOM) ? 1 : 0;
  573. break;
  574. case AD1843_HPO_MUTE:
  575. value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
  576. mc->un.ord = (value & AD1843_HPOM) ? 1 : 0;
  577. break;
  578. default:
  579. return (EINVAL);
  580. }
  581. return (0);
  582. }
  583. int
  584. mavb_query_devinfo(void *hdl, struct mixer_devinfo *di)
  585. {
  586. int i;
  587. di->prev = di->next = AUDIO_MIXER_LAST;
  588. switch (di->index) {
  589. case AD1843_RECORD_CLASS:
  590. di->type = AUDIO_MIXER_CLASS;
  591. di->mixer_class = AD1843_RECORD_CLASS;
  592. strlcpy(di->label.name, AudioCrecord, sizeof di->label.name);
  593. break;
  594. case AD1843_ADC_SOURCE:
  595. di->type = AUDIO_MIXER_ENUM;
  596. di->mixer_class = AD1843_RECORD_CLASS;
  597. di->next = AD1843_ADC_GAIN;
  598. strlcpy(di->label.name, AudioNsource, sizeof di->label.name);
  599. di->un.e.num_mem =
  600. sizeof ad1843_source / sizeof ad1843_source[1];
  601. for (i = 0; i < di->un.e.num_mem; i++) {
  602. strlcpy(di->un.e.member[i].label.name,
  603. ad1843_source[i],
  604. sizeof di->un.e.member[0].label.name);
  605. di->un.e.member[i].ord = i;
  606. }
  607. break;
  608. case AD1843_ADC_GAIN:
  609. di->type = AUDIO_MIXER_VALUE;
  610. di->mixer_class = AD1843_RECORD_CLASS;
  611. di->prev = AD1843_ADC_SOURCE;
  612. strlcpy(di->label.name, AudioNvolume, sizeof di->label.name);
  613. di->un.v.num_channels = 2;
  614. strlcpy(di->un.v.units.name, AudioNvolume,
  615. sizeof di->un.v.units.name);
  616. break;
  617. case AD1843_ADC_MIC_GAIN:
  618. di->type = AUDIO_MIXER_ENUM;
  619. di->mixer_class = AD1843_RECORD_CLASS;
  620. strlcpy(di->label.name, AudioNmicrophone "." AudioNpreamp,
  621. sizeof di->label.name);
  622. di->un.e.num_mem = 2;
  623. strlcpy(di->un.e.member[0].label.name, AudioNoff,
  624. sizeof di->un.e.member[0].label.name);
  625. di->un.e.member[0].ord = 0;
  626. strlcpy(di->un.e.member[1].label.name, AudioNon,
  627. sizeof di->un.e.member[1].label.name);
  628. di->un.e.member[1].ord = 1;
  629. break;
  630. case AD1843_INPUT_CLASS:
  631. di->type = AUDIO_MIXER_CLASS;
  632. di->mixer_class = AD1843_INPUT_CLASS;
  633. strlcpy(di->label.name, AudioCinputs, sizeof di->label.name);
  634. break;
  635. case AD1843_DAC1_GAIN:
  636. di->type = AUDIO_MIXER_VALUE;
  637. di->mixer_class = AD1843_INPUT_CLASS;
  638. di->next = AD1843_DAC1_MUTE;
  639. strlcpy(di->label.name, AudioNdac "1", sizeof di->label.name);
  640. di->un.v.num_channels = 2;
  641. strlcpy(di->un.v.units.name, AudioNvolume,
  642. sizeof di->un.v.units.name);
  643. break;
  644. case AD1843_DAC1_MUTE:
  645. di->type = AUDIO_MIXER_ENUM;
  646. di->mixer_class = AD1843_INPUT_CLASS;
  647. di->prev = AD1843_DAC1_GAIN;
  648. strlcpy(di->label.name, AudioNmute, sizeof di->label.name);
  649. di->un.e.num_mem = 2;
  650. strlcpy(di->un.e.member[0].label.name, AudioNoff,
  651. sizeof di->un.e.member[0].label.name);
  652. di->un.e.member[0].ord = 0;
  653. strlcpy(di->un.e.member[1].label.name, AudioNon,
  654. sizeof di->un.e.member[1].label.name);
  655. di->un.e.member[1].ord = 1;
  656. break;
  657. case AD1843_DAC2_GAIN:
  658. case AD1843_AUX1_GAIN:
  659. case AD1843_AUX2_GAIN:
  660. case AD1843_AUX3_GAIN:
  661. case AD1843_MIC_GAIN:
  662. case AD1843_MONO_GAIN:
  663. di->type = AUDIO_MIXER_VALUE;
  664. di->mixer_class = AD1843_INPUT_CLASS;
  665. di->next = di->index + AD1843_DAC2_MUTE - AD1843_DAC2_GAIN;
  666. strlcpy(di->label.name,
  667. ad1843_input[di->index - AD1843_DAC2_GAIN],
  668. sizeof di->label.name);
  669. if (di->index == AD1843_MONO_GAIN)
  670. di->un.v.num_channels = 1;
  671. else
  672. di->un.v.num_channels = 2;
  673. strlcpy(di->un.v.units.name, AudioNvolume,
  674. sizeof di->un.v.units.name);
  675. break;
  676. case AD1843_DAC2_MUTE:
  677. case AD1843_AUX1_MUTE:
  678. case AD1843_AUX2_MUTE:
  679. case AD1843_AUX3_MUTE:
  680. case AD1843_MIC_MUTE:
  681. case AD1843_MONO_MUTE:
  682. di->type = AUDIO_MIXER_ENUM;
  683. di->mixer_class = AD1843_INPUT_CLASS;
  684. di->prev = di->index + AD1843_DAC2_GAIN - AD1843_DAC2_MUTE;
  685. strlcpy(di->label.name, AudioNmute, sizeof di->label.name);
  686. di->un.e.num_mem = 2;
  687. strlcpy(di->un.e.member[0].label.name, AudioNoff,
  688. sizeof di->un.e.member[0].label.name);
  689. di->un.e.member[0].ord = 0;
  690. strlcpy(di->un.e.member[1].label.name, AudioNon,
  691. sizeof di->un.e.member[1].label.name);
  692. di->un.e.member[1].ord = 1;
  693. break;
  694. case AD1843_SUM_MUTE:
  695. di->type = AUDIO_MIXER_ENUM;
  696. di->mixer_class = AD1843_INPUT_CLASS;
  697. strlcpy(di->label.name, "sum." AudioNmute,
  698. sizeof di->label.name);
  699. di->un.e.num_mem = 2;
  700. strlcpy(di->un.e.member[0].label.name, AudioNoff,
  701. sizeof di->un.e.member[0].label.name);
  702. di->un.e.member[0].ord = 0;
  703. strlcpy(di->un.e.member[1].label.name, AudioNon,
  704. sizeof di->un.e.member[1].label.name);
  705. di->un.e.member[1].ord = 1;
  706. break;
  707. case AD1843_OUTPUT_CLASS:
  708. di->type = AUDIO_MIXER_CLASS;
  709. di->mixer_class = AD1843_OUTPUT_CLASS;
  710. strlcpy(di->label.name, AudioCoutputs, sizeof di->label.name);
  711. break;
  712. case AD1843_MNO_MUTE:
  713. di->type = AUDIO_MIXER_ENUM;
  714. di->mixer_class = AD1843_OUTPUT_CLASS;
  715. strlcpy(di->label.name, AudioNmono "." AudioNmute,
  716. sizeof di->label.name);
  717. di->un.e.num_mem = 2;
  718. strlcpy(di->un.e.member[0].label.name, AudioNoff,
  719. sizeof di->un.e.member[0].label.name);
  720. di->un.e.member[0].ord = 0;
  721. strlcpy(di->un.e.member[1].label.name, AudioNon,
  722. sizeof di->un.e.member[1].label.name);
  723. di->un.e.member[1].ord = 1;
  724. break;
  725. case AD1843_HPO_MUTE:
  726. di->type = AUDIO_MIXER_ENUM;
  727. di->mixer_class = AD1843_OUTPUT_CLASS;
  728. strlcpy(di->label.name, AudioNheadphone "." AudioNmute,
  729. sizeof di->label.name);
  730. di->un.e.num_mem = 2;
  731. strlcpy(di->un.e.member[0].label.name, AudioNoff,
  732. sizeof di->un.e.member[0].label.name);
  733. di->un.e.member[0].ord = 0;
  734. strlcpy(di->un.e.member[1].label.name, AudioNon,
  735. sizeof di->un.e.member[1].label.name);
  736. di->un.e.member[1].ord = 1;
  737. break;
  738. default:
  739. return (EINVAL);
  740. }
  741. return (0);
  742. }
  743. int
  744. mavb_get_props(void *hdl)
  745. {
  746. return (AUDIO_PROP_FULLDUPLEX | AUDIO_PROP_INDEPENDENT);
  747. }
  748. static void
  749. mavb_dma_output(struct mavb_softc *sc)
  750. {
  751. bus_space_tag_t st = sc->sc_st;
  752. bus_space_handle_t sh = sc->sc_sh;
  753. u_int64_t write_ptr;
  754. caddr_t src, dst, end;
  755. int count;
  756. write_ptr = bus_space_read_8(st, sh, MAVB_CHANNEL2_WRITE_PTR);
  757. end = sc->play.hw_start + MAVB_CHAN_RING_SIZE;
  758. dst = sc->play.hw_start + write_ptr;
  759. src = sc->play.sw_cur;
  760. if (write_ptr % MAVB_CHAN_CHUNK_SIZE) {
  761. printf("%s: write_ptr=%lld\n", sc->sc_dev.dv_xname, write_ptr);
  762. return;
  763. }
  764. if ((src - sc->play.sw_start) % MAVB_CHAN_CHUNK_SIZE) {
  765. printf("%s: src=%ld\n", sc->sc_dev.dv_xname,
  766. src - sc->play.sw_start);
  767. return;
  768. }
  769. count = MAVB_CHAN_INTR_SIZE / MAVB_CHAN_CHUNK_SIZE;
  770. while (--count >= 0) {
  771. memcpy(dst, src, MAVB_CHAN_CHUNK_SIZE);
  772. dst += MAVB_CHAN_CHUNK_SIZE;
  773. src += MAVB_CHAN_CHUNK_SIZE;
  774. if (dst >= end)
  775. dst = sc->play.hw_start;
  776. if (src >= sc->play.sw_end)
  777. src = sc->play.sw_start;
  778. if (!((src - sc->play.sw_start) % sc->play.blksize)) {
  779. if (sc->play.intr)
  780. sc->play.intr(sc->play.intrarg);
  781. }
  782. }
  783. write_ptr = dst - sc->play.hw_start;
  784. bus_space_write_8(st, sh, MAVB_CHANNEL2_WRITE_PTR, write_ptr);
  785. sc->play.sw_cur = src;
  786. }
  787. static void
  788. mavb_dma_input(struct mavb_softc *sc)
  789. {
  790. bus_space_tag_t st = sc->sc_st;
  791. bus_space_handle_t sh = sc->sc_sh;
  792. u_int64_t read_ptr;
  793. caddr_t src, dst, end;
  794. int count;
  795. read_ptr = bus_space_read_8(st, sh, MAVB_CHANNEL1_READ_PTR);
  796. end = sc->rec.hw_start + MAVB_CHAN_RING_SIZE;
  797. src = sc->rec.hw_start + read_ptr;
  798. dst = sc->rec.sw_cur;
  799. if (read_ptr % MAVB_CHAN_CHUNK_SIZE) {
  800. printf("%s: read_ptr=%lld\n", sc->sc_dev.dv_xname, read_ptr);
  801. return;
  802. }
  803. if ((dst - sc->rec.sw_start) % MAVB_CHAN_CHUNK_SIZE) {
  804. printf("%s: dst=%ld\n", sc->sc_dev.dv_xname,
  805. dst - sc->rec.sw_start);
  806. return;
  807. }
  808. count = MAVB_CHAN_INTR_SIZE / MAVB_CHAN_CHUNK_SIZE;
  809. while (--count >= 0) {
  810. memcpy(dst, src, MAVB_CHAN_CHUNK_SIZE);
  811. dst += MAVB_CHAN_CHUNK_SIZE;
  812. src += MAVB_CHAN_CHUNK_SIZE;
  813. if (src >= end)
  814. src = sc->rec.hw_start;
  815. if (dst >= sc->rec.sw_end)
  816. dst = sc->rec.sw_start;
  817. if (!((dst - sc->rec.sw_start) % sc->rec.blksize)) {
  818. if (sc->rec.intr)
  819. sc->rec.intr(sc->rec.intrarg);
  820. }
  821. }
  822. read_ptr = src - sc->rec.hw_start;
  823. bus_space_write_8(st, sh, MAVB_CHANNEL1_READ_PTR, read_ptr);
  824. sc->rec.sw_cur = dst;
  825. }
  826. int
  827. mavb_trigger_output(void *hdl, void *start, void *end, int blksize,
  828. void (*intr)(void *), void *intrarg, struct audio_params *param)
  829. {
  830. struct mavb_softc *sc = (struct mavb_softc *)hdl;
  831. DPRINTF(1, ("%s: mavb_trigger_output: start=%p end=%p "
  832. "blksize=%d intr=%p(%p)\n", sc->sc_dev.dv_xname,
  833. start, end, blksize, intr, intrarg));
  834. mtx_enter(&audio_lock);
  835. sc->play.blksize = blksize;
  836. sc->play.intr = intr;
  837. sc->play.intrarg = intrarg;
  838. sc->play.sw_start = sc->play.sw_cur = start;
  839. sc->play.sw_end = end;
  840. bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL,
  841. MAVB_CHANNEL_RESET);
  842. delay(1000);
  843. bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL, 0);
  844. /* Fill first 25% of buffer with silence. */
  845. bzero(sc->play.hw_start, MAVB_CHAN_CHUNK_SIZE);
  846. bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_WRITE_PTR,
  847. MAVB_CHAN_CHUNK_SIZE);
  848. /* Fill next 50% of buffer with audio data. */
  849. mavb_dma_output(sc);
  850. /* The buffer is now 75% full. Start DMA and get interrupts
  851. * when the buffer is 25% full. The interrupt handler fills
  852. * in 50% of the buffer size, putting it back to 75% full.
  853. */
  854. bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL2_CONTROL,
  855. MAVB_CHANNEL_DMA_ENABLE | MAVB_CHANNEL_INT_25);
  856. mtx_leave(&audio_lock);
  857. return (0);
  858. }
  859. int
  860. mavb_trigger_input(void *hdl, void *start, void *end, int blksize,
  861. void (*intr)(void *), void *intrarg, struct audio_params *param)
  862. {
  863. struct mavb_softc *sc = (struct mavb_softc *)hdl;
  864. DPRINTF(1, ("%s: mavb_trigger_output: start=%p end=%p "
  865. "blksize=%d intr=%p(%p)\n", sc->sc_dev.dv_xname,
  866. start, end, blksize, intr, intrarg));
  867. mtx_enter(&audio_lock);
  868. sc->rec.blksize = blksize;
  869. sc->rec.intr = intr;
  870. sc->rec.intrarg = intrarg;
  871. sc->rec.sw_start = sc->rec.sw_cur = start;
  872. sc->rec.sw_end = end;
  873. bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL1_CONTROL,
  874. MAVB_CHANNEL_RESET);
  875. delay(1000);
  876. bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL1_CONTROL, 0);
  877. bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CHANNEL1_CONTROL,
  878. MAVB_CHANNEL_DMA_ENABLE | MAVB_CHANNEL_INT_50);
  879. mtx_leave(&audio_lock);
  880. return (0);
  881. }
  882. static void
  883. mavb_button_repeat(void *hdl)
  884. {
  885. struct mavb_softc *sc = (struct mavb_softc *)hdl;
  886. u_int64_t intmask, control;
  887. u_int16_t value, left, right;
  888. DPRINTF(1, ("%s: mavb_repeat called\n", sc->sc_dev.dv_xname));
  889. #define MAVB_CONTROL_VOLUME_BUTTONS \
  890. (MAVB_CONTROL_VOLUME_BUTTON_UP | MAVB_CONTROL_VOLUME_BUTTON_DOWN)
  891. control = bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL);
  892. if (control & MAVB_CONTROL_VOLUME_BUTTONS) {
  893. value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
  894. left = (value & AD1843_LDA1G_MASK) >> AD1843_LDA1G_SHIFT;
  895. right = (value & AD1843_RDA1G_MASK) >> AD1843_RDA1G_SHIFT;
  896. if (control & MAVB_CONTROL_VOLUME_BUTTON_UP) {
  897. control &= ~MAVB_CONTROL_VOLUME_BUTTON_UP;
  898. if (left > 0)
  899. left--; /* attenuation! */
  900. if (right > 0)
  901. right--;
  902. }
  903. if (control & MAVB_CONTROL_VOLUME_BUTTON_DOWN) {
  904. control &= ~MAVB_CONTROL_VOLUME_BUTTON_DOWN;
  905. if (left < 63)
  906. left++;
  907. if (right < 63)
  908. right++;
  909. }
  910. bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL, control);
  911. value &= ~(AD1843_LDA1G_MASK | AD1843_RDA1G_MASK);
  912. value |= (left << AD1843_LDA1G_SHIFT);
  913. value |= (right << AD1843_RDA1G_SHIFT);
  914. ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN, value);
  915. timeout_add_msec(&sc->sc_volume_button_to,
  916. MAVB_VOLUME_BUTTON_REPEAT_DELN);
  917. } else {
  918. /* Enable volume button interrupts again. */
  919. intmask = bus_space_read_8(sc->sc_st, sc->sc_isash,
  920. MACE_ISA_INT_MASK);
  921. bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_MASK,
  922. intmask | MACE_ISA_INT_AUDIO_SC);
  923. }
  924. }
  925. static int
  926. mavb_intr(void *arg)
  927. {
  928. struct mavb_softc *sc = arg;
  929. u_int64_t intstat, intmask;
  930. mtx_enter(&audio_lock);
  931. intstat = bus_space_read_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_STAT);
  932. DPRINTF(MAVB_DEBUG_INTR, ("%s: mavb_intr: intstat = 0x%lx\n",
  933. sc->sc_dev.dv_xname, intstat));
  934. if (intstat & MACE_ISA_INT_AUDIO_SC) {
  935. /* Disable volume button interrupts. */
  936. intmask = bus_space_read_8(sc->sc_st, sc->sc_isash,
  937. MACE_ISA_INT_MASK);
  938. bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_INT_MASK,
  939. intmask & ~MACE_ISA_INT_AUDIO_SC);
  940. timeout_add_msec(&sc->sc_volume_button_to,
  941. MAVB_VOLUME_BUTTON_REPEAT_DEL1);
  942. }
  943. if (intstat & MACE_ISA_INT_AUDIO_DMA1)
  944. mavb_dma_input(sc);
  945. if (intstat & MACE_ISA_INT_AUDIO_DMA2)
  946. mavb_dma_output(sc);
  947. mtx_leave(&audio_lock);
  948. return 1;
  949. }
  950. int
  951. mavb_match(struct device *parent, void *match, void *aux)
  952. {
  953. struct macebus_attach_args *maa = aux;
  954. bus_space_handle_t ioh;
  955. u_int64_t control;
  956. if (bus_space_map(maa->maa_iot, maa->maa_baseaddr, MAVB_NREGS, 0,
  957. &ioh) != 0)
  958. return (0);
  959. control = bus_space_read_8(maa->maa_iot, ioh, MAVB_CONTROL);
  960. bus_space_unmap(maa->maa_iot, ioh, MAVB_NREGS);
  961. return ((control & MAVB_CONTROL_CODEC_PRESENT) != 0);
  962. }
  963. void
  964. mavb_attach(struct device *parent, struct device *self, void *aux)
  965. {
  966. struct mavb_softc *sc = (void *)self;
  967. struct macebus_attach_args *maa = aux;
  968. bus_dma_segment_t seg;
  969. u_int16_t value;
  970. int rseg;
  971. sc->sc_st = maa->maa_iot;
  972. if (bus_space_map(sc->sc_st, maa->maa_baseaddr, MAVB_NREGS, 0,
  973. &sc->sc_sh) != 0) {
  974. printf(": can't map i/o space\n");
  975. return;
  976. }
  977. /* XXX We need access to some of the MACE ISA registers. */
  978. extern bus_space_handle_t mace_h;
  979. bus_space_subregion(sc->sc_st, mace_h, 0, MAVB_ISA_NREGS,
  980. &sc->sc_isash);
  981. /* Set up DMA structures. */
  982. sc->sc_dmat = maa->maa_dmat;
  983. if (bus_dmamap_create(sc->sc_dmat, MAVB_ISA_RING_SIZE, 1,
  984. MAVB_ISA_RING_SIZE, 0, 0, &sc->sc_dmamap)) {
  985. printf(": can't create MACE ISA DMA map\n");
  986. return;
  987. }
  988. if (bus_dmamem_alloc(sc->sc_dmat, MAVB_ISA_RING_SIZE,
  989. MACE_ISA_RING_ALIGN, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
  990. printf(": can't allocate ring buffer\n");
  991. return;
  992. }
  993. if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, MAVB_ISA_RING_SIZE,
  994. &sc->sc_ring, BUS_DMA_COHERENT)) {
  995. printf(": can't map ring buffer\n");
  996. return;
  997. }
  998. if (bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap, sc->sc_ring,
  999. MAVB_ISA_RING_SIZE, NULL, BUS_DMA_NOWAIT)) {
  1000. printf(": can't load MACE ISA DMA map\n");
  1001. return;
  1002. }
  1003. sc->rec.hw_start = sc->sc_ring;
  1004. sc->play.hw_start = sc->sc_ring + MAVB_CHAN_RING_SIZE;
  1005. bus_space_write_8(sc->sc_st, sc->sc_isash, MACE_ISA_RING_BASE,
  1006. sc->sc_dmamap->dm_segs[0].ds_addr);
  1007. /* Establish interrupt. */
  1008. macebus_intr_establish(maa->maa_intr, maa->maa_mace_intr,
  1009. IST_EDGE, IPL_AUDIO, mavb_intr, sc, sc->sc_dev.dv_xname);
  1010. /* 2. Assert the RESET signal. */
  1011. bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL,
  1012. MAVB_CONTROL_RESET);
  1013. delay(1); /* at least 100 ns */
  1014. /* 3. Deassert the RESET signal and enter a wait period to
  1015. allow the AD1843 internal clocks and the external
  1016. crystal oscillator to stabilize. */
  1017. bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CONTROL, 0);
  1018. delay(800); /* typically 400 us to 800 us */
  1019. if (ad1843_reg_read(sc, AD1843_CODEC_STATUS) & AD1843_INIT) {
  1020. printf(": codec not ready\n");
  1021. return;
  1022. }
  1023. /* 4. Put the conversion sources into standby. */
  1024. value = ad1843_reg_read(sc, AD1843_FUNDAMENTAL_SETTINGS);
  1025. ad1843_reg_write(sc, AD1843_FUNDAMENTAL_SETTINGS,
  1026. value & ~AD1843_PDNI);
  1027. delay (500000); /* approximately 474 ms */
  1028. if (ad1843_reg_read(sc, AD1843_CODEC_STATUS) & AD1843_PDNO) {
  1029. printf(": can't power up conversion resources\n");
  1030. return;
  1031. }
  1032. /* 5. Power up the clock generators and enable clock output pins. */
  1033. value = ad1843_reg_read(sc, AD1843_FUNDAMENTAL_SETTINGS);
  1034. ad1843_reg_write(sc, AD1843_FUNDAMENTAL_SETTINGS,
  1035. value | AD1843_C1EN | AD1843_C2EN);
  1036. /* 6. Configure conversion resources while they are in standby. */
  1037. value = ad1843_reg_read(sc, AD1843_SERIAL_INTERFACE);
  1038. ad1843_reg_write(sc, AD1843_SERIAL_INTERFACE, value | AD1843_ADTLK);
  1039. value = ad1843_reg_read(sc, AD1843_CHANNEL_SAMPLE_RATE);
  1040. ad1843_reg_write(sc, AD1843_CHANNEL_SAMPLE_RATE,
  1041. value | (2 << AD1843_DA1C_SHIFT) |
  1042. (1 << AD1843_ADRC_SHIFT) | (1 << AD1843_ADLC_SHIFT));
  1043. /* 7. Enable conversion resources. */
  1044. value = ad1843_reg_read(sc, AD1843_CHANNEL_POWER_DOWN);
  1045. ad1843_reg_write(sc, AD1843_CHANNEL_POWER_DOWN,
  1046. value | (AD1843_DA1EN | AD1843_ANAEN | AD1843_AAMEN |
  1047. AD1843_ADREN | AD1843_ADLEN));
  1048. /* 8. Configure conversion resources while they are enabled. */
  1049. value = ad1843_reg_read(sc, AD1843_DAC1_ANALOG_GAIN);
  1050. ad1843_reg_write(sc, AD1843_DAC1_ANALOG_GAIN,
  1051. value & ~(AD1843_LDA1GM | AD1843_RDA1GM));
  1052. value = ad1843_reg_read(sc, AD1843_DAC1_DIGITAL_GAIN);
  1053. ad1843_reg_write(sc, AD1843_DAC1_DIGITAL_GAIN,
  1054. value & ~(AD1843_LDA1AM | AD1843_RDA1AM));
  1055. value = ad1843_reg_read(sc, AD1843_MISC_SETTINGS);
  1056. ad1843_reg_write(sc, AD1843_MISC_SETTINGS,
  1057. value & ~(AD1843_HPOM | AD1843_MNOM));
  1058. value = ad1843_reg_read(sc, AD1843_CODEC_STATUS);
  1059. printf(": AD1843 rev %d\n", (u_int)value & AD1843_REVISION_MASK);
  1060. sc->play.rate = sc->rec.rate = 48000;
  1061. sc->play.format = sc->rec.format = AD1843_PCM8;
  1062. timeout_set(&sc->sc_volume_button_to, mavb_button_repeat, sc);
  1063. audio_attach_mi(&mavb_sa_hw_if, sc, &sc->sc_dev);
  1064. return;
  1065. }
  1066. u_int16_t
  1067. ad1843_reg_read(struct mavb_softc *sc, ad1843_addr_t addr)
  1068. {
  1069. bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_CONTROL,
  1070. (addr & MAVB_CODEC_ADDRESS_MASK) << MAVB_CODEC_ADDRESS_SHIFT |
  1071. MAVB_CODEC_READ);
  1072. delay(200);
  1073. return bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_STATUS);
  1074. }
  1075. u_int16_t
  1076. ad1843_reg_write(struct mavb_softc *sc, ad1843_addr_t addr, u_int16_t value)
  1077. {
  1078. bus_space_write_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_CONTROL,
  1079. (addr & MAVB_CODEC_ADDRESS_MASK) << MAVB_CODEC_ADDRESS_SHIFT |
  1080. (value & MAVB_CODEC_WORD_MASK) << MAVB_CODEC_WORD_SHIFT);
  1081. delay(200);
  1082. return bus_space_read_8(sc->sc_st, sc->sc_sh, MAVB_CODEC_STATUS);
  1083. }
  1084. void
  1085. ad1843_dump_regs(struct mavb_softc *sc)
  1086. {
  1087. u_int16_t addr;
  1088. for (addr = 0; addr < AD1843_NREGS; addr++)
  1089. printf("%d: 0x%04x\n", addr, ad1843_reg_read(sc, addr));
  1090. }