1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25 /*
26 * Purpose: Creative/Ensoniq AudioPCI driver (ES1370)
27 *
28 * This driver is used with the original Ensoniq AudioPCI.
29 */
30
31 /*
32 * This file is part of Open Sound System
33 *
34 * Copyright (C) 4Front Technologies 1996-2008.
35 *
36 * This software is released under CDDL 1.0 source license.
37 * See the COPYING file included in the main directory of this source
38 * distribution for the license terms and conditions.
39 */
40
41 #include <sys/audio/audio_driver.h>
42 #include <sys/note.h>
43 #include <sys/pci.h>
44 #include "audiopci.h"
45
46 /*
47 * The original OSS driver used a single duplex engine and a separate
48 * playback only engine. Instead, we expose three engines, one for input
49 * and two for output.
50 */
51
52 #define ENSONIQ_VENDOR_ID 0x1274
53 #define CREATIVE_VENDOR_ID 0x1102
54 #define ENSONIQ_ES1370 0x5000
55
56 #define DRVNAME "audiopci"
57
58 #define INPUT_MIC 0
59 #define INPUT_LINEIN 1
60 #define INPUT_CD 2
61 #define INPUT_VIDEO 3
62 #define INPUT_PHONE 4
63 #define INSRCS 0x1f /* bits 0-4 */
64
65 static const char *audiopci_insrcs[] = {
66 AUDIO_PORT_MIC,
67 AUDIO_PORT_LINEIN,
68 AUDIO_PORT_CD,
69 AUDIO_PORT_VIDEO,
70 AUDIO_PORT_PHONE,
71 NULL
72 };
73
74 typedef struct audiopci_port
75 {
76 /* Audio parameters */
77 int speed;
78 int fmt;
79
80 int num;
81 #define PORT_DAC 0
82 #define PORT_SYN 1
83 #define PORT_ADC 2
84 #define PORT_MAX PORT_ADC
85
86 caddr_t kaddr;
87 uint32_t paddr;
88 ddi_acc_handle_t acch;
89 ddi_dma_handle_t dmah;
90 unsigned nframes;
91 unsigned frameno;
92 uint64_t count;
93
94 struct audiopci_dev *dev;
95 audio_engine_t *engine;
96 } audiopci_port_t;
97
98 typedef enum {
99 CTL_VOLUME = 0,
100 CTL_FRONT,
101 CTL_MONO,
102 CTL_MIC,
103 CTL_LINE,
104 CTL_CD,
105 CTL_VID,
106 CTL_PHONE,
107 CTL_MICBOOST,
108 CTL_RECSRC,
109 CTL_MONSRC,
110 CTL_NUM /* must be last */
111 } audiopci_ctrl_num_t;
112
113 typedef struct audiopci_ctrl
114 {
115 struct audiopci_dev *dev;
116 audio_ctrl_t *ctrl;
117 audiopci_ctrl_num_t num;
118 uint64_t val;
119 } audiopci_ctrl_t;
120
121
122 typedef struct audiopci_dev
123 {
124 audio_dev_t *adev;
125 kmutex_t mutex;
126 uint16_t devid;
127 dev_info_t *dip;
128
129 uint8_t ak_regs[0x20];
130 int micbias;
131
132 /*
133 * Controls
134 */
135 audiopci_ctrl_t controls[CTL_NUM];
136 #if 0
137 audiopci_ctrl_t *micbias;
138 #endif
139
140 audiopci_port_t port[PORT_MAX + 1];
141
142
143 caddr_t regs;
144 ddi_acc_handle_t acch;
145 } audiopci_dev_t;
146
147 static ddi_device_acc_attr_t acc_attr = {
148 DDI_DEVICE_ATTR_V0,
149 DDI_STRUCTURE_LE_ACC,
150 DDI_STRICTORDER_ACC
151 };
152
153 static ddi_device_acc_attr_t buf_attr = {
154 DDI_DEVICE_ATTR_V0,
155 DDI_NEVERSWAP_ACC,
156 DDI_STRICTORDER_ACC
157 };
158
159 /*
160 * The hardware appears to be able to address up to 16-bits worth of longwords,
161 * giving a total address space of 256K. But we need substantially less.
162 */
163 #define AUDIOPCI_BUF_LEN (16384)
164
165 static ddi_dma_attr_t dma_attr = {
166 DMA_ATTR_VERSION, /* dma_attr_version */
167 0x0, /* dma_attr_addr_lo */
168 0xffffffffU, /* dma_attr_addr_hi */
169 0x3ffff, /* dma_attr_count_max */
170 0x8, /* dma_attr_align */
171 0x7f, /* dma_attr_burstsizes */
172 0x1, /* dma_attr_minxfer */
173 0x3ffff, /* dma_attr_maxxfer */
174 0x3ffff, /* dma_attr_seg */
175 0x1, /* dma_attr_sgllen */
176 0x1, /* dma_attr_granular */
177 0 /* dma_attr_flags */
178 };
179
180 #define GET8(dev, offset) \
181 ddi_get8(dev->acch, (uint8_t *)(dev->regs + (offset)))
182 #define GET16(dev, offset) \
183 ddi_get16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset)))
184 #define GET32(dev, offset) \
185 ddi_get32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset)))
186 #define PUT8(dev, offset, v) \
187 ddi_put8(dev->acch, (uint8_t *)(dev->regs + (offset)), v)
188 #define PUT16(dev, offset, v) \
189 ddi_put16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset)), v)
190 #define PUT32(dev, offset, v) \
191 ddi_put32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset)), v)
192
193 #define CLR8(dev, offset, v) PUT8(dev, offset, GET8(dev, offset) & ~(v))
194 #define SET8(dev, offset, v) PUT8(dev, offset, GET8(dev, offset) | (v))
195 #define CLR16(dev, offset, v) PUT16(dev, offset, GET16(dev, offset) & ~(v))
196 #define SET16(dev, offset, v) PUT16(dev, offset, GET16(dev, offset) | (v))
197
198 static void audiopci_init_hw(audiopci_dev_t *);
199 static void audiopci_init_port(audiopci_port_t *);
200 static uint16_t audiopci_dac_rate(int);
201 static int audiopci_add_controls(audiopci_dev_t *);
202 static void audiopci_del_controls(audiopci_dev_t *);
203 static void audiopci_ak_write(audiopci_dev_t *, uint16_t, uint8_t);
204
205 static int
audiopci_ak_wait(audiopci_dev_t * dev,uint8_t wstat)206 audiopci_ak_wait(audiopci_dev_t *dev, uint8_t wstat)
207 {
208 for (int i = 4000; i; i--) {
209 if (!(GET8(dev, CONC_bCODECSTAT_OFF) & wstat))
210 return (DDI_SUCCESS);
211 drv_usecwait(10);
212 }
213 return (DDI_FAILURE);
214 }
215
216 static void
audiopci_ak_idle(audiopci_dev_t * dev)217 audiopci_ak_idle(audiopci_dev_t *dev)
218 {
219 for (int i = 0; i < 5; i++) {
220 if (audiopci_ak_wait(dev, CONC_CSTAT_CSTAT) == DDI_SUCCESS)
221 return;
222 }
223 audio_dev_warn(dev->adev, "timed out waiting for codec to idle");
224 }
225
226 static void
audiopci_ak_write(audiopci_dev_t * dev,uint16_t addr,uint8_t data)227 audiopci_ak_write(audiopci_dev_t *dev, uint16_t addr, uint8_t data)
228 {
229 uint8_t wstat;
230
231 /* shadow the value */
232 dev->ak_regs[addr] = data;
233
234 wstat = addr == CODEC_RESET_PWRD ? CONC_CSTAT_CWRIP : CONC_CSTAT_CSTAT;
235
236 /* wait for codec to be available */
237 if (audiopci_ak_wait(dev, wstat) != DDI_SUCCESS) {
238 audio_dev_warn(dev->adev, "timeout waiting for codec");
239 }
240
241 PUT16(dev, CONC_wCODECCTL_OFF, (addr << 8) | data);
242 }
243
244 static void
audiopci_writemem(audiopci_dev_t * dev,uint32_t page,uint32_t offs,uint32_t data)245 audiopci_writemem(audiopci_dev_t *dev, uint32_t page, uint32_t offs,
246 uint32_t data)
247 {
248 /* Select memory page */
249 PUT32(dev, CONC_bMEMPAGE_OFF, page);
250 PUT32(dev, offs, data);
251 }
252
253 static uint32_t
audiopci_readmem(audiopci_dev_t * dev,uint32_t page,uint32_t offs)254 audiopci_readmem(audiopci_dev_t *dev, uint32_t page, uint32_t offs)
255 {
256 PUT32(dev, CONC_bMEMPAGE_OFF, page); /* Select memory page */
257 return (GET32(dev, offs));
258 }
259
260 /*
261 * Audio routines
262 */
263
264 static int
audiopci_format(void * arg)265 audiopci_format(void *arg)
266 {
267 _NOTE(ARGUNUSED(arg));
268 return (AUDIO_FORMAT_S16_LE);
269 }
270
271 static int
audiopci_channels(void * arg)272 audiopci_channels(void *arg)
273 {
274 _NOTE(ARGUNUSED(arg));
275 return (2);
276 }
277
278 static int
audiopci_rate(void * arg)279 audiopci_rate(void *arg)
280 {
281 audiopci_port_t *port = arg;
282
283 return (port->speed);
284 }
285
286 static void
audiopci_init_port(audiopci_port_t * port)287 audiopci_init_port(audiopci_port_t *port)
288 {
289 audiopci_dev_t *dev = port->dev;
290 unsigned tmp;
291
292 switch (port->num) {
293 case PORT_DAC:
294
295 /* Set physical address of the DMA buffer */
296 audiopci_writemem(dev, CONC_DACCTL_PAGE, CONC_dDACPADDR_OFF,
297 port->paddr);
298
299 /* Set DAC rate */
300 PUT16(dev, CONC_wDACRATE_OFF, audiopci_dac_rate(48000));
301
302 /* Set format */
303 tmp = GET8(dev, CONC_bSERFMT_OFF);
304 tmp |= CONC_PCM_DAC_16BIT;
305 tmp |= CONC_PCM_DAC_STEREO;
306
307 PUT8(dev, CONC_bSKIPC_OFF, 0x10);
308 PUT8(dev, CONC_bSERFMT_OFF, tmp);
309
310 /* Set the frame count */
311 audiopci_writemem(dev, CONC_DACCTL_PAGE, CONC_wDACFC_OFF,
312 port->nframes - 1);
313
314 /* Set # of frames between interrupts */
315 PUT16(dev, CONC_wDACIC_OFF, port->nframes - 1);
316
317 break;
318
319 case PORT_SYN:
320
321 /* Set physical address of the DMA buffer */
322 audiopci_writemem(dev, CONC_SYNCTL_PAGE, CONC_dSYNPADDR_OFF,
323 port->paddr);
324
325 /* Set rate - we force to 44.1 kHz */
326 SET8(dev, CONC_bMISCCTL_OFF, CONC_MISCCTL_SYN_44KHZ);
327
328 /* Set format */
329 tmp = GET8(dev, CONC_bSERFMT_OFF);
330 tmp |= CONC_PCM_SYN_16BIT;
331 tmp |= CONC_PCM_SYN_STEREO;
332
333 PUT8(dev, CONC_bSERFMT_OFF, tmp);
334
335 /* Set the frame count */
336 audiopci_writemem(dev, CONC_SYNCTL_PAGE, CONC_wSYNFC_OFF,
337 port->nframes - 1);
338
339 /* Set # of frames between interrupts */
340 PUT16(dev, CONC_wSYNIC_OFF, port->nframes - 1);
341
342 break;
343
344 case PORT_ADC:
345 /* Set physical address of the DMA buffer */
346 audiopci_writemem(dev, CONC_ADCCTL_PAGE, CONC_dADCPADDR_OFF,
347 port->paddr);
348
349 /* Set ADC rate */
350 PUT16(dev, CONC_wDACRATE_OFF, audiopci_dac_rate(48000));
351
352 /* Set format - for input we only support 16 bit input */
353 tmp = GET8(dev, CONC_bSERFMT_OFF);
354 tmp |= CONC_PCM_ADC_16BIT;
355 tmp |= CONC_PCM_ADC_STEREO;
356
357 PUT8(dev, CONC_bSKIPC_OFF, 0x10);
358
359 PUT8(dev, CONC_bSERFMT_OFF, tmp);
360
361 /* Set the frame count */
362 audiopci_writemem(dev, CONC_ADCCTL_PAGE, CONC_wADCFC_OFF,
363 port->nframes - 1);
364
365 /* Set # of frames between interrupts */
366 PUT16(dev, CONC_wADCIC_OFF, port->nframes - 1);
367
368 break;
369 }
370
371 port->frameno = 0;
372 }
373
374 static int
audiopci_open(void * arg,int flag,unsigned * nframes,caddr_t * bufp)375 audiopci_open(void *arg, int flag, unsigned *nframes, caddr_t *bufp)
376 {
377 audiopci_port_t *port = arg;
378
379 _NOTE(ARGUNUSED(flag));
380
381 /* NB: frame size = 4 (16-bit stereo) */
382 port->nframes = AUDIOPCI_BUF_LEN / 4;
383 port->count = 0;
384
385 *nframes = port->nframes;
386 *bufp = port->kaddr;
387
388 return (0);
389 }
390
391 static int
audiopci_start(void * arg)392 audiopci_start(void *arg)
393 {
394 audiopci_port_t *port = arg;
395 audiopci_dev_t *dev = port->dev;
396
397 mutex_enter(&dev->mutex);
398
399 audiopci_init_port(port);
400
401 switch (port->num) {
402 case PORT_DAC:
403 SET8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_DAC_EN);
404 break;
405 case PORT_SYN:
406 SET8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_SYN_EN);
407 break;
408 case PORT_ADC:
409 SET8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_ADC_EN);
410 break;
411 }
412 mutex_exit(&dev->mutex);
413
414 return (0);
415 }
416
417 static void
audiopci_stop(void * arg)418 audiopci_stop(void *arg)
419 {
420 audiopci_port_t *port = arg;
421 audiopci_dev_t *dev = port->dev;
422
423 mutex_enter(&dev->mutex);
424 switch (port->num) {
425 case PORT_DAC:
426 CLR8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_DAC_EN);
427 break;
428 case PORT_SYN:
429 CLR8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_SYN_EN);
430 break;
431 case PORT_ADC:
432 CLR8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_ADC_EN);
433 break;
434 }
435 mutex_exit(&dev->mutex);
436 }
437
438 static uint64_t
audiopci_count(void * arg)439 audiopci_count(void *arg)
440 {
441 audiopci_port_t *port = arg;
442 audiopci_dev_t *dev = port->dev;
443 uint64_t val;
444 uint32_t page, offs;
445 int frameno, n;
446
447 switch (port->num) {
448 case PORT_DAC:
449 page = CONC_DACCTL_PAGE;
450 offs = CONC_wDACFC_OFF;
451 break;
452
453 case PORT_SYN:
454 page = CONC_SYNCTL_PAGE;
455 offs = CONC_wSYNFC_OFF;
456 break;
457
458 case PORT_ADC:
459 page = CONC_ADCCTL_PAGE;
460 offs = CONC_wADCFC_OFF;
461 break;
462 }
463
464 /*
465 * Note that the current frame counter is in the high nybble.
466 */
467 mutex_enter(&dev->mutex);
468 frameno = audiopci_readmem(port->dev, page, offs) >> 16;
469 mutex_exit(&dev->mutex);
470
471 n = frameno >= port->frameno ?
472 frameno - port->frameno :
473 frameno + port->nframes - port->frameno;
474 port->frameno = frameno;
475 port->count += n;
476
477 val = port->count;
478 return (val);
479 }
480
481 static void
audiopci_close(void * arg)482 audiopci_close(void *arg)
483 {
484 _NOTE(ARGUNUSED(arg));
485 }
486
487 static void
audiopci_sync(void * arg,unsigned nframes)488 audiopci_sync(void *arg, unsigned nframes)
489 {
490 audiopci_port_t *port = arg;
491
492 _NOTE(ARGUNUSED(nframes));
493
494 if (port->num == PORT_ADC) {
495 (void) ddi_dma_sync(port->dmah, 0, 0, DDI_DMA_SYNC_FORCPU);
496 } else {
497 (void) ddi_dma_sync(port->dmah, 0, 0, DDI_DMA_SYNC_FORDEV);
498 }
499 }
500
501 audio_engine_ops_t audiopci_engine_ops = {
502 AUDIO_ENGINE_VERSION, /* version number */
503 audiopci_open,
504 audiopci_close,
505 audiopci_start,
506 audiopci_stop,
507 audiopci_count,
508 audiopci_format,
509 audiopci_channels,
510 audiopci_rate,
511 audiopci_sync,
512 NULL,
513 NULL,
514 NULL,
515 };
516
517 static uint16_t
audiopci_dac_rate(int samPerSec)518 audiopci_dac_rate(int samPerSec)
519 {
520 unsigned short usTemp;
521
522 /* samPerSec /= 2; */
523
524 usTemp = (unsigned short) ((DAC_CLOCK_DIVIDE / 8) / samPerSec);
525
526 if (usTemp & 0x00000001) {
527 usTemp >>= 1;
528 usTemp -= 1;
529 } else {
530 usTemp >>= 1;
531 usTemp -= 2;
532 }
533 return (usTemp);
534 }
535
536 void
audiopci_init_hw(audiopci_dev_t * dev)537 audiopci_init_hw(audiopci_dev_t *dev)
538 {
539 int tmp;
540
541 /* setup DAC frequency */
542 PUT16(dev, CONC_wDACRATE_OFF, audiopci_dac_rate(48000));
543
544 CLR8(dev, CONC_bMISCCTL_OFF, CONC_MISCCTL_CCB_INTRM);
545 SET8(dev, CONC_bMISCCTL_OFF, CONC_MISCCTL_SYN_44KHZ);
546
547 /* Turn on CODEC (UART and joystick left disabled) */
548 tmp = GET8(dev, CONC_bDEVCTL_OFF);
549 tmp |= CONC_DEVCTL_SERR_DIS;
550 tmp |= CONC_DEVCTL_CODEC_EN;
551 PUT8(dev, CONC_bDEVCTL_OFF, tmp);
552
553 /* Reset the UART */
554 PUT8(dev, CONC_bUARTCSTAT_OFF, 0x00);
555
556 /* Disable NMI */
557 PUT8(dev, CONC_bNMIENA_OFF, 0);
558 PUT16(dev, CONC_wNMISTAT_OFF, 0);
559
560 /* Initialize serial interface */
561 PUT8(dev, CONC_bSERCTL_OFF, 0);
562 PUT8(dev, CONC_bSERFMT_OFF,
563 CONC_PCM_SYN_STEREO | CONC_PCM_SYN_16BIT);
564
565 /* Unmute codec */
566 CLR8(dev, CONC_bMISCCTL_OFF, CONC_MISCCTL_MUTE);
567
568 /* mixer initialization */
569 audiopci_ak_idle(dev);
570
571 /* power/reset down the codec */
572 audiopci_ak_write(dev, CODEC_RESET_PWRD, 0);
573 drv_usecwait(10);
574
575 /* now powerup and bring out of reset */
576 audiopci_ak_write(dev, CODEC_RESET_PWRD, 0x3);
577 audiopci_ak_idle(dev);
578
579 /* enable PLL for DAC2 */
580 audiopci_ak_write(dev, CODEC_CLKSELECT, 0);
581
582 /* select input mixer */
583 audiopci_ak_write(dev, CODEC_ADSELECT, 0);
584
585 /* mark FM for output mixer */
586 audiopci_ak_write(dev, CODEC_OUT_SW1, CODEC_OUT_ENABLE_SYNTH);
587 audiopci_ak_write(dev, CODEC_OUT_SW2, CODEC_OUT_ENABLE_WAVE);
588
589 /* initialize some reasonable values for the WAVE and SYNTH inputs */
590 audiopci_ak_write(dev, CODEC_VOL_WAVE_L, 6);
591 audiopci_ak_write(dev, CODEC_VOL_WAVE_R, 6);
592 audiopci_ak_write(dev, CODEC_VOL_SYNTH_L, 6);
593 audiopci_ak_write(dev, CODEC_VOL_SYNTH_R, 6);
594
595 /* enable microphone phantom power */
596 if (dev->micbias) {
597 SET16(dev, 2, CONC_DEVCTL_MICBIAS);
598 }
599 }
600
601 static int
audiopci_init(audiopci_dev_t * dev)602 audiopci_init(audiopci_dev_t *dev)
603 {
604 dev->micbias = 1;
605
606 audiopci_init_hw(dev);
607
608 for (int i = 0; i <= PORT_MAX; i++) {
609 audiopci_port_t *port;
610 unsigned caps;
611 unsigned dmaflags;
612 size_t rlen;
613 ddi_dma_cookie_t c;
614 unsigned ccnt;
615
616 port = &dev->port[i];
617 port->dev = dev;
618
619 switch (i) {
620 case PORT_SYN:
621 caps = ENGINE_OUTPUT_CAP;
622 dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT;
623 port->speed = 44100;
624 break;
625
626 case PORT_DAC:
627 caps = ENGINE_OUTPUT_CAP;
628 dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT;
629 port->speed = 48000;
630 break;
631
632 case PORT_ADC:
633 caps = ENGINE_INPUT_CAP;
634 dmaflags = DDI_DMA_READ | DDI_DMA_CONSISTENT;
635 port->speed = 48000;
636 break;
637 }
638
639 port->num = i;
640
641 /*
642 * Allocate DMA resources.
643 */
644
645 if (ddi_dma_alloc_handle(dev->dip, &dma_attr, DDI_DMA_SLEEP,
646 NULL, &port->dmah) != DDI_SUCCESS) {
647 audio_dev_warn(dev->adev,
648 "port %d: dma handle allocation failed", i);
649 return (DDI_FAILURE);
650 }
651 if (ddi_dma_mem_alloc(port->dmah, AUDIOPCI_BUF_LEN, &buf_attr,
652 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &port->kaddr,
653 &rlen, &port->acch) != DDI_SUCCESS) {
654 audio_dev_warn(dev->adev,
655 "port %d: dma memory allocation failed", i);
656 return (DDI_FAILURE);
657 }
658 /* ensure that the buffer is zeroed out properly */
659 bzero(port->kaddr, rlen);
660 if (ddi_dma_addr_bind_handle(port->dmah, NULL, port->kaddr,
661 AUDIOPCI_BUF_LEN, dmaflags, DDI_DMA_SLEEP, NULL,
662 &c, &ccnt) != DDI_DMA_MAPPED) {
663 audio_dev_warn(dev->adev,
664 "port %d: dma binding failed", i);
665 return (DDI_FAILURE);
666 }
667 port->paddr = c.dmac_address;
668
669 /*
670 * Allocate and configure audio engine.
671 */
672 port->engine = audio_engine_alloc(&audiopci_engine_ops, caps);
673 if (port->engine == NULL) {
674 audio_dev_warn(dev->adev,
675 "port %d: audio_engine_alloc failed", i);
676 return (DDI_FAILURE);
677 }
678
679 audio_engine_set_private(port->engine, port);
680 audio_dev_add_engine(dev->adev, port->engine);
681 }
682
683 /*
684 * Register audio controls.
685 */
686 if (audiopci_add_controls(dev) == DDI_FAILURE) {
687 return (DDI_FAILURE);
688 }
689
690
691 if (audio_dev_register(dev->adev) != DDI_SUCCESS) {
692 audio_dev_warn(dev->adev,
693 "unable to register with audio framework");
694 return (DDI_FAILURE);
695 }
696
697 return (DDI_SUCCESS);
698 }
699
700 static void
audiopci_destroy(audiopci_dev_t * dev)701 audiopci_destroy(audiopci_dev_t *dev)
702 {
703 int i;
704
705 mutex_destroy(&dev->mutex);
706
707 /* free up ports, including DMA resources for ports */
708 for (i = 0; i <= PORT_MAX; i++) {
709 audiopci_port_t *port = &dev->port[i];
710
711 if (port->paddr != 0)
712 (void) ddi_dma_unbind_handle(port->dmah);
713 if (port->acch != NULL)
714 ddi_dma_mem_free(&port->acch);
715 if (port->dmah != NULL)
716 ddi_dma_free_handle(&port->dmah);
717
718 if (port->engine != NULL) {
719 audio_dev_remove_engine(dev->adev, port->engine);
720 audio_engine_free(port->engine);
721 }
722 }
723
724 if (dev->acch != NULL) {
725 ddi_regs_map_free(&dev->acch);
726 }
727
728 audiopci_del_controls(dev);
729
730 if (dev->adev != NULL) {
731 audio_dev_free(dev->adev);
732 }
733
734 kmem_free(dev, sizeof (*dev));
735 }
736
737 static void
audiopci_stereo(audiopci_dev_t * dev,audiopci_ctrl_num_t num,uint8_t lreg)738 audiopci_stereo(audiopci_dev_t *dev, audiopci_ctrl_num_t num, uint8_t lreg)
739 {
740 uint8_t lval, rval;
741 uint8_t lmute, rmute;
742 uint64_t val;
743 uint8_t rreg;
744
745 rreg = lreg + 1;
746 val = dev->controls[num].val;
747 lval = (val & 0xff00) >> 8;
748 rval = val & 0xff;
749
750 lmute = lval ? 0 : CODEC_ATT_MUTE;
751 rmute = rval ? 0 : CODEC_ATT_MUTE;
752
753 /* convert to attenuation & apply mute if appropriate */
754 lval = ((((100U - lval) * CODEC_ATT_MAX) / 100) & 0xff) | lmute;
755 rval = ((((100U - rval) * CODEC_ATT_MAX) / 100) & 0xff) | rmute;
756
757 audiopci_ak_write(dev, lreg, lval);
758 audiopci_ak_write(dev, rreg, rval);
759 }
760
761 static void
audiopci_mono(audiopci_dev_t * dev,audiopci_ctrl_num_t num,uint8_t reg)762 audiopci_mono(audiopci_dev_t *dev, audiopci_ctrl_num_t num, uint8_t reg)
763 {
764 uint64_t val = (dev->controls[num].val & 0xff);
765 uint8_t mute;
766
767 mute = val ? 0 : CODEC_ATT_MUTE;
768 val = ((((100U - val) * CODEC_ATT_MAX) / 100) & 0xff) | mute;
769
770 audiopci_ak_write(dev, reg, val);
771 }
772
773 static void
audiopci_mono8(audiopci_dev_t * dev,audiopci_ctrl_num_t num,uint8_t reg)774 audiopci_mono8(audiopci_dev_t *dev, audiopci_ctrl_num_t num, uint8_t reg)
775 {
776 uint64_t val = (dev->controls[num].val & 0xff);
777 uint8_t mute;
778
779 mute = val ? 0 : CODEC_ATT_MUTE;
780 val = ((((100U - val) * CODEC_ATT_MONO) / 100) & 0xff) | mute;
781
782 audiopci_ak_write(dev, reg, val);
783 }
784
785 static int
audiopci_get_value(void * arg,uint64_t * val)786 audiopci_get_value(void *arg, uint64_t *val)
787 {
788 audiopci_ctrl_t *pc = arg;
789
790 *val = pc->val;
791
792 return (0);
793 }
794
795 static void
audiopci_configure_output(audiopci_dev_t * dev)796 audiopci_configure_output(audiopci_dev_t *dev)
797 {
798 uint64_t val;
799 uint8_t tmp;
800
801 /* PCM/Wave level */
802 audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_WAVE_L);
803 audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_WAVE_R);
804 audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_SYNTH_L);
805 audiopci_mono(dev, CTL_VOLUME, CODEC_VOL_SYNTH_R);
806
807 /* front & mono outputs */
808 audiopci_stereo(dev, CTL_FRONT, CODEC_VOL_MASTER_L);
809 audiopci_mono8(dev, CTL_MONO, CODEC_VOL_MONO);
810
811 val = dev->controls[CTL_MONSRC].val;
812
813 /* setup output monitoring as well */
814 tmp = CODEC_OUT_ENABLE_SYNTH;
815 if (val & (1U << INPUT_MIC))
816 tmp |= CODEC_OUT_ENABLE_MIC;
817 if (val & (1U << INPUT_CD))
818 tmp |= CODEC_OUT_ENABLE_CD;
819 if (val & (1U << INPUT_LINEIN))
820 tmp |= CODEC_OUT_ENABLE_AUX;
821 audiopci_ak_write(dev, CODEC_OUT_SW1, tmp);
822
823 tmp = CODEC_OUT_ENABLE_WAVE;
824 if (val & (1U << INPUT_VIDEO))
825 tmp |= CODEC_OUT_ENABLE_TV;
826 if (val & (1U << INPUT_PHONE))
827 tmp |= CODEC_OUT_ENABLE_TAD;
828 audiopci_ak_write(dev, CODEC_OUT_SW2, tmp);
829 }
830
831 static void
audiopci_configure_input(audiopci_dev_t * dev)832 audiopci_configure_input(audiopci_dev_t *dev)
833 {
834 uint64_t val = dev->controls[CTL_RECSRC].val;
835 uint8_t tmp;
836
837 tmp = 0;
838 if (val & (1U << INPUT_LINEIN))
839 tmp |= CODEC_IN_ENABLE_AUX_L;
840 if (val & (1U << INPUT_CD))
841 tmp |= CODEC_IN_ENABLE_CD_L;
842 if (val & (1U << INPUT_MIC))
843 tmp |= CODEC_IN_ENABLE_MIC;
844 if (val & (1U << INPUT_PHONE))
845 tmp |= CODEC_IN_ENABLE_TAD;
846 audiopci_ak_write(dev, CODEC_LIN_SW1, tmp);
847
848 tmp = 0;
849 if (val & (1U << INPUT_LINEIN))
850 tmp |= CODEC_IN_ENABLE_AUX_R;
851 if (val & (1U << INPUT_CD))
852 tmp |= CODEC_IN_ENABLE_CD_R;
853 if (val & (1U << INPUT_PHONE))
854 tmp |= CODEC_IN_ENABLE_TAD;
855 if (val & (1U << INPUT_MIC))
856 tmp |= CODEC_IN_ENABLE_MIC;
857 audiopci_ak_write(dev, CODEC_RIN_SW1, tmp);
858
859 tmp = 0;
860 if (val & (1U << INPUT_VIDEO))
861 tmp |= CODEC_IN_ENABLE_TV_L;
862 if (val & (1U << INPUT_MIC))
863 tmp |= CODEC_IN_ENABLE_TMIC;
864 audiopci_ak_write(dev, CODEC_LIN_SW2, tmp);
865
866 tmp = 0;
867 if (val & (1U << INPUT_VIDEO))
868 tmp |= CODEC_IN_ENABLE_TV_R;
869 if (val & (1U << INPUT_MIC))
870 tmp |= CODEC_IN_ENABLE_TMIC;
871 audiopci_ak_write(dev, CODEC_RIN_SW2, tmp);
872
873 /* configure volumes */
874 audiopci_mono(dev, CTL_MIC, CODEC_VOL_MIC);
875 audiopci_mono(dev, CTL_PHONE, CODEC_VOL_TAD);
876 audiopci_stereo(dev, CTL_LINE, CODEC_VOL_AUX_L);
877 audiopci_stereo(dev, CTL_CD, CODEC_VOL_CD_L);
878 audiopci_stereo(dev, CTL_VID, CODEC_VOL_TV_L);
879
880 /* activate 30dB mic boost */
881 audiopci_ak_write(dev, CODEC_MICBOOST,
882 dev->controls[CTL_MICBOOST].val ? 1 : 0);
883 }
884
885 static int
audiopci_set_reclevel(void * arg,uint64_t val)886 audiopci_set_reclevel(void *arg, uint64_t val)
887 {
888 audiopci_ctrl_t *pc = arg;
889 audiopci_dev_t *dev = pc->dev;
890 uint8_t l;
891 uint8_t r;
892
893 l = (val & 0xff00) >> 8;
894 r = val & 0xff;
895
896 if ((l > 100) || (r > 100))
897 return (EINVAL);
898
899 mutex_enter(&dev->mutex);
900 pc->val = val;
901 audiopci_configure_input(dev);
902
903 mutex_exit(&dev->mutex);
904 return (0);
905 }
906
907 static int
audiopci_set_micboost(void * arg,uint64_t val)908 audiopci_set_micboost(void *arg, uint64_t val)
909 {
910 audiopci_ctrl_t *pc = arg;
911 audiopci_dev_t *dev = pc->dev;
912
913 mutex_enter(&dev->mutex);
914 pc->val = val;
915 audiopci_configure_input(dev);
916 mutex_exit(&dev->mutex);
917 return (0);
918 }
919
920 static int
audiopci_set_monsrc(void * arg,uint64_t val)921 audiopci_set_monsrc(void *arg, uint64_t val)
922 {
923 audiopci_ctrl_t *pc = arg;
924 audiopci_dev_t *dev = pc->dev;
925
926 if ((val & ~INSRCS) != 0)
927 return (EINVAL);
928
929 mutex_enter(&dev->mutex);
930 pc->val = val;
931 audiopci_configure_output(dev);
932 mutex_exit(&dev->mutex);
933 return (0);
934 }
935
936 static int
audiopci_set_recsrc(void * arg,uint64_t val)937 audiopci_set_recsrc(void *arg, uint64_t val)
938 {
939 audiopci_ctrl_t *pc = arg;
940 audiopci_dev_t *dev = pc->dev;
941
942 if ((val & ~INSRCS) != 0)
943 return (EINVAL);
944
945 mutex_enter(&dev->mutex);
946 pc->val = val;
947 audiopci_configure_input(dev);
948 mutex_exit(&dev->mutex);
949 return (0);
950 }
951
952 static int
audiopci_set_volume(void * arg,uint64_t val)953 audiopci_set_volume(void *arg, uint64_t val)
954 {
955 audiopci_ctrl_t *pc = arg;
956 audiopci_dev_t *dev = pc->dev;
957
958 val &= 0xff;
959 if (val > 100)
960 return (EINVAL);
961
962 val = (val & 0xff) | ((val & 0xff) << 8);
963
964 mutex_enter(&dev->mutex);
965 pc->val = val;
966 audiopci_configure_output(dev);
967 mutex_exit(&dev->mutex);
968
969 return (0);
970 }
971
972 static int
audiopci_set_front(void * arg,uint64_t val)973 audiopci_set_front(void *arg, uint64_t val)
974 {
975 audiopci_ctrl_t *pc = arg;
976 audiopci_dev_t *dev = pc->dev;
977 uint8_t l;
978 uint8_t r;
979
980 l = (val & 0xff00) >> 8;
981 r = val & 0xff;
982
983 if ((l > 100) || (r > 100))
984 return (EINVAL);
985
986 mutex_enter(&dev->mutex);
987 pc->val = val;
988 audiopci_configure_output(dev);
989
990 mutex_exit(&dev->mutex);
991 return (0);
992 }
993
994 static int
audiopci_set_speaker(void * arg,uint64_t val)995 audiopci_set_speaker(void *arg, uint64_t val)
996 {
997 audiopci_ctrl_t *pc = arg;
998 audiopci_dev_t *dev = pc->dev;
999
1000 val &= 0xff;
1001
1002 if (val > 100)
1003 return (EINVAL);
1004
1005 mutex_enter(&dev->mutex);
1006 pc->val = val;
1007 audiopci_configure_output(dev);
1008
1009 mutex_exit(&dev->mutex);
1010 return (0);
1011 }
1012
1013 #define PLAYCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY)
1014 #define RECCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC)
1015 #define MONCTL (AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR)
1016 #define PCMVOL (PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL)
1017 #define MAINVOL (PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL)
1018 #define RECVOL (RECCTL | AUDIO_CTRL_FLAG_RECVOL)
1019
1020 static void
audiopci_alloc_ctrl(audiopci_dev_t * dev,uint32_t num,uint64_t val)1021 audiopci_alloc_ctrl(audiopci_dev_t *dev, uint32_t num, uint64_t val)
1022 {
1023 audio_ctrl_desc_t desc;
1024 audio_ctrl_wr_t fn;
1025 audiopci_ctrl_t *pc;
1026
1027 bzero(&desc, sizeof (desc));
1028
1029 pc = &dev->controls[num];
1030 pc->num = num;
1031 pc->dev = dev;
1032
1033 switch (num) {
1034 case CTL_VOLUME:
1035 desc.acd_name = AUDIO_CTRL_ID_VOLUME;
1036 desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1037 desc.acd_minvalue = 0;
1038 desc.acd_maxvalue = 100;
1039 desc.acd_flags = PCMVOL;
1040 fn = audiopci_set_volume;
1041 break;
1042
1043 case CTL_FRONT:
1044 desc.acd_name = AUDIO_CTRL_ID_LINEOUT;
1045 desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1046 desc.acd_minvalue = 0;
1047 desc.acd_maxvalue = 100;
1048 desc.acd_flags = MAINVOL;
1049 fn = audiopci_set_front;
1050 break;
1051
1052 case CTL_MONO:
1053 desc.acd_name = AUDIO_CTRL_ID_SPEAKER;
1054 desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1055 desc.acd_minvalue = 0;
1056 desc.acd_maxvalue = 100;
1057 desc.acd_flags = MAINVOL;
1058 fn = audiopci_set_speaker;
1059 break;
1060
1061 case CTL_MIC:
1062 desc.acd_name = AUDIO_CTRL_ID_MIC;
1063 desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1064 desc.acd_minvalue = 0;
1065 desc.acd_maxvalue = 100;
1066 desc.acd_flags = RECVOL;
1067 fn = audiopci_set_reclevel;
1068 break;
1069
1070 case CTL_LINE:
1071 desc.acd_name = AUDIO_CTRL_ID_LINEIN;
1072 desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1073 desc.acd_minvalue = 0;
1074 desc.acd_maxvalue = 100;
1075 desc.acd_flags = RECVOL;
1076 fn = audiopci_set_reclevel;
1077 break;
1078
1079 case CTL_CD:
1080 desc.acd_name = AUDIO_CTRL_ID_CD;
1081 desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1082 desc.acd_minvalue = 0;
1083 desc.acd_maxvalue = 100;
1084 desc.acd_flags = RECVOL;
1085 fn = audiopci_set_reclevel;
1086 break;
1087
1088 case CTL_VID:
1089 desc.acd_name = AUDIO_CTRL_ID_VIDEO;
1090 desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
1091 desc.acd_minvalue = 0;
1092 desc.acd_maxvalue = 100;
1093 desc.acd_flags = RECVOL;
1094 fn = audiopci_set_reclevel;
1095 break;
1096
1097 case CTL_PHONE:
1098 desc.acd_name = AUDIO_CTRL_ID_PHONE;
1099 desc.acd_type = AUDIO_CTRL_TYPE_MONO;
1100 desc.acd_minvalue = 0;
1101 desc.acd_maxvalue = 100;
1102 desc.acd_flags = RECVOL;
1103 fn = audiopci_set_reclevel;
1104 break;
1105
1106 case CTL_RECSRC:
1107 desc.acd_name = AUDIO_CTRL_ID_RECSRC;
1108 desc.acd_type = AUDIO_CTRL_TYPE_ENUM;
1109 desc.acd_minvalue = INSRCS;
1110 desc.acd_maxvalue = INSRCS;
1111 desc.acd_flags = RECCTL | AUDIO_CTRL_FLAG_MULTI;
1112 for (int i = 0; audiopci_insrcs[i]; i++) {
1113 desc.acd_enum[i] = audiopci_insrcs[i];
1114 }
1115 fn = audiopci_set_recsrc;
1116 break;
1117
1118 case CTL_MONSRC:
1119 desc.acd_name = AUDIO_CTRL_ID_MONSRC;
1120 desc.acd_type = AUDIO_CTRL_TYPE_ENUM;
1121 desc.acd_minvalue = INSRCS;
1122 desc.acd_maxvalue = INSRCS;
1123 desc.acd_flags = MONCTL | AUDIO_CTRL_FLAG_MULTI;
1124 for (int i = 0; audiopci_insrcs[i]; i++) {
1125 desc.acd_enum[i] = audiopci_insrcs[i];
1126 }
1127 fn = audiopci_set_monsrc;
1128 break;
1129
1130 case CTL_MICBOOST:
1131 desc.acd_name = AUDIO_CTRL_ID_MICBOOST;
1132 desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN;
1133 desc.acd_minvalue = 0;
1134 desc.acd_maxvalue = 100;
1135 desc.acd_flags = RECCTL;
1136 fn = audiopci_set_micboost;
1137 break;
1138 }
1139
1140 pc->val = val;
1141 pc->ctrl = audio_dev_add_control(dev->adev, &desc,
1142 audiopci_get_value, fn, pc);
1143 }
1144
1145 static int
audiopci_add_controls(audiopci_dev_t * dev)1146 audiopci_add_controls(audiopci_dev_t *dev)
1147 {
1148 audiopci_alloc_ctrl(dev, CTL_VOLUME, 75);
1149 audiopci_alloc_ctrl(dev, CTL_FRONT, ((75) | (75 << 8)));
1150 audiopci_alloc_ctrl(dev, CTL_MONO, 75);
1151 audiopci_alloc_ctrl(dev, CTL_MIC, 50);
1152 audiopci_alloc_ctrl(dev, CTL_LINE, 0);
1153 audiopci_alloc_ctrl(dev, CTL_CD, 0);
1154 audiopci_alloc_ctrl(dev, CTL_VID, 0);
1155 audiopci_alloc_ctrl(dev, CTL_PHONE, 0);
1156 audiopci_alloc_ctrl(dev, CTL_RECSRC, (1U << INPUT_MIC));
1157 audiopci_alloc_ctrl(dev, CTL_MONSRC, 0);
1158 audiopci_alloc_ctrl(dev, CTL_MICBOOST, 1);
1159
1160 audiopci_configure_output(dev);
1161 audiopci_configure_input(dev);
1162
1163 return (DDI_SUCCESS);
1164 }
1165
1166 static void
audiopci_del_controls(audiopci_dev_t * dev)1167 audiopci_del_controls(audiopci_dev_t *dev)
1168 {
1169 for (int i = 0; i < CTL_NUM; i++) {
1170 if (dev->controls[i].ctrl) {
1171 audio_dev_del_control(dev->controls[i].ctrl);
1172 }
1173 }
1174 }
1175
1176 static int
audiopci_attach(dev_info_t * dip)1177 audiopci_attach(dev_info_t *dip)
1178 {
1179 uint16_t pci_command, vendor, device;
1180 audiopci_dev_t *dev;
1181 ddi_acc_handle_t pcih;
1182
1183 dev = kmem_zalloc(sizeof (*dev), KM_SLEEP);
1184 dev->dip = dip;
1185 ddi_set_driver_private(dip, dev);
1186
1187 mutex_init(&dev->mutex, NULL, MUTEX_DRIVER, NULL);
1188
1189 if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) {
1190 audio_dev_warn(dev->adev, "pci_config_setup failed");
1191 mutex_destroy(&dev->mutex);
1192 kmem_free(dev, sizeof (*dev));
1193 return (DDI_FAILURE);
1194 }
1195
1196 vendor = pci_config_get16(pcih, PCI_CONF_VENID);
1197 device = pci_config_get16(pcih, PCI_CONF_DEVID);
1198
1199 if ((vendor != ENSONIQ_VENDOR_ID && vendor != CREATIVE_VENDOR_ID) ||
1200 (device != ENSONIQ_ES1370))
1201 goto err_exit;
1202
1203 dev->devid = device;
1204
1205 dev->adev = audio_dev_alloc(dip, 0);
1206 if (dev->adev == NULL) {
1207 goto err_exit;
1208 }
1209
1210 audio_dev_set_description(dev->adev, "AudioPCI");
1211 audio_dev_set_version(dev->adev, "ES1370");
1212 audio_dev_add_info(dev->adev, "Legacy codec: Asahi Kasei AK4531");
1213
1214 /* activate the device */
1215 pci_command = pci_config_get16(pcih, PCI_CONF_COMM);
1216 pci_command |= PCI_COMM_ME | PCI_COMM_IO;
1217 pci_config_put16(pcih, PCI_CONF_COMM, pci_command);
1218
1219 /* map registers */
1220 if (ddi_regs_map_setup(dip, 1, &dev->regs, 0, 0, &acc_attr,
1221 &dev->acch) != DDI_SUCCESS) {
1222 audio_dev_warn(dev->adev, "can't map registers");
1223 goto err_exit;
1224 }
1225
1226
1227 /* This allocates and configures the engines */
1228 if (audiopci_init(dev) != DDI_SUCCESS) {
1229 audio_dev_warn(dev->adev, "can't init device");
1230 goto err_exit;
1231 }
1232
1233 pci_config_teardown(&pcih);
1234
1235 ddi_report_dev(dip);
1236
1237 return (DDI_SUCCESS);
1238
1239 err_exit:
1240 mutex_destroy(&dev->mutex);
1241 pci_config_teardown(&pcih);
1242
1243 audiopci_destroy(dev);
1244
1245 return (DDI_FAILURE);
1246 }
1247
1248 static int
audiopci_detach(audiopci_dev_t * dev)1249 audiopci_detach(audiopci_dev_t *dev)
1250 {
1251 int tmp;
1252
1253 /* first unregister us from the DDI framework, might be busy */
1254 if (audio_dev_unregister(dev->adev) != DDI_SUCCESS)
1255 return (DDI_FAILURE);
1256
1257 mutex_enter(&dev->mutex);
1258
1259 tmp = GET8(dev, CONC_bSERCTL_OFF) &
1260 ~(CONC_SERCTL_DACIE | CONC_SERCTL_SYNIE | CONC_SERCTL_ADCIE);
1261 PUT8(dev, CONC_bSERCTL_OFF, tmp);
1262 PUT8(dev, CONC_bSERCTL_OFF, tmp);
1263 PUT8(dev, CONC_bSERCTL_OFF, tmp);
1264 PUT8(dev, CONC_bSERCTL_OFF, tmp);
1265
1266 tmp = GET8(dev, CONC_bDEVCTL_OFF) &
1267 ~(CONC_DEVCTL_DAC_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_SYN_EN);
1268 PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1269 PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1270 PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1271 PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1272
1273 mutex_exit(&dev->mutex);
1274
1275 audiopci_destroy(dev);
1276
1277 return (DDI_SUCCESS);
1278 }
1279
1280 static int
audiopci_resume(audiopci_dev_t * dev)1281 audiopci_resume(audiopci_dev_t *dev)
1282 {
1283 /* reinitialize hardware */
1284 audiopci_init_hw(dev);
1285
1286 audio_dev_resume(dev->adev);
1287 return (DDI_SUCCESS);
1288 }
1289
1290 static int
audiopci_suspend(audiopci_dev_t * dev)1291 audiopci_suspend(audiopci_dev_t *dev)
1292 {
1293 audio_dev_suspend(dev->adev);
1294
1295 return (DDI_SUCCESS);
1296 }
1297
1298 static int
audiopci_quiesce(dev_info_t * dip)1299 audiopci_quiesce(dev_info_t *dip)
1300 {
1301 audiopci_dev_t *dev;
1302 uint8_t tmp;
1303
1304 if ((dev = ddi_get_driver_private(dip)) == NULL) {
1305 return (DDI_FAILURE);
1306 }
1307
1308 /* This disables all DMA engines and interrupts */
1309 tmp = GET8(dev, CONC_bSERCTL_OFF) &
1310 ~(CONC_SERCTL_DACIE | CONC_SERCTL_SYNIE | CONC_SERCTL_ADCIE);
1311 PUT8(dev, CONC_bSERCTL_OFF, tmp);
1312 PUT8(dev, CONC_bSERCTL_OFF, tmp);
1313 PUT8(dev, CONC_bSERCTL_OFF, tmp);
1314 PUT8(dev, CONC_bSERCTL_OFF, tmp);
1315
1316 tmp = GET8(dev, CONC_bDEVCTL_OFF) &
1317 ~(CONC_DEVCTL_DAC_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_SYN_EN);
1318 PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1319 PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1320 PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1321 PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1322
1323 return (DDI_SUCCESS);
1324 }
1325
1326
1327 static int
audiopci_ddi_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)1328 audiopci_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1329 {
1330 audiopci_dev_t *dev;
1331
1332 switch (cmd) {
1333 case DDI_ATTACH:
1334 return (audiopci_attach(dip));
1335
1336 case DDI_RESUME:
1337 if ((dev = ddi_get_driver_private(dip)) == NULL) {
1338 return (DDI_FAILURE);
1339 }
1340 return (audiopci_resume(dev));
1341
1342 default:
1343 return (DDI_FAILURE);
1344 }
1345 }
1346
1347 static int
audiopci_ddi_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)1348 audiopci_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1349 {
1350 audiopci_dev_t *dev;
1351
1352 if ((dev = ddi_get_driver_private(dip)) == NULL) {
1353 return (DDI_FAILURE);
1354 }
1355
1356 switch (cmd) {
1357 case DDI_DETACH:
1358 return (audiopci_detach(dev));
1359
1360 case DDI_SUSPEND:
1361 return (audiopci_suspend(dev));
1362 default:
1363 return (DDI_FAILURE);
1364 }
1365 }
1366
1367 static struct dev_ops audiopci_dev_ops = {
1368 DEVO_REV, /* rev */
1369 0, /* refcnt */
1370 NULL, /* getinfo */
1371 nulldev, /* identify */
1372 nulldev, /* probe */
1373 audiopci_ddi_attach, /* attach */
1374 audiopci_ddi_detach, /* detach */
1375 nodev, /* reset */
1376 NULL, /* cb_ops */
1377 NULL, /* bus_ops */
1378 NULL, /* power */
1379 audiopci_quiesce, /* quiesce */
1380 };
1381
1382 static struct modldrv audiopci_modldrv = {
1383 &mod_driverops, /* drv_modops */
1384 "Ensoniq 1370 Audio", /* linkinfo */
1385 &audiopci_dev_ops, /* dev_ops */
1386 };
1387
1388 static struct modlinkage modlinkage = {
1389 MODREV_1,
1390 { &audiopci_modldrv, NULL }
1391 };
1392
1393 int
_init(void)1394 _init(void)
1395 {
1396 int rv;
1397
1398 audio_init_ops(&audiopci_dev_ops, DRVNAME);
1399 if ((rv = mod_install(&modlinkage)) != 0) {
1400 audio_fini_ops(&audiopci_dev_ops);
1401 }
1402 return (rv);
1403 }
1404
1405 int
_fini(void)1406 _fini(void)
1407 {
1408 int rv;
1409
1410 if ((rv = mod_remove(&modlinkage)) == 0) {
1411 audio_fini_ops(&audiopci_dev_ops);
1412 }
1413 return (rv);
1414 }
1415
1416 int
_info(struct modinfo * modinfop)1417 _info(struct modinfo *modinfop)
1418 {
1419 return (mod_info(&modlinkage, modinfop));
1420 }
1421