This source file includes following definitions.
- salloc_t
- maestro_get_flags
- maestro_match
- maestro_attach
- maestro_init
- maestro_round_blocksize
- maestro_malloc
- maestro_free
- maestro_mappage
- maestro_get_props
- maestro_getdev
- maestro_set_port
- maestro_get_port
- maestro_query_devinfo
- maestro_query_encoding
- maestro_set_speed
- maestro_calc_timer_freq
- maestro_update_timer
- maestro_set_params
- maestro_open
- maestro_close
- maestro_channel_stop
- maestro_halt_input
- maestro_halt_output
- maestro_trigger_input
- maestro_channel_start
- maestro_trigger_output
- maestro_read_codec
- maestro_write_codec
- maestro_attach_codec
- maestro_reset_codec
- maestro_initcodec
- maestro_powerhook
- maestro_power
- maestro_channel_advance_dma
- maestro_channel_suppress_jitter
- maestro_intr
- ringbus_setdest
- wp_reg_read
- wp_reg_write
- apu_setindex
- wp_apu_read
- wp_apu_write
- wp_settimer
- wp_starttimer
- wp_stoptimer
- wc_reg_read
- wc_reg_write
- wc_ctrl_read
- wc_ctrl_write
- salloc_new
- salloc_destroy
- salloc_insert
- salloc_alloc
- salloc_free
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/kernel.h>
52 #include <sys/malloc.h>
53 #include <sys/device.h>
54 #include <sys/proc.h>
55 #include <sys/queue.h>
56 #include <sys/fcntl.h>
57
58 #include <dev/pci/pcidevs.h>
59 #include <dev/pci/pcivar.h>
60
61 #include <sys/audioio.h>
62 #include <dev/audio_if.h>
63 #include <dev/mulaw.h>
64 #include <dev/auconv.h>
65
66 #include <dev/ic/ac97.h>
67
68
69
70
71
72
73 #define CONF_LEGACY 0x40
74
75 #define LEGACY_DISABLED 0x8000
76
77
78 #define CONF_MAESTRO 0x50
79 #define MAESTRO_CHIBUS 0x00100000
80 #define MAESTRO_POSTEDWRITE 0x00000080
81 #define MAESTRO_DMA_PCITIMING 0x00000040
82 #define MAESTRO_SWAP_LR 0x00000010
83
84
85 #define CONF_ACPI_STOPCLOCK 0x54
86 #define ACPI_PART_2ndC_CLOCK 15
87 #define ACPI_PART_CODEC_CLOCK 14
88 #define ACPI_PART_978 13
89 #define ACPI_PART_SPDIF 12
90 #define ACPI_PART_GLUE 11
91 #define ACPI_PART_DAA 10
92 #define ACPI_PART_PCI_IF 9
93 #define ACPI_PART_HW_VOL 8
94 #define ACPI_PART_GPIO 7
95 #define ACPI_PART_ASSP 6
96 #define ACPI_PART_SB 5
97 #define ACPI_PART_FM 4
98 #define ACPI_PART_RINGBUS 3
99 #define ACPI_PART_MIDI 2
100 #define ACPI_PART_GAME_PORT 1
101 #define ACPI_PART_WP 0
102
103
104 #define CONF_PM_PTR 0x34
105 #define PM_CID 0
106 #define PPMI_CID 1
107 #define PM_CTRL 4
108 #define PPMI_D0 0
109 #define PPMI_D1 1
110 #define PPMI_D2 2
111 #define PPMI_D3 3
112
113
114
115
116
117
118
119 #define PORT_DSP_DATA 0x00
120 #define PORT_DSP_INDEX 0x02
121 #define PORT_INT_STAT 0x04
122 #define PORT_SAMPLE_CNT 0x06
123
124
125 #define PORT_WAVCACHE_INDEX 0x10
126 #define PORT_WAVCACHE_DATA 0x12
127 #define WAVCACHE_PCMBAR 0x1fc
128 #define WAVCACHE_WTBAR 0x1f0
129 #define WAVCACHE_BASEADDR_SHIFT 12
130
131 #define WAVCACHE_CHCTL_ADDRTAG_MASK 0xfff8
132 #define WAVCACHE_CHCTL_U8 0x0004
133 #define WAVCACHE_CHCTL_STEREO 0x0002
134 #define WAVCACHE_CHCTL_DECREMENTAL 0x0001
135
136 #define PORT_WAVCACHE_CTRL 0x14
137 #define WAVCACHE_EXTRA_CH_ENABLED 0x0200
138 #define WAVCACHE_ENABLED 0x0100
139 #define WAVCACHE_CH_60_ENABLED 0x0080
140 #define WAVCACHE_WTSIZE_MASK 0x0060
141 #define WAVCACHE_WTSIZE_1MB 0x0000
142 #define WAVCACHE_WTSIZE_2MB 0x0020
143 #define WAVCACHE_WTSIZE_4MB 0x0040
144 #define WAVCACHE_WTSIZE_8MB 0x0060
145 #define WAVCACHE_SGC_MASK 0x000c
146 #define WAVCACHE_SGC_DISABLED 0x0000
147 #define WAVCACHE_SGC_40_47 0x0004
148 #define WAVCACHE_SGC_32_47 0x0008
149 #define WAVCACHE_TESTMODE 0x0001
150
151
152 #define PORT_HOSTINT_CTRL 0x18
153 #define HOSTINT_CTRL_SOFT_RESET 0x8000
154 #define HOSTINT_CTRL_DSOUND_RESET 0x4000
155 #define HOSTINT_CTRL_HW_VOL_TO_PME 0x0400
156 #define HOSTINT_CTRL_CLKRUN_ENABLED 0x0100
157 #define HOSTINT_CTRL_HWVOL_ENABLED 0x0040
158 #define HOSTINT_CTRL_ASSP_INT_ENABLED 0x0010
159 #define HOSTINT_CTRL_ISDN_INT_ENABLED 0x0008
160 #define HOSTINT_CTRL_DSOUND_INT_ENABLED 0x0004
161 #define HOSTINT_CTRL_MPU401_INT_ENABLED 0x0002
162 #define HOSTINT_CTRL_SB_INT_ENABLED 0x0001
163
164 #define PORT_HOSTINT_STAT 0x1a
165 #define HOSTINT_STAT_HWVOL 0x40
166 #define HOSTINT_STAT_ASSP 0x10
167 #define HOSTINT_STAT_ISDN 0x08
168 #define HOSTINT_STAT_DSOUND 0x04
169 #define HOSTINT_STAT_MPU401 0x02
170 #define HOSTINT_STAT_SB 0x01
171
172
173 #define PORT_HWVOL_VOICE_SHADOW 0x1c
174 #define PORT_HWVOL_VOICE 0x1d
175 #define PORT_HWVOL_MASTER_SHADOW 0x1e
176 #define PORT_HWVOL_MASTER 0x1f
177
178
179 #define PORT_CODEC_CMD 0x30
180 #define CODEC_CMD_READ 0x80
181 #define CODEC_CMD_WRITE 0x00
182 #define CODEC_CMD_ADDR_MASK 0x7f
183
184 #define PORT_CODEC_STAT 0x30
185 #define CODEC_STAT_MASK 0x01
186 #define CODEC_STAT_RW_DONE 0x00
187 #define CODEC_STAT_PROGLESS 0x01
188
189 #define PORT_CODEC_REG 0x32
190
191
192 #define PORT_RINGBUS_CTRL 0x34
193 #define RINGBUS_CTRL_I2S_ENABLED 0x80000000
194 #define RINGBUS_CTRL_RINGBUS_ENABLED 0x20000000
195 #define RINGBUS_CTRL_ACLINK_ENABLED 0x10000000
196 #define RINGBUS_CTRL_AC97_SWRESET 0x08000000
197 #define RINGBUS_CTRL_IODMA_PLAYBACK_ENABLED 0x04000000
198 #define RINGBUS_CTRL_IODMA_RECORD_ENABLED 0x02000000
199
200 #define RINGBUS_SRC_MIC 20
201 #define RINGBUS_SRC_I2S 16
202 #define RINGBUS_SRC_ADC 12
203 #define RINGBUS_SRC_MODEM 8
204 #define RINGBUS_SRC_DSOUND 4
205 #define RINGBUS_SRC_ASSP 0
206
207 #define RINGBUS_DEST_MONORAL 000
208 #define RINGBUS_DEST_STEREO 010
209 #define RINGBUS_DEST_NONE 0
210 #define RINGBUS_DEST_DAC 1
211 #define RINGBUS_DEST_MODEM_IN 2
212 #define RINGBUS_DEST_RESERVED3 3
213 #define RINGBUS_DEST_DSOUND_IN 4
214 #define RINGBUS_DEST_ASSP_IN 5
215
216
217 #define PORT_GPIO_DATA 0x60
218 #define PORT_GPIO_MASK 0x64
219 #define PORT_GPIO_DIR 0x68
220
221
222 #define PORT_ASSP_MEM_INDEX 0x80
223 #define PORT_ASSP_MEM_DATA 0x84
224 #define PORT_ASSP_CTRL_A 0xa2
225 #define PORT_ASSP_CTRL_B 0xa4
226 #define PORT_ASSP_CTRL_C 0xa6
227 #define PORT_ASSP_HOST_WR_INDEX 0xa8
228 #define PORT_ASSP_HOST_WR_DATA 0xaa
229 #define PORT_ASSP_INT_STAT 0xac
230
231
232
233
234
235
236 #define WPREG_DATA_PORT 0
237 #define WPREG_CRAM_PTR 1
238 #define WPREG_CRAM_DATA 2
239 #define WPREG_WAVE_DATA 3
240 #define WPREG_WAVE_PTR_LOW 4
241 #define WPREG_WAVE_PTR_HIGH 5
242
243 #define WPREG_TIMER_FREQ 6
244 #define WP_TIMER_FREQ_PRESCALE_MASK 0x00e0
245 #define WP_TIMER_FREQ_PRESCALE_SHIFT 5
246 #define WP_TIMER_FREQ_DIVIDE_MASK 0x001f
247 #define WP_TIMER_FREQ_DIVIDE_SHIFT 0
248
249 #define WPREG_WAVE_ROMRAM 7
250 #define WP_WAVE_VIRTUAL_ENABLED 0x0400
251 #define WP_WAVE_8BITRAM_ENABLED 0x0200
252 #define WP_WAVE_DRAM_ENABLED 0x0100
253 #define WP_WAVE_RAMSPLIT_MASK 0x00ff
254 #define WP_WAVE_RAMSPLIT_SHIFT 0
255
256 #define WPREG_BASE 12
257 #define WP_PARAOUT_BASE_MASK 0xf000
258 #define WP_PARAOUT_BASE_SHIFT 12
259 #define WP_PARAIN_BASE_MASK 0x0f00
260 #define WP_PARAIN_BASE_SHIFT 8
261 #define WP_SERIAL0_BASE_MASK 0x00f0
262 #define WP_SERIAL0_BASE_SHIFT 4
263 #define WP_SERIAL1_BASE_MASK 0x000f
264 #define WP_SERIAL1_BASE_SHIFT 0
265
266 #define WPREG_TIMER_ENABLE 17
267 #define WPREG_TIMER_START 23
268
269
270
271
272
273 #define APUREG_APUTYPE 0
274 #define APU_DMA_ENABLED 0x4000
275 #define APU_INT_ON_LOOP 0x2000
276 #define APU_ENDCURVE 0x1000
277 #define APU_APUTYPE_MASK 0x00f0
278 #define APU_FILTERTYPE_MASK 0x000c
279 #define APU_FILTERQ_MASK 0x0003
280
281
282 #define APU_APUTYPE_SHIFT 4
283
284 #define APUTYPE_INACTIVE 0
285 #define APUTYPE_16BITLINEAR 1
286 #define APUTYPE_16BITSTEREO 2
287 #define APUTYPE_8BITLINEAR 3
288 #define APUTYPE_8BITSTEREO 4
289 #define APUTYPE_8BITDIFF 5
290 #define APUTYPE_DIGITALDELAY 6
291 #define APUTYPE_DUALTAP_READER 7
292 #define APUTYPE_CORRELATOR 8
293 #define APUTYPE_INPUTMIXER 9
294 #define APUTYPE_WAVETABLE 10
295 #define APUTYPE_RATECONV 11
296 #define APUTYPE_16BITPINGPONG 12
297
298
299
300 #define APU_FILTERTYPE_SHIFT 2
301
302 #define FILTERTYPE_2POLE_LOPASS 0
303 #define FILTERTYPE_2POLE_BANDPASS 1
304 #define FILTERTYPE_2POLE_HIPASS 2
305 #define FILTERTYPE_1POLE_LOPASS 3
306 #define FILTERTYPE_1POLE_HIPASS 4
307 #define FILTERTYPE_PASSTHROUGH 5
308
309
310 #define APU_FILTERQ_SHIFT 0
311
312 #define FILTERQ_LESSQ 0
313 #define FILTERQ_MOREQ 3
314
315
316 #define APUREG_FREQ_LOBYTE 2
317 #define APU_FREQ_LOBYTE_MASK 0xff00
318 #define APU_plus6dB 0x0010
319
320
321 #define APUREG_FREQ_HIWORD 3
322 #define APU_FREQ_HIWORD_MASK 0x0fff
323
324
325 #define APU_FREQ_LOBYTE_SHIFT 8
326 #define APU_FREQ_HIWORD_SHIFT 0
327 #define FREQ_Hz2DIV(freq) (((u_int64_t)(freq) << 16) / 48000)
328
329
330 #define APUREG_WAVESPACE 4
331 #define APU_STEREO 0x8000
332 #define APU_USE_SYSMEM 0x4000
333 #define APU_PCMBAR_MASK 0x6000
334 #define APU_64KPAGE_MASK 0xff00
335
336
337 #define APU_PCMBAR_SHIFT 13
338
339
340 #define APU_64KPAGE_SHIFT 8
341
342
343 #define APUREG_CURPTR 5
344 #define APUREG_ENDPTR 6
345 #define APUREG_LOOPLEN 7
346
347
348 #define APUREG_AMPLITUDE 9
349 #define APU_AMPLITUDE_NOW_MASK 0xff00
350 #define APU_AMPLITUDE_DEST_MASK 0x00ff
351
352
353 #define APU_AMPLITUDE_NOW_SHIFT 8
354
355
356 #define APUREG_POSITION 10
357 #define APU_RADIUS_MASK 0x00c0
358 #define APU_PAN_MASK 0x003f
359
360
361 #define APU_RADIUS_SHIFT 6
362 #define RADIUS_CENTERCIRCLE 0
363 #define RADIUS_MIDDLE 1
364 #define RADIUS_OUTSIDE 2
365
366
367 #define APU_PAN_SHIFT 0
368 #define PAN_RIGHT 0x00
369 #define PAN_FRONT 0x08
370 #define PAN_LEFT 0x10
371
372
373
374
375
376 #define WPWA_MAX ((1 << 22) - 1)
377 #define WPWA_MAXADDR ((1 << 23) - 1)
378 #define MAESTRO_MAXADDR ((1 << 28) - 1)
379
380
381
382 #ifdef AUDIO_DEBUG
383 #define DPRINTF(x) if (maestrodebug) printf x
384 #define DLPRINTF(i, x) if (maestrodebug & i) printf x
385 int maestrodebug = 0;
386 u_long maestrointr_called;
387 u_long maestrodma_effective;
388
389 #define MAESTRODEBUG_INTR 1
390 #define MAESTRODEBUG_TIMER 2
391 #else
392 #define DPRINTF(x)
393 #define DLPRINTF(i, x)
394 #endif
395
396 #define MAESTRO_BUFSIZ 0x4000
397 #define lengthof(array) (sizeof (array) / sizeof (array)[0])
398
399 #define STEP_VOLUME 0x22
400 #define MIDDLE_VOLUME (STEP_VOLUME * 4)
401
402 typedef struct salloc_pool {
403 struct salloc_zone {
404 SLIST_ENTRY(salloc_zone) link;
405 caddr_t addr;
406 size_t size;
407 } *zones;
408 SLIST_HEAD(salloc_head, salloc_zone) free, used, spare;
409 } *salloc_t;
410
411 struct maestro_softc;
412
413 #define MAESTRO_PLAY 1
414 #define MAESTRO_STEREO 2
415 #define MAESTRO_8BIT 4
416 #define MAESTRO_UNSIGNED 8
417 #define MAESTRO_RUNNING 16
418
419 struct maestro_channel {
420 struct maestro_softc *sc;
421 int num;
422 u_int32_t blocksize;
423 u_int16_t mode;
424 u_int32_t speed;
425 u_int32_t dv;
426 u_int16_t start;
427 u_int16_t threshold;
428 u_int16_t end;
429 u_int16_t current;
430 u_int wpwa;
431 void (*intr)(void *);
432 void *intr_arg;
433 };
434
435 struct maestro_softc {
436 struct device dev;
437
438 void *ih;
439 pci_chipset_tag_t pc;
440 pcitag_t pt;
441
442 #define MAESTRO_FLAG_SETUPGPIO 0x0001
443 int flags;
444 bus_space_tag_t iot;
445 bus_space_handle_t ioh;
446 bus_dma_tag_t dmat;
447
448 caddr_t dmabase;
449 bus_addr_t physaddr;
450 size_t dmasize;
451 bus_dmamap_t dmamap;
452 bus_dma_segment_t dmaseg;
453 salloc_t dmapool;
454
455 struct ac97_codec_if *codec_if;
456 struct ac97_host_if host_if;
457 struct audio_device *sc_audev;
458
459 void *powerhook;
460 int suspend;
461
462 struct maestro_channel play;
463 struct maestro_channel record;
464 };
465
466
467 typedef u_int16_t wpreg_t;
468 typedef u_int16_t wcreg_t;
469
470 salloc_t salloc_new(caddr_t, size_t, int);
471 void salloc_destroy(salloc_t);
472 caddr_t salloc_alloc(salloc_t, size_t);
473 void salloc_free(salloc_t, caddr_t);
474 void salloc_insert(salloc_t, struct salloc_head *,
475 struct salloc_zone *, int);
476
477 int maestro_match(struct device *, void *, void *);
478 void maestro_attach(struct device *, struct device *, void *);
479 int maestro_intr(void *);
480
481 int maestro_open(void *, int);
482 void maestro_close(void *);
483 int maestro_query_encoding(void *, struct audio_encoding *);
484 int maestro_set_params(void *, int, int, struct audio_params *,
485 struct audio_params *);
486 int maestro_round_blocksize(void *, int);
487 int maestro_halt_output(void *);
488 int maestro_halt_input(void *);
489 int maestro_getdev(void *, struct audio_device *);
490 int maestro_set_port(void *, mixer_ctrl_t *);
491 int maestro_get_port(void *, mixer_ctrl_t *);
492 int maestro_query_devinfo(void *, mixer_devinfo_t *);
493 void *maestro_malloc(void *, int, size_t, int, int);
494 void maestro_free(void *, void *, int);
495 paddr_t maestro_mappage(void *, void *, off_t, int);
496 int maestro_get_props(void *);
497 int maestro_trigger_output(void *, void *, void *, int, void (*)(void *),
498 void *, struct audio_params *);
499 int maestro_trigger_input(void *, void *, void *, int, void (*)(void *),
500 void *, struct audio_params *);
501
502 int maestro_attach_codec(void *, struct ac97_codec_if *);
503 int maestro_read_codec(void *, u_int8_t, u_int16_t *);
504 int maestro_write_codec(void *, u_int8_t, u_int16_t);
505 void maestro_reset_codec(void *);
506
507 void maestro_initcodec(void *);
508
509 void maestro_set_speed(struct maestro_channel *, u_long *);
510 void maestro_init(struct maestro_softc *);
511 void maestro_power(struct maestro_softc *, int);
512 void maestro_powerhook(int, void *);
513
514 void maestro_channel_start(struct maestro_channel *);
515 void maestro_channel_stop(struct maestro_channel *);
516 void maestro_channel_advance_dma(struct maestro_channel *);
517 void maestro_channel_suppress_jitter(struct maestro_channel *);
518
519 int maestro_get_flags(struct pci_attach_args *);
520
521 void ringbus_setdest(struct maestro_softc *, int, int);
522
523 wpreg_t wp_reg_read(struct maestro_softc *, int);
524 void wp_reg_write(struct maestro_softc *, int, wpreg_t);
525 wpreg_t wp_apu_read(struct maestro_softc *, int, int);
526 void wp_apu_write(struct maestro_softc *, int, int, wpreg_t);
527 void wp_settimer(struct maestro_softc *, u_int);
528 void wp_starttimer(struct maestro_softc *);
529 void wp_stoptimer(struct maestro_softc *);
530
531 wcreg_t wc_reg_read(struct maestro_softc *, int);
532 void wc_reg_write(struct maestro_softc *, int, wcreg_t);
533 wcreg_t wc_ctrl_read(struct maestro_softc *, int);
534 void wc_ctrl_write(struct maestro_softc *, int, wcreg_t);
535
536 u_int maestro_calc_timer_freq(struct maestro_channel *);
537 void maestro_update_timer(struct maestro_softc *);
538
539 struct cfdriver maestro_cd = {
540 NULL, "maestro", DV_DULL
541 };
542
543 struct cfattach maestro_ca = {
544 sizeof (struct maestro_softc), maestro_match, maestro_attach
545 };
546
547 struct audio_hw_if maestro_hw_if = {
548 maestro_open,
549 maestro_close,
550 NULL,
551 maestro_query_encoding,
552 maestro_set_params,
553 maestro_round_blocksize,
554 NULL,
555 NULL,
556 NULL,
557 NULL,
558 NULL,
559 maestro_halt_output,
560 maestro_halt_input,
561 NULL,
562 maestro_getdev,
563 NULL,
564 maestro_set_port,
565 maestro_get_port,
566 maestro_query_devinfo,
567 maestro_malloc,
568 maestro_free,
569 NULL,
570 maestro_mappage,
571 maestro_get_props,
572 maestro_trigger_output,
573 maestro_trigger_input
574 };
575
576 struct audio_device maestro_audev = {
577 "ESS Maestro", "", "maestro"
578 };
579
580 struct {
581 u_short vendor, product;
582 int flags;
583 } maestro_pcitab[] = {
584 { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTROII, 0 },
585 { PCI_VENDOR_ESSTECH, PCI_PRODUCT_ESSTECH_MAESTRO2E, 0 },
586 { PCI_VENDOR_PLATFORM, PCI_PRODUCT_PLATFORM_ES1849, 0 },
587 { PCI_VENDOR_NEC, PCI_PRODUCT_NEC_VERSAMAESTRO, MAESTRO_FLAG_SETUPGPIO },
588 { PCI_VENDOR_NEC, PCI_PRODUCT_NEC_VERSAPRONXVA26D, MAESTRO_FLAG_SETUPGPIO }
589 };
590 #define NMAESTRO_PCITAB lengthof(maestro_pcitab)
591
592 int
593 maestro_get_flags(pa)
594 struct pci_attach_args *pa;
595 {
596 int i;
597
598
599 if (PCI_CLASS(pa->pa_class) != PCI_CLASS_MULTIMEDIA)
600 return (-1);
601 if (PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_MULTIMEDIA_AUDIO)
602 return (-1);
603 for (i = 0; i < NMAESTRO_PCITAB; i++)
604 if (PCI_VENDOR(pa->pa_id) == maestro_pcitab[i].vendor &&
605 PCI_PRODUCT(pa->pa_id) == maestro_pcitab[i].product)
606 return (maestro_pcitab[i].flags);
607 return (-1);
608 }
609
610
611
612
613
614 int
615 maestro_match(parent, match, aux)
616 struct device *parent;
617 void *match;
618 void *aux;
619 {
620 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
621
622 if (maestro_get_flags(pa) == -1)
623 return (0);
624 else
625 return (1);
626 }
627
628 void
629 maestro_attach(parent, self, aux)
630 struct device *parent;
631 struct device *self;
632 void *aux;
633 {
634 struct maestro_softc *sc = (struct maestro_softc *)self;
635 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
636 pci_chipset_tag_t pc = pa->pa_pc;
637 char const *intrstr;
638 pci_intr_handle_t ih;
639 int error;
640 u_int16_t cdata;
641 int dmastage = 0;
642 int rseg;
643
644 sc->sc_audev = &maestro_audev;
645 sc->flags = maestro_get_flags(pa);
646
647 sc->pc = pa->pa_pc;
648 sc->pt = pa->pa_tag;
649 sc->dmat = pa->pa_dmat;
650
651
652 if (pci_intr_map(pa, &ih)) {
653 printf(": couldn't map interrupt\n");
654 return;
655 }
656 intrstr = pci_intr_string(pc, ih);
657 sc->ih = pci_intr_establish(pc, ih, IPL_AUDIO, maestro_intr, sc,
658 sc->dev.dv_xname);
659 if (sc->ih == NULL) {
660 printf(": couldn't establish interrupt");
661 if (intrstr != NULL)
662 printf(" at %s\n", intrstr);
663 return;
664 }
665 printf(": %s", intrstr);
666
667
668 maestro_power(sc, PPMI_D0);
669 DELAY(100000);
670
671
672 if ((error = pci_mapreg_map(pa, PCI_MAPS, PCI_MAPREG_TYPE_IO,
673 0, &sc->iot, &sc->ioh, NULL, NULL, 0)) != 0) {
674 printf(", couldn't map i/o space\n");
675 goto bad;
676 };
677
678
679 sc->dmasize = MAESTRO_BUFSIZ * 16;
680 if ((error = bus_dmamem_alloc(sc->dmat, sc->dmasize, NBPG, 0,
681 &sc->dmaseg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
682 printf(", unable to alloc dma, error %d\n", error);
683 goto bad;
684 }
685 dmastage = 1;
686 if ((error = bus_dmamem_map(sc->dmat, &sc->dmaseg, 1,
687 sc->dmasize, &sc->dmabase, BUS_DMA_NOWAIT |
688 BUS_DMA_COHERENT)) != 0) {
689 printf(", unable to map dma, error %d\n", error);
690 goto bad;
691 }
692 dmastage = 2;
693 if ((error = bus_dmamap_create(sc->dmat, sc->dmasize, 1,
694 sc->dmasize, 0, BUS_DMA_NOWAIT, &sc->dmamap)) != 0) {
695 printf(", unable to create dma map, error %d\n", error);
696 goto bad;
697 }
698 dmastage = 3;
699 if ((error = bus_dmamap_load(sc->dmat, sc->dmamap,
700 sc->dmabase, sc->dmasize, NULL, BUS_DMA_NOWAIT)) != 0) {
701 printf(", unable to load dma map, error %d\n", error);
702 goto bad;
703 }
704
705
706
707
708
709
710 if ((sc->dmapool = salloc_new(sc->dmabase+16, sc->dmasize-16,
711 128)) == NULL) {
712 printf(", unable to make dma pool\n");
713 goto bad;
714 }
715
716 sc->physaddr = sc->dmamap->dm_segs[0].ds_addr;
717
718 printf("\n");
719
720
721 maestro_init(sc);
722 maestro_read_codec(sc, 0, &cdata);
723 if (cdata == 0x80) {
724 printf("%s: PT101 codec unsupported, no mixer\n",
725 sc->dev.dv_xname);
726
727 maestro_write_codec(sc, 0x2a, 0x0001);
728 maestro_write_codec(sc, 0x2C, 0x0000);
729 maestro_write_codec(sc, 0x2C, 0xFFFF);
730 maestro_write_codec(sc, 0x10, 0x9F1F);
731 maestro_write_codec(sc, 0x12, 0x0808);
732 maestro_write_codec(sc, 0x14, 0x9F1F);
733 maestro_write_codec(sc, 0x16, 0x9F1F);
734 maestro_write_codec(sc, 0x18, 0x0404);
735 maestro_write_codec(sc, 0x1A, 0x0000);
736 maestro_write_codec(sc, 0x1C, 0x0000);
737 maestro_write_codec(sc, 0x02, 0x0404);
738 maestro_write_codec(sc, 0x04, 0x0808);
739 maestro_write_codec(sc, 0x0C, 0x801F);
740 maestro_write_codec(sc, 0x0E, 0x801F);
741
742 sc->codec_if = NULL;
743 } else {
744
745 sc->host_if.arg = sc;
746 sc->host_if.attach = maestro_attach_codec;
747 sc->host_if.read = maestro_read_codec;
748 sc->host_if.write = maestro_write_codec;
749 sc->host_if.reset = maestro_reset_codec;
750 if (ac97_attach(&sc->host_if) != 0) {
751 printf("%s: couldn't attach codec\n", sc->dev.dv_xname);
752 goto bad;
753 }
754 }
755
756 sc->play.mode = MAESTRO_PLAY;
757 sc->play.sc = sc;
758 sc->play.num = 0;
759 sc->record.sc = sc;
760 sc->record.num = 2;
761 sc->record.mode = 0;
762
763
764 audio_attach_mi(&maestro_hw_if, sc, &sc->dev);
765
766
767 sc->suspend = PWR_RESUME;
768 sc->powerhook = powerhook_establish(maestro_powerhook, sc);
769
770 return;
771
772 bad:
773
774 maestro_power(sc, PPMI_D3);
775 if (sc->ih)
776 pci_intr_disestablish(pc, sc->ih);
777 printf("%s: disabled\n", sc->dev.dv_xname);
778 if (sc->dmapool)
779 salloc_destroy(sc->dmapool);
780 if (dmastage >= 3)
781 bus_dmamap_destroy(sc->dmat, sc->dmamap);
782 if (dmastage >= 2)
783 bus_dmamem_unmap(sc->dmat, sc->dmabase, sc->dmasize);
784 if (dmastage >= 1)
785 bus_dmamem_free(sc->dmat, &sc->dmaseg, 1);
786 }
787
788 void
789 maestro_init(sc)
790 struct maestro_softc *sc;
791 {
792 int reg;
793 pcireg_t data;
794
795
796 data = pci_conf_read(sc->pc, sc->pt, CONF_LEGACY);
797 data |= LEGACY_DISABLED;
798 pci_conf_write(sc->pc, sc->pt, CONF_LEGACY, data);
799
800
801
802
803
804 data = pci_conf_read(sc->pc, sc->pt, CONF_MAESTRO);
805 data |= MAESTRO_CHIBUS | MAESTRO_POSTEDWRITE | MAESTRO_DMA_PCITIMING;
806 data &= ~MAESTRO_SWAP_LR;
807 pci_conf_write(sc->pc, sc->pt, CONF_MAESTRO, data);
808
809 bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL,
810 HOSTINT_CTRL_DSOUND_RESET);
811 DELAY(10000);
812 bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL, 0);
813 DELAY(10000);
814
815
816 bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL,
817 HOSTINT_CTRL_DSOUND_INT_ENABLED | HOSTINT_CTRL_HWVOL_ENABLED);
818
819
820
821
822 wp_reg_write(sc, WPREG_WAVE_ROMRAM,
823 WP_WAVE_VIRTUAL_ENABLED | WP_WAVE_DRAM_ENABLED);
824 bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_CTRL,
825 WAVCACHE_ENABLED | WAVCACHE_WTSIZE_4MB);
826
827 for (reg = WAVCACHE_PCMBAR; reg < WAVCACHE_PCMBAR + 4; reg++)
828 wc_reg_write(sc, reg,
829 sc->physaddr >> WAVCACHE_BASEADDR_SHIFT);
830
831
832 maestro_initcodec(sc);
833 bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL,
834 RINGBUS_CTRL_RINGBUS_ENABLED | RINGBUS_CTRL_ACLINK_ENABLED);
835
836 wp_reg_write(sc, WPREG_BASE, 0x8500);
837 ringbus_setdest(sc, RINGBUS_SRC_ADC,
838 RINGBUS_DEST_STEREO | RINGBUS_DEST_DSOUND_IN);
839 ringbus_setdest(sc, RINGBUS_SRC_DSOUND,
840 RINGBUS_DEST_STEREO | RINGBUS_DEST_DAC);
841
842
843 bus_space_write_1(sc->iot, sc->ioh, PORT_ASSP_CTRL_B, 0x00);
844 bus_space_write_1(sc->iot, sc->ioh, PORT_ASSP_CTRL_A, 0x03);
845 bus_space_write_1(sc->iot, sc->ioh, PORT_ASSP_CTRL_C, 0x00);
846
847
848
849
850
851
852 bus_space_write_1(sc->iot, sc->ioh, PORT_HWVOL_MASTER, MIDDLE_VOLUME);
853
854 if (sc->flags & MAESTRO_FLAG_SETUPGPIO) {
855
856
857 bus_space_write_2(sc->iot, sc->ioh,
858 PORT_GPIO_MASK, 0x9ff);
859 bus_space_write_2(sc->iot, sc->ioh, PORT_GPIO_DIR,
860 bus_space_read_2(sc->iot, sc->ioh, PORT_GPIO_DIR) | 0x600);
861 bus_space_write_2(sc->iot, sc->ioh,
862 PORT_GPIO_DATA, 0x200);
863 }
864 }
865
866
867
868
869
870 int
871 maestro_round_blocksize(self, blk)
872 void *self;
873 int blk;
874 {
875 return ((blk + 0xf) & ~0xf);
876 }
877
878 void *
879 maestro_malloc(arg, dir, size, pool, flags)
880 void *arg;
881 int dir;
882 size_t size;
883 int pool, flags;
884 {
885 struct maestro_softc *sc = (struct maestro_softc *)arg;
886
887 return (salloc_alloc(sc->dmapool, size));
888 }
889
890 void
891 maestro_free(self, ptr, pool)
892 void *self, *ptr;
893 int pool;
894 {
895 struct maestro_softc *sc = (struct maestro_softc *)self;
896
897 salloc_free(sc->dmapool, ptr);
898 }
899
900 paddr_t
901 maestro_mappage(self, mem, off, prot)
902 void *self, *mem;
903 off_t off;
904 int prot;
905 {
906 struct maestro_softc *sc = (struct maestro_softc *)self;
907
908 if (off < 0)
909 return -1;
910 return bus_dmamem_mmap(sc->dmat, &sc->dmaseg, 1,
911 off, prot, BUS_DMA_WAITOK);
912 }
913
914 int
915 maestro_get_props(self)
916 void *self;
917 {
918
919
920 return (AUDIO_PROP_MMAP | AUDIO_PROP_INDEPENDENT);
921 }
922
923 int
924 maestro_getdev(self, retp)
925 void *self;
926 struct audio_device *retp;
927 {
928 struct maestro_softc *sc = (struct maestro_softc *)self;
929
930 *retp = *sc->sc_audev;
931 return 0;
932 }
933
934 int
935 maestro_set_port(self, cp)
936 void *self;
937 mixer_ctrl_t *cp;
938 {
939 struct ac97_codec_if *c = ((struct maestro_softc *)self)->codec_if;
940
941 if (c)
942 return (c->vtbl->mixer_set_port(c, cp));
943 else
944 return (ENXIO);
945 }
946
947 int
948 maestro_get_port(self, cp)
949 void *self;
950 mixer_ctrl_t *cp;
951 {
952 struct ac97_codec_if *c = ((struct maestro_softc *)self)->codec_if;
953
954 if (c)
955 return (c->vtbl->mixer_get_port(c, cp));
956 else
957 return (ENXIO);
958 }
959
960 int
961 maestro_query_devinfo(self, cp)
962 void *self;
963 mixer_devinfo_t *cp;
964 {
965 struct ac97_codec_if *c = ((struct maestro_softc *)self)->codec_if;
966
967 if (c)
968 return (c->vtbl->query_devinfo(c, cp));
969 else
970 return (ENXIO);
971 }
972
973 struct audio_encoding maestro_tab[] = {
974 {0, AudioEslinear_le, AUDIO_ENCODING_SLINEAR_LE, 16, 0},
975 {1, AudioEslinear, AUDIO_ENCODING_SLINEAR, 8, 0},
976 {2, AudioEulinear, AUDIO_ENCODING_ULINEAR, 8, 0},
977 {3, AudioEslinear_be, AUDIO_ENCODING_SLINEAR_BE, 16,
978 AUDIO_ENCODINGFLAG_EMULATED},
979 {4, AudioEulinear_le, AUDIO_ENCODING_ULINEAR_LE, 16,
980 AUDIO_ENCODINGFLAG_EMULATED},
981 {5, AudioEulinear_be, AUDIO_ENCODING_ULINEAR_BE, 16,
982 AUDIO_ENCODINGFLAG_EMULATED},
983 {6, AudioEmulaw, AUDIO_ENCODING_ULAW, 8,
984 AUDIO_ENCODINGFLAG_EMULATED},
985 {7, AudioEalaw, AUDIO_ENCODING_ALAW, 8,
986 AUDIO_ENCODINGFLAG_EMULATED}
987 };
988
989 int
990 maestro_query_encoding(hdl, fp)
991 void *hdl;
992 struct audio_encoding *fp;
993 {
994 if (fp->index < 0 || fp->index >= lengthof(maestro_tab))
995 return (EINVAL);
996 *fp = maestro_tab[fp->index];
997 return (0);
998 }
999
1000 #define UNUSED __attribute__((unused))
1001
1002 void
1003 maestro_set_speed(ch, prate)
1004 struct maestro_channel *ch;
1005 u_long *prate;
1006 {
1007 ch->speed = *prate;
1008 if ((ch->mode & (MAESTRO_8BIT | MAESTRO_STEREO)) == MAESTRO_8BIT)
1009 ch->speed /= 2;
1010
1011
1012 if (ch->speed == 48000) {
1013 ch->dv = 0x10000;
1014 } else {
1015
1016
1017 ch->dv = (((ch->speed % 48000) << 16U) + 24000) / 48000
1018 + ((ch->speed / 48000) << 16U);
1019
1020 ch->speed = (ch->dv >> 16U) * 48000 +
1021 (((ch->dv & 0xffff)*48000)>>16U);
1022 }
1023 *prate = ch->speed;
1024 if ((ch->mode & (MAESTRO_8BIT | MAESTRO_STEREO)) == MAESTRO_8BIT)
1025 *prate *= 2;
1026 }
1027
1028 u_int
1029 maestro_calc_timer_freq(ch)
1030 struct maestro_channel *ch;
1031 {
1032 u_int ss = 2;
1033
1034 if (ch->mode & MAESTRO_8BIT)
1035 ss = 1;
1036 return (ch->speed * ss) / ch->blocksize;
1037 }
1038
1039 void
1040 maestro_update_timer(sc)
1041 struct maestro_softc *sc;
1042 {
1043 u_int freq = 0;
1044 u_int n;
1045
1046 if (sc->play.mode & MAESTRO_RUNNING)
1047 freq = maestro_calc_timer_freq(&sc->play);
1048 if (sc->record.mode & MAESTRO_RUNNING) {
1049 n = maestro_calc_timer_freq(&sc->record);
1050 if (freq < n)
1051 freq = n;
1052 }
1053 if (freq) {
1054 wp_settimer(sc, freq);
1055 wp_starttimer(sc);
1056 } else
1057 wp_stoptimer(sc);
1058 }
1059
1060
1061 int
1062 maestro_set_params(hdl, setmode, usemode, play, rec)
1063 void *hdl;
1064 int setmode, usemode;
1065 struct audio_params *play, *rec;
1066 {
1067 struct maestro_softc *sc = (struct maestro_softc *)hdl;
1068
1069 if ((setmode & AUMODE_PLAY) == 0)
1070 return (0);
1071
1072
1073 if (sc->play.mode & MAESTRO_RUNNING)
1074 return (EINVAL);
1075
1076 if (play->sample_rate < 4000)
1077 play->sample_rate = 4000;
1078 else if (play->sample_rate > 48000)
1079 play->sample_rate = 48000;
1080
1081 play->factor = 1;
1082 play->sw_code = NULL;
1083 if (play->channels != 1 && play->channels != 2)
1084 return (EINVAL);
1085
1086
1087 sc->play.mode = MAESTRO_PLAY;
1088 if (play->channels == 2)
1089 sc->play.mode |= MAESTRO_STEREO;
1090
1091 if (play->encoding == AUDIO_ENCODING_ULAW) {
1092 play->factor = 2;
1093 play->sw_code = mulaw_to_slinear16_le;
1094 } else if (play->encoding == AUDIO_ENCODING_ALAW) {
1095 play->factor = 2;
1096 play->sw_code = alaw_to_slinear16_le;
1097 } else if (play->precision == 8) {
1098 sc->play.mode |= MAESTRO_8BIT;
1099 if (play->encoding == AUDIO_ENCODING_ULINEAR_LE ||
1100 play->encoding == AUDIO_ENCODING_ULINEAR_BE)
1101 sc->play.mode |= MAESTRO_UNSIGNED;
1102 }
1103 else if (play->encoding == AUDIO_ENCODING_ULINEAR_LE)
1104 play->sw_code = change_sign16_le;
1105 else if (play->encoding == AUDIO_ENCODING_SLINEAR_BE)
1106 play->sw_code = swap_bytes;
1107 else if (play->encoding == AUDIO_ENCODING_ULINEAR_BE)
1108 play->sw_code = change_sign16_swap_bytes_le;
1109 else if (play->encoding != AUDIO_ENCODING_SLINEAR_LE)
1110 return (EINVAL);
1111
1112 maestro_set_speed(&sc->play, &play->sample_rate);
1113 return (0);
1114 }
1115
1116 int
1117 maestro_open(hdl, flags)
1118 void *hdl;
1119 int flags;
1120 {
1121 struct maestro_softc *sc = (struct maestro_softc *)hdl;
1122 DPRINTF(("%s: open(%d)\n", sc->dev.dv_xname, flags));
1123
1124
1125 #if 0
1126 if ((OFLAGS(flags) & O_ACCMODE) != O_WRONLY)
1127 return (EINVAL);
1128 #endif
1129 sc->play.mode = MAESTRO_PLAY;
1130 sc->record.mode = 0;
1131 #ifdef AUDIO_DEBUG
1132 maestrointr_called = 0;
1133 maestrodma_effective = 0;
1134 #endif
1135 return (0);
1136 }
1137
1138 void
1139 maestro_close(hdl)
1140 void *hdl;
1141 {
1142 struct maestro_softc *sc UNUSED = (struct maestro_softc *)hdl;
1143
1144 }
1145
1146
1147 void
1148 maestro_channel_stop(ch)
1149 struct maestro_channel *ch;
1150 {
1151 wp_apu_write(ch->sc, ch->num, APUREG_APUTYPE,
1152 APUTYPE_INACTIVE << APU_APUTYPE_SHIFT);
1153 if (ch->mode & MAESTRO_STEREO)
1154 wp_apu_write(ch->sc, ch->num+1, APUREG_APUTYPE,
1155 APUTYPE_INACTIVE << APU_APUTYPE_SHIFT);
1156
1157 if (ch->mode & MAESTRO_PLAY)
1158 return;
1159 wp_apu_write(ch->sc, ch->num+2, APUREG_APUTYPE,
1160 APUTYPE_INACTIVE << APU_APUTYPE_SHIFT);
1161 if (ch->mode & MAESTRO_STEREO)
1162 wp_apu_write(ch->sc, ch->num+3, APUREG_APUTYPE,
1163 APUTYPE_INACTIVE << APU_APUTYPE_SHIFT);
1164
1165 }
1166
1167 int
1168 maestro_halt_input(hdl)
1169 void *hdl;
1170 {
1171 struct maestro_softc *sc = (struct maestro_softc *)hdl;
1172 maestro_channel_stop(&sc->record);
1173 sc->record.mode &= ~MAESTRO_RUNNING;
1174 maestro_update_timer(sc);
1175 return 0;
1176 }
1177
1178 int
1179 maestro_halt_output(hdl)
1180 void *hdl;
1181 {
1182 struct maestro_softc *sc = (struct maestro_softc *)hdl;
1183
1184 maestro_channel_stop(&sc->play);
1185 sc->play.mode &= ~MAESTRO_RUNNING;
1186 maestro_update_timer(sc);
1187 return 0;
1188 }
1189
1190 int
1191 maestro_trigger_input(hdl, start, end, blksize, intr, arg, param)
1192 void *hdl;
1193 void *start, *end;
1194 int blksize;
1195 void (*intr)(void *);
1196 void *arg;
1197 struct audio_params *param;
1198 {
1199 struct maestro_softc *sc = (struct maestro_softc *)hdl;
1200
1201 sc->record.mode |= MAESTRO_RUNNING;
1202 sc->record.blocksize = blksize;
1203
1204 maestro_channel_start(&sc->record);
1205
1206 sc->record.threshold = sc->record.start;
1207 maestro_update_timer(sc);
1208 return 0;
1209 }
1210
1211 void
1212 maestro_channel_start(ch)
1213 struct maestro_channel *ch;
1214 {
1215 struct maestro_softc *sc = ch->sc;
1216 int n = ch->num;
1217 int aputype;
1218 wcreg_t wcreg = (sc->physaddr - 16) & WAVCACHE_CHCTL_ADDRTAG_MASK;
1219
1220 switch(ch->mode & (MAESTRO_STEREO | MAESTRO_8BIT)) {
1221 case 0:
1222 aputype = APUTYPE_16BITLINEAR;
1223 break;
1224 case MAESTRO_STEREO:
1225 aputype = APUTYPE_16BITSTEREO;
1226 break;
1227 case MAESTRO_8BIT:
1228 aputype = APUTYPE_8BITLINEAR;
1229 break;
1230 case MAESTRO_8BIT|MAESTRO_STEREO:
1231 aputype = APUTYPE_8BITSTEREO;
1232 break;
1233 }
1234 if (ch->mode & MAESTRO_UNSIGNED)
1235 wcreg |= WAVCACHE_CHCTL_U8;
1236 if ((ch->mode & MAESTRO_STEREO) == 0) {
1237 DPRINTF(("Setting mono parameters\n"));
1238 wp_apu_write(sc, n, APUREG_WAVESPACE, ch->wpwa & 0xff00);
1239 wp_apu_write(sc, n, APUREG_CURPTR, ch->current);
1240 wp_apu_write(sc, n, APUREG_ENDPTR, ch->end);
1241 wp_apu_write(sc, n, APUREG_LOOPLEN, ch->end - ch->start);
1242 wp_apu_write(sc, n, APUREG_AMPLITUDE, 0xe800);
1243 wp_apu_write(sc, n, APUREG_POSITION, 0x8f00
1244 | (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT)
1245 | (PAN_FRONT << APU_PAN_SHIFT));
1246 wp_apu_write(sc, n, APUREG_FREQ_LOBYTE, APU_plus6dB
1247 | ((ch->dv & 0xff) << APU_FREQ_LOBYTE_SHIFT));
1248 wp_apu_write(sc, n, APUREG_FREQ_HIWORD, ch->dv >> 8);
1249 wc_ctrl_write(sc, n, wcreg);
1250 wp_apu_write(sc, n, APUREG_APUTYPE,
1251 (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
1252 } else {
1253 wcreg |= WAVCACHE_CHCTL_STEREO;
1254 DPRINTF(("Setting stereo parameters\n"));
1255 wp_apu_write(sc, n+1, APUREG_WAVESPACE, ch->wpwa & 0xff00);
1256 wp_apu_write(sc, n+1, APUREG_CURPTR, ch->current);
1257 wp_apu_write(sc, n+1, APUREG_ENDPTR, ch->end);
1258 wp_apu_write(sc, n+1, APUREG_LOOPLEN, ch->end - ch->start);
1259 wp_apu_write(sc, n+1, APUREG_AMPLITUDE, 0xe800);
1260 wp_apu_write(sc, n+1, APUREG_POSITION, 0x8f00
1261 | (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT)
1262 | (PAN_LEFT << APU_PAN_SHIFT));
1263 wp_apu_write(sc, n+1, APUREG_FREQ_LOBYTE, APU_plus6dB
1264 | ((ch->dv & 0xff) << APU_FREQ_LOBYTE_SHIFT));
1265 wp_apu_write(sc, n+1, APUREG_FREQ_HIWORD, ch->dv >> 8);
1266 if (ch->mode & MAESTRO_8BIT)
1267 wp_apu_write(sc, n, APUREG_WAVESPACE,
1268 ch->wpwa & 0xff00);
1269 else
1270 wp_apu_write(sc, n, APUREG_WAVESPACE,
1271 (ch->wpwa|(APU_STEREO >> 1)) & 0xff00);
1272 wp_apu_write(sc, n, APUREG_CURPTR, ch->current);
1273 wp_apu_write(sc, n, APUREG_ENDPTR, ch->end);
1274 wp_apu_write(sc, n, APUREG_LOOPLEN, ch->end - ch->start);
1275 wp_apu_write(sc, n, APUREG_AMPLITUDE, 0xe800);
1276 wp_apu_write(sc, n, APUREG_POSITION, 0x8f00
1277 | (RADIUS_CENTERCIRCLE << APU_RADIUS_SHIFT)
1278 | (PAN_RIGHT << APU_PAN_SHIFT));
1279 wp_apu_write(sc, n, APUREG_FREQ_LOBYTE, APU_plus6dB
1280 | ((ch->dv & 0xff) << APU_FREQ_LOBYTE_SHIFT));
1281 wp_apu_write(sc, n, APUREG_FREQ_HIWORD, ch->dv >> 8);
1282 wc_ctrl_write(sc, n, wcreg);
1283 wc_ctrl_write(sc, n+1, wcreg);
1284 wp_apu_write(sc, n, APUREG_APUTYPE,
1285 (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
1286 wp_apu_write(sc, n+1, APUREG_APUTYPE,
1287 (aputype << APU_APUTYPE_SHIFT) | APU_DMA_ENABLED | 0xf);
1288 }
1289 }
1290
1291 int
1292 maestro_trigger_output(hdl, start, end, blksize, intr, arg, param)
1293 void *hdl;
1294 void *start, *end;
1295 int blksize;
1296 void (*intr)(void *);
1297 void *arg;
1298 struct audio_params *param;
1299 {
1300 struct maestro_softc *sc = (struct maestro_softc *)hdl;
1301
1302 u_int offset = ((caddr_t)start - sc->dmabase) >> 1;
1303 u_int size = ((char *)end - (char *)start) >> 1;
1304 sc->play.mode |= MAESTRO_RUNNING;
1305 sc->play.wpwa = APU_USE_SYSMEM | (offset >> 8);
1306 DPRINTF(("maestro_trigger_output: start=%x, end=%x, blksize=%x ",
1307 start, end, blksize));
1308 DPRINTF(("offset = %x, size=%x\n", offset, size));
1309
1310 sc->play.intr = intr;
1311 sc->play.intr_arg = arg;
1312 sc->play.blocksize = blksize;
1313 sc->play.end = offset+size;
1314 sc->play.start = offset;
1315 sc->play.current = sc->play.start;
1316 if ((sc->play.mode & (MAESTRO_STEREO | MAESTRO_8BIT)) == MAESTRO_STEREO) {
1317 sc->play.wpwa >>= 1;
1318 sc->play.start >>= 1;
1319 sc->play.end >>= 1;
1320 sc->play.blocksize >>= 1;
1321 }
1322 maestro_channel_start(&sc->play);
1323
1324 sc->play.threshold = sc->play.start;
1325 maestro_update_timer(sc);
1326
1327 return 0;
1328 }
1329
1330
1331
1332
1333
1334 int
1335 maestro_read_codec(self, regno, datap)
1336 void *self;
1337 u_int8_t regno;
1338 u_int16_t *datap;
1339 {
1340 struct maestro_softc *sc = (struct maestro_softc *)self;
1341 int t;
1342
1343
1344 for (t = 0; t < 20; t++) {
1345 if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT)
1346 & CODEC_STAT_MASK) != CODEC_STAT_PROGLESS)
1347 break;
1348 DELAY(2);
1349 }
1350 if (t == 20)
1351 printf("%s: maestro_read_codec() PROGLESS timed out.\n",
1352 sc->dev.dv_xname);
1353
1354
1355 bus_space_write_1(sc->iot, sc->ioh, PORT_CODEC_CMD,
1356 CODEC_CMD_READ | regno);
1357 DELAY(21);
1358
1359
1360 for (t = 0; t < 20; t++) {
1361 if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT)
1362 & CODEC_STAT_MASK) == CODEC_STAT_RW_DONE)
1363 break;
1364 DELAY(2);
1365 }
1366 if (t == 20)
1367
1368 printf("%s: maestro_read_codec() RW_DONE timed out.\n",
1369 sc->dev.dv_xname);
1370
1371 *datap = bus_space_read_2(sc->iot, sc->ioh, PORT_CODEC_REG);
1372 return 0;
1373 }
1374
1375 int
1376 maestro_write_codec(self, regno, data)
1377 void *self;
1378 u_int8_t regno;
1379 u_int16_t data;
1380 {
1381 struct maestro_softc *sc = (struct maestro_softc *)self;
1382 int t;
1383
1384
1385 for (t = 0; t < 20; t++) {
1386 if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT)
1387 & CODEC_STAT_MASK) != CODEC_STAT_PROGLESS)
1388 break;
1389 DELAY(2);
1390 }
1391 if (t == 20) {
1392
1393 printf("%s: maestro_write_codec() PROGLESS timed out.\n",
1394 sc->dev.dv_xname);
1395 return 1;
1396 }
1397
1398 bus_space_write_2(sc->iot, sc->ioh, PORT_CODEC_REG, data);
1399 bus_space_write_1(sc->iot, sc->ioh, PORT_CODEC_CMD,
1400 CODEC_CMD_WRITE | regno);
1401
1402 return 0;
1403 }
1404
1405 int
1406 maestro_attach_codec(self, cif)
1407 void *self;
1408 struct ac97_codec_if *cif;
1409 {
1410 struct maestro_softc *sc = (struct maestro_softc *)self;
1411
1412 sc->codec_if = cif;
1413 return 0;
1414 }
1415
1416 void
1417 maestro_reset_codec(self)
1418 void *self UNUSED;
1419 {
1420 }
1421
1422 void
1423 maestro_initcodec(self)
1424 void *self;
1425 {
1426 struct maestro_softc *sc = (struct maestro_softc *)self;
1427 u_int16_t data;
1428
1429 if (bus_space_read_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL)
1430 & RINGBUS_CTRL_ACLINK_ENABLED) {
1431 bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL, 0);
1432 DELAY(104);
1433 }
1434
1435 bus_space_write_4(sc->iot, sc->ioh,
1436 PORT_RINGBUS_CTRL, RINGBUS_CTRL_AC97_SWRESET);
1437 DELAY(2);
1438 bus_space_write_4(sc->iot, sc->ioh,
1439 PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED);
1440 DELAY(21);
1441
1442 maestro_read_codec(sc, 0, &data);
1443 if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT)
1444 & CODEC_STAT_MASK) != 0) {
1445 bus_space_write_4(sc->iot, sc->ioh,
1446 PORT_RINGBUS_CTRL, 0);
1447 DELAY(21);
1448
1449
1450 printf("%s: resetting codec\n", sc->dev.dv_xname);
1451
1452 data = bus_space_read_2(sc->iot, sc->ioh, PORT_GPIO_DIR);
1453 if (pci_conf_read(sc->pc, sc->pt, 0x58) & 1)
1454 data |= 0x10;
1455 data |= 0x009 &
1456 ~bus_space_read_2(sc->iot, sc->ioh, PORT_GPIO_DATA);
1457 bus_space_write_2(sc->iot, sc->ioh,
1458 PORT_GPIO_MASK, 0xff6);
1459 bus_space_write_2(sc->iot, sc->ioh,
1460 PORT_GPIO_DIR, data | 0x009);
1461 bus_space_write_2(sc->iot, sc->ioh,
1462 PORT_GPIO_DATA, 0x000);
1463 DELAY(2);
1464 bus_space_write_2(sc->iot, sc->ioh,
1465 PORT_GPIO_DATA, 0x001);
1466 DELAY(1);
1467 bus_space_write_2(sc->iot, sc->ioh,
1468 PORT_GPIO_DATA, 0x009);
1469 DELAY(500000);
1470 bus_space_write_2(sc->iot, sc->ioh,
1471 PORT_GPIO_DIR, data);
1472 DELAY(84);
1473 bus_space_write_4(sc->iot, sc->ioh,
1474 PORT_RINGBUS_CTRL, RINGBUS_CTRL_ACLINK_ENABLED);
1475 DELAY(21);
1476 }
1477
1478
1479 if ((bus_space_read_1(sc->iot, sc->ioh, PORT_CODEC_STAT) &
1480 CODEC_STAT_MASK) != 0) {
1481 printf("%s: codec failure\n", sc->dev.dv_xname);
1482 }
1483 }
1484
1485
1486
1487
1488
1489 void
1490 maestro_powerhook(why, self)
1491 int why;
1492 void *self;
1493 {
1494 struct maestro_softc *sc = (struct maestro_softc *)self;
1495
1496 if (why != PWR_RESUME) {
1497
1498 DPRINTF(("maestro: power down\n"));
1499 sc->suspend = why;
1500 if (sc->record.mode & MAESTRO_RUNNING) {
1501 sc->record.current = wp_apu_read(sc, sc->record.num, APUREG_CURPTR);
1502 maestro_channel_stop(&sc->record);
1503 }
1504 if (sc->play.mode & MAESTRO_RUNNING) {
1505 sc->play.current = wp_apu_read(sc, sc->play.num, APUREG_CURPTR);
1506 maestro_channel_stop(&sc->play);
1507 }
1508
1509 wp_stoptimer(sc);
1510
1511
1512 bus_space_write_2(sc->iot, sc->ioh, PORT_HOSTINT_CTRL, 0);
1513 maestro_write_codec(sc, AC97_REG_POWER, 0xdf00);
1514 DELAY(20);
1515 bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL, 0);
1516 DELAY(1);
1517 maestro_power(sc, PPMI_D3);
1518 } else {
1519
1520 DPRINTF(("maestro: power resume\n"));
1521 if (sc->suspend == PWR_RESUME) {
1522 printf("%s: resume without suspend?\n",
1523 sc->dev.dv_xname);
1524 sc->suspend = why;
1525 return;
1526 }
1527 sc->suspend = why;
1528 maestro_power(sc, PPMI_D0);
1529 DELAY(100000);
1530 maestro_init(sc);
1531
1532 if (sc->codec_if)
1533 sc->codec_if->vtbl->restore_ports(sc->codec_if);
1534 if (sc->play.mode & MAESTRO_RUNNING)
1535 maestro_channel_start(&sc->play);
1536 if (sc->record.mode & MAESTRO_RUNNING)
1537 maestro_channel_start(&sc->record);
1538 maestro_update_timer(sc);
1539 }
1540 }
1541
1542 void
1543 maestro_power(sc, status)
1544 struct maestro_softc *sc;
1545 int status;
1546 {
1547 int data;
1548
1549
1550 data = pci_conf_read(sc->pc, sc->pt, CONF_PM_PTR);
1551 data = pci_conf_read(sc->pc, sc->pt, data);
1552 if (data == PPMI_CID)
1553 pci_conf_write(sc->pc, sc->pt, data + PM_CTRL, status);
1554 }
1555
1556 void
1557 maestro_channel_advance_dma(ch)
1558 struct maestro_channel *ch;
1559 {
1560 wpreg_t pos;
1561 #ifdef AUDIO_DEBUG
1562 maestrointr_called++;
1563 #endif
1564 for (;;) {
1565 pos = wp_apu_read(ch->sc, ch->num, APUREG_CURPTR);
1566
1567 if (pos >= ch->threshold &&
1568 pos < ch->threshold + ch->blocksize/2)
1569 break;
1570 ch->threshold += ch->blocksize/2;
1571 if (ch->threshold >= ch->end)
1572 ch->threshold = ch->start;
1573 (*ch->intr)(ch->intr_arg);
1574 #ifdef AUDIO_DEBUG
1575 maestrodma_effective++;
1576 #endif
1577 }
1578
1579 #ifdef AUDIO_DEBUG
1580 if (maestrodebug && maestrointr_called % 64 == 0)
1581 printf("maestro: dma advanced %lu for %lu calls\n",
1582 maestrodma_effective, maestrointr_called);
1583 #endif
1584 }
1585
1586
1587 void
1588 maestro_channel_suppress_jitter(ch)
1589 struct maestro_channel *ch;
1590 {
1591 int cp, diff;
1592
1593
1594 cp = wp_apu_read(ch->sc, ch->num, APUREG_CURPTR);
1595 diff = wp_apu_read(ch->sc, ch->num+1, APUREG_CURPTR) - cp;
1596 if (diff > 4 || diff < -4)
1597
1598 bus_space_write_2(ch->sc->iot, ch->sc->ioh,
1599 PORT_DSP_DATA, cp);
1600 }
1601
1602
1603
1604
1605 int
1606 maestro_intr(arg)
1607 void *arg;
1608 {
1609 struct maestro_softc *sc = (struct maestro_softc *)arg;
1610 u_int16_t status;
1611
1612 status = bus_space_read_1(sc->iot, sc->ioh, PORT_HOSTINT_STAT);
1613 if (status == 0)
1614 return 0;
1615
1616
1617 bus_space_write_2(sc->iot, sc->ioh, PORT_INT_STAT, 1);
1618 bus_space_write_1(sc->iot, sc->ioh, PORT_HOSTINT_STAT, status);
1619
1620
1621 if (status & HOSTINT_STAT_HWVOL && sc->codec_if != NULL) {
1622 int n, i, delta, v;
1623 mixer_ctrl_t hwvol;
1624
1625 n = bus_space_read_1(sc->iot, sc->ioh, PORT_HWVOL_MASTER);
1626
1627 if (n & 0x11) {
1628 hwvol.type = AUDIO_MIXER_ENUM;
1629 hwvol.dev =
1630 sc->codec_if->vtbl->get_portnum_by_name(sc->codec_if,
1631 AudioCoutputs, AudioNmaster, AudioNmute);
1632 sc->codec_if->vtbl->mixer_get_port(sc->codec_if, &hwvol);
1633 hwvol.un.ord = !hwvol.un.ord;
1634 } else {
1635 hwvol.type = AUDIO_MIXER_VALUE;
1636 hwvol.un.value.num_channels = 2;
1637 hwvol.dev =
1638 sc->codec_if->vtbl->get_portnum_by_name(
1639 sc->codec_if, AudioCoutputs, AudioNmaster,
1640 NULL);
1641 sc->codec_if->vtbl->mixer_get_port(sc->codec_if, &hwvol);
1642
1643 delta = (n - MIDDLE_VOLUME)/STEP_VOLUME * 8;
1644 for (i = 0; i < hwvol.un.value.num_channels; i++) {
1645 v = ((int)hwvol.un.value.level[i]) + delta;
1646 if (v < 0)
1647 v = 0;
1648 else if (v > 255)
1649 v = 255;
1650 hwvol.un.value.level[i] = v;
1651 }
1652 }
1653 sc->codec_if->vtbl->mixer_set_port(sc->codec_if, &hwvol);
1654
1655 bus_space_write_1(sc->iot, sc->ioh, PORT_HWVOL_MASTER,
1656 MIDDLE_VOLUME);
1657 }
1658
1659 if (sc->play.mode & MAESTRO_RUNNING) {
1660 maestro_channel_advance_dma(&sc->play);
1661 if (sc->play.mode & MAESTRO_STEREO)
1662 maestro_channel_suppress_jitter(&sc->play);
1663 }
1664
1665 if (sc->record.mode & MAESTRO_RUNNING)
1666 maestro_channel_advance_dma(&sc->record);
1667
1668 return 1;
1669 }
1670
1671
1672
1673
1674
1675
1676
1677 void
1678 ringbus_setdest(struct maestro_softc *sc, int src, int dest)
1679 {
1680 u_int32_t data;
1681
1682 data = bus_space_read_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL);
1683 data &= ~(0xfU << src);
1684 data |= (0xfU & dest) << src;
1685 bus_space_write_4(sc->iot, sc->ioh, PORT_RINGBUS_CTRL, data);
1686 }
1687
1688
1689
1690 wpreg_t
1691 wp_reg_read(struct maestro_softc *sc, int reg)
1692 {
1693 bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_INDEX, reg);
1694 return bus_space_read_2(sc->iot, sc->ioh, PORT_DSP_DATA);
1695 }
1696
1697 void
1698 wp_reg_write(struct maestro_softc *sc, int reg, wpreg_t data)
1699 {
1700 bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_INDEX, reg);
1701 bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_DATA, data);
1702 }
1703
1704 static void
1705 apu_setindex(struct maestro_softc *sc, int reg)
1706 {
1707 int t;
1708
1709 wp_reg_write(sc, WPREG_CRAM_PTR, reg);
1710
1711 for (t = 0; t < 1000; t++) {
1712 if (bus_space_read_2(sc->iot, sc->ioh,
1713 PORT_DSP_DATA) == reg)
1714 break;
1715 bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_DATA, reg);
1716 }
1717 if (t == 1000)
1718 printf("%s: apu_setindex() timeout\n", sc->dev.dv_xname);
1719 }
1720
1721 wpreg_t
1722 wp_apu_read(struct maestro_softc *sc, int ch, int reg)
1723 {
1724 wpreg_t ret;
1725
1726 apu_setindex(sc, ((unsigned)ch << 4) + reg);
1727 ret = wp_reg_read(sc, WPREG_DATA_PORT);
1728 return ret;
1729 }
1730
1731 void
1732 wp_apu_write(struct maestro_softc *sc, int ch, int reg, wpreg_t data)
1733 {
1734 int t;
1735
1736 apu_setindex(sc, ((unsigned)ch << 4) + reg);
1737 wp_reg_write(sc, WPREG_DATA_PORT, data);
1738 for (t = 0; t < 1000; t++) {
1739 if (bus_space_read_2(sc->iot, sc->ioh, PORT_DSP_DATA) == data)
1740 break;
1741 bus_space_write_2(sc->iot, sc->ioh, PORT_DSP_DATA, data);
1742 }
1743 if (t == 1000)
1744 printf("%s: wp_apu_write() timeout\n", sc->dev.dv_xname);
1745 }
1746
1747 void
1748 wp_settimer(struct maestro_softc *sc, u_int freq)
1749 {
1750 u_int clock = 48000 << 2;
1751 u_int prescale = 0, divide = (freq != 0) ? (clock / freq) : ~0;
1752
1753 if (divide < 4)
1754 divide = 4;
1755 else if (divide > 32 << 8)
1756 divide = 32 << 8;
1757
1758 for (; divide > 32 << 1; divide >>= 1)
1759 prescale++;
1760 divide = (divide + 1) >> 1;
1761
1762 for (; prescale < 7 && divide > 2 && !(divide & 1); divide >>= 1)
1763 prescale++;
1764
1765 wp_reg_write(sc, WPREG_TIMER_ENABLE, 0);
1766 wp_reg_write(sc, WPREG_TIMER_FREQ,
1767 (prescale << WP_TIMER_FREQ_PRESCALE_SHIFT) | (divide - 1));
1768 wp_reg_write(sc, WPREG_TIMER_ENABLE, 1);
1769 }
1770
1771 void
1772 wp_starttimer(struct maestro_softc *sc)
1773 {
1774 wp_reg_write(sc, WPREG_TIMER_START, 1);
1775 }
1776
1777 void
1778 wp_stoptimer(struct maestro_softc *sc)
1779 {
1780 wp_reg_write(sc, WPREG_TIMER_START, 0);
1781 bus_space_write_2(sc->iot, sc->ioh, PORT_INT_STAT, 1);
1782 }
1783
1784
1785
1786 wcreg_t
1787 wc_reg_read(struct maestro_softc *sc, int reg)
1788 {
1789 bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_INDEX, reg);
1790 return bus_space_read_2(sc->iot, sc->ioh, PORT_WAVCACHE_DATA);
1791 }
1792
1793 void
1794 wc_reg_write(struct maestro_softc *sc, int reg, wcreg_t data)
1795 {
1796 bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_INDEX, reg);
1797 bus_space_write_2(sc->iot, sc->ioh, PORT_WAVCACHE_DATA, data);
1798 }
1799
1800 u_int16_t
1801 wc_ctrl_read(struct maestro_softc *sc, int ch)
1802 {
1803 return wc_reg_read(sc, ch << 3);
1804 }
1805
1806 void
1807 wc_ctrl_write(struct maestro_softc *sc, int ch, wcreg_t data)
1808 {
1809 wc_reg_write(sc, ch << 3, data);
1810 }
1811
1812
1813
1814
1815
1816
1817 salloc_t
1818 salloc_new(addr, size, nzones)
1819 caddr_t addr;
1820 size_t size;
1821 int nzones;
1822 {
1823 struct salloc_pool *pool;
1824 struct salloc_zone *space;
1825 int i;
1826
1827 MALLOC(pool, salloc_t, sizeof *pool + nzones * sizeof pool->zones[0],
1828 M_TEMP, M_NOWAIT);
1829 if (pool == NULL)
1830 return NULL;
1831 SLIST_INIT(&pool->free);
1832 SLIST_INIT(&pool->used);
1833 SLIST_INIT(&pool->spare);
1834
1835 pool->zones = (struct salloc_zone *)(pool + 1);
1836 for (i = 1; i < nzones; i++)
1837 SLIST_INSERT_HEAD(&pool->spare, &pool->zones[i], link);
1838 space = &pool->zones[0];
1839 space->addr = addr;
1840 space->size = size;
1841 SLIST_INSERT_HEAD(&pool->free, space, link);
1842 return pool;
1843 }
1844
1845 void
1846 salloc_destroy(pool)
1847 salloc_t pool;
1848 {
1849 FREE(pool, M_TEMP);
1850 }
1851
1852 void
1853 salloc_insert(pool, head, zone, merge)
1854 salloc_t pool;
1855 struct salloc_head *head;
1856 struct salloc_zone *zone;
1857 int merge;
1858 {
1859 struct salloc_zone *prev, *next;
1860
1861
1862
1863
1864
1865 prev = NULL;
1866 SLIST_FOREACH(next, head, link) {
1867 if (next->addr > zone->addr)
1868 break;
1869 prev = next;
1870 }
1871
1872 if (merge && prev && prev->addr + prev->size == zone->addr) {
1873 prev->size += zone->size;
1874 SLIST_INSERT_HEAD(&pool->spare, zone, link);
1875 zone = prev;
1876 } else if (prev)
1877 SLIST_INSERT_AFTER(prev, zone, link);
1878 else
1879 SLIST_INSERT_HEAD(head, zone, link);
1880 if (merge && next && zone->addr + zone->size == next->addr) {
1881 zone->size += next->size;
1882 SLIST_REMOVE(head, next, salloc_zone, link);
1883 SLIST_INSERT_HEAD(&pool->spare, next, link);
1884 }
1885 }
1886
1887 caddr_t
1888 salloc_alloc(pool, size)
1889 salloc_t pool;
1890 size_t size;
1891 {
1892 struct salloc_zone *zone, *uzone;
1893
1894 SLIST_FOREACH(zone, &pool->free, link)
1895 if (zone->size >= size)
1896 break;
1897 if (zone == SLIST_END(&pool->free))
1898 return NULL;
1899 if (zone->size == size) {
1900 SLIST_REMOVE(&pool->free, zone, salloc_zone, link);
1901 uzone = zone;
1902 } else {
1903 uzone = SLIST_FIRST(&pool->spare);
1904 if (uzone == NULL)
1905 return NULL;
1906 SLIST_REMOVE_HEAD(&pool->spare, link);
1907 uzone->size = size;
1908 uzone->addr = zone->addr;
1909 zone->size -= size;
1910 zone->addr += size;
1911 }
1912 salloc_insert(pool, &pool->used, uzone, 0);
1913 return uzone->addr;
1914 }
1915
1916 void
1917 salloc_free(pool, addr)
1918 salloc_t pool;
1919 caddr_t addr;
1920 {
1921 struct salloc_zone *zone;
1922
1923 SLIST_FOREACH(zone, &pool->used, link)
1924 if (zone->addr == addr)
1925 break;
1926 #ifdef DIAGNOSTIC
1927 if (zone == SLIST_END(&pool->used))
1928 panic("salloc_free: freeing unallocated memory");
1929 #endif
1930 SLIST_REMOVE(&pool->used, zone, salloc_zone, link);
1931 salloc_insert(pool, &pool->free, zone, 1);
1932 }