2 * Copyright (c) 2001 Scott Long <scottl@freebsd.org>
3 * Copyright (c) 2001 Darrell Anderson <anderson@cs.duke.edu>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * $FreeBSD: src/sys/dev/sound/pci/maestro3.c,v 1.28.2.2 2007/03/12 02:03:25 ariff Exp $
31 * Maestro-3/Allegro FreeBSD pcm sound driver
33 * executive status summary:
34 * (+) /dev/dsp multiple concurrent play channels.
35 * (+) /dev/dsp config (speed, mono/stereo, 8/16 bit).
36 * (+) /dev/mixer sets left/right volumes.
37 * (+) /dev/dsp recording works. Tested successfully with the cdrom channel
38 * (+) apm suspend/resume works, and works properly!.
39 * (-) hardware volme controls don't work =-(
40 * (-) setblocksize() does nothing.
42 * The real credit goes to:
44 * Zach Brown for his Linux driver core and helpful technical comments.
45 * <zab@zabbo.net>, http://www.zabbo.net/maestro3
47 * Cameron Grant created the pcm framework used here nearly verbatim.
48 * <cg@freebsd.org>, http://people.freebsd.org/~cg/template.c
50 * Taku YAMAMOTO for his Maestro-1/2 FreeBSD driver and sanity reference.
51 * <taku@cent.saitama-u.ac.jp>
53 * ESS docs explained a few magic registers and numbers.
54 * http://virgo.caltech.edu/~dmoore/maestro3.pdf.gz
57 #include <dev/sound/pcm/sound.h>
58 #include <dev/sound/pcm/ac97.h>
60 #include <bus/pci/pcireg.h>
61 #include <bus/pci/pcivar.h>
63 #include <gnu/dev/sound/pci/maestro3_reg.h>
64 #include <gnu/dev/sound/pci/maestro3_dsp.h>
66 /* -------------------------------------------------------------------- */
68 enum {CHANGE
=0, CALL
=1, INTR
=2, BORING
=3, NONE
=-1};
69 #ifndef M3_DEBUG_LEVEL
70 #define M3_DEBUG_LEVEL NONE
72 #define M3_DEBUG(level, _msg) {if ((level) <= M3_DEBUG_LEVEL) {kprintf _msg;}}
74 /* -------------------------------------------------------------------- */
80 static struct m3_card_type
{
81 u_int32_t pci_id
; int which
; int delay1
; int delay2
; char *name
;
83 { 0x1988125d, ESS_ALLEGRO_1
, 50, 800, "ESS Technology Allegro-1" },
84 { 0x1998125d, ESS_MAESTRO3
, 20, 500, "ESS Technology Maestro3" },
85 { 0x199a125d, ESS_MAESTRO3
, 20, 500, "ESS Technology Maestro3" },
89 #define M3_BUFSIZE_MIN 4096
90 #define M3_BUFSIZE_MAX 65536
91 #define M3_BUFSIZE_DEFAULT 4096
92 #define M3_PCHANS 4 /* create /dev/dsp0.[0-N] to use more than one */
94 #define M3_MAXADDR ((1 << 27) - 1)
101 struct snd_dbuf
*buffer
;
102 struct pcm_channel
*channel
;
103 struct sc_info
*parent
;
115 struct snd_dbuf
*buffer
;
116 struct pcm_channel
*channel
;
117 struct sc_info
*parent
;
134 bus_space_handle_t sh
;
135 bus_dma_tag_t parent_dmat
;
137 struct resource
*reg
;
138 struct resource
*irq
;
144 struct sc_pchinfo pch
[M3_PCHANS
];
145 struct sc_rchinfo rch
[M3_RCHANS
];
155 #define M3_LOCK(_sc) snd_mtxlock((_sc)->sc_lock)
156 #define M3_UNLOCK(_sc) snd_mtxunlock((_sc)->sc_lock)
157 #define M3_LOCK_ASSERT(_sc) snd_mtxassert((_sc)->sc_lock)
159 /* -------------------------------------------------------------------- */
161 /* play channel interface */
162 static void *m3_pchan_init(kobj_t
, void *, struct snd_dbuf
*, struct pcm_channel
*, int);
163 static int m3_pchan_free(kobj_t
, void *);
164 static int m3_pchan_setformat(kobj_t
, void *, u_int32_t
);
165 static int m3_pchan_setspeed(kobj_t
, void *, u_int32_t
);
166 static int m3_pchan_setblocksize(kobj_t
, void *, u_int32_t
);
167 static int m3_pchan_trigger(kobj_t
, void *, int);
168 static int m3_pchan_trigger_locked(kobj_t
, void *, int);
169 static u_int32_t
m3_pchan_getptr_internal(struct sc_pchinfo
*);
170 static u_int32_t
m3_pchan_getptr(kobj_t
, void *);
171 static struct pcmchan_caps
*m3_pchan_getcaps(kobj_t
, void *);
173 /* record channel interface */
174 static void *m3_rchan_init(kobj_t
, void *, struct snd_dbuf
*, struct pcm_channel
*, int);
175 static int m3_rchan_free(kobj_t
, void *);
176 static int m3_rchan_setformat(kobj_t
, void *, u_int32_t
);
177 static int m3_rchan_setspeed(kobj_t
, void *, u_int32_t
);
178 static int m3_rchan_setblocksize(kobj_t
, void *, u_int32_t
);
179 static int m3_rchan_trigger(kobj_t
, void *, int);
180 static int m3_rchan_trigger_locked(kobj_t
, void *, int);
181 static u_int32_t
m3_rchan_getptr_internal(struct sc_rchinfo
*);
182 static u_int32_t
m3_rchan_getptr(kobj_t
, void *);
183 static struct pcmchan_caps
*m3_rchan_getcaps(kobj_t
, void *);
185 static int m3_chan_active(struct sc_info
*);
187 /* talk to the codec - called from ac97.c */
188 static int m3_initcd(kobj_t
, void *);
189 static int m3_rdcd(kobj_t
, void *, int);
190 static int m3_wrcd(kobj_t
, void *, int, u_int32_t
);
193 static void m3_intr(void *);
194 static int m3_power(struct sc_info
*, int);
195 static int m3_init(struct sc_info
*);
196 static int m3_uninit(struct sc_info
*);
197 static u_int8_t
m3_assp_halt(struct sc_info
*);
198 static void m3_config(struct sc_info
*);
199 static void m3_amp_enable(struct sc_info
*);
200 static void m3_enable_ints(struct sc_info
*);
201 static void m3_codec_reset(struct sc_info
*);
203 /* -------------------------------------------------------------------- */
204 /* Codec descriptor */
205 static kobj_method_t m3_codec_methods
[] = {
206 KOBJMETHOD(ac97_init
, m3_initcd
),
207 KOBJMETHOD(ac97_read
, m3_rdcd
),
208 KOBJMETHOD(ac97_write
, m3_wrcd
),
211 AC97_DECLARE(m3_codec
);
213 /* -------------------------------------------------------------------- */
214 /* channel descriptors */
216 static u_int32_t m3_playfmt
[] = {
218 AFMT_STEREO
| AFMT_U8
,
220 AFMT_STEREO
| AFMT_S16_LE
,
223 static struct pcmchan_caps m3_playcaps
= {8000, 48000, m3_playfmt
, 0};
225 static kobj_method_t m3_pch_methods
[] = {
226 KOBJMETHOD(channel_init
, m3_pchan_init
),
227 KOBJMETHOD(channel_setformat
, m3_pchan_setformat
),
228 KOBJMETHOD(channel_setspeed
, m3_pchan_setspeed
),
229 KOBJMETHOD(channel_setblocksize
, m3_pchan_setblocksize
),
230 KOBJMETHOD(channel_trigger
, m3_pchan_trigger
),
231 KOBJMETHOD(channel_getptr
, m3_pchan_getptr
),
232 KOBJMETHOD(channel_getcaps
, m3_pchan_getcaps
),
233 KOBJMETHOD(channel_free
, m3_pchan_free
),
236 CHANNEL_DECLARE(m3_pch
);
238 static u_int32_t m3_recfmt
[] = {
240 AFMT_STEREO
| AFMT_U8
,
242 AFMT_STEREO
| AFMT_S16_LE
,
245 static struct pcmchan_caps m3_reccaps
= {8000, 48000, m3_recfmt
, 0};
247 static kobj_method_t m3_rch_methods
[] = {
248 KOBJMETHOD(channel_init
, m3_rchan_init
),
249 KOBJMETHOD(channel_setformat
, m3_rchan_setformat
),
250 KOBJMETHOD(channel_setspeed
, m3_rchan_setspeed
),
251 KOBJMETHOD(channel_setblocksize
, m3_rchan_setblocksize
),
252 KOBJMETHOD(channel_trigger
, m3_rchan_trigger
),
253 KOBJMETHOD(channel_getptr
, m3_rchan_getptr
),
254 KOBJMETHOD(channel_getcaps
, m3_rchan_getcaps
),
255 KOBJMETHOD(channel_free
, m3_rchan_free
),
258 CHANNEL_DECLARE(m3_rch
);
260 /* -------------------------------------------------------------------- */
261 /* some i/o convenience functions */
263 #define m3_rd_1(sc, regno) bus_space_read_1(sc->st, sc->sh, regno)
264 #define m3_rd_2(sc, regno) bus_space_read_2(sc->st, sc->sh, regno)
265 #define m3_rd_4(sc, regno) bus_space_read_4(sc->st, sc->sh, regno)
266 #define m3_wr_1(sc, regno, data) bus_space_write_1(sc->st, sc->sh, regno, data)
267 #define m3_wr_2(sc, regno, data) bus_space_write_2(sc->st, sc->sh, regno, data)
268 #define m3_wr_4(sc, regno, data) bus_space_write_4(sc->st, sc->sh, regno, data)
269 #define m3_rd_assp_code(sc, index) \
270 m3_rd_assp(sc, MEMTYPE_INTERNAL_CODE, index)
271 #define m3_wr_assp_code(sc, index, data) \
272 m3_wr_assp(sc, MEMTYPE_INTERNAL_CODE, index, data)
273 #define m3_rd_assp_data(sc, index) \
274 m3_rd_assp(sc, MEMTYPE_INTERNAL_DATA, index)
275 #define m3_wr_assp_data(sc, index, data) \
276 m3_wr_assp(sc, MEMTYPE_INTERNAL_DATA, index, data)
278 static __inline u_int16_t
279 m3_rd_assp(struct sc_info
*sc
, u_int16_t region
, u_int16_t index
)
281 m3_wr_2(sc
, DSP_PORT_MEMORY_TYPE
, region
& MEMTYPE_MASK
);
282 m3_wr_2(sc
, DSP_PORT_MEMORY_INDEX
, index
);
283 return m3_rd_2(sc
, DSP_PORT_MEMORY_DATA
);
287 m3_wr_assp(struct sc_info
*sc
, u_int16_t region
, u_int16_t index
,
290 m3_wr_2(sc
, DSP_PORT_MEMORY_TYPE
, region
& MEMTYPE_MASK
);
291 m3_wr_2(sc
, DSP_PORT_MEMORY_INDEX
, index
);
292 m3_wr_2(sc
, DSP_PORT_MEMORY_DATA
, data
);
296 m3_wait(struct sc_info
*sc
)
300 for (i
=0 ; i
<20 ; i
++) {
301 if ((m3_rd_1(sc
, CODEC_STATUS
) & 1) == 0) {
309 /* -------------------------------------------------------------------- */
313 m3_initcd(kobj_t kobj
, void *devinfo
)
315 struct sc_info
*sc
= (struct sc_info
*)devinfo
;
318 M3_DEBUG(CALL
, ("m3_initcd\n"));
322 data
= m3_rd_1(sc
, CODEC_COMMAND
);
323 return ((data
& 0x1) ? 0 : 1);
327 m3_rdcd(kobj_t kobj
, void *devinfo
, int regno
)
329 struct sc_info
*sc
= (struct sc_info
*)devinfo
;
333 device_printf(sc
->dev
, "m3_rdcd timed out.\n");
336 m3_wr_1(sc
, CODEC_COMMAND
, (regno
& 0x7f) | 0x80);
337 DELAY(50); /* ac97 cycle = 20.8 usec */
339 device_printf(sc
->dev
, "m3_rdcd timed out.\n");
342 data
= m3_rd_2(sc
, CODEC_DATA
);
347 m3_wrcd(kobj_t kobj
, void *devinfo
, int regno
, u_int32_t data
)
349 struct sc_info
*sc
= (struct sc_info
*)devinfo
;
351 device_printf(sc
->dev
, "m3_wrcd timed out.\n");
354 m3_wr_2(sc
, CODEC_DATA
, data
);
355 m3_wr_1(sc
, CODEC_COMMAND
, regno
& 0x7f);
356 DELAY(50); /* ac97 cycle = 20.8 usec */
360 /* -------------------------------------------------------------------- */
361 /* play channel interface */
363 #define LO(x) (((x) & 0x0000ffff) )
364 #define HI(x) (((x) & 0xffff0000) >> 16)
367 m3_pchan_init(kobj_t kobj
, void *devinfo
, struct snd_dbuf
*b
, struct pcm_channel
*c
, int dir
)
369 struct sc_info
*sc
= devinfo
;
370 struct sc_pchinfo
*ch
;
371 u_int32_t bus_addr
, i
;
372 int idx
, data_bytes
, dac_data
;
373 int dsp_in_size
, dsp_out_size
, dsp_in_buf
, dsp_out_buf
;
376 idx
= sc
->pch_cnt
; /* dac instance number, no active reuse! */
377 M3_DEBUG(CHANGE
, ("m3_pchan_init(dac=%d)\n", idx
));
379 if (dir
!= PCMDIR_PLAY
) {
381 device_printf(sc
->dev
, "m3_pchan_init not PCMDIR_PLAY\n");
385 data_bytes
= (((MINISRC_TMP_BUFFER_SIZE
& ~1) +
386 (MINISRC_IN_BUFFER_SIZE
& ~1) +
387 (MINISRC_OUT_BUFFER_SIZE
& ~1) + 4) + 255) &~ 255;
388 dac_data
= 0x1100 + (data_bytes
* idx
);
390 dsp_in_size
= MINISRC_IN_BUFFER_SIZE
- (0x20 * 2);
391 dsp_out_size
= MINISRC_OUT_BUFFER_SIZE
- (0x20 * 2);
392 dsp_in_buf
= dac_data
+ (MINISRC_TMP_BUFFER_SIZE
/2);
393 dsp_out_buf
= dsp_in_buf
+ (dsp_in_size
/2) + 1;
397 ch
->dac_data
= dac_data
;
398 if (ch
->dac_data
+ data_bytes
/2 >= 0x1c00) {
400 device_printf(sc
->dev
, "m3_pchan_init: revb mem exhausted\n");
408 ch
->spd
= DSP_DEFAULT_SPEED
;
409 M3_UNLOCK(sc
); /* XXX */
410 if (sndbuf_alloc(ch
->buffer
, sc
->parent_dmat
, sc
->bufsz
) != 0) {
411 device_printf(sc
->dev
, "m3_pchan_init chn_allocbuf failed\n");
415 ch
->bufsize
= sndbuf_getsize(ch
->buffer
);
417 /* host dma buffer pointers */
418 bus_addr
= sndbuf_getbufaddr(ch
->buffer
);
420 device_printf(sc
->dev
, "m3_pchan_init unaligned bus_addr\n");
421 bus_addr
= (bus_addr
+ 4) & ~3;
423 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_HOST_SRC_ADDRL
, LO(bus_addr
));
424 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_HOST_SRC_ADDRH
, HI(bus_addr
));
425 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_HOST_SRC_END_PLUS_1L
,
426 LO(bus_addr
+ ch
->bufsize
));
427 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_HOST_SRC_END_PLUS_1H
,
428 HI(bus_addr
+ ch
->bufsize
));
429 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_HOST_SRC_CURRENTL
,
431 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_HOST_SRC_CURRENTH
,
435 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_IN_BUF_BEGIN
, dsp_in_buf
);
436 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_IN_BUF_END_PLUS_1
,
437 dsp_in_buf
+ dsp_in_size
/2);
438 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_IN_BUF_HEAD
, dsp_in_buf
);
439 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_IN_BUF_TAIL
, dsp_in_buf
);
440 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_OUT_BUF_BEGIN
, dsp_out_buf
);
441 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_OUT_BUF_END_PLUS_1
,
442 dsp_out_buf
+ dsp_out_size
/2);
443 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_OUT_BUF_HEAD
, dsp_out_buf
);
444 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_OUT_BUF_TAIL
, dsp_out_buf
);
446 /* some per client initializers */
447 m3_wr_assp_data(sc
, ch
->dac_data
+ SRC3_DIRECTION_OFFSET
+ 12,
448 ch
->dac_data
+ 40 + 8);
449 m3_wr_assp_data(sc
, ch
->dac_data
+ SRC3_DIRECTION_OFFSET
+ 19,
450 0x400 + MINISRC_COEF_LOC
);
451 /* enable or disable low pass filter? (0xff if rate> 45000) */
452 m3_wr_assp_data(sc
, ch
->dac_data
+ SRC3_DIRECTION_OFFSET
+ 22, 0);
453 /* tell it which way dma is going? */
454 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_DMA_CONTROL
,
455 DMACONTROL_AUTOREPEAT
+ DMAC_PAGE3_SELECTOR
+
456 DMAC_BLOCKF_SELECTOR
);
458 /* set an armload of static initializers */
459 for(i
= 0 ; i
< NELEM(pv
) ; i
++) {
460 m3_wr_assp_data(sc
, ch
->dac_data
+ pv
[i
].addr
, pv
[i
].val
);
463 /* put us in the packed task lists */
464 m3_wr_assp_data(sc
, KDATA_INSTANCE0_MINISRC
+
465 (sc
->pch_cnt
+ sc
->rch_cnt
),
466 ch
->dac_data
>> DP_SHIFT_COUNT
);
467 m3_wr_assp_data(sc
, KDATA_DMA_XFER0
+ (sc
->pch_cnt
+ sc
->rch_cnt
),
468 ch
->dac_data
>> DP_SHIFT_COUNT
);
469 m3_wr_assp_data(sc
, KDATA_MIXER_XFER0
+ sc
->pch_cnt
,
470 ch
->dac_data
>> DP_SHIFT_COUNT
);
472 /* gotta start before stop */
473 m3_pchan_trigger_locked(NULL
, ch
, PCMTRIG_START
);
474 /* silence noise on load */
475 m3_pchan_trigger_locked(NULL
, ch
, PCMTRIG_STOP
);
484 m3_pchan_free(kobj_t kobj
, void *chdata
)
486 struct sc_pchinfo
*ch
= chdata
;
487 struct sc_info
*sc
= ch
->parent
;
490 M3_DEBUG(CHANGE
, ("m3_pchan_free(dac=%d)\n", ch
->dac_idx
));
493 * should remove this exact instance from the packed lists, but all
494 * are released at once (and in a stopped state) so this is ok.
496 m3_wr_assp_data(sc
, KDATA_INSTANCE0_MINISRC
+
497 (sc
->pch_cnt
- 1) + sc
->rch_cnt
, 0);
498 m3_wr_assp_data(sc
, KDATA_DMA_XFER0
+
499 (sc
->pch_cnt
- 1) + sc
->rch_cnt
, 0);
500 m3_wr_assp_data(sc
, KDATA_MIXER_XFER0
+ (sc
->pch_cnt
-1), 0);
508 m3_pchan_setformat(kobj_t kobj
, void *chdata
, u_int32_t format
)
510 struct sc_pchinfo
*ch
= chdata
;
511 struct sc_info
*sc
= ch
->parent
;
516 ("m3_pchan_setformat(dac=%d, format=0x%x{%s-%s})\n",
518 format
& (AFMT_U8
|AFMT_S8
) ? "8bit":"16bit",
519 format
& AFMT_STEREO
? "STEREO":"MONO"));
522 data
= (format
& AFMT_STEREO
) ? 0 : 1;
523 m3_wr_assp_data(sc
, ch
->dac_data
+ SRC3_MODE_OFFSET
, data
);
526 data
= ((format
& AFMT_U8
) || (format
& AFMT_S8
)) ? 1 : 0;
527 m3_wr_assp_data(sc
, ch
->dac_data
+ SRC3_WORD_LENGTH_OFFSET
, data
);
536 m3_pchan_setspeed(kobj_t kobj
, void *chdata
, u_int32_t speed
)
538 struct sc_pchinfo
*ch
= chdata
;
539 struct sc_info
*sc
= ch
->parent
;
543 M3_DEBUG(CHANGE
, ("m3_pchan_setspeed(dac=%d, speed=%d)\n",
544 ch
->dac_idx
, speed
));
546 if ((freq
= ((speed
<< 15) + 24000) / 48000) != 0) {
550 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_FREQUENCY
, freq
);
554 /* return closest possible speed */
559 m3_pchan_setblocksize(kobj_t kobj
, void *chdata
, u_int32_t blocksize
)
561 struct sc_pchinfo
*ch
= chdata
;
563 M3_DEBUG(CHANGE
, ("m3_pchan_setblocksize(dac=%d, blocksize=%d)\n",
564 ch
->dac_idx
, blocksize
));
566 return (sndbuf_getblksz(ch
->buffer
));
570 m3_pchan_trigger(kobj_t kobj
, void *chdata
, int go
)
572 struct sc_pchinfo
*ch
= chdata
;
573 struct sc_info
*sc
= ch
->parent
;
577 ret
= m3_pchan_trigger_locked(kobj
, chdata
, go
);
584 m3_chan_active(struct sc_info
*sc
)
590 for (i
= 0; i
< sc
->pch_cnt
; i
++)
591 ret
+= sc
->pch
[i
].active
;
593 for (i
= 0; i
< sc
->rch_cnt
; i
++)
594 ret
+= sc
->rch
[i
].active
;
600 m3_pchan_trigger_locked(kobj_t kobj
, void *chdata
, int go
)
602 struct sc_pchinfo
*ch
= chdata
;
603 struct sc_info
*sc
= ch
->parent
;
607 M3_DEBUG(go
== PCMTRIG_START
? CHANGE
:
608 go
== PCMTRIG_STOP
? CHANGE
:
609 go
== PCMTRIG_ABORT
? CHANGE
:
611 ("m3_pchan_trigger(dac=%d, go=0x%x{%s})\n", ch
->dac_idx
, go
,
612 go
== PCMTRIG_START
? "PCMTRIG_START" :
613 go
== PCMTRIG_STOP
? "PCMTRIG_STOP" :
614 go
== PCMTRIG_ABORT
? "PCMTRIG_ABORT" : "ignore"));
624 sc
->pch_active_cnt
++;
626 /*[[inc_timer_users]]*/
627 if (m3_chan_active(sc
) == 1) {
628 m3_wr_assp_data(sc
, KDATA_TIMER_COUNT_RELOAD
, 240);
629 m3_wr_assp_data(sc
, KDATA_TIMER_COUNT_CURRENT
, 240);
630 data
= m3_rd_2(sc
, HOST_INT_CTRL
);
631 m3_wr_2(sc
, HOST_INT_CTRL
, data
| CLKRUN_GEN_ENABLE
);
634 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_INSTANCE_READY
, 1);
635 m3_wr_assp_data(sc
, KDATA_MIXER_TASK_NUMBER
,
641 if (ch
->active
== 0) {
645 sc
->pch_active_cnt
--;
647 /* XXX should the channel be drained? */
648 /*[[dec_timer_users]]*/
649 if (m3_chan_active(sc
) == 0) {
650 m3_wr_assp_data(sc
, KDATA_TIMER_COUNT_RELOAD
, 0);
651 m3_wr_assp_data(sc
, KDATA_TIMER_COUNT_CURRENT
, 0);
652 data
= m3_rd_2(sc
, HOST_INT_CTRL
);
653 m3_wr_2(sc
, HOST_INT_CTRL
, data
& ~CLKRUN_GEN_ENABLE
);
656 m3_wr_assp_data(sc
, ch
->dac_data
+ CDATA_INSTANCE_READY
, 0);
657 m3_wr_assp_data(sc
, KDATA_MIXER_TASK_NUMBER
,
661 case PCMTRIG_EMLDMAWR
:
662 /* got play irq, transfer next buffer - ignore if using dma */
663 case PCMTRIG_EMLDMARD
:
664 /* got rec irq, transfer next buffer - ignore if using dma */
672 m3_pchan_getptr_internal(struct sc_pchinfo
*ch
)
674 struct sc_info
*sc
= ch
->parent
;
675 u_int32_t hi
, lo
, bus_base
, bus_crnt
;
677 bus_base
= sndbuf_getbufaddr(ch
->buffer
);
678 hi
= m3_rd_assp_data(sc
, ch
->dac_data
+ CDATA_HOST_SRC_CURRENTH
);
679 lo
= m3_rd_assp_data(sc
, ch
->dac_data
+ CDATA_HOST_SRC_CURRENTL
);
680 bus_crnt
= lo
| (hi
<< 16);
682 M3_DEBUG(CALL
, ("m3_pchan_getptr(dac=%d) result=%d\n",
683 ch
->dac_idx
, bus_crnt
- bus_base
));
685 return (bus_crnt
- bus_base
); /* current byte offset of channel */
689 m3_pchan_getptr(kobj_t kobj
, void *chdata
)
691 struct sc_pchinfo
*ch
= chdata
;
692 struct sc_info
*sc
= ch
->parent
;
702 static struct pcmchan_caps
*
703 m3_pchan_getcaps(kobj_t kobj
, void *chdata
)
705 struct sc_pchinfo
*ch
= chdata
;
707 M3_DEBUG(CALL
, ("m3_pchan_getcaps(dac=%d)\n", ch
->dac_idx
));
712 /* -------------------------------------------------------------------- */
713 /* rec channel interface */
716 m3_rchan_init(kobj_t kobj
, void *devinfo
, struct snd_dbuf
*b
, struct pcm_channel
*c
, int dir
)
718 struct sc_info
*sc
= devinfo
;
719 struct sc_rchinfo
*ch
;
720 u_int32_t bus_addr
, i
;
722 int idx
, data_bytes
, adc_data
;
723 int dsp_in_size
, dsp_out_size
, dsp_in_buf
, dsp_out_buf
;
726 idx
= sc
->rch_cnt
; /* adc instance number, no active reuse! */
727 M3_DEBUG(CHANGE
, ("m3_rchan_init(adc=%d)\n", idx
));
729 if (dir
!= PCMDIR_REC
) {
731 device_printf(sc
->dev
, "m3_pchan_init not PCMDIR_REC\n");
735 data_bytes
= (((MINISRC_TMP_BUFFER_SIZE
& ~1) +
736 (MINISRC_IN_BUFFER_SIZE
& ~1) +
737 (MINISRC_OUT_BUFFER_SIZE
& ~1) + 4) + 255) &~ 255;
738 adc_data
= 0x1100 + (data_bytes
* idx
) + data_bytes
/2;
739 dsp_in_size
= MINISRC_IN_BUFFER_SIZE
+ (0x10 * 2);
740 dsp_out_size
= MINISRC_OUT_BUFFER_SIZE
- (0x10 * 2);
741 dsp_in_buf
= adc_data
+ (MINISRC_TMP_BUFFER_SIZE
/ 2);
742 dsp_out_buf
= dsp_in_buf
+ (dsp_in_size
/ 2) + 1;
746 ch
->adc_data
= adc_data
;
747 if (ch
->adc_data
+ data_bytes
/2 >= 0x1c00) {
749 device_printf(sc
->dev
, "m3_rchan_init: revb mem exhausted\n");
757 ch
->spd
= DSP_DEFAULT_SPEED
;
758 M3_UNLOCK(sc
); /* XXX */
759 if (sndbuf_alloc(ch
->buffer
, sc
->parent_dmat
, sc
->bufsz
) != 0) {
760 device_printf(sc
->dev
, "m3_rchan_init chn_allocbuf failed\n");
764 ch
->bufsize
= sndbuf_getsize(ch
->buffer
);
766 /* host dma buffer pointers */
767 bus_addr
= sndbuf_getbufaddr(ch
->buffer
);
769 device_printf(sc
->dev
, "m3_rchan_init unaligned bus_addr\n");
770 bus_addr
= (bus_addr
+ 4) & ~3;
772 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_HOST_SRC_ADDRL
, LO(bus_addr
));
773 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_HOST_SRC_ADDRH
, HI(bus_addr
));
774 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_HOST_SRC_END_PLUS_1L
,
775 LO(bus_addr
+ ch
->bufsize
));
776 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_HOST_SRC_END_PLUS_1H
,
777 HI(bus_addr
+ ch
->bufsize
));
778 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_HOST_SRC_CURRENTL
,
780 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_HOST_SRC_CURRENTH
,
784 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_IN_BUF_BEGIN
, dsp_in_buf
);
785 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_IN_BUF_END_PLUS_1
,
786 dsp_in_buf
+ dsp_in_size
/2);
787 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_IN_BUF_HEAD
, dsp_in_buf
);
788 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_IN_BUF_TAIL
, dsp_in_buf
);
789 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_OUT_BUF_BEGIN
, dsp_out_buf
);
790 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_OUT_BUF_END_PLUS_1
,
791 dsp_out_buf
+ dsp_out_size
/2);
792 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_OUT_BUF_HEAD
, dsp_out_buf
);
793 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_OUT_BUF_TAIL
, dsp_out_buf
);
795 /* some per client initializers */
796 m3_wr_assp_data(sc
, ch
->adc_data
+ SRC3_DIRECTION_OFFSET
+ 12,
797 ch
->adc_data
+ 40 + 8);
798 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_DMA_CONTROL
,
799 DMACONTROL_DIRECTION
+ DMACONTROL_AUTOREPEAT
+
800 DMAC_PAGE3_SELECTOR
+ DMAC_BLOCKF_SELECTOR
);
802 /* set an armload of static initializers */
803 for(i
= 0 ; i
< NELEM(rv
) ; i
++) {
804 m3_wr_assp_data(sc
, ch
->adc_data
+ rv
[i
].addr
, rv
[i
].val
);
807 /* put us in the packed task lists */
808 m3_wr_assp_data(sc
, KDATA_INSTANCE0_MINISRC
+
809 (sc
->pch_cnt
+ sc
->rch_cnt
),
810 ch
->adc_data
>> DP_SHIFT_COUNT
);
811 m3_wr_assp_data(sc
, KDATA_DMA_XFER0
+ (sc
->pch_cnt
+ sc
->rch_cnt
),
812 ch
->adc_data
>> DP_SHIFT_COUNT
);
813 m3_wr_assp_data(sc
, KDATA_ADC1_XFER0
+ sc
->rch_cnt
,
814 ch
->adc_data
>> DP_SHIFT_COUNT
);
816 /* gotta start before stop */
817 m3_rchan_trigger_locked(NULL
, ch
, PCMTRIG_START
);
819 m3_rchan_trigger_locked(NULL
, ch
, PCMTRIG_STOP
);
828 m3_rchan_free(kobj_t kobj
, void *chdata
)
830 struct sc_rchinfo
*ch
= chdata
;
831 struct sc_info
*sc
= ch
->parent
;
834 M3_DEBUG(CHANGE
, ("m3_rchan_free(adc=%d)\n", ch
->adc_idx
));
837 * should remove this exact instance from the packed lists, but all
838 * are released at once (and in a stopped state) so this is ok.
840 m3_wr_assp_data(sc
, KDATA_INSTANCE0_MINISRC
+
841 (sc
->rch_cnt
- 1) + sc
->pch_cnt
, 0);
842 m3_wr_assp_data(sc
, KDATA_DMA_XFER0
+
843 (sc
->rch_cnt
- 1) + sc
->pch_cnt
, 0);
844 m3_wr_assp_data(sc
, KDATA_ADC1_XFER0
+ (sc
->rch_cnt
- 1), 0);
852 m3_rchan_setformat(kobj_t kobj
, void *chdata
, u_int32_t format
)
854 struct sc_rchinfo
*ch
= chdata
;
855 struct sc_info
*sc
= ch
->parent
;
860 ("m3_rchan_setformat(dac=%d, format=0x%x{%s-%s})\n",
862 format
& (AFMT_U8
|AFMT_S8
) ? "8bit":"16bit",
863 format
& AFMT_STEREO
? "STEREO":"MONO"));
866 data
= (format
& AFMT_STEREO
) ? 0 : 1;
867 m3_wr_assp_data(sc
, ch
->adc_data
+ SRC3_MODE_OFFSET
, data
);
870 data
= ((format
& AFMT_U8
) || (format
& AFMT_S8
)) ? 1 : 0;
871 m3_wr_assp_data(sc
, ch
->adc_data
+ SRC3_WORD_LENGTH_OFFSET
, data
);
879 m3_rchan_setspeed(kobj_t kobj
, void *chdata
, u_int32_t speed
)
881 struct sc_rchinfo
*ch
= chdata
;
882 struct sc_info
*sc
= ch
->parent
;
886 M3_DEBUG(CHANGE
, ("m3_rchan_setspeed(adc=%d, speed=%d)\n",
887 ch
->adc_idx
, speed
));
889 if ((freq
= ((speed
<< 15) + 24000) / 48000) != 0) {
893 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_FREQUENCY
, freq
);
897 /* return closest possible speed */
902 m3_rchan_setblocksize(kobj_t kobj
, void *chdata
, u_int32_t blocksize
)
904 struct sc_rchinfo
*ch
= chdata
;
906 M3_DEBUG(CHANGE
, ("m3_rchan_setblocksize(adc=%d, blocksize=%d)\n",
907 ch
->adc_idx
, blocksize
));
909 return (sndbuf_getblksz(ch
->buffer
));
913 m3_rchan_trigger(kobj_t kobj
, void *chdata
, int go
)
915 struct sc_rchinfo
*ch
= chdata
;
916 struct sc_info
*sc
= ch
->parent
;
920 ret
= m3_rchan_trigger_locked(kobj
, chdata
, go
);
927 m3_rchan_trigger_locked(kobj_t kobj
, void *chdata
, int go
)
929 struct sc_rchinfo
*ch
= chdata
;
930 struct sc_info
*sc
= ch
->parent
;
934 M3_DEBUG(go
== PCMTRIG_START
? CHANGE
:
935 go
== PCMTRIG_STOP
? CHANGE
:
936 go
== PCMTRIG_ABORT
? CHANGE
:
938 ("m3_rchan_trigger(adc=%d, go=0x%x{%s})\n", ch
->adc_idx
, go
,
939 go
== PCMTRIG_START
? "PCMTRIG_START" :
940 go
== PCMTRIG_STOP
? "PCMTRIG_STOP" :
941 go
== PCMTRIG_ABORT
? "PCMTRIG_ABORT" : "ignore"));
952 /*[[inc_timer_users]]*/
953 if (m3_chan_active(sc
) == 1) {
954 m3_wr_assp_data(sc
, KDATA_TIMER_COUNT_RELOAD
, 240);
955 m3_wr_assp_data(sc
, KDATA_TIMER_COUNT_CURRENT
, 240);
956 data
= m3_rd_2(sc
, HOST_INT_CTRL
);
957 m3_wr_2(sc
, HOST_INT_CTRL
, data
| CLKRUN_GEN_ENABLE
);
960 m3_wr_assp_data(sc
, KDATA_ADC1_REQUEST
, 1);
961 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_INSTANCE_READY
, 1);
966 if (ch
->active
== 0) {
971 /*[[dec_timer_users]]*/
972 if (m3_chan_active(sc
) == 0) {
973 m3_wr_assp_data(sc
, KDATA_TIMER_COUNT_RELOAD
, 0);
974 m3_wr_assp_data(sc
, KDATA_TIMER_COUNT_CURRENT
, 0);
975 data
= m3_rd_2(sc
, HOST_INT_CTRL
);
976 m3_wr_2(sc
, HOST_INT_CTRL
, data
& ~CLKRUN_GEN_ENABLE
);
979 m3_wr_assp_data(sc
, ch
->adc_data
+ CDATA_INSTANCE_READY
, 0);
980 m3_wr_assp_data(sc
, KDATA_ADC1_REQUEST
, 0);
983 case PCMTRIG_EMLDMAWR
:
984 /* got play irq, transfer next buffer - ignore if using dma */
985 case PCMTRIG_EMLDMARD
:
986 /* got rec irq, transfer next buffer - ignore if using dma */
994 m3_rchan_getptr_internal(struct sc_rchinfo
*ch
)
996 struct sc_info
*sc
= ch
->parent
;
997 u_int32_t hi
, lo
, bus_base
, bus_crnt
;
999 bus_base
= sndbuf_getbufaddr(ch
->buffer
);
1000 hi
= m3_rd_assp_data(sc
, ch
->adc_data
+ CDATA_HOST_SRC_CURRENTH
);
1001 lo
= m3_rd_assp_data(sc
, ch
->adc_data
+ CDATA_HOST_SRC_CURRENTL
);
1002 bus_crnt
= lo
| (hi
<< 16);
1004 M3_DEBUG(CALL
, ("m3_rchan_getptr(adc=%d) result=%d\n",
1005 ch
->adc_idx
, bus_crnt
- bus_base
));
1007 return (bus_crnt
- bus_base
); /* current byte offset of channel */
1011 m3_rchan_getptr(kobj_t kobj
, void *chdata
)
1013 struct sc_rchinfo
*ch
= chdata
;
1014 struct sc_info
*sc
= ch
->parent
;
1024 static struct pcmchan_caps
*
1025 m3_rchan_getcaps(kobj_t kobj
, void *chdata
)
1027 struct sc_rchinfo
*ch
= chdata
;
1029 M3_DEBUG(CALL
, ("m3_rchan_getcaps(adc=%d)\n", ch
->adc_idx
));
1034 /* -------------------------------------------------------------------- */
1035 /* The interrupt handler */
1040 struct sc_info
*sc
= (struct sc_info
*)p
;
1041 struct sc_pchinfo
*pch
;
1042 struct sc_rchinfo
*rch
;
1043 u_int32_t status
, ctl
, i
, delta
;
1045 M3_DEBUG(INTR
, ("m3_intr\n"));
1048 status
= m3_rd_1(sc
, HOST_INT_STATUS
);
1054 m3_wr_1(sc
, HOST_INT_STATUS
, 0xff); /* ack the int? */
1056 if (status
& HV_INT_PENDING
) {
1059 event
= m3_rd_1(sc
, HW_VOL_COUNTER_MASTER
);
1062 mixer_hwvol_mute(sc
->dev
);
1065 mixer_hwvol_step(sc
->dev
, 1, 1);
1068 mixer_hwvol_step(sc
->dev
, -1, -1);
1073 device_printf(sc
->dev
, "Unknown HWVOL event\n");
1075 m3_wr_1(sc
, HW_VOL_COUNTER_MASTER
, 0x88);
1079 if (status
& ASSP_INT_PENDING
) {
1080 ctl
= m3_rd_1(sc
, ASSP_CONTROL_B
);
1081 if (!(ctl
& STOP_ASSP_CLOCK
)) {
1082 ctl
= m3_rd_1(sc
, ASSP_HOST_INT_STATUS
);
1083 if (ctl
& DSP2HOST_REQ_TIMER
) {
1084 m3_wr_1(sc
, ASSP_HOST_INT_STATUS
,
1085 DSP2HOST_REQ_TIMER
);
1086 /*[[ess_update_ptr]]*/
1087 goto m3_handle_channel_intr
;
1092 goto m3_handle_channel_intr_out
;
1094 m3_handle_channel_intr
:
1095 for (i
=0 ; i
<sc
->pch_cnt
; i
++) {
1098 pch
->ptr
= m3_pchan_getptr_internal(pch
);
1099 delta
= pch
->bufsize
+ pch
->ptr
- pch
->prevptr
;
1100 delta
%= pch
->bufsize
;
1101 if (delta
< sndbuf_getblksz(pch
->buffer
))
1103 pch
->prevptr
= pch
->ptr
;
1105 chn_intr(pch
->channel
);
1109 for (i
=0 ; i
<sc
->rch_cnt
; i
++) {
1112 rch
->ptr
= m3_rchan_getptr_internal(rch
);
1113 delta
= rch
->bufsize
+ rch
->ptr
- rch
->prevptr
;
1114 delta
%= rch
->bufsize
;
1115 if (delta
< sndbuf_getblksz(rch
->buffer
))
1117 rch
->prevptr
= rch
->ptr
;
1119 chn_intr(rch
->channel
);
1124 m3_handle_channel_intr_out
:
1128 /* -------------------------------------------------------------------- */
1132 m3_power(struct sc_info
*sc
, int state
)
1136 M3_DEBUG(CHANGE
, ("m3_power(%d)\n", state
));
1139 data
= pci_read_config(sc
->dev
, 0x34, 1);
1140 if (pci_read_config(sc
->dev
, data
, 1) == 1) {
1141 pci_write_config(sc
->dev
, data
+ 4, state
, 1);
1148 m3_init(struct sc_info
*sc
)
1150 u_int32_t data
, i
, size
;
1151 u_int8_t reset_state
;
1154 M3_DEBUG(CHANGE
, ("m3_init\n"));
1156 /* diable legacy emulations. */
1157 data
= pci_read_config(sc
->dev
, PCI_LEGACY_AUDIO_CTRL
, 2);
1158 data
|= DISABLE_LEGACY
;
1159 pci_write_config(sc
->dev
, PCI_LEGACY_AUDIO_CTRL
, data
, 2);
1163 reset_state
= m3_assp_halt(sc
);
1167 /* [m3_assp_init] */
1168 /* zero kernel data */
1169 size
= REV_B_DATA_MEMORY_UNIT_LENGTH
* NUM_UNITS_KERNEL_DATA
;
1170 for(i
= 0 ; i
< size
/ 2 ; i
++) {
1171 m3_wr_assp_data(sc
, KDATA_BASE_ADDR
+ i
, 0);
1173 /* zero mixer data? */
1174 size
= REV_B_DATA_MEMORY_UNIT_LENGTH
* NUM_UNITS_KERNEL_DATA
;
1175 for(i
= 0 ; i
< size
/ 2 ; i
++) {
1176 m3_wr_assp_data(sc
, KDATA_BASE_ADDR2
+ i
, 0);
1178 /* init dma pointer */
1179 m3_wr_assp_data(sc
, KDATA_CURRENT_DMA
,
1181 /* write kernel into code memory */
1182 size
= sizeof(assp_kernel_image
);
1183 for(i
= 0 ; i
< size
/ 2; i
++) {
1184 m3_wr_assp_code(sc
, REV_B_CODE_MEMORY_BEGIN
+ i
,
1185 assp_kernel_image
[i
]);
1188 * We only have this one client and we know that 0x400 is kfree in
1189 * our kernel's mem map, so lets just drop it there. It seems that
1190 * the minisrc doesn't need vectors, so we won't bother with them..
1192 size
= sizeof(assp_minisrc_image
);
1193 for(i
= 0 ; i
< size
/ 2; i
++) {
1194 m3_wr_assp_code(sc
, 0x400 + i
, assp_minisrc_image
[i
]);
1196 /* write the coefficients for the low pass filter? */
1197 size
= sizeof(minisrc_lpf_image
);
1198 for(i
= 0; i
< size
/ 2 ; i
++) {
1199 m3_wr_assp_code(sc
,0x400 + MINISRC_COEF_LOC
+ i
,
1200 minisrc_lpf_image
[i
]);
1202 m3_wr_assp_code(sc
, 0x400 + MINISRC_COEF_LOC
+ size
, 0x8000);
1203 /* the minisrc is the only thing on our task list */
1204 m3_wr_assp_data(sc
, KDATA_TASK0
, 0x400);
1205 /* init the mixer number */
1206 m3_wr_assp_data(sc
, KDATA_MIXER_TASK_NUMBER
, 0);
1207 /* extreme kernel master volume */
1208 m3_wr_assp_data(sc
, KDATA_DAC_LEFT_VOLUME
, ARB_VOLUME
);
1209 m3_wr_assp_data(sc
, KDATA_DAC_RIGHT_VOLUME
, ARB_VOLUME
);
1213 /* [m3_assp_client_init] (only one client at index 0) */
1214 for (i
=0x1100 ; i
<0x1c00 ; i
++) {
1215 m3_wr_assp_data(sc
, i
, 0); /* zero entire dac/adc area */
1218 /* [m3_assp_continue] */
1219 m3_wr_1(sc
, DSP_PORT_CONTROL_REG_B
, reset_state
| REGB_ENABLE_RESET
);
1225 m3_uninit(struct sc_info
*sc
)
1227 M3_DEBUG(CHANGE
, ("m3_uninit\n"));
1231 /* -------------------------------------------------------------------- */
1232 /* Probe and attach the card */
1235 m3_pci_probe(device_t dev
)
1237 struct m3_card_type
*card
;
1239 M3_DEBUG(CALL
, ("m3_pci_probe(0x%x)\n", pci_get_devid(dev
)));
1241 for (card
= m3_card_types
; card
->pci_id
; card
++) {
1242 if (pci_get_devid(dev
) == card
->pci_id
) {
1243 device_set_desc(dev
, card
->name
);
1244 return BUS_PROBE_DEFAULT
;
1251 m3_pci_attach(device_t dev
)
1254 struct ac97_info
*codec
= NULL
;
1256 char status
[SND_STATUSLEN
];
1257 struct m3_card_type
*card
;
1258 int i
, len
, dacn
, adcn
;
1260 M3_DEBUG(CALL
, ("m3_pci_attach\n"));
1262 sc
= kmalloc(sizeof(*sc
), M_DEVBUF
, M_WAITOK
| M_ZERO
);
1264 sc
->type
= pci_get_devid(dev
);
1265 sc
->sc_lock
= snd_mtxcreate(device_get_nameunit(dev
),
1267 if (sc
->sc_lock
== NULL
) {
1268 device_printf(dev
, "cannot create mutex\n");
1269 kfree(sc
, M_DEVBUF
);
1272 for (card
= m3_card_types
; card
->pci_id
; card
++) {
1273 if (sc
->type
== card
->pci_id
) {
1274 sc
->which
= card
->which
;
1275 sc
->delay1
= card
->delay1
;
1276 sc
->delay2
= card
->delay2
;
1281 if (resource_int_value(device_get_name(dev
), device_get_unit(dev
),
1285 else if (i
> M3_PCHANS
)
1294 data
= pci_read_config(dev
, PCIR_COMMAND
, 2);
1295 data
|= (PCIM_CMD_PORTEN
| PCIM_CMD_MEMEN
| PCIM_CMD_BUSMASTEREN
);
1296 pci_write_config(dev
, PCIR_COMMAND
, data
, 2);
1298 sc
->regid
= PCIR_BAR(0);
1299 sc
->regtype
= SYS_RES_MEMORY
;
1300 sc
->reg
= bus_alloc_resource_any(dev
, sc
->regtype
, &sc
->regid
,
1303 sc
->regtype
= SYS_RES_IOPORT
;
1304 sc
->reg
= bus_alloc_resource_any(dev
, sc
->regtype
, &sc
->regid
,
1308 device_printf(dev
, "unable to allocate register space\n");
1311 sc
->st
= rman_get_bustag(sc
->reg
);
1312 sc
->sh
= rman_get_bushandle(sc
->reg
);
1315 sc
->irq
= bus_alloc_resource_any(dev
, SYS_RES_IRQ
, &sc
->irqid
,
1316 RF_ACTIVE
| RF_SHAREABLE
);
1318 device_printf(dev
, "unable to allocate interrupt\n");
1322 if (snd_setup_intr(dev
, sc
->irq
, INTR_MPSAFE
, m3_intr
, sc
, &sc
->ih
)) {
1323 device_printf(dev
, "unable to setup interrupt\n");
1327 sc
->bufsz
= pcm_getbuffersize(dev
, M3_BUFSIZE_MIN
, M3_BUFSIZE_DEFAULT
,
1330 if (bus_dma_tag_create(
1332 2, 0, /* alignment, boundary */
1333 M3_MAXADDR
, /* lowaddr */
1334 BUS_SPACE_MAXADDR
, /* highaddr */
1335 NULL
, NULL
, /* filtfunc, filtfuncarg */
1336 sc
->bufsz
, /* maxsize */
1338 0x3ffff, /* maxsegz */
1340 &sc
->parent_dmat
) != 0) {
1341 device_printf(dev
, "unable to create dma tag\n");
1346 m3_power(sc
, 0); /* power up */
1351 device_printf(dev
, "unable to initialize the card\n");
1355 /* create/init mixer */
1356 codec
= AC97_CREATE(dev
, sc
, m3_codec
);
1357 if (codec
== NULL
) {
1358 device_printf(dev
, "ac97_create error\n");
1361 if (mixer_init(dev
, ac97_getmixerclass(), codec
)) {
1362 device_printf(dev
, "mixer_init error\n");
1368 if (pcm_register(dev
, sc
, dacn
, adcn
)) {
1369 device_printf(dev
, "pcm_register error\n");
1372 for (i
=0 ; i
<dacn
; i
++) {
1373 if (pcm_addchan(dev
, PCMDIR_PLAY
, &m3_pch_class
, sc
)) {
1374 device_printf(dev
, "pcm_addchan (play) error\n");
1378 for (i
=0 ; i
<adcn
; i
++) {
1379 if (pcm_addchan(dev
, PCMDIR_REC
, &m3_rch_class
, sc
)) {
1380 device_printf(dev
, "pcm_addchan (rec) error\n");
1384 ksnprintf(status
, SND_STATUSLEN
, "at %s 0x%lx irq %ld %s",
1385 (sc
->regtype
== SYS_RES_IOPORT
)? "io" : "memory",
1386 rman_get_start(sc
->reg
), rman_get_start(sc
->irq
),
1387 PCM_KLDSTRING(snd_maestro3
));
1388 if (pcm_setstatus(dev
, status
)) {
1389 device_printf(dev
, "attach: pcm_setstatus error\n");
1393 mixer_hwvol_init(dev
);
1395 /* Create the buffer for saving the card state during suspend */
1396 len
= sizeof(u_int16_t
) * (REV_B_CODE_MEMORY_LENGTH
+
1397 REV_B_DATA_MEMORY_LENGTH
);
1398 sc
->savemem
= kmalloc(len
, M_DEVBUF
, M_WAITOK
| M_ZERO
);
1404 ac97_destroy(codec
);
1406 bus_teardown_intr(dev
, sc
->irq
, sc
->ih
);
1408 bus_release_resource(dev
, SYS_RES_IRQ
, sc
->irqid
, sc
->irq
);
1410 bus_release_resource(dev
, sc
->regtype
, sc
->regid
, sc
->reg
);
1411 if (sc
->parent_dmat
)
1412 bus_dma_tag_destroy(sc
->parent_dmat
);
1414 snd_mtxfree(sc
->sc_lock
);
1415 kfree(sc
, M_DEVBUF
);
1420 m3_pci_detach(device_t dev
)
1422 struct sc_info
*sc
= pcm_getdevinfo(dev
);
1425 M3_DEBUG(CALL
, ("m3_pci_detach\n"));
1427 if ((r
= pcm_unregister(dev
)) != 0) {
1432 m3_uninit(sc
); /* shutdown chip */
1433 m3_power(sc
, 3); /* power off */
1436 bus_teardown_intr(dev
, sc
->irq
, sc
->ih
);
1437 bus_release_resource(dev
, SYS_RES_IRQ
, sc
->irqid
, sc
->irq
);
1438 bus_release_resource(dev
, sc
->regtype
, sc
->regid
, sc
->reg
);
1439 bus_dma_tag_destroy(sc
->parent_dmat
);
1441 kfree(sc
->savemem
, M_DEVBUF
);
1442 snd_mtxfree(sc
->sc_lock
);
1443 kfree(sc
, M_DEVBUF
);
1448 m3_pci_suspend(device_t dev
)
1450 struct sc_info
*sc
= pcm_getdevinfo(dev
);
1453 M3_DEBUG(CHANGE
, ("m3_pci_suspend\n"));
1456 for (i
=0 ; i
<sc
->pch_cnt
; i
++) {
1457 if (sc
->pch
[i
].active
) {
1458 m3_pchan_trigger_locked(NULL
, &sc
->pch
[i
],
1462 for (i
=0 ; i
<sc
->rch_cnt
; i
++) {
1463 if (sc
->rch
[i
].active
) {
1464 m3_rchan_trigger_locked(NULL
, &sc
->rch
[i
],
1468 DELAY(10 * 1000); /* give things a chance to stop */
1470 /* Disable interrupts */
1471 m3_wr_2(sc
, HOST_INT_CTRL
, 0);
1472 m3_wr_1(sc
, ASSP_CONTROL_C
, 0);
1476 /* Save the state of the ASSP */
1477 for (i
= REV_B_CODE_MEMORY_BEGIN
; i
<= REV_B_CODE_MEMORY_END
; i
++)
1478 sc
->savemem
[index
++] = m3_rd_assp_code(sc
, i
);
1479 for (i
= REV_B_DATA_MEMORY_BEGIN
; i
<= REV_B_DATA_MEMORY_END
; i
++)
1480 sc
->savemem
[index
++] = m3_rd_assp_data(sc
, i
);
1482 /* Power down the card to D3 state */
1490 m3_pci_resume(device_t dev
)
1492 struct sc_info
*sc
= pcm_getdevinfo(dev
);
1494 u_int8_t reset_state
;
1496 M3_DEBUG(CHANGE
, ("m3_pci_resume\n"));
1499 /* Power the card back to D0 */
1504 reset_state
= m3_assp_halt(sc
);
1508 /* Restore the ASSP state */
1509 for (i
= REV_B_CODE_MEMORY_BEGIN
; i
<= REV_B_CODE_MEMORY_END
; i
++)
1510 m3_wr_assp_code(sc
, i
, sc
->savemem
[index
++]);
1511 for (i
= REV_B_DATA_MEMORY_BEGIN
; i
<= REV_B_DATA_MEMORY_END
; i
++)
1512 m3_wr_assp_data(sc
, i
, sc
->savemem
[index
++]);
1514 /* Restart the DMA engine */
1515 m3_wr_assp_data(sc
, KDATA_DMA_ACTIVE
, 0);
1517 /* [m3_assp_continue] */
1518 m3_wr_1(sc
, DSP_PORT_CONTROL_REG_B
, reset_state
| REGB_ENABLE_RESET
);
1524 M3_UNLOCK(sc
); /* XXX */
1525 if (mixer_reinit(dev
) == -1) {
1526 device_printf(dev
, "unable to reinitialize the mixer\n");
1531 /* Turn the channels back on */
1532 for (i
=0 ; i
<sc
->pch_cnt
; i
++) {
1533 if (sc
->pch
[i
].active
) {
1534 m3_pchan_trigger_locked(NULL
, &sc
->pch
[i
],
1538 for (i
=0 ; i
<sc
->rch_cnt
; i
++) {
1539 if (sc
->rch
[i
].active
) {
1540 m3_rchan_trigger_locked(NULL
, &sc
->rch
[i
],
1550 m3_pci_shutdown(device_t dev
)
1552 struct sc_info
*sc
= pcm_getdevinfo(dev
);
1554 M3_DEBUG(CALL
, ("m3_pci_shutdown\n"));
1557 m3_power(sc
, 3); /* power off */
1564 m3_assp_halt(struct sc_info
*sc
)
1566 u_int8_t data
, reset_state
;
1570 data
= m3_rd_1(sc
, DSP_PORT_CONTROL_REG_B
);
1571 reset_state
= data
& ~REGB_STOP_CLOCK
; /* remember for continue */
1573 m3_wr_1(sc
, DSP_PORT_CONTROL_REG_B
, reset_state
& ~REGB_ENABLE_RESET
);
1574 DELAY(10 * 1000); /* necessary? */
1580 m3_config(struct sc_info
*sc
)
1582 u_int32_t data
, hv_cfg
;
1589 * The volume buttons can be wired up via two different sets of pins.
1590 * This presents a problem since we can't tell which way it's
1591 * configured. Allow the user to set a hint in order to twiddle
1594 if (resource_int_value(device_get_name(sc
->dev
),
1595 device_get_unit(sc
->dev
),
1596 "hwvol_config", &hint
) == 0)
1597 hv_cfg
= (hint
> 0) ? HV_BUTTON_FROM_GD
: 0;
1599 hv_cfg
= HV_BUTTON_FROM_GD
;
1602 data
= pci_read_config(sc
->dev
, PCI_ALLEGRO_CONFIG
, 4);
1603 data
&= ~HV_BUTTON_FROM_GD
;
1604 data
|= REDUCED_DEBOUNCE
| HV_CTRL_ENABLE
| hv_cfg
;
1605 data
|= PM_CTRL_ENABLE
| CLK_DIV_BY_49
| USE_PCI_TIMING
;
1606 pci_write_config(sc
->dev
, PCI_ALLEGRO_CONFIG
, data
, 4);
1608 m3_wr_1(sc
, ASSP_CONTROL_B
, RESET_ASSP
);
1609 data
= pci_read_config(sc
->dev
, PCI_ALLEGRO_CONFIG
, 4);
1610 data
&= ~INT_CLK_SELECT
;
1611 if (sc
->which
== ESS_MAESTRO3
) {
1612 data
&= ~INT_CLK_MULT_ENABLE
;
1613 data
|= INT_CLK_SRC_NOT_PCI
;
1615 data
&= ~(CLK_MULT_MODE_SELECT
| CLK_MULT_MODE_SELECT_2
);
1616 pci_write_config(sc
->dev
, PCI_ALLEGRO_CONFIG
, data
, 4);
1618 if (sc
->which
== ESS_ALLEGRO_1
) {
1619 data
= pci_read_config(sc
->dev
, PCI_USER_CONFIG
, 4);
1620 data
|= IN_CLK_12MHZ_SELECT
;
1621 pci_write_config(sc
->dev
, PCI_USER_CONFIG
, data
, 4);
1624 data
= m3_rd_1(sc
, ASSP_CONTROL_A
);
1625 data
&= ~(DSP_CLK_36MHZ_SELECT
| ASSP_CLK_49MHZ_SELECT
);
1626 data
|= ASSP_CLK_49MHZ_SELECT
; /*XXX assumes 49MHZ dsp XXX*/
1627 data
|= ASSP_0_WS_ENABLE
;
1628 m3_wr_1(sc
, ASSP_CONTROL_A
, data
);
1630 m3_wr_1(sc
, ASSP_CONTROL_B
, RUN_ASSP
);
1634 m3_enable_ints(struct sc_info
*sc
)
1638 m3_wr_2(sc
, HOST_INT_CTRL
, ASSP_INT_ENABLE
| HV_INT_ENABLE
);
1639 data
= m3_rd_1(sc
, ASSP_CONTROL_C
);
1640 m3_wr_1(sc
, ASSP_CONTROL_C
, data
| ASSP_HOST_INT_ENABLE
);
1644 m3_amp_enable(struct sc_info
*sc
)
1646 u_int32_t gpo
, polarity_port
, polarity
;
1651 switch (sc
->which
) {
1653 polarity_port
= 0x1800;
1656 polarity_port
= 0x1100;
1659 panic("bad sc->which");
1661 gpo
= (polarity_port
>> 8) & 0x0f;
1662 polarity
= polarity_port
>> 12;
1663 polarity
= !polarity
; /* enable */
1664 polarity
= polarity
<< gpo
;
1666 m3_wr_2(sc
, GPIO_MASK
, ~gpo
);
1667 data
= m3_rd_2(sc
, GPIO_DIRECTION
);
1668 m3_wr_2(sc
, GPIO_DIRECTION
, data
| gpo
);
1669 data
= GPO_SECONDARY_AC97
| GPO_PRIMARY_AC97
| polarity
;
1670 m3_wr_2(sc
, GPIO_DATA
, data
);
1671 m3_wr_2(sc
, GPIO_MASK
, ~0);
1675 m3_codec_reset(struct sc_info
*sc
)
1677 u_int16_t data
, dir
;
1682 data
= m3_rd_2(sc
, GPIO_DIRECTION
);
1683 dir
= data
| 0x10; /* assuming pci bus master? */
1685 /* [[remote_codec_config]] */
1686 data
= m3_rd_2(sc
, RING_BUS_CTRL_B
);
1687 m3_wr_2(sc
, RING_BUS_CTRL_B
, data
& ~SECOND_CODEC_ID_MASK
);
1688 data
= m3_rd_2(sc
, SDO_OUT_DEST_CTRL
);
1689 m3_wr_2(sc
, SDO_OUT_DEST_CTRL
, data
& ~COMMAND_ADDR_OUT
);
1690 data
= m3_rd_2(sc
, SDO_IN_DEST_CTRL
);
1691 m3_wr_2(sc
, SDO_IN_DEST_CTRL
, data
& ~STATUS_ADDR_IN
);
1693 m3_wr_2(sc
, RING_BUS_CTRL_A
, IO_SRAM_ENABLE
);
1696 m3_wr_2(sc
, GPIO_DIRECTION
, dir
& ~GPO_PRIMARY_AC97
);
1697 m3_wr_2(sc
, GPIO_MASK
, ~GPO_PRIMARY_AC97
);
1698 m3_wr_2(sc
, GPIO_DATA
, 0);
1699 m3_wr_2(sc
, GPIO_DIRECTION
, dir
| GPO_PRIMARY_AC97
);
1700 DELAY(sc
->delay1
* 1000); /*delay1 (ALLEGRO:50, MAESTRO3:20)*/
1701 m3_wr_2(sc
, GPIO_DATA
, GPO_PRIMARY_AC97
);
1703 m3_wr_2(sc
, RING_BUS_CTRL_A
, IO_SRAM_ENABLE
|
1704 SERIAL_AC_LINK_ENABLE
);
1705 m3_wr_2(sc
, GPIO_MASK
, ~0);
1706 DELAY(sc
->delay2
* 1000); /*delay2 (ALLEGRO:800, MAESTRO3:500)*/
1708 /* [[try read vendor]] */
1709 data
= m3_rdcd(NULL
, sc
, 0x7c);
1710 if ((data
== 0) || (data
== 0xffff)) {
1713 device_printf(sc
->dev
, "Codec reset failed\n");
1716 device_printf(sc
->dev
, "Codec reset retry\n");
1721 static device_method_t m3_methods
[] = {
1722 DEVMETHOD(device_probe
, m3_pci_probe
),
1723 DEVMETHOD(device_attach
, m3_pci_attach
),
1724 DEVMETHOD(device_detach
, m3_pci_detach
),
1725 DEVMETHOD(device_suspend
, m3_pci_suspend
),
1726 DEVMETHOD(device_resume
, m3_pci_resume
),
1727 DEVMETHOD(device_shutdown
, m3_pci_shutdown
),
1731 static driver_t m3_driver
= {
1737 DRIVER_MODULE(snd_maestro3
, pci
, m3_driver
, pcm_devclass
, NULL
, NULL
);
1738 MODULE_DEPEND(snd_maestro3
, sound
, SOUND_MINVER
, SOUND_PREFVER
, SOUND_MAXVER
);
1739 MODULE_VERSION(snd_maestro3
, 1);