1 /*        $NetBSD: arcofi.c,v 1.4 2022/05/31 08:43:15 andvar Exp $    */
2 /*        $OpenBSD: arcofi.c,v 1.6 2013/05/15 08:29:24 ratchov Exp $  */
3 
4 /*
5  * Copyright (c) 2011 Miodrag Vallat.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*
21  * Driver for the HP ``Audio1'' device, which is a FIFO layer around a
22  * Siemens PSB 2160 ``ARCOFI'' phone quality audio chip.
23  *
24  * It is known to exist in two flavours: on-board the HP9000/425e as a DIO
25  * device, an on-board the HP9000/{705,710,745,747} as a GIO device.
26  *
27  * The FIFO logic buffers up to 128 bytes. When using 8 bit samples and
28  * the logic set to interrupt every half FIFO, the device will interrupt
29  * 125 times per second.
30  */
31 
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/conf.h>
35 #include <sys/device.h>
36 #include <sys/kernel.h>
37 #include <sys/proc.h>
38 #include <sys/mutex.h>
39 #include <sys/bus.h>
40 #include <sys/intr.h>
41 
42 #include <sys/audioio.h>
43 
44 #include <dev/audio/audio_if.h>
45 #include <dev/audio/mulaw.h>
46 
47 #include <dev/ic/arcofivar.h>
48 
49 #include "ioconf.h"
50 
51 #if 0
52 #define   ARCOFI_DEBUG
53 #endif
54 
55 /*
56  * Siemens PSB2160 registers
57  */
58 
59 /* CMDR */
60 #define   CMDR_AD             0x80      /* SP1/PS2 address convention */
61 #define   CMDR_READ 0x40
62 #define   CMDR_WRITE          0x00
63 #define   CMDR_PU             0x20      /* Power Up */
64 #define   CMDR_RCS  0x10      /* Receive and transmit in CH B2 */
65 #define   CMDR_MASK 0x0f
66 
67           /* command               length         data */
68 #define   SOP_0     0x00      /*        5         CR4 CR3 CR2 CR1 */
69 #define   COP_1     0x01      /*        5         t1_hi t1_lo f1_hi f1_lo */
70 #define   COP_2     0x02      /*        3         gr1 gr2 */
71 #define   COP_3     0x03      /*        3         t2_hi t2_lo f2_hi f2_lo */
72 #define   SOP_4     0x04      /*        2         CR1 */
73 #define   SOP_5     0x05      /*        2         CR2 */
74 #define   SOP_6     0x06      /*        2         CR3 */
75 #define   SOP_7     0x07      /*        2         CR4 */
76 #define   COP_8     0x08      /*        3         dtmf_hi dtmf_lo */
77 #define   COP_9     0x09      /*        5         gz a3 a2 a1 */
78 #define   COP_A     0x0a      /*        9         fx1 to fx8 */
79 #define   COP_B     0x0b      /*        3         gx1 gx2 */
80 #define   COP_C     0x0c      /*        9         fr1 to fr 8 */
81 #define   COP_D     0x0d      /*        5         fr9 fr10 fx9 fx10 */
82 #define   COP_E     0x0e      /*        5         t3_hi t3_lo f3_hi f3_lo */
83 
84 /* CR1 */
85 #define   CR1_GR              0x80      /* GR gain loaded from CRAM vs 0dB */
86 #define   CR1_GZ              0x40      /* Z gain loaded from CRAM vs -18dB */
87 #define   CR1_FX              0x20      /* X filter loaded from CRAM vs 0dB flat */
88 #define   CR1_FR              0x10      /* R filter loaded from CRAM vs 0dB flat */
89 #define   CR1_GX              0x08      /* GX gain loaded from CRAM vs 0dB */
90 #define   CR1_T_MASK          0x07      /* test mode */
91 #define   CR1_DLP             0x07      /* digital loopback via PCM registers */
92 #define   CR1_DLM             0x06      /* D/A output looped back to A/D input */
93 #define   CR1_DLS             0x05      /* digital loopback via converter registers */
94 #define   CR1_IDR             0x04      /* data RAM initialization */
95 #define   CR1_BYP             0x03      /* bypass analog frontend */
96 #define   CR1_ALM             0x02      /* analog loopback via MUX */
97 #define   CR1_ALS             0x01      /* analog loopback via converter registers */
98 
99 /* CR2 */
100 #define   CR2_SD              0x80      /* SD pin set to input vs output */
101 #define   CR2_SC              0x40      /* SC pin set to input vs output */
102 #define   CR2_SB              0x20      /* SB pin set to input vs output */
103 #define   CR2_SA              0x10      /* SA pin set to input vs output */
104 #define   CR2_ELS             0x08      /* non-input S pins tristate SIP vs sending 0 */
105 #define   CR2_AM              0x04      /* only one device on the SLD bus */
106 #define   CR2_TR              0x02      /* three party conferencing */
107 #define   CR2_EFC             0x01      /* enable feature control */
108 
109 /* CR3 */
110 #define   CR3_MIC_G_MASK      0xe0                /* MIC input analog gain  */
111 #define   CR3_MIC_X_INPUT               0xe0      /* MIC disabled, X input 15.1 dB */
112 #define   CR3_MIC_G_17                  0xc0      /* 17 dB */
113 #define   CR3_MIC_G_22                  0xa0      /* 22 dB */
114 #define   CR3_MIC_G_28                  0x80      /* 28 dB */
115 #define   CR3_MIC_G_34                  0x60      /* 34 dB */
116 #define   CR3_MIC_G_40                  0x40      /* 40 dB */
117 #define   CR3_MIC_G_46                  0x20      /* 46 dB */
118 #define   CR3_MIC_G_52                  0x00      /* 52 dB (reset default) */
119 #define   CR3_AFEC_MASK       0x1c
120 #define   CR3_AFEC_MUTE                 0x18      /* mute: Hout */
121 #define   CR3_AFEC_HFS                  0x14      /* hands free: FHM, LS out */
122 #define   CR3_AFEC_LH3                  0x10      /* loud hearing 3: MIC, H out, LS out */
123 #define   CR3_AFEC_LH2                  0x0c      /* loud hearing 2: MIC, LS out */
124 #define   CR3_AFEC_LH1                  0x08      /* loud hearing 1: LS out */
125 #define   CR3_AFEC_RDY                  0x04      /* ready: MIC, H out */
126 #define   CR3_AFEC_POR                  0x00      /* power on reset: all off */
127 #define   CR3_OPMODE_MASK     0x03
128 #define   CR3_OPMODE_LINEAR   0x02      /* linear (16 bit) */
129 #define   CR3_OPMODE_MIXED    0x01      /* mixed */
130 #define   CR3_OPMODE_NORMAL   0x00      /* normal (A/u-Law) */
131 
132 /* CR4 */
133 #define   CR4_DHF             0x80      /* TX digital high frequency enable */
134 #define   CR4_DTMF  0x40      /* DTMF generator enable */
135 #define   CR4_TG              0x20      /* tone ring enable */
136 #define   CR4_BT              0x10      /* beat tone generator enable */
137 #define   CR4_TM              0x08      /* incoming voice enable */
138 #define   CR4_BM              0x04      /* beat mode (3 tone vs 2 tone) */
139 #define   CR4_PM              0x02      /* tone sent to piezo vs loudspeaker */
140 #define   CR4_ULAW  0x01      /* u-Law vs A-Law */
141 
142 
143 /*
144  * Glue logic registers
145  * Note the register values here are symbolic, as actual addresses
146  * depend upon the particular bus the device is connected to.
147  */
148 
149 #define   ARCOFI_ID           0         /* id (r) and reset (w) register */
150 
151 #define   ARCOFI_CSR                    1         /* status and control register */
152 #define   CSR_INTR_ENABLE                         0x80
153 #define   CSR_INTR_REQUEST              0x40      /* unacknowledged interrupt */
154 /* 0x20 and 0x10 used in DIO flavours, to provide IPL */
155 #define   CSR_WIDTH_16                            0x08      /* 16-bit samples */
156 #define   CSR_CTRL_FIFO_ENABLE                    0x04      /* connect FIFO to CMDR */
157 #define   CSR_DATA_FIFO_ENABLE                    0x01      /* connect FIFO to DU/DD */
158 
159 #define   ARCOFI_FIFO_IR                2         /* FIFO interrupt register */
160 #define   FIFO_IR_ENABLE(ev)            ((ev) << 4)
161 #define   FIFO_IR_EVENT(ev)             (ev)
162 #define   FIFO_IR_OUT_EMPTY             0x08
163 #define   FIFO_IR_CTRL_EMPTY            0x04
164 #define   FIFO_IR_OUT_HALF_EMPTY                  0x02
165 #define   FIFO_IR_IN_HALF_EMPTY                   0x01
166 
167 #define   ARCOFI_FIFO_SR                3         /* FIFO status register (ro) */
168 #define   FIFO_SR_CTRL_FULL             0x20
169 #define   FIFO_SR_CTRL_EMPTY            0x10
170 #define   FIFO_SR_OUT_FULL              0x08
171 #define   FIFO_SR_OUT_EMPTY             0x04
172 #define   FIFO_SR_IN_FULL                         0x02
173 #define   FIFO_SR_IN_EMPTY              0x01
174 
175 #define   ARCOFI_FIFO_DATA    4         /* data FIFO port */
176 
177 #define   ARCOFI_FIFO_CTRL    5         /* control FIFO port (wo) */
178 
179 #define   ARCOFI_FIFO_SIZE    128
180 
181 #ifdef hp300        /* XXX */
182 #define   arcofi_read(sc, r) \
183           bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (r))
184 #define   arcofi_write(sc, r, v) \
185           bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (r), (v))
186 #else
187 #define   arcofi_read(sc, r) \
188           bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, (sc)->sc_reg[(r)])
189 #define   arcofi_write(sc, r, v) \
190           bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (sc)->sc_reg[(r)], (v))
191 #endif
192 
193 static int          arcofi_cmd(struct arcofi_softc *, uint8_t, const uint8_t *);
194 static int          arcofi_cr3_to_portmask(uint, int);
195 static int          arcofi_gain_to_mi(uint);
196 static uint         arcofi_mi_to_gain(int);
197 static uint         arcofi_portmask_to_cr3(int);
198 static int          arcofi_recv_data(struct arcofi_softc *);
199 static int          arcofi_xmit_data(struct arcofi_softc *);
200 
201 static int          arcofi_open(void *, int);
202 static int          arcofi_query_format(void *, audio_format_query_t *);
203 static int          arcofi_set_format(void *, int,
204                         const audio_params_t *, const audio_params_t *,
205                         audio_filter_reg_t *, audio_filter_reg_t *);
206 static int          arcofi_round_blocksize(void *, int, int,
207                         const audio_params_t *);
208 static int          arcofi_commit_settings(void *);
209 static int          arcofi_start_output(void *, void *, int, void (*)(void *),
210                         void *);
211 static int          arcofi_start_input(void *, void *, int, void (*)(void *),
212                         void *);
213 static int          arcofi_halt_output(void *);
214 static int          arcofi_halt_input(void *);
215 static int          arcofi_getdev(void *, struct audio_device *);
216 static int          arcofi_set_port(void *, mixer_ctrl_t *);
217 static int          arcofi_get_port(void *, mixer_ctrl_t *);
218 static int          arcofi_query_devinfo(void *, mixer_devinfo_t *);
219 static int          arcofi_get_props(void *);
220 static void         arcofi_get_locks(void *, kmutex_t **, kmutex_t **);
221 
222 static const struct audio_hw_if arcofi_hw_if = {
223           .open                 = arcofi_open,
224           .query_format         = arcofi_query_format,
225           .set_format           = arcofi_set_format,
226           .round_blocksize  = arcofi_round_blocksize,
227           .commit_settings  = arcofi_commit_settings,
228           .start_output         = arcofi_start_output,
229           .start_input          = arcofi_start_input,
230           .halt_output          = arcofi_halt_output,
231           .halt_input           = arcofi_halt_input,
232           .speaker_ctl          = NULL,
233           .getdev               = arcofi_getdev,
234           .set_port   = arcofi_set_port,
235           .get_port   = arcofi_get_port,
236           .query_devinfo        = arcofi_query_devinfo,
237           .allocm               = NULL,
238           .freem                = NULL,
239           .round_buffersize = NULL,
240           .get_props            = arcofi_get_props,
241           .trigger_output       = NULL,
242           .trigger_input        = NULL,
243           .dev_ioctl            = NULL,
244           .get_locks            = arcofi_get_locks,
245 };
246 
247 #define ARCOFI_FORMAT(prio, enc, prec) \
248           { \
249                     .mode               = AUMODE_PLAY | AUMODE_RECORD, \
250                     .priority = (prio), \
251                     .encoding = (enc), \
252                     .validbits          = (prec), \
253                     .precision          = (prec), \
254                     .channels = 1, \
255                     .channel_mask       = AUFMT_MONAURAL, \
256                     .frequency_type     = 1, \
257                     .frequency          = { 8000 }, \
258           }
259 static const struct audio_format arcofi_formats[] = {
260           /*
261            * 8-bit u-Law and A-Law are native.
262            */
263           ARCOFI_FORMAT(1, AUDIO_ENCODING_ULAW,        8),
264           ARCOFI_FORMAT(0, AUDIO_ENCODING_ALAW,        8),
265           /*
266            * 16-bit slinear big-endian is native.
267            * But it's hard to use due to hardware restrictions.
268            */
269           ARCOFI_FORMAT(0, AUDIO_ENCODING_SLINEAR_BE, 16),
270 };
271 #define ARCOFI_NFORMATS  __arraycount(arcofi_formats)
272 
273 /* mixer items */
274 #define   ARCOFI_PORT_AUDIO_IN_VOLUME   0         /* line in volume (GR) */
275 #define   ARCOFI_PORT_AUDIO_OUT_VOLUME  1         /* line out volume (GX) */
276 #define   ARCOFI_PORT_AUDIO_SPKR_VOLUME 2         /* speaker volume (GX) */
277 #define   ARCOFI_PORT_AUDIO_IN_MUTE     3         /* line in mute (MIC) */
278 #define   ARCOFI_PORT_AUDIO_OUT_MUTE    4         /* line out mute (H out) */
279 #define   ARCOFI_PORT_AUDIO_SPKR_MUTE   5         /* line in mute (LS out) */
280 /* mixer classes */
281 #define   ARCOFI_CLASS_INPUT            6
282 #define   ARCOFI_CLASS_OUTPUT           7
283 
284 /*
285  * Gain programming formulae are a complete mystery to me, and of course
286  * no two chips are compatible - not even the PSB 2163 and PSB 2165
287  * later ARCOFI chips, from the same manufacturer as the PSB 2160!
288  *
289  * Of course, the PSB 2160 datasheet does not give any set of values.
290  * The following table is taken from the HP-UX audio driver (audio_shared.o
291  * private_audio_gain_tab).
292  */
293 
294 #define   NEGATIVE_GAINS      60
295 #define   POSITIVE_GAINS      14
296 static const uint16_t arcofi_gains[1 + NEGATIVE_GAINS + 1 + POSITIVE_GAINS] = {
297           /* minus infinity */
298           0x0988,
299 
300           0xf8b8, 0xf8b8, 0xf8b8, 0xf8b8, 0x099f, 0x099f, 0x099f, 0x099f,
301           0x09af, 0x09af, 0x09af, 0x09cf, 0x09cf, 0x09cf, 0xf8a9, 0xf83a,
302           0xf83a, 0xf82b, 0xf82d, 0xf8a3, 0xf8b2, 0xf8a1, 0xe8aa, 0xe84b,
303           0xe89e, 0xe8d3, 0xe891, 0xe8b1, 0xd8aa, 0xd8cb, 0xd8a6, 0xd8b3,
304           0xd842, 0xd8b1, 0xc8aa, 0xc8bb, 0xc888, 0xc853, 0xc852, 0xc8b1,
305           0xb8aa, 0xb8ab, 0xb896, 0xb892, 0xb842, 0xb8b1, 0xa8aa, 0xa8bb,
306           0x199f, 0x195b, 0x29c1, 0x2923, 0x29aa, 0x392b, 0xf998, 0xb988,
307           0x1aac, 0x3aa1, 0xbaa1, 0xbb88,
308 
309           /* 0 */
310           0x8888,
311 
312           0xd388, 0x5288, 0xb1a1, 0x31a1, 0x1192, 0x11d0, 0x30c0, 0x2050,
313           0x1021, 0x1020, 0x1000, 0x0001, 0x0010, 0x0000
314 };
315 
316 static int
arcofi_open(void * v,int flags)317 arcofi_open(void *v, int flags)
318 {
319           struct arcofi_softc *sc __diagused = (struct arcofi_softc *)v;
320 
321           KASSERT(sc->sc_mode == 0);
322 
323           return 0;
324 }
325 
326 static int
arcofi_query_format(void * v,audio_format_query_t * afp)327 arcofi_query_format(void *v, audio_format_query_t *afp)
328 {
329 
330           return audio_query_format(arcofi_formats, ARCOFI_NFORMATS, afp);
331 }
332 
333 static int
arcofi_set_format(void * handle,int setmode,const audio_params_t * play,const audio_params_t * rec,audio_filter_reg_t * pfil,audio_filter_reg_t * rfil)334 arcofi_set_format(void *handle, int setmode,
335     const audio_params_t *play, const audio_params_t *rec,
336     audio_filter_reg_t *pfil, audio_filter_reg_t *rfil)
337 {
338           struct arcofi_softc *sc;
339 
340           sc = handle;
341 
342           if ((setmode & AUMODE_PLAY)) {
343                     switch (play->encoding) {
344                     case AUDIO_ENCODING_ULAW:
345                               pfil->codec = audio_internal_to_mulaw;
346                               break;
347                     case AUDIO_ENCODING_ALAW:
348                               pfil->codec = audio_internal_to_alaw;
349                               break;
350                     }
351           }
352           if ((setmode & AUMODE_RECORD)) {
353                     switch (rec->encoding) {
354                     case AUDIO_ENCODING_ULAW:
355                               rfil->codec = audio_mulaw_to_internal;
356                               break;
357                     case AUDIO_ENCODING_ALAW:
358                               rfil->codec = audio_alaw_to_internal;
359                               break;
360                     }
361           }
362 
363           /* *play and *rec are identical because !AUDIO_PROP_INDEPENDENT */
364 
365           if (play->precision == 8) {
366                     if (play->encoding == AUDIO_ENCODING_ULAW)
367                               sc->sc_shadow.cr4 |= CR4_ULAW;
368                     else
369                               sc->sc_shadow.cr4 &= ~CR4_ULAW;
370                     sc->sc_shadow.cr3 =
371                         (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) |
372                         CR3_OPMODE_NORMAL;
373           } else {
374                     sc->sc_shadow.cr3 =
375                         (sc->sc_shadow.cr3 & ~CR3_OPMODE_MASK) |
376                         CR3_OPMODE_LINEAR;
377           }
378 
379           return 0;
380 }
381 
382 static int
arcofi_round_blocksize(void * handle,int block,int mode,const audio_params_t * param)383 arcofi_round_blocksize(void *handle, int block, int mode,
384     const audio_params_t *param)
385 {
386 
387           /*
388            * Round the size up to a multiple of half the FIFO, to favour
389            * smooth interrupt operation.
390            */
391           return roundup(block, ARCOFI_FIFO_SIZE / 2);
392 }
393 
394 static int
arcofi_commit_settings(void * v)395 arcofi_commit_settings(void *v)
396 {
397           struct arcofi_softc *sc = (struct arcofi_softc *)v;
398           int rc;
399           uint8_t cmd[2], csr, ocsr;
400 
401 #ifdef ARCOFI_DEBUG
402           printf("%s: %s, gr %04x gx %04x cr3 %02x cr4 %02x mute %d\n",
403               device_xname(sc->sc_dev), __func__,
404               arcofi_gains[sc->sc_shadow.gr_idx],
405               arcofi_gains[sc->sc_shadow.gx_idx],
406               sc->sc_shadow.cr3, sc->sc_shadow.cr4, sc->sc_shadow.output_mute);
407 #endif
408 
409           if (memcmp(&sc->sc_active, &sc->sc_shadow, sizeof(sc->sc_active)) == 0)
410                     return 0;
411 
412           mutex_spin_enter(&sc->sc_intr_lock);
413 
414           if (sc->sc_active.gr_idx != sc->sc_shadow.gr_idx) {
415                     cmd[0] = arcofi_gains[sc->sc_shadow.gr_idx] >> 8;
416                     cmd[1] = arcofi_gains[sc->sc_shadow.gr_idx];
417                     if ((rc = arcofi_cmd(sc, COP_2, cmd)) != 0)
418                               goto error;
419                     sc->sc_active.gr_idx = sc->sc_shadow.gr_idx;
420           }
421 
422           if (sc->sc_active.gx_idx != sc->sc_shadow.gx_idx ||
423               sc->sc_active.output_mute != sc->sc_shadow.output_mute) {
424                     if (sc->sc_shadow.output_mute) {
425                               cmd[0] = arcofi_gains[0] >> 8;
426                               cmd[1] = arcofi_gains[0];
427                     } else {
428                               cmd[0] = arcofi_gains[sc->sc_shadow.gx_idx] >> 8;
429                               cmd[1] = arcofi_gains[sc->sc_shadow.gx_idx];
430                     }
431                     if ((rc = arcofi_cmd(sc, COP_B, cmd)) != 0)
432                               goto error;
433                     sc->sc_active.gx_idx = sc->sc_shadow.gx_idx;
434                     sc->sc_active.output_mute = sc->sc_shadow.output_mute;
435           }
436 
437           if (sc->sc_active.cr3 != sc->sc_shadow.cr3) {
438                     cmd[0] = sc->sc_shadow.cr3;
439                     if ((rc = arcofi_cmd(sc, SOP_6, cmd)) != 0)
440                               goto error;
441                     sc->sc_active.cr3 = sc->sc_shadow.cr3;
442 
443                     ocsr = arcofi_read(sc, ARCOFI_CSR);
444                     if ((sc->sc_active.cr3 & CR3_OPMODE_MASK) != CR3_OPMODE_NORMAL)
445                               csr = ocsr | CSR_WIDTH_16;
446                     else
447                               csr = ocsr & ~CSR_WIDTH_16;
448                     if (csr != ocsr)
449                               arcofi_write(sc, ARCOFI_CSR, csr);
450           }
451 
452           if (sc->sc_active.cr4 != sc->sc_shadow.cr4) {
453                     cmd[0] = sc->sc_shadow.cr4;
454                     if ((rc = arcofi_cmd(sc, SOP_7, cmd)) != 0)
455                               goto error;
456                     sc->sc_active.cr4 = sc->sc_shadow.cr4;
457           }
458 
459           rc = 0;
460  error:
461           mutex_spin_exit(&sc->sc_intr_lock);
462           return rc;
463 }
464 
465 /*
466  * Take it out of the queue as much as possible.
467  */
468 static int
arcofi_recv_data(struct arcofi_softc * sc)469 arcofi_recv_data(struct arcofi_softc *sc)
470 {
471           uint8_t *cur;
472           uint8_t *past;
473 
474           cur = sc->sc_recv.buf;
475           past = sc->sc_recv.past;
476 
477           while (cur != past &&
478               (arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_IN_EMPTY) == 0) {
479                     *cur++ = arcofi_read(sc, ARCOFI_FIFO_DATA);
480           }
481           sc->sc_recv.buf = cur;
482 
483           return past - cur;
484 }
485 
486 /*
487  * Fill the queue as much as possible.
488  */
489 static int
arcofi_xmit_data(struct arcofi_softc * sc)490 arcofi_xmit_data(struct arcofi_softc *sc)
491 {
492           uint8_t *cur;
493           uint8_t *past;
494 
495           cur = sc->sc_xmit.buf;
496           past = sc->sc_xmit.past;
497 
498           while (cur != past &&
499               (arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_OUT_FULL) == 0) {
500                     arcofi_write(sc, ARCOFI_FIFO_DATA, *cur++);
501           }
502           sc->sc_xmit.buf = cur;
503 
504           return past - cur;
505 }
506 
507 static int
arcofi_start_input(void * v,void * rbuf,int rsz,void (* cb)(void *),void * cbarg)508 arcofi_start_input(void *v, void *rbuf, int rsz, void (*cb)(void *),
509     void *cbarg)
510 {
511           struct arcofi_softc *sc = (struct arcofi_softc *)v;
512 
513 #ifdef ARCOFI_DEBUG
514           printf("%s: %s, mode %d\n",
515               device_xname(sc->sc_dev), __func__, sc->sc_mode);
516 #endif
517 
518           /* enable data FIFO if becoming active */
519           if (sc->sc_mode == 0)
520                     arcofi_write(sc, ARCOFI_CSR,
521                         arcofi_read(sc, ARCOFI_CSR) | CSR_DATA_FIFO_ENABLE);
522           sc->sc_mode |= AUMODE_RECORD;
523 
524           sc->sc_recv.buf = (uint8_t *)rbuf;
525           sc->sc_recv.past = (uint8_t *)rbuf + rsz;
526           sc->sc_recv.cb = cb;
527           sc->sc_recv.cbarg = cbarg;
528 
529           /* enable input FIFO interrupts */
530           arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) |
531               FIFO_IR_ENABLE(FIFO_IR_IN_HALF_EMPTY));
532 
533           return 0;
534 }
535 
536 static int
arcofi_start_output(void * v,void * wbuf,int wsz,void (* cb)(void *),void * cbarg)537 arcofi_start_output(void *v, void *wbuf, int wsz, void (*cb)(void *),
538     void *cbarg)
539 {
540           struct arcofi_softc *sc = (struct arcofi_softc *)v;
541 
542 #ifdef ARCOFI_DEBUG
543           printf("%s: %s, mode %d\n",
544               device_xname(sc->sc_dev), __func__, sc->sc_mode);
545 #endif
546 
547           /* enable data FIFO if becoming active */
548           if (sc->sc_mode == 0)
549                     arcofi_write(sc, ARCOFI_CSR,
550                         arcofi_read(sc, ARCOFI_CSR) | CSR_DATA_FIFO_ENABLE);
551           sc->sc_mode |= AUMODE_PLAY;
552 
553           sc->sc_xmit.buf = (uint8_t *)wbuf;
554           sc->sc_xmit.past = (uint8_t *)wbuf + wsz;
555           sc->sc_xmit.cb = cb;
556           sc->sc_xmit.cbarg = cbarg;
557 
558           /* Fill FIFO */
559           arcofi_xmit_data(sc);
560 
561           /* enable output FIFO interrupts */
562           arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) |
563               FIFO_IR_ENABLE(FIFO_IR_OUT_HALF_EMPTY));
564 
565           return 0;
566 }
567 
568 static int
arcofi_halt_input(void * v)569 arcofi_halt_input(void *v)
570 {
571           struct arcofi_softc *sc = (struct arcofi_softc *)v;
572 
573 #ifdef ARCOFI_DEBUG
574           printf("%s: %s, mode %d\n",
575               device_xname(sc->sc_dev), __func__, sc->sc_mode);
576 #endif
577 
578           /* disable input FIFO interrupts */
579           arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) &
580               ~FIFO_IR_ENABLE(FIFO_IR_IN_HALF_EMPTY));
581           /* disable data FIFO if becoming idle */
582           sc->sc_mode &= ~AUMODE_RECORD;
583           if (sc->sc_mode == 0)
584                     arcofi_write(sc, ARCOFI_CSR,
585                         arcofi_read(sc, ARCOFI_CSR) & ~CSR_DATA_FIFO_ENABLE);
586 
587           return 0;
588 }
589 
590 static int
arcofi_halt_output(void * v)591 arcofi_halt_output(void *v)
592 {
593           struct arcofi_softc *sc = (struct arcofi_softc *)v;
594 
595 #ifdef ARCOFI_DEBUG
596           printf("%s: %s, mode %d\n",
597               device_xname(sc->sc_dev), __func__, sc->sc_mode);
598 #endif
599 
600           /* disable output FIFO interrupts */
601           arcofi_write(sc, ARCOFI_FIFO_IR, arcofi_read(sc, ARCOFI_FIFO_IR) &
602               ~FIFO_IR_ENABLE(FIFO_IR_OUT_HALF_EMPTY));
603           /* disable data FIFO if becoming idle */
604           sc->sc_mode &= ~AUMODE_PLAY;
605           if (sc->sc_mode == 0)
606                     arcofi_write(sc, ARCOFI_CSR,
607                         arcofi_read(sc, ARCOFI_CSR) & ~CSR_DATA_FIFO_ENABLE);
608 
609           return 0;
610 }
611 
612 static int
arcofi_getdev(void * v,struct audio_device * ad)613 arcofi_getdev(void *v, struct audio_device *ad)
614 {
615           struct arcofi_softc *sc = (struct arcofi_softc *)v;
616 
617           *ad = sc->sc_audio_device;
618           return 0;
619 }
620 
621 /*
622  * Convert gain table index to AUDIO_MIN_GAIN..AUDIO_MAX_GAIN scale.
623  */
624 static int
arcofi_gain_to_mi(uint idx)625 arcofi_gain_to_mi(uint idx)
626 {
627 
628           if (idx == 0)
629                     return AUDIO_MIN_GAIN;
630           if (idx == __arraycount(arcofi_gains) - 1)
631                     return AUDIO_MAX_GAIN;
632 
633           return ((idx - 1) * (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN)) /
634               (__arraycount(arcofi_gains) - 1) + AUDIO_MIN_GAIN + 1;
635 }
636 
637 /*
638  * Convert AUDIO_MIN_GAIN..AUDIO_MAX_GAIN scale to gain table index.
639  */
640 static uint
arcofi_mi_to_gain(int lvl)641 arcofi_mi_to_gain(int lvl)
642 {
643 
644           if (lvl <= AUDIO_MIN_GAIN)
645                     return 0;
646           if (lvl >= AUDIO_MAX_GAIN)
647                     return __arraycount(arcofi_gains) - 1;
648 
649           return ((lvl - AUDIO_MIN_GAIN - 1) * (__arraycount(arcofi_gains) - 1)) /
650               (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN);
651 }
652 
653 /*
654  * The following routines rely upon this...
655  */
656 #if (AUDIO_SPEAKER == AUDIO_LINE_IN) || (AUDIO_LINE_OUT == AUDIO_LINE_IN) || \
657     (AUDIO_SPEAKER == AUDIO_LINE_OUT)
658 #error Please rework the cr3 handling logic.
659 #endif
660 
661 /*
662  * The mapping between the available inputs and outputs, and CR3, is as
663  * follows:
664  * - the `line in' connector is the `MIC' input.
665  * - the `line out' connector is the `H out' (heaphones) output.
666  * - the internal `speaker' is the `LS out' (loudspeaker) output.
667  *
668  * Each of these can be enabled or disabled independently, except for
669  * MIC enabled with H out and LS out disabled, which is not allowed
670  * by the chip (and makes no sense for a chip which was intended to
671  * be used in phones, not voice recorders); we cheat by keeping one
672  * output source enabled, but with the output gain forced to minus
673  * infinity to mute it.
674  *
675  * The truth table is thus:
676  *
677  *        MIC       LS out    H out     AFEC
678  *        off       off       off       POR
679  *        off       off       on        MUTE
680  *        off       on        off       LH1
681  *        off       on        on        LH3, X input enabled
682  *        on        off       off       RDY, GX forced to minus infinity
683  *        on        off       on        RDY
684  *        on        on        off       LH2
685  *        on        on        on        LH3
686  */
687 
688 /*
689  * Convert logical port enable settings to a valid CR3 value.
690  */
691 static uint
arcofi_portmask_to_cr3(int mask)692 arcofi_portmask_to_cr3(int mask)
693 {
694 
695           switch (mask) {
696           default:
697           case 0:
698                     return CR3_MIC_G_17 | CR3_AFEC_POR;
699           case AUDIO_LINE_OUT:
700                     return CR3_MIC_G_17 | CR3_AFEC_MUTE;
701           case AUDIO_SPEAKER:
702                     return CR3_MIC_G_17 | CR3_AFEC_LH1;
703           case AUDIO_SPEAKER | AUDIO_LINE_OUT:
704                     return CR3_MIC_X_INPUT | CR3_AFEC_LH3;
705           case AUDIO_LINE_IN:
706                     /* since we can't do this, just... */
707                     /* FALLTHROUGH */
708           case AUDIO_LINE_IN | AUDIO_LINE_OUT:
709                     return CR3_MIC_G_17 | CR3_AFEC_RDY;
710           case AUDIO_LINE_IN | AUDIO_SPEAKER:
711                     return CR3_MIC_G_17 | CR3_AFEC_LH2;
712           case AUDIO_LINE_IN | AUDIO_SPEAKER | AUDIO_LINE_OUT:
713                     return CR3_MIC_G_17 | CR3_AFEC_LH3;
714           }
715 }
716 
717 /*
718  * Convert CR3 to an enabled ports mask.
719  */
720 static int
arcofi_cr3_to_portmask(uint cr3,int output_mute)721 arcofi_cr3_to_portmask(uint cr3, int output_mute)
722 {
723 
724           switch (cr3 & CR3_AFEC_MASK) {
725           default:
726           case CR3_AFEC_POR:
727                     return 0;
728           case CR3_AFEC_RDY:
729                     return output_mute ?
730                         AUDIO_LINE_IN : AUDIO_LINE_IN | AUDIO_LINE_OUT;
731           case CR3_AFEC_HFS:
732           case CR3_AFEC_LH1:
733                     return AUDIO_SPEAKER;
734           case CR3_AFEC_LH2:
735                     return AUDIO_LINE_IN | AUDIO_SPEAKER;
736           case CR3_AFEC_LH3:
737                     if ((cr3 & CR3_MIC_G_MASK) == CR3_MIC_X_INPUT)
738                               return AUDIO_SPEAKER | AUDIO_LINE_OUT;
739                     else
740                               return AUDIO_LINE_IN | AUDIO_SPEAKER | AUDIO_LINE_OUT;
741           case CR3_AFEC_MUTE:
742                     return AUDIO_LINE_OUT;
743           }
744 }
745 
746 static int
arcofi_set_port(void * v,mixer_ctrl_t * mc)747 arcofi_set_port(void *v, mixer_ctrl_t *mc)
748 {
749           struct arcofi_softc *sc = (struct arcofi_softc *)v;
750           int portmask = 0;
751 
752 #ifdef ARCOFI_DEBUG
753           printf("%s: %s, mode %d\n",
754               device_xname(sc->sc_dev), __func__, sc->sc_mode);
755 #endif
756           /* check for proper type */
757           switch (mc->dev) {
758           /* volume settings */
759           case ARCOFI_PORT_AUDIO_IN_VOLUME:
760           case ARCOFI_PORT_AUDIO_OUT_VOLUME:
761           case ARCOFI_PORT_AUDIO_SPKR_VOLUME:
762                     if (mc->un.value.num_channels != 1)
763                               return EINVAL;
764                     break;
765           /* mute settings */
766           case ARCOFI_PORT_AUDIO_IN_MUTE:
767           case ARCOFI_PORT_AUDIO_OUT_MUTE:
768           case ARCOFI_PORT_AUDIO_SPKR_MUTE:
769                     if (mc->type != AUDIO_MIXER_ENUM)
770                               return EINVAL;
771                     portmask = arcofi_cr3_to_portmask(sc->sc_shadow.cr3,
772                         sc->sc_shadow.output_mute);
773 #ifdef ARCOFI_DEBUG
774                     printf("%s: %s cr3 %02x -> mask %02x\n",
775                         device_xname(sc->sc_dev), __func__,
776                         sc->sc_shadow.cr3, portmask);
777 #endif
778                     break;
779           default:
780                     return EINVAL;
781           }
782 
783           switch (mc->dev) {
784           /* volume settings */
785           case ARCOFI_PORT_AUDIO_IN_VOLUME:
786                     sc->sc_shadow.gr_idx =
787                         arcofi_mi_to_gain(mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
788                     return 0;
789           case ARCOFI_PORT_AUDIO_OUT_VOLUME:
790           case ARCOFI_PORT_AUDIO_SPKR_VOLUME:
791                     sc->sc_shadow.gx_idx =
792                         arcofi_mi_to_gain(mc->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
793                     return 0;
794 
795           /* mute settings */
796           case ARCOFI_PORT_AUDIO_IN_MUTE:
797                     if (mc->un.ord)
798                               portmask &= ~AUDIO_LINE_IN;
799                     else
800                               portmask |= AUDIO_LINE_IN;
801                     break;
802           case ARCOFI_PORT_AUDIO_OUT_MUTE:
803                     if (mc->un.ord)
804                               portmask &= ~AUDIO_LINE_OUT;
805                     else
806                               portmask |= AUDIO_LINE_OUT;
807                     break;
808           case ARCOFI_PORT_AUDIO_SPKR_MUTE:
809                     if (mc->un.ord)
810                               portmask &= ~AUDIO_SPEAKER;
811                     else
812                               portmask |= AUDIO_SPEAKER;
813                     break;
814           }
815 
816           sc->sc_shadow.cr3 = (sc->sc_shadow.cr3 & CR3_OPMODE_MASK) |
817               arcofi_portmask_to_cr3(portmask);
818           sc->sc_shadow.output_mute = (portmask == AUDIO_LINE_IN);
819 #ifdef ARCOFI_DEBUG
820           printf("%s: %s mask %02x -> cr3 %02x m %d\n",
821               device_xname(sc->sc_dev), __func__,
822               portmask, sc->sc_shadow.cr3, sc->sc_shadow.output_mute);
823 #endif
824 
825           return 0;
826 }
827 
828 static int
arcofi_get_port(void * v,mixer_ctrl_t * mc)829 arcofi_get_port(void *v, mixer_ctrl_t *mc)
830 {
831           struct arcofi_softc *sc = (struct arcofi_softc *)v;
832           int portmask = 0;
833 
834 #ifdef ARCOFI_DEBUG
835           printf("%s: %s, mode %d\n",
836               device_xname(sc->sc_dev), __func__, sc->sc_mode);
837 #endif
838           /* check for proper type */
839           switch (mc->dev) {
840           /* volume settings */
841           case ARCOFI_PORT_AUDIO_IN_VOLUME:
842           case ARCOFI_PORT_AUDIO_OUT_VOLUME:
843           case ARCOFI_PORT_AUDIO_SPKR_VOLUME:
844                     if (mc->un.value.num_channels != 1)
845                               return EINVAL;
846                     break;
847 
848           /* mute settings */
849           case ARCOFI_PORT_AUDIO_IN_MUTE:
850           case ARCOFI_PORT_AUDIO_OUT_MUTE:
851           case ARCOFI_PORT_AUDIO_SPKR_MUTE:
852                     if (mc->type != AUDIO_MIXER_ENUM)
853                               return EINVAL;
854                     portmask = arcofi_cr3_to_portmask(sc->sc_shadow.cr3,
855                         sc->sc_shadow.output_mute);
856 #ifdef ARCOFI_DEBUG
857                     printf("%s: %s cr3 %02x -> mask %02x\n",
858                         device_xname(sc->sc_dev), __func__,
859                         sc->sc_shadow.cr3, portmask);
860 #endif
861                     break;
862           default:
863                     return EINVAL;
864           }
865 
866           switch (mc->dev) {
867           /* volume settings */
868           case ARCOFI_PORT_AUDIO_IN_VOLUME:
869                     mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
870                         arcofi_gain_to_mi(sc->sc_shadow.gr_idx);
871                     break;
872           case ARCOFI_PORT_AUDIO_OUT_VOLUME:
873           case ARCOFI_PORT_AUDIO_SPKR_VOLUME:
874                     mc->un.value.level[AUDIO_MIXER_LEVEL_MONO] =
875                         arcofi_gain_to_mi(sc->sc_shadow.gx_idx);
876                     break;
877 
878           /* mute settings */
879           case ARCOFI_PORT_AUDIO_IN_MUTE:
880                     mc->un.ord = portmask & AUDIO_LINE_IN ? 0 : 1;
881                     break;
882           case ARCOFI_PORT_AUDIO_OUT_MUTE:
883                     mc->un.ord = portmask & AUDIO_LINE_OUT ? 0 : 1;
884                     break;
885           case ARCOFI_PORT_AUDIO_SPKR_MUTE:
886                     mc->un.ord = portmask & AUDIO_SPEAKER ? 0 : 1;
887                     break;
888           }
889 
890           return 0;
891 }
892 
893 static int
arcofi_query_devinfo(void * v,mixer_devinfo_t * md)894 arcofi_query_devinfo(void *v, mixer_devinfo_t *md)
895 {
896 
897           switch (md->index) {
898           default:
899                     return ENXIO;
900 
901           /* items */
902           case ARCOFI_PORT_AUDIO_IN_VOLUME:
903                     md->type = AUDIO_MIXER_VALUE;
904                     md->mixer_class = ARCOFI_CLASS_INPUT;
905                     md->prev = AUDIO_MIXER_LAST;
906                     md->next = ARCOFI_PORT_AUDIO_IN_MUTE;
907                     strlcpy(md->label.name, AudioNline,
908                         sizeof md->label.name);
909                     goto mono_volume;
910           case ARCOFI_PORT_AUDIO_OUT_VOLUME:
911                     md->type = AUDIO_MIXER_VALUE;
912                     md->mixer_class = ARCOFI_CLASS_OUTPUT;
913                     md->prev = AUDIO_MIXER_LAST;
914                     md->next = ARCOFI_PORT_AUDIO_OUT_MUTE;
915                     strlcpy(md->label.name, AudioNline,
916                         sizeof md->label.name);
917                     goto mono_volume;
918           case ARCOFI_PORT_AUDIO_SPKR_VOLUME:
919                     md->type = AUDIO_MIXER_VALUE;
920                     md->mixer_class = ARCOFI_CLASS_OUTPUT;
921                     md->prev = AUDIO_MIXER_LAST;
922                     md->next = ARCOFI_PORT_AUDIO_SPKR_MUTE;
923                     strlcpy(md->label.name, AudioNspeaker,
924                         sizeof md->label.name);
925                     /* goto mono_volume; */
926  mono_volume:
927                     md->un.v.num_channels = 1;
928                     strlcpy(md->un.v.units.name, AudioNvolume,
929                         sizeof md->un.v.units.name);
930                     break;
931 
932           case ARCOFI_PORT_AUDIO_IN_MUTE:
933                     md->type = AUDIO_MIXER_ENUM;
934                     md->mixer_class = ARCOFI_CLASS_INPUT;
935                     md->prev = ARCOFI_PORT_AUDIO_IN_VOLUME;
936                     md->next = AUDIO_MIXER_LAST;
937                     goto mute;
938           case ARCOFI_PORT_AUDIO_OUT_MUTE:
939                     md->type = AUDIO_MIXER_ENUM;
940                     md->mixer_class = ARCOFI_CLASS_OUTPUT;
941                     md->prev = ARCOFI_PORT_AUDIO_OUT_VOLUME;
942                     md->next = AUDIO_MIXER_LAST;
943                     goto mute;
944           case ARCOFI_PORT_AUDIO_SPKR_MUTE:
945                     md->type = AUDIO_MIXER_ENUM;
946                     md->mixer_class = ARCOFI_CLASS_OUTPUT;
947                     md->prev = ARCOFI_PORT_AUDIO_SPKR_VOLUME;
948                     md->next = AUDIO_MIXER_LAST;
949                     /* goto mute; */
950  mute:
951                     strlcpy(md->label.name, AudioNmute, sizeof md->label.name);
952                     md->un.e.num_mem = 2;
953                     strlcpy(md->un.e.member[0].label.name, AudioNoff,
954                         sizeof md->un.e.member[0].label.name);
955                     md->un.e.member[0].ord = 0;
956                     strlcpy(md->un.e.member[1].label.name, AudioNon,
957                         sizeof md->un.e.member[1].label.name);
958                     md->un.e.member[1].ord = 1;
959                     break;
960 
961           /* classes */
962           case ARCOFI_CLASS_INPUT:
963                     md->type = AUDIO_MIXER_CLASS;
964                     md->mixer_class = ARCOFI_CLASS_INPUT;
965                     md->prev = AUDIO_MIXER_LAST;
966                     md->next = AUDIO_MIXER_LAST;
967                     strlcpy(md->label.name, AudioCinputs,
968                         sizeof md->label.name);
969                     break;
970           case ARCOFI_CLASS_OUTPUT:
971                     md->type = AUDIO_MIXER_CLASS;
972                     md->mixer_class = ARCOFI_CLASS_OUTPUT;
973                     md->prev = AUDIO_MIXER_LAST;
974                     md->next = AUDIO_MIXER_LAST;
975                     strlcpy(md->label.name, AudioCoutputs,
976                         sizeof md->label.name);
977                     break;
978           }
979 
980           return 0;
981 }
982 
983 static int
arcofi_get_props(void * v)984 arcofi_get_props(void *v)
985 {
986 
987           return AUDIO_PROP_PLAYBACK | AUDIO_PROP_CAPTURE;
988 }
989 
990 static void
arcofi_get_locks(void * v,kmutex_t ** intr,kmutex_t ** thread)991 arcofi_get_locks(void *v, kmutex_t **intr, kmutex_t **thread)
992 {
993           struct arcofi_softc *sc = (struct arcofi_softc *)v;
994 
995           *intr = &sc->sc_intr_lock;
996           *thread = &sc->sc_lock;
997 }
998 
999 int
arcofi_hwintr(void * v)1000 arcofi_hwintr(void *v)
1001 {
1002           struct arcofi_softc *sc = (struct arcofi_softc *)v;
1003           uint8_t csr, fir;
1004           int rc = 0;
1005 
1006           csr = arcofi_read(sc, ARCOFI_CSR);
1007           if ((csr & CSR_INTR_REQUEST) == 0)
1008                     return 0;
1009 
1010           fir = arcofi_read(sc, ARCOFI_FIFO_IR);
1011 
1012           /* receive */
1013           if ((sc->sc_mode & AUMODE_RECORD) &&
1014               (fir & FIFO_IR_EVENT(FIFO_IR_IN_HALF_EMPTY))) {
1015                     rc = 1;
1016 
1017                     if (arcofi_recv_data(sc) == 0) {
1018                               /* disable further interrupts */
1019                               arcofi_write(sc, ARCOFI_FIFO_IR,
1020                                   arcofi_read(sc, ARCOFI_FIFO_IR) &
1021                                   ~FIFO_IR_ENABLE(FIFO_IR_IN_HALF_EMPTY));
1022 
1023                               /* callback */
1024                               sc->sc_recv.cb(sc->sc_recv.cbarg);
1025                     }
1026           }
1027 
1028           /* xmit */
1029           if ((sc->sc_mode & AUMODE_PLAY) &&
1030               (fir & FIFO_IR_EVENT(FIFO_IR_OUT_HALF_EMPTY))) {
1031                     rc = 1;
1032 
1033                     if (arcofi_xmit_data(sc) == 0) {
1034                               /* disable further interrupts */
1035                               arcofi_write(sc, ARCOFI_FIFO_IR,
1036                                   arcofi_read(sc, ARCOFI_FIFO_IR) &
1037                                   ~FIFO_IR_ENABLE(FIFO_IR_OUT_HALF_EMPTY));
1038 
1039                               /* callback */
1040                               sc->sc_xmit.cb(sc->sc_xmit.cbarg);
1041                     }
1042           }
1043 
1044 #ifdef ARCOFI_DEBUG
1045           if (rc == 0)
1046                     printf("%s: unclaimed interrupt, csr %02x fir %02x fsr %02x\n",
1047                         device_xname(sc->sc_dev), csr, fir,
1048                         arcofi_read(sc, ARCOFI_FIFO_SR));
1049 #endif
1050 
1051           return rc;
1052 }
1053 
1054 static int
arcofi_cmd(struct arcofi_softc * sc,uint8_t cmd,const uint8_t * data)1055 arcofi_cmd(struct arcofi_softc *sc, uint8_t cmd, const uint8_t *data)
1056 {
1057           size_t len;
1058           uint8_t csr;
1059           int cnt;
1060           static const uint8_t cmdlen[] = {
1061               [SOP_0] = 4,
1062               [COP_1] = 4,
1063               [COP_2] = 2,
1064               [COP_3] = 2,
1065               [SOP_4] = 1,
1066               [SOP_5] = 1,
1067               [SOP_6] = 1,
1068               [SOP_7] = 1,
1069               [COP_8] = 2,
1070               [COP_9] = 4,
1071               [COP_A] = 8,
1072               [COP_B] = 2,
1073               [COP_C] = 8,
1074               [COP_D] = 4,
1075               [COP_E] = 4
1076           };
1077 
1078           /*
1079            * Compute command length.
1080            */
1081           if (cmd >= __arraycount(cmdlen))
1082                     return EINVAL;
1083           len = cmdlen[cmd];
1084 
1085           KASSERT(cold || mutex_owned(&sc->sc_intr_lock));
1086 
1087           /*
1088            * Disable all FIFO processing.
1089            */
1090           csr = arcofi_read(sc, ARCOFI_CSR);
1091           arcofi_write(sc, ARCOFI_CSR,
1092               csr & ~(CSR_DATA_FIFO_ENABLE | CSR_CTRL_FIFO_ENABLE));
1093 
1094           /*
1095            * Fill the FIFO with the command bytes.
1096            */
1097           arcofi_write(sc, ARCOFI_FIFO_CTRL, CMDR_PU | CMDR_WRITE | cmd);
1098           for (; len != 0; len--)
1099                     arcofi_write(sc, ARCOFI_FIFO_CTRL, *data++);
1100 
1101           /*
1102            * Enable command processing.
1103            */
1104           arcofi_write(sc, ARCOFI_CSR,
1105               (csr & ~CSR_DATA_FIFO_ENABLE) | CSR_CTRL_FIFO_ENABLE);
1106 
1107           /*
1108            * Wait for the command FIFO to be empty.
1109            */
1110           cnt = 100;
1111           while ((arcofi_read(sc, ARCOFI_FIFO_SR) & FIFO_SR_CTRL_EMPTY) == 0) {
1112                     if (cnt-- == 0) {
1113                               return EBUSY;
1114                     }
1115                     delay(10);
1116           }
1117 
1118           arcofi_write(sc, ARCOFI_CSR, csr);
1119 
1120           return 0;
1121 }
1122 
1123 void
arcofi_attach(struct arcofi_softc * sc,const char * versionstr)1124 arcofi_attach(struct arcofi_softc *sc, const char *versionstr)
1125 {
1126           device_t self;
1127           int rc;
1128           uint8_t op, cmd[4];
1129 
1130           self = sc->sc_dev;
1131           mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
1132           mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_AUDIO);
1133 
1134           /*
1135            * Reset logic.
1136            */
1137           arcofi_write(sc, ARCOFI_ID, 0);
1138           delay(100000);
1139           arcofi_write(sc, ARCOFI_CSR, 0);
1140 
1141           /*
1142            * Initialize the chip to default settings (8 bit, u-Law).
1143            */
1144           sc->sc_active.cr3 =
1145               arcofi_portmask_to_cr3(AUDIO_SPEAKER) | CR3_OPMODE_NORMAL;
1146           sc->sc_active.cr4 = CR4_TM | CR4_ULAW;
1147           sc->sc_active.gr_idx = sc->sc_active.gx_idx = 1 + NEGATIVE_GAINS;
1148           sc->sc_active.output_mute = 0;
1149           memcpy(&sc->sc_shadow, &sc->sc_active, sizeof(sc->sc_active));
1150 
1151           /* clear CRAM */
1152           op = SOP_4;
1153           cmd[0] = CR1_IDR;
1154           if ((rc = arcofi_cmd(sc, op, cmd)) != 0)
1155                     goto error;
1156           delay(1000);
1157 
1158           /* set gain values before enabling them in CR1 */
1159           op = COP_2;
1160           cmd[0] = arcofi_gains[sc->sc_active.gr_idx] >> 8;
1161           cmd[1] = arcofi_gains[sc->sc_active.gr_idx];
1162           if ((rc = arcofi_cmd(sc, op, cmd)) != 0)
1163                     goto error;
1164           /* same value for gx... */
1165           op = COP_B;
1166           if ((rc = arcofi_cmd(sc, op, cmd)) != 0)
1167                     goto error;
1168 
1169           /* set all CR registers at once */
1170           op = SOP_0;
1171           cmd[0] = sc->sc_active.cr4;
1172           cmd[1] = sc->sc_active.cr3;
1173           cmd[2] = CR2_SD | CR2_SC | CR2_SB | CR2_SA | CR2_ELS | CR2_AM | CR2_EFC;
1174           cmd[3] = CR1_GR | CR1_GX;
1175           if ((rc = arcofi_cmd(sc, op, cmd)) != 0)
1176                     goto error;
1177 
1178           arcofi_write(sc, ARCOFI_FIFO_IR, 0);
1179           arcofi_write(sc, ARCOFI_CSR, CSR_INTR_ENABLE);
1180 
1181           strlcpy(sc->sc_audio_device.name, arcofi_cd.cd_name,
1182               sizeof(sc->sc_audio_device.name));
1183           strlcpy(sc->sc_audio_device.version, versionstr,
1184               sizeof(sc->sc_audio_device.version));
1185           strlcpy(sc->sc_audio_device.config, device_xname(self),
1186               sizeof(sc->sc_audio_device.config));
1187 
1188           audio_attach_mi(&arcofi_hw_if, sc, self);
1189           return;
1190 
1191  error:
1192           arcofi_write(sc, ARCOFI_ID, 0);
1193           aprint_error("%s: %02x command failed, error %d\n",
1194               __func__, op, rc);
1195           mutex_destroy(&sc->sc_intr_lock);
1196           mutex_destroy(&sc->sc_lock);
1197 }
1198