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 (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 /*
  25  * Purpose: Creative/Ensoniq AudioPCI97  driver (ES1371/ES1373)
  26  *
  27  * This driver is used with the original Ensoniq AudioPCI97 card and many
  28  * PCI based Sound Blaster cards by Creative Technologies. For example
  29  * Sound Blaster PCI128 and Creative/Ectiva EV1938.
  30  */
  31 
  32 /*
  33  * This file is part of Open Sound System
  34  *
  35  * Copyright (C) 4Front Technologies 1996-2008.
  36  *
  37  * This software is released under CDDL 1.0 source license.
  38  * See the COPYING file included in the main directory of this source
  39  * distribution for the license terms and conditions.
  40  */
  41 
  42 #include <sys/audio/audio_driver.h>
  43 #include <sys/audio/ac97.h>
  44 #include <sys/note.h>
  45 #include <sys/pci.h>
  46 #include "audioens.h"
  47 
  48 /*
  49  * Set the latency to 32, 64, 96, 128 clocks - some APCI97 devices exhibit
  50  * garbled audio in some cases and setting the latency to higer values fixes it
  51  * Values: 32, 64, 96, 128 - Default: 64 (or defined by bios)
  52  */
  53 int audioens_latency = 0;
  54 
  55 /*
  56  * Enable SPDIF port on SoundBlaster 128D or Sound Blaster Digital-4.1 models
  57  * Values: 1=Enable 0=Disable Default: 0
  58  */
  59 int audioens_spdif = 0;
  60 
  61 /*
  62  * Note: Latest devices can support SPDIF with AC3 pass thru.
  63  * However, in order to do this, one of the two DMA engines must be
  64  * dedicated to this, which would prevent the card from supporting 4
  65  * channel audio.  For now we don't bother with the AC3 pass through
  66  * mode, and instead just focus on 4 channel support.  In the future,
  67  * this could be selectable via a property.
  68  */
  69 
  70 #define ENSONIQ_VENDOR_ID       0x1274
  71 #define CREATIVE_VENDOR_ID      0x1102
  72 #define ECTIVA_VENDOR_ID        0x1102
  73 #define ENSONIQ_ES1371          0x1371
  74 #define ENSONIQ_ES5880          0x8001
  75 #define ENSONIQ_ES5880A         0x8002
  76 #define ENSONIQ_ES5880B         0x5880
  77 #define ECTIVA_ES1938           0x8938
  78 
  79 #define DEFRATE                 48000
  80 #define DRVNAME                 "audioens"
  81 
  82 typedef struct audioens_port
  83 {
  84         /* Audio parameters */
  85         int                     speed;
  86 
  87         int                     num;
  88 #define PORT_DAC                0
  89 #define PORT_ADC                1
  90 #define PORT_MAX                PORT_ADC
  91 
  92         caddr_t                 kaddr;
  93         uint32_t                paddr;
  94         ddi_acc_handle_t        acch;
  95         ddi_dma_handle_t        dmah;
  96         int                     nchan;
  97         unsigned                nframes;
  98         unsigned                frameno;
  99         uint64_t                count;
 100 
 101         struct audioens_dev     *dev;
 102         audio_engine_t  *engine;
 103 } audioens_port_t;
 104 
 105 typedef struct audioens_dev
 106 {
 107         audio_dev_t             *osdev;
 108         kmutex_t                mutex;
 109         uint16_t                devid;
 110         uint8_t                 revision;
 111         dev_info_t              *dip;
 112 
 113         audioens_port_t         port[PORT_MAX + 1];
 114 
 115         ac97_t                  *ac97;
 116 
 117         caddr_t                 regs;
 118         ddi_acc_handle_t        acch;
 119 } audioens_dev_t;
 120 
 121 static ddi_device_acc_attr_t acc_attr = {
 122         DDI_DEVICE_ATTR_V0,
 123         DDI_STRUCTURE_LE_ACC,
 124         DDI_STRICTORDER_ACC
 125 };
 126 
 127 static ddi_device_acc_attr_t buf_attr = {
 128         DDI_DEVICE_ATTR_V0,
 129         DDI_NEVERSWAP_ACC,
 130         DDI_STRICTORDER_ACC
 131 };
 132 
 133 /*
 134  * The hardware appears to be able to address up to 16-bits worth of longwords,
 135  * giving a total address space of 256K.  But we need substantially less.
 136  */
 137 #define AUDIOENS_BUF_LEN        (16384)
 138 
 139 static ddi_dma_attr_t dma_attr = {
 140         DMA_ATTR_VERSION,       /* dma_attr_version */
 141         0x0,                    /* dma_attr_addr_lo */
 142         0xffffffffU,            /* dma_attr_addr_hi */
 143         0x3ffff,                /* dma_attr_count_max */
 144         0x8,                    /* dma_attr_align */
 145         0x7f,                   /* dma_attr_burstsizes */
 146         0x1,                    /* dma_attr_minxfer */
 147         0x3ffff,                /* dma_attr_maxxfer */
 148         0x3ffff,                /* dma_attr_seg */
 149         0x1,                    /* dma_attr_sgllen */
 150         0x1,                    /* dma_attr_granular */
 151         0                       /* dma_attr_flags */
 152 };
 153 
 154 #define GET8(dev, offset)       \
 155         ddi_get8(dev->acch, (uint8_t *)(dev->regs + (offset)))
 156 #define GET16(dev, offset)      \
 157         ddi_get16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset)))
 158 #define GET32(dev, offset)      \
 159         ddi_get32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset)))
 160 #define PUT8(dev, offset, v)    \
 161         ddi_put8(dev->acch, (uint8_t *)(dev->regs + (offset)), v)
 162 #define PUT16(dev, offset, v)   \
 163         ddi_put16(dev->acch, (uint16_t *)(void *)(dev->regs + (offset)), v)
 164 #define PUT32(dev, offset, v)   \
 165         ddi_put32(dev->acch, (uint32_t *)(void *)(dev->regs + (offset)), v)
 166 
 167 #define CLR8(dev, offset, v)    PUT8(dev, offset, GET8(dev, offset) & ~(v))
 168 #define SET8(dev, offset, v)    PUT8(dev, offset, GET8(dev, offset) | (v))
 169 #define CLR32(dev, offset, v)   PUT32(dev, offset, GET32(dev, offset) & ~(v))
 170 #define SET32(dev, offset, v)   PUT32(dev, offset, GET32(dev, offset) | (v))
 171 
 172 static void audioens_init_hw(audioens_dev_t *);
 173 
 174 static uint16_t
 175 audioens_rd97(void *dev_, uint8_t wAddr)
 176 {
 177         audioens_dev_t *dev = dev_;
 178         int i, dtemp;
 179 
 180         mutex_enter(&dev->mutex);
 181         dtemp = GET32(dev, CONC_dCODECCTL_OFF);
 182         /* wait for WIP to go away saving the current state for later */
 183         for (i = 0; i < 0x100UL; ++i) {
 184                 dtemp = GET32(dev, CONC_dCODECCTL_OFF);
 185                 if ((dtemp & (1UL << 30)) == 0)
 186                         break;
 187         }
 188 
 189         /* write addr w/data=0 and assert read request ... */
 190         PUT32(dev, CONC_dCODECCTL_OFF, ((int)wAddr << 16) | (1UL << 23));
 191 
 192         /* now wait for the data (RDY) */
 193         for (i = 0; i < 0x100UL; ++i) {
 194                 dtemp = GET32(dev, CONC_dCODECCTL_OFF);
 195                 if (dtemp & (1UL << 31))
 196                         break;
 197         }
 198         dtemp = GET32(dev, CONC_dCODECCTL_OFF);
 199         mutex_exit(&dev->mutex);
 200 
 201         return (dtemp & 0xffff);
 202 }
 203 
 204 static void
 205 audioens_wr97(void *dev_, uint8_t wAddr, uint16_t wData)
 206 {
 207         audioens_dev_t *dev = dev_;
 208         int i, dtemp;
 209 
 210         mutex_enter(&dev->mutex);
 211         /* wait for WIP to go away */
 212         for (i = 0; i < 0x100UL; ++i) {
 213                 dtemp = GET32(dev, CONC_dCODECCTL_OFF);
 214                 if ((dtemp & (1UL << 30)) == 0)
 215                         break;
 216         }
 217 
 218         PUT32(dev, CONC_dCODECCTL_OFF, ((int)wAddr << 16) | wData);
 219 
 220         mutex_exit(&dev->mutex);
 221 }
 222 
 223 static unsigned short
 224 SRCRegRead(audioens_dev_t *dev, unsigned short reg)
 225 {
 226         int i, dtemp;
 227 
 228         dtemp = GET32(dev, CONC_dSRCIO_OFF);
 229         /* wait for ready */
 230         for (i = 0; i < SRC_IOPOLL_COUNT; ++i) {
 231                 dtemp = GET32(dev, CONC_dSRCIO_OFF);
 232                 if ((dtemp & SRC_BUSY) == 0)
 233                         break;
 234         }
 235 
 236         /* assert a read request */
 237         PUT32(dev, CONC_dSRCIO_OFF, (dtemp & SRC_CTLMASK) | ((int)reg << 25));
 238 
 239         /* now wait for the data */
 240         for (i = 0; i < SRC_IOPOLL_COUNT; ++i) {
 241                 dtemp = GET32(dev, CONC_dSRCIO_OFF);
 242                 if ((dtemp & SRC_BUSY) == 0)
 243                         break;
 244         }
 245 
 246         return ((unsigned short) dtemp);
 247 }
 248 
 249 static void
 250 SRCRegWrite(audioens_dev_t *dev, unsigned short reg, unsigned short val)
 251 {
 252         int i, dtemp;
 253         int writeval;
 254 
 255         dtemp = GET32(dev, CONC_dSRCIO_OFF);
 256         /* wait for ready */
 257         for (i = 0; i < SRC_IOPOLL_COUNT; ++i) {
 258                 dtemp = GET32(dev, CONC_dSRCIO_OFF);
 259                 if ((dtemp & SRC_BUSY) == 0)
 260                         break;
 261         }
 262 
 263         /* assert the write request */
 264         writeval = (dtemp & SRC_CTLMASK) | SRC_WENABLE |
 265             ((int)reg << 25) | val;
 266         PUT32(dev, CONC_dSRCIO_OFF, writeval);
 267 }
 268 
 269 static void
 270 SRCSetRate(audioens_dev_t *dev, unsigned char base, unsigned short rate)
 271 {
 272         int i, freq, dtemp;
 273         unsigned short N, truncM, truncStart;
 274 
 275         if (base != SRC_ADC_BASE) {
 276                 /* freeze the channel */
 277                 dtemp = (base == SRC_DAC1_BASE) ?
 278                     SRC_DAC1FREEZE : SRC_DAC2FREEZE;
 279                 for (i = 0; i < SRC_IOPOLL_COUNT; ++i) {
 280                         if (!(GET32(dev, CONC_dSRCIO_OFF) & SRC_BUSY))
 281                                 break;
 282                 }
 283                 PUT32(dev, CONC_dSRCIO_OFF,
 284                     (GET32(dev, CONC_dSRCIO_OFF) & SRC_CTLMASK) | dtemp);
 285 
 286                 /* calculate new frequency and write it - preserve accum */
 287                 freq = ((int)rate << 16) / 3000U;
 288                 SRCRegWrite(dev, (unsigned short) base + SRC_INT_REGS_OFF,
 289                     (SRCRegRead(dev, (unsigned short) base + SRC_INT_REGS_OFF)
 290                     & 0x00ffU) | ((unsigned short) (freq >> 6) & 0xfc00));
 291                 SRCRegWrite(dev, (unsigned short) base + SRC_VFREQ_FRAC_OFF,
 292                     (unsigned short) freq >> 1);
 293 
 294                 /* un-freeze the channel */
 295                 for (i = 0; i < SRC_IOPOLL_COUNT; ++i)
 296                         if (!(GET32(dev, CONC_dSRCIO_OFF) & SRC_BUSY))
 297                                 break;
 298                 PUT32(dev, CONC_dSRCIO_OFF,
 299                     (GET32(dev, CONC_dSRCIO_OFF) & SRC_CTLMASK) & ~dtemp);
 300         } else {
 301                 /* derive oversample ratio */
 302                 N = rate / 3000U;
 303                 if (N == 15 || N == 13 || N == 11 || N == 9)
 304                         --N;
 305 
 306                 /* truncate the filter and write n/trunc_start */
 307                 truncM = (21 * N - 1) | 1;
 308                 if (rate >= 24000U) {
 309                         if (truncM > 239)
 310                                 truncM = 239;
 311                         truncStart = (239 - truncM) >> 1;
 312 
 313                         SRCRegWrite(dev, base + SRC_TRUNC_N_OFF,
 314                             (truncStart << 9) | (N << 4));
 315                 } else {
 316                         if (truncM > 119)
 317                                 truncM = 119;
 318                         truncStart = (119 - truncM) >> 1;
 319 
 320                         SRCRegWrite(dev, base + SRC_TRUNC_N_OFF,
 321                             0x8000U | (truncStart << 9) | (N << 4));
 322                 }
 323 
 324                 /* calculate new frequency and write it - preserve accum */
 325                 freq = ((48000UL << 16) / rate) * N;
 326                 SRCRegWrite(dev, base + SRC_INT_REGS_OFF,
 327                     (SRCRegRead(dev, (unsigned short) base + SRC_INT_REGS_OFF)
 328                     & 0x00ff) | ((unsigned short) (freq >> 6) & 0xfc00));
 329                 SRCRegWrite(dev, base + SRC_VFREQ_FRAC_OFF,
 330                     (unsigned short) freq >> 1);
 331 
 332                 SRCRegWrite(dev, SRC_ADC_VOL_L, N << 8);
 333                 SRCRegWrite(dev, SRC_ADC_VOL_R, N << 8);
 334         }
 335 }
 336 
 337 static void
 338 SRCInit(audioens_dev_t *dev)
 339 {
 340         int i;
 341 
 342         /* Clear all SRC RAM then init - keep SRC disabled until done */
 343         for (i = 0; i < SRC_IOPOLL_COUNT; ++i) {
 344                 if (!(GET32(dev, CONC_dSRCIO_OFF) & SRC_BUSY))
 345                         break;
 346         }
 347         PUT32(dev, CONC_dSRCIO_OFF, SRC_DISABLE);
 348 
 349         for (i = 0; i < 0x80; ++i)
 350                 SRCRegWrite(dev, (unsigned short) i, 0U);
 351 
 352         SRCRegWrite(dev, SRC_DAC1_BASE + SRC_TRUNC_N_OFF, 16 << 4);
 353         SRCRegWrite(dev, SRC_DAC1_BASE + SRC_INT_REGS_OFF, 16 << 10);
 354         SRCRegWrite(dev, SRC_DAC2_BASE + SRC_TRUNC_N_OFF, 16 << 4);
 355         SRCRegWrite(dev, SRC_DAC2_BASE + SRC_INT_REGS_OFF, 16 << 10);
 356         SRCRegWrite(dev, SRC_DAC1_VOL_L, 1 << 12);
 357         SRCRegWrite(dev, SRC_DAC1_VOL_R, 1 << 12);
 358         SRCRegWrite(dev, SRC_DAC2_VOL_L, 1 << 12);
 359         SRCRegWrite(dev, SRC_DAC2_VOL_R, 1 << 12);
 360         SRCRegWrite(dev, SRC_ADC_VOL_L, 1 << 12);
 361         SRCRegWrite(dev, SRC_ADC_VOL_R, 1 << 12);
 362 
 363         /* default some rates */
 364         SRCSetRate(dev, SRC_DAC1_BASE, 48000);
 365         SRCSetRate(dev, SRC_DAC2_BASE, 48000);
 366         SRCSetRate(dev, SRC_ADC_BASE, 48000);
 367 
 368         /* now enable the whole deal */
 369         for (i = 0; i < SRC_IOPOLL_COUNT; ++i) {
 370                 if (!(GET32(dev, CONC_dSRCIO_OFF) & SRC_BUSY))
 371                         break;
 372         }
 373         PUT32(dev, CONC_dSRCIO_OFF, 0);
 374 }
 375 
 376 static void
 377 audioens_writemem(audioens_dev_t *dev, uint32_t page, uint32_t offs,
 378     uint32_t data)
 379 {
 380         /* Select memory page */
 381         PUT32(dev, CONC_bMEMPAGE_OFF, page);
 382         PUT32(dev, offs, data);
 383 }
 384 
 385 static uint32_t
 386 audioens_readmem(audioens_dev_t *dev, uint32_t page, uint32_t offs)
 387 {
 388         PUT32(dev, CONC_bMEMPAGE_OFF, page);    /* Select memory page */
 389         return (GET32(dev, offs));
 390 }
 391 
 392 /*
 393  * Audio routines
 394  */
 395 static int
 396 audioens_format(void *arg)
 397 {
 398         _NOTE(ARGUNUSED(arg));
 399 
 400         /* hardware can also do AUDIO_FORMAT_U8, but no need for it */
 401         return (AUDIO_FORMAT_S16_LE);
 402 }
 403 
 404 static int
 405 audioens_channels(void *arg)
 406 {
 407         audioens_port_t *port = arg;
 408 
 409         return (port->nchan);
 410 }
 411 
 412 static int
 413 audioens_rate(void *arg)
 414 {
 415         audioens_port_t *port = arg;
 416 
 417         return (port->speed);
 418 }
 419 
 420 static int
 421 audioens_open(void *arg, int flag, unsigned *nframes, caddr_t *bufp)
 422 {
 423         audioens_port_t *port = arg;
 424         audioens_dev_t  *dev = port->dev;
 425 
 426         _NOTE(ARGUNUSED(flag));
 427 
 428         mutex_enter(&dev->mutex);
 429 
 430         port->nframes = AUDIOENS_BUF_LEN / (port->nchan * sizeof (int16_t));
 431         port->count = 0;
 432 
 433         *nframes = port->nframes;
 434         *bufp = port->kaddr;
 435         mutex_exit(&dev->mutex);
 436 
 437         return (0);
 438 }
 439 
 440 static int
 441 audioens_start(void *arg)
 442 {
 443         audioens_port_t *port = arg;
 444         audioens_dev_t *dev = port->dev;
 445         uint32_t tmp;
 446 
 447         mutex_enter(&dev->mutex);
 448 
 449         switch (port->num) {
 450         case PORT_DAC:
 451                 /* Set physical address of the DMA buffer */
 452                 audioens_writemem(dev, CONC_DAC1CTL_PAGE, CONC_dDAC1PADDR_OFF,
 453                     port->paddr);
 454                 audioens_writemem(dev, CONC_DAC2CTL_PAGE, CONC_dDAC2PADDR_OFF,
 455                     port->paddr + (port->nframes * sizeof (int16_t) * 2));
 456 
 457                 /* Set DAC rate */
 458                 SRCSetRate(dev, SRC_DAC1_BASE, port->speed);
 459                 SRCSetRate(dev, SRC_DAC2_BASE, port->speed);
 460 
 461                 /* Configure the channel setup - SPDIF only uses front */
 462                 tmp = GET32(dev, CONC_dSTATUS_OFF);
 463                 tmp &= ~(CONC_STATUS_SPKR_MASK | CONC_STATUS_SPDIF_MASK);
 464                 tmp |= CONC_STATUS_SPKR_4CH | CONC_STATUS_SPDIF_P1;
 465                 PUT32(dev, CONC_dSTATUS_OFF, tmp);
 466 
 467                 /* Set format */
 468                 PUT8(dev, CONC_bSKIPC_OFF, 0x10);
 469                 SET8(dev, CONC_bSERFMT_OFF,
 470                     CONC_PCM_DAC1_16BIT | CONC_PCM_DAC2_16BIT |
 471                     CONC_PCM_DAC1_STEREO | CONC_PCM_DAC2_STEREO);
 472 
 473                 /* Set the frame count */
 474                 audioens_writemem(dev, CONC_DAC1CTL_PAGE, CONC_wDAC1FC_OFF,
 475                     port->nframes - 1);
 476                 audioens_writemem(dev, CONC_DAC2CTL_PAGE, CONC_wDAC2FC_OFF,
 477                     port->nframes - 1);
 478 
 479                 /* Set # of frames between interrupts */
 480                 PUT16(dev, CONC_wDAC1IC_OFF, port->nframes - 1);
 481                 PUT16(dev, CONC_wDAC2IC_OFF, port->nframes - 1);
 482 
 483                 SET8(dev, CONC_bDEVCTL_OFF,
 484                     CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_DAC1_EN);
 485 
 486                 break;
 487 
 488         case PORT_ADC:
 489                 /* Set physical address of the DMA buffer */
 490                 audioens_writemem(dev, CONC_ADCCTL_PAGE, CONC_dADCPADDR_OFF,
 491                     port->paddr);
 492 
 493                 /* Set ADC rate */
 494                 SRCSetRate(dev, SRC_ADC_BASE, port->speed);
 495 
 496                 /* Set format - for input we only support 16 bit input */
 497                 tmp = GET8(dev, CONC_bSERFMT_OFF);
 498                 tmp |= CONC_PCM_ADC_16BIT;
 499                 tmp |= CONC_PCM_ADC_STEREO;
 500 
 501                 PUT8(dev, CONC_bSKIPC_OFF, 0x10);
 502 
 503                 PUT8(dev, CONC_bSERFMT_OFF, tmp);
 504 
 505                 /* Set the frame count */
 506                 audioens_writemem(dev, CONC_ADCCTL_PAGE, CONC_wADCFC_OFF,
 507                     port->nframes - 1);
 508 
 509                 /* Set # of frames between interrupts */
 510                 PUT16(dev, CONC_wADCIC_OFF, port->nframes - 1);
 511 
 512                 SET8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_ADC_EN);
 513                 break;
 514         }
 515 
 516         port->frameno = 0;
 517         mutex_exit(&dev->mutex);
 518 
 519         return (0);
 520 }
 521 
 522 static void
 523 audioens_stop(void *arg)
 524 {
 525         audioens_port_t *port = arg;
 526         audioens_dev_t *dev = port->dev;
 527 
 528         mutex_enter(&dev->mutex);
 529         switch (port->num) {
 530         case PORT_DAC:
 531                 CLR8(dev, CONC_bDEVCTL_OFF,
 532                     CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_DAC1_EN);
 533                 break;
 534         case PORT_ADC:
 535                 CLR8(dev, CONC_bDEVCTL_OFF, CONC_DEVCTL_ADC_EN);
 536                 break;
 537         }
 538         mutex_exit(&dev->mutex);
 539 }
 540 
 541 static uint64_t
 542 audioens_count(void *arg)
 543 {
 544         audioens_port_t *port = arg;
 545         audioens_dev_t *dev = port->dev;
 546         uint64_t val;
 547         uint32_t page, offs;
 548         int frameno, n;
 549 
 550         switch (port->num) {
 551         case PORT_DAC:
 552                 page = CONC_DAC1CTL_PAGE;
 553                 offs = CONC_wDAC1FC_OFF;
 554                 break;
 555 
 556         case PORT_ADC:
 557                 page = CONC_ADCCTL_PAGE;
 558                 offs = CONC_wADCFC_OFF;
 559                 break;
 560         }
 561 
 562         mutex_enter(&dev->mutex);
 563         /*
 564          * Note that the current frame counter is in the high nybble.
 565          */
 566         frameno = audioens_readmem(port->dev, page, offs) >> 16;
 567         n = frameno >= port->frameno ?
 568             frameno - port->frameno :
 569             frameno + port->nframes - port->frameno;
 570         port->frameno = frameno;
 571         port->count += n;
 572 
 573         val = port->count;
 574         mutex_exit(&dev->mutex);
 575 
 576         return (val);
 577 }
 578 
 579 static void
 580 audioens_close(void *arg)
 581 {
 582         _NOTE(ARGUNUSED(arg));
 583 }
 584 
 585 static void
 586 audioens_sync(void *arg, unsigned nframes)
 587 {
 588         audioens_port_t *port = arg;
 589 
 590         _NOTE(ARGUNUSED(nframes));
 591 
 592         if (port->num == PORT_ADC) {
 593                 (void) ddi_dma_sync(port->dmah, 0, 0, DDI_DMA_SYNC_FORKERNEL);
 594         } else {
 595                 (void) ddi_dma_sync(port->dmah, 0, 0, DDI_DMA_SYNC_FORDEV);
 596         }
 597 }
 598 
 599 static void
 600 audioens_chinfo(void *arg, int chan, unsigned *offset, unsigned *incr)
 601 {
 602         audioens_port_t *port = arg;
 603 
 604         if ((port->num == PORT_DAC) && (chan >= 2)) {
 605                 *offset = (port->nframes * 2) + (chan % 2);
 606                 *incr = 2;
 607         } else {
 608                 *offset = chan;
 609                 *incr = 2;
 610         }
 611 }
 612 
 613 audio_engine_ops_t audioens_engine_ops = {
 614         AUDIO_ENGINE_VERSION,           /* version number */
 615         audioens_open,
 616         audioens_close,
 617         audioens_start,
 618         audioens_stop,
 619         audioens_count,
 620         audioens_format,
 621         audioens_channels,
 622         audioens_rate,
 623         audioens_sync,
 624         NULL,
 625         audioens_chinfo,
 626         NULL,
 627 };
 628 
 629 void
 630 audioens_init_hw(audioens_dev_t *dev)
 631 {
 632         int tmp;
 633 
 634         if ((dev->devid == ENSONIQ_ES5880) ||
 635             (dev->devid == ENSONIQ_ES5880A) ||
 636             (dev->devid == ENSONIQ_ES5880B) ||
 637             (dev->devid == 0x1371 && dev->revision == 7) ||
 638             (dev->devid == 0x1371 && dev->revision >= 9)) {
 639 
 640                 /* Have a ES5880 so enable the codec manually */
 641                 tmp = GET8(dev, CONC_bINTSUMM_OFF) & 0xff;
 642                 tmp |= 0x20;
 643                 PUT8(dev, CONC_bINTSUMM_OFF, tmp);
 644                 for (int i = 0; i < 2000; i++)
 645                         drv_usecwait(10);
 646         }
 647 
 648         SRCInit(dev);
 649 
 650         /*
 651          * Turn on CODEC (UART and joystick left disabled)
 652          */
 653         tmp = GET32(dev, CONC_bDEVCTL_OFF) & 0xff;
 654         tmp &= ~(CONC_DEVCTL_PCICLK_DS | CONC_DEVCTL_XTALCLK_DS);
 655         PUT8(dev, CONC_bDEVCTL_OFF, tmp);
 656         PUT8(dev, CONC_bUARTCSTAT_OFF, 0x00);
 657 
 658         /* Perform AC97 codec warm reset */
 659         tmp = GET8(dev, CONC_bMISCCTL_OFF) & 0xff;
 660         PUT8(dev, CONC_bMISCCTL_OFF, tmp | CONC_MISCCTL_SYNC_RES);
 661         drv_usecwait(200);
 662         PUT8(dev, CONC_bMISCCTL_OFF, tmp);
 663         drv_usecwait(200);
 664 
 665         if (dev->revision >= 4) {
 666                 /* XXX: enable SPDIF - PCM only for now */
 667                 if (audioens_spdif) {
 668                         /* enable SPDIF */
 669                         PUT32(dev, 0x04, GET32(dev, 0x04) | (1 << 18));
 670                         /* SPDIF out = data from DAC */
 671                         PUT32(dev, 0x00, GET32(dev, 0x00) | (1 << 26));
 672                         CLR32(dev, CONC_dSPDIF_OFF, CONC_SPDIF_AC3);
 673 
 674                 } else {
 675                         /* disable spdif out */
 676                         PUT32(dev, 0x04, GET32(dev, 0x04) & ~(1 << 18));
 677                         PUT32(dev, 0x00, GET32(dev, 0x00) & ~(1 << 26));
 678                 }
 679 
 680                 /* we want to run each channel independently */
 681                 CLR32(dev, CONC_dSTATUS_OFF, CONC_STATUS_ECHO);
 682         }
 683 }
 684 
 685 static int
 686 audioens_init(audioens_dev_t *dev)
 687 {
 688 
 689         audioens_init_hw(dev);
 690 
 691         /*
 692          * On this hardware, we want to disable the internal speaker by
 693          * default, if it exists.  (We don't have a speakerphone on any
 694          * of these cards, and no SPARC hardware uses it either!)
 695          */
 696         (void) ddi_prop_update_int(DDI_DEV_T_NONE, dev->dip, AC97_PROP_SPEAKER,
 697             0);
 698 
 699         /*
 700          * Init mixer
 701          */
 702 
 703         dev->ac97 = ac97_alloc(dev->dip, audioens_rd97, audioens_wr97, dev);
 704         if (dev->ac97 == NULL)
 705                 return (DDI_FAILURE);
 706 
 707         if (ac97_init(dev->ac97, dev->osdev) != 0) {
 708                 return (DDI_FAILURE);
 709         }
 710 
 711         for (int i = 0; i <= PORT_MAX; i++) {
 712                 audioens_port_t *port;
 713                 unsigned caps;
 714                 unsigned dmaflags;
 715                 size_t rlen;
 716                 ddi_dma_cookie_t c;
 717                 unsigned ccnt;
 718 
 719                 port = &dev->port[i];
 720                 port->dev = dev;
 721 
 722                 switch (i) {
 723                 case PORT_DAC:
 724                         port->nchan = 4;
 725                         port->speed = 48000;
 726                         caps = ENGINE_OUTPUT_CAP;
 727                         dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT;
 728                         break;
 729 
 730                 case PORT_ADC:
 731                         port->nchan = 2;
 732                         port->speed = 48000;
 733                         caps = ENGINE_INPUT_CAP;
 734                         dmaflags = DDI_DMA_READ | DDI_DMA_CONSISTENT;
 735                         break;
 736                 }
 737 
 738                 port->num = i;
 739 
 740                 /*
 741                  * Allocate DMA resources.
 742                  */
 743 
 744                 if (ddi_dma_alloc_handle(dev->dip, &dma_attr, DDI_DMA_SLEEP,
 745                     NULL, &port->dmah) != DDI_SUCCESS) {
 746                         audio_dev_warn(dev->osdev,
 747                             "port %d: dma handle allocation failed", i);
 748                         return (DDI_FAILURE);
 749                 }
 750                 if (ddi_dma_mem_alloc(port->dmah, AUDIOENS_BUF_LEN, &buf_attr,
 751                     DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &port->kaddr,
 752                     &rlen, &port->acch) != DDI_SUCCESS) {
 753                         audio_dev_warn(dev->osdev,
 754                             "port %d: dma memory allocation failed", i);
 755                         return (DDI_FAILURE);
 756                 }
 757                 /* ensure that the buffer is zeroed out properly */
 758                 bzero(port->kaddr, rlen);
 759                 if (ddi_dma_addr_bind_handle(port->dmah, NULL, port->kaddr,
 760                     AUDIOENS_BUF_LEN, dmaflags, DDI_DMA_SLEEP, NULL,
 761                     &c, &ccnt) != DDI_DMA_MAPPED) {
 762                         audio_dev_warn(dev->osdev,
 763                             "port %d: dma binding failed", i);
 764                         return (DDI_FAILURE);
 765                 }
 766                 port->paddr = c.dmac_address;
 767 
 768                 /*
 769                  * Allocate and configure audio engine.
 770                  */
 771                 port->engine = audio_engine_alloc(&audioens_engine_ops, caps);
 772                 if (port->engine == NULL) {
 773                         audio_dev_warn(dev->osdev,
 774                             "port %d: audio_engine_alloc failed", i);
 775                         return (DDI_FAILURE);
 776                 }
 777 
 778                 audio_engine_set_private(port->engine, port);
 779                 audio_dev_add_engine(dev->osdev, port->engine);
 780         }
 781 
 782         /*
 783          * Set up kstats for interrupt reporting.
 784          */
 785         if (audio_dev_register(dev->osdev) != DDI_SUCCESS) {
 786                 audio_dev_warn(dev->osdev,
 787                     "unable to register with audio framework");
 788                 return (DDI_FAILURE);
 789         }
 790 
 791         return (DDI_SUCCESS);
 792 }
 793 
 794 void
 795 audioens_destroy(audioens_dev_t *dev)
 796 {
 797         int     i;
 798 
 799         mutex_destroy(&dev->mutex);
 800 
 801         /* free up ports, including DMA resources for ports */
 802         for (i = 0; i <= PORT_MAX; i++) {
 803                 audioens_port_t *port = &dev->port[i];
 804 
 805                 if (port->paddr != 0)
 806                         (void) ddi_dma_unbind_handle(port->dmah);
 807                 if (port->acch != NULL)
 808                         ddi_dma_mem_free(&port->acch);
 809                 if (port->dmah != NULL)
 810                         ddi_dma_free_handle(&port->dmah);
 811 
 812                 if (port->engine != NULL) {
 813                         audio_dev_remove_engine(dev->osdev, port->engine);
 814                         audio_engine_free(port->engine);
 815                 }
 816         }
 817 
 818         if (dev->acch != NULL) {
 819                 ddi_regs_map_free(&dev->acch);
 820         }
 821 
 822         if (dev->ac97) {
 823                 ac97_free(dev->ac97);
 824         }
 825 
 826         if (dev->osdev != NULL) {
 827                 audio_dev_free(dev->osdev);
 828         }
 829 
 830         kmem_free(dev, sizeof (*dev));
 831 }
 832 
 833 int
 834 audioens_attach(dev_info_t *dip)
 835 {
 836         uint16_t pci_command, vendor, device;
 837         uint8_t revision;
 838         audioens_dev_t *dev;
 839         ddi_acc_handle_t pcih;
 840         const char *chip_name;
 841         const char *chip_vers;
 842 
 843         dev = kmem_zalloc(sizeof (*dev), KM_SLEEP);
 844         dev->dip = dip;
 845         ddi_set_driver_private(dip, dev);
 846         mutex_init(&dev->mutex, NULL, MUTEX_DRIVER, NULL);
 847 
 848         if (pci_config_setup(dip, &pcih) != DDI_SUCCESS) {
 849                 audio_dev_warn(dev->osdev, "pci_config_setup failed");
 850                 mutex_destroy(&dev->mutex);
 851                 kmem_free(dev, sizeof (*dev));
 852                 return (DDI_FAILURE);
 853         }
 854 
 855         vendor = pci_config_get16(pcih, PCI_CONF_VENID);
 856         device = pci_config_get16(pcih, PCI_CONF_DEVID);
 857         revision = pci_config_get8(pcih, PCI_CONF_REVID);
 858 
 859         if ((vendor != ENSONIQ_VENDOR_ID && vendor != CREATIVE_VENDOR_ID) ||
 860             (device != ENSONIQ_ES1371 && device != ENSONIQ_ES5880 &&
 861             device != ENSONIQ_ES5880A && device != ECTIVA_ES1938 &&
 862             device != ENSONIQ_ES5880B))
 863                 goto err_exit;
 864 
 865         chip_name = "AudioPCI97";
 866         chip_vers = "unknown";
 867 
 868         switch (device) {
 869         case ENSONIQ_ES1371:
 870                 chip_name = "AudioPCI97";
 871                 switch (revision) {
 872                 case 0x02:
 873                 case 0x09:
 874                 default:
 875                         chip_vers = "ES1371";
 876                         break;
 877                 case 0x04:
 878                 case 0x06:
 879                 case 0x08:
 880                         chip_vers = "ES1373";
 881                         break;
 882                 case 0x07:
 883                         chip_vers = "ES5880";
 884                         break;
 885                 }
 886                 break;
 887 
 888         case ENSONIQ_ES5880:
 889                 chip_name = "SB PCI128";
 890                 chip_vers = "ES5880";
 891                 break;
 892         case ENSONIQ_ES5880A:
 893                 chip_name = "SB PCI128";
 894                 chip_vers = "ES5880A";
 895                 break;
 896         case ENSONIQ_ES5880B:
 897                 chip_name = "SB PCI128";
 898                 chip_vers = "ES5880B";
 899                 break;
 900 
 901         case ECTIVA_ES1938:
 902                 chip_name = "AudioPCI";
 903                 chip_vers = "ES1938";
 904                 break;
 905         }
 906 
 907         dev->revision = revision;
 908         dev->devid = device;
 909 
 910         dev->osdev = audio_dev_alloc(dip, 0);
 911         if (dev->osdev == NULL) {
 912                 goto err_exit;
 913         }
 914 
 915         audio_dev_set_description(dev->osdev, chip_name);
 916         audio_dev_set_version(dev->osdev, chip_vers);
 917 
 918         /* set the PCI latency */
 919         if ((audioens_latency == 32) || (audioens_latency == 64) ||
 920             (audioens_latency == 96))
 921                 pci_config_put8(pcih, PCI_CONF_LATENCY_TIMER,
 922                     audioens_latency);
 923 
 924         /* activate the device */
 925         pci_command = pci_config_get16(pcih, PCI_CONF_COMM);
 926         pci_command |= PCI_COMM_ME | PCI_COMM_IO;
 927         pci_config_put16(pcih, PCI_CONF_COMM, pci_command);
 928 
 929         /* map registers */
 930         if (ddi_regs_map_setup(dip, 1, &dev->regs, 0, 0, &acc_attr,
 931             &dev->acch) != DDI_SUCCESS) {
 932                 audio_dev_warn(dev->osdev, "can't map registers");
 933                 goto err_exit;
 934         }
 935 
 936         /* This allocates and configures the engines */
 937         if (audioens_init(dev) != DDI_SUCCESS) {
 938                 audio_dev_warn(dev->osdev, "can't init device");
 939                 goto err_exit;
 940         }
 941 
 942         pci_config_teardown(&pcih);
 943 
 944         ddi_report_dev(dip);
 945 
 946         return (DDI_SUCCESS);
 947 
 948 err_exit:
 949         pci_config_teardown(&pcih);
 950 
 951         audioens_destroy(dev);
 952 
 953         return (DDI_FAILURE);
 954 }
 955 
 956 int
 957 audioens_detach(audioens_dev_t *dev)
 958 {
 959         int tmp;
 960 
 961         /* first unregister us from the DDI framework, might be busy */
 962         if (audio_dev_unregister(dev->osdev) != DDI_SUCCESS)
 963                 return (DDI_FAILURE);
 964 
 965         mutex_enter(&dev->mutex);
 966 
 967         tmp = GET8(dev, CONC_bSERCTL_OFF) &
 968             ~(CONC_SERCTL_DAC2IE | CONC_SERCTL_DAC1IE | CONC_SERCTL_ADCIE);
 969         PUT8(dev, CONC_bSERCTL_OFF, tmp);
 970         PUT8(dev, CONC_bSERCTL_OFF, tmp);
 971         PUT8(dev, CONC_bSERCTL_OFF, tmp);
 972         PUT8(dev, CONC_bSERCTL_OFF, tmp);
 973 
 974         tmp = GET8(dev, CONC_bDEVCTL_OFF) &
 975             ~(CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_DAC1_EN);
 976         PUT8(dev, CONC_bDEVCTL_OFF, tmp);
 977         PUT8(dev, CONC_bDEVCTL_OFF, tmp);
 978         PUT8(dev, CONC_bDEVCTL_OFF, tmp);
 979         PUT8(dev, CONC_bDEVCTL_OFF, tmp);
 980 
 981         mutex_exit(&dev->mutex);
 982 
 983         audioens_destroy(dev);
 984 
 985         return (DDI_SUCCESS);
 986 }
 987 
 988 static int
 989 audioens_resume(audioens_dev_t *dev)
 990 {
 991         /* reinitialize hardware */
 992         audioens_init_hw(dev);
 993 
 994         /* restore AC97 state */
 995         ac97_reset(dev->ac97);
 996 
 997         audio_dev_resume(dev->osdev);
 998 
 999         return (DDI_SUCCESS);
1000 }
1001 
1002 static int
1003 audioens_suspend(audioens_dev_t *dev)
1004 {
1005         audio_dev_suspend(dev->osdev);
1006 
1007         return (DDI_SUCCESS);
1008 }
1009 
1010 static int
1011 audioens_quiesce(dev_info_t *dip)
1012 {
1013         audioens_dev_t  *dev;
1014         uint8_t         tmp;
1015 
1016         if ((dev = ddi_get_driver_private(dip)) == NULL) {
1017                 return (DDI_FAILURE);
1018         }
1019 
1020         /* This disables all DMA engines and interrupts */
1021         tmp = GET8(dev, CONC_bSERCTL_OFF) &
1022             ~(CONC_SERCTL_DAC2IE | CONC_SERCTL_DAC1IE | CONC_SERCTL_ADCIE);
1023         PUT8(dev, CONC_bSERCTL_OFF, tmp);
1024         PUT8(dev, CONC_bSERCTL_OFF, tmp);
1025         PUT8(dev, CONC_bSERCTL_OFF, tmp);
1026         PUT8(dev, CONC_bSERCTL_OFF, tmp);
1027 
1028         tmp = GET8(dev, CONC_bDEVCTL_OFF) &
1029             ~(CONC_DEVCTL_DAC2_EN | CONC_DEVCTL_ADC_EN | CONC_DEVCTL_DAC1_EN);
1030         PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1031         PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1032         PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1033         PUT8(dev, CONC_bDEVCTL_OFF, tmp);
1034 
1035         return (DDI_SUCCESS);
1036 }
1037 
1038 
1039 static int
1040 audioens_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1041 {
1042         audioens_dev_t *dev;
1043 
1044         switch (cmd) {
1045         case DDI_ATTACH:
1046                 return (audioens_attach(dip));
1047 
1048         case DDI_RESUME:
1049                 if ((dev = ddi_get_driver_private(dip)) == NULL) {
1050                         return (DDI_FAILURE);
1051                 }
1052                 return (audioens_resume(dev));
1053 
1054         default:
1055                 return (DDI_FAILURE);
1056         }
1057 }
1058 
1059 static int
1060 audioens_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1061 {
1062         audioens_dev_t *dev;
1063 
1064         if ((dev = ddi_get_driver_private(dip)) == NULL) {
1065                 return (DDI_FAILURE);
1066         }
1067 
1068         switch (cmd) {
1069         case DDI_DETACH:
1070                 return (audioens_detach(dev));
1071 
1072         case DDI_SUSPEND:
1073                 return (audioens_suspend(dev));
1074         default:
1075                 return (DDI_FAILURE);
1076         }
1077 }
1078 
1079 static int audioens_ddi_attach(dev_info_t *, ddi_attach_cmd_t);
1080 static int audioens_ddi_detach(dev_info_t *, ddi_detach_cmd_t);
1081 
1082 static struct dev_ops audioens_dev_ops = {
1083         DEVO_REV,               /* rev */
1084         0,                      /* refcnt */
1085         NULL,                   /* getinfo */
1086         nulldev,                /* identify */
1087         nulldev,                /* probe */
1088         audioens_ddi_attach,    /* attach */
1089         audioens_ddi_detach,    /* detach */
1090         nodev,                  /* reset */
1091         NULL,                   /* cb_ops */
1092         NULL,                   /* bus_ops */
1093         NULL,                   /* power */
1094         audioens_quiesce,       /* quiesce */
1095 };
1096 
1097 static struct modldrv audioens_modldrv = {
1098         &mod_driverops,                     /* drv_modops */
1099         "Ensoniq 1371/1373 Audio",      /* linkinfo */
1100         &audioens_dev_ops,          /* dev_ops */
1101 };
1102 
1103 static struct modlinkage modlinkage = {
1104         MODREV_1,
1105         { &audioens_modldrv, NULL }
1106 };
1107 
1108 int
1109 _init(void)
1110 {
1111         int     rv;
1112 
1113         audio_init_ops(&audioens_dev_ops, DRVNAME);
1114         if ((rv = mod_install(&modlinkage)) != 0) {
1115                 audio_fini_ops(&audioens_dev_ops);
1116         }
1117         return (rv);
1118 }
1119 
1120 int
1121 _fini(void)
1122 {
1123         int     rv;
1124 
1125         if ((rv = mod_remove(&modlinkage)) == 0) {
1126                 audio_fini_ops(&audioens_dev_ops);
1127         }
1128         return (rv);
1129 }
1130 
1131 int
1132 _info(struct modinfo *modinfop)
1133 {
1134         return (mod_info(&modlinkage, modinfop));
1135 }