188447a0Garrett D'Amore/*
288447a0Garrett D'Amore * CDDL HEADER START
388447a0Garrett D'Amore *
488447a0Garrett D'Amore * The contents of this file are subject to the terms of the
588447a0Garrett D'Amore * Common Development and Distribution License (the "License").
688447a0Garrett D'Amore * You may not use this file except in compliance with the License.
788447a0Garrett D'Amore *
888447a0Garrett D'Amore * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
988447a0Garrett D'Amore * or http://www.opensolaris.org/os/licensing.
1088447a0Garrett D'Amore * See the License for the specific language governing permissions
1188447a0Garrett D'Amore * and limitations under the License.
1288447a0Garrett D'Amore *
1388447a0Garrett D'Amore * When distributing Covered Code, include this CDDL HEADER in each
1488447a0Garrett D'Amore * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1588447a0Garrett D'Amore * If applicable, add the following below this CDDL HEADER, with the
1688447a0Garrett D'Amore * fields enclosed by brackets "[]" replaced with your own identifying
1788447a0Garrett D'Amore * information: Portions Copyright [yyyy] [name of copyright owner]
1888447a0Garrett D'Amore *
1988447a0Garrett D'Amore * CDDL HEADER END
2088447a0Garrett D'Amore */
2188447a0Garrett D'Amore/*
22239924dGarrett D'Amore * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
235b16275Garrett D'Amore * Copyright 2016 Garrett D'Amore <garrett@damore.org>
2488447a0Garrett D'Amore */
2588447a0Garrett D'Amore/*
2688447a0Garrett D'Amore * Purpose: Creative/Ensoniq AudioPCI97  driver (ES1371/ES1373)
2788447a0Garrett D'Amore *
2888447a0Garrett D'Amore * This driver is used with the original Ensoniq AudioPCI97 card and many
2988447a0Garrett D'Amore * PCI based Sound Blaster cards by Creative Technologies. For example
3088447a0Garrett D'Amore * Sound Blaster PCI128 and Creative/Ectiva EV1938.
3188447a0Garrett D'Amore */
3288447a0Garrett D'Amore
3388447a0Garrett D'Amore/*
3488447a0Garrett D'Amore * This file is part of Open Sound System
3588447a0Garrett D'Amore *
3688447a0Garrett D'Amore * Copyright (C) 4Front Technologies 1996-2008.
3788447a0Garrett D'Amore *
3888447a0Garrett D'Amore * This software is released under CDDL 1.0 source license.
3988447a0Garrett D'Amore * See the COPYING file included in the main directory of this source
4088447a0Garrett D'Amore * distribution for the license terms and conditions.
4188447a0Garrett D'Amore */
4288447a0Garrett D'Amore
4388447a0Garrett D'Amore#include <sys/audio/audio_driver.h>
4488447a0Garrett D'Amore#include <sys/audio/ac97.h>
4588447a0Garrett D'Amore#include <sys/note.h>
4688447a0Garrett D'Amore#include <sys/pci.h>
475b16275Garrett D'Amore
485b16275Garrett D'Amore/*
495b16275Garrett D'Amore * For VMWare platforms, we have to utilize the (emulated) hardware interrupts
505b16275Garrett D'Amore * of the device.  This is necessary for audio playback to function, as
515b16275Garrett D'Amore * the toggling of the interrupt bits apparently triggers logic inside the
525b16275Garrett D'Amore * emulated device.  So we need to detect this platform, and conditionally
535b16275Garrett D'Amore * wire up the interrupt handler.
545b16275Garrett D'Amore */
555b16275Garrett D'Amore#ifdef __x86
565b16275Garrett D'Amore#include <sys/x86_archext.h>
575b16275Garrett D'Amore#endif
585b16275Garrett D'Amore
5988447a0Garrett D'Amore#include "audioens.h"
6088447a0Garrett D'Amore
6188447a0Garrett D'Amore/*
6288447a0Garrett D'Amore * Set the latency to 32, 64, 96, 128 clocks - some APCI97 devices exhibit
6388447a0Garrett D'Amore * garbled audio in some cases and setting the latency to higer values fixes it
6488447a0Garrett D'Amore * Values: 32, 64, 96, 128 - Default: 64 (or defined by bios)
6588447a0Garrett D'Amore */
6688447a0Garrett D'Amoreint audioens_latency = 0;
6788447a0Garrett D'Amore
6888447a0Garrett D'Amore/*
6988447a0Garrett D'Amore * Enable SPDIF port on SoundBlaster 128D or Sound Blaster Digital-4.1 models
7088447a0Garrett D'Amore * Values: 1=Enable 0=Disable Default: 0
7188447a0Garrett D'Amore */
7288447a0Garrett D'Amoreint audioens_spdif = 0;
7388447a0Garrett D'Amore
7488447a0Garrett D'Amore/*
7588447a0Garrett D'Amore * Note: Latest devices can support SPDIF with AC3 pass thru.
7688447a0Garrett D'Amore * However, in order to do this, one of the two DMA engines must be
7788447a0Garrett D'Amore * dedicated to this, which would prevent the card from supporting 4
7888447a0Garrett D'Amore * channel audio.  For now we don't bother with the AC3 pass through
7988447a0Garrett D'Amore * mode, and instead just focus on 4 channel support.  In the future,
8088447a0Garrett D'Amore * this could be selectable via a property.
8188447a0Garrett D'Amore */
8288447a0Garrett D'Amore
8388447a0Garrett D'Amore#define	ENSONIQ_VENDOR_ID	0x1274
8488447a0Garrett D'Amore#define	CREATIVE_VENDOR_ID	0x1102
8588447a0Garrett D'Amore#define	ECTIVA_VENDOR_ID	0x1102
8688447a0Garrett D'Amore#define	ENSONIQ_ES1371		0x1371
8788447a0Garrett D'Amore#define	ENSONIQ_ES5880		0x8001
8888447a0Garrett D'Amore#define	ENSONIQ_ES5880A		0x8002
8988447a0Garrett D'Amore#define	ENSONIQ_ES5880B		0x5880
9088447a0Garrett D'Amore#define	ECTIVA_ES1938		0x8938
9188447a0Garrett D'Amore
9288447a0Garrett D'Amore#define	DEFRATE			48000
9388447a0Garrett D'Amore#define	DRVNAME			"audioens"
9488447a0Garrett D'Amore
9588447a0Garrett D'Amoretypedef struct audioens_port
9688447a0Garrett D'Amore{
9788447a0Garrett D'Amore	/* Audio parameters */
9888447a0Garrett D'Amore	int			speed;
9988447a0Garrett D'Amore
10088447a0Garrett D'Amore	int			num;
10188447a0Garrett D'Amore#define	PORT_DAC		0
10288447a0Garrett D'Amore#define	PORT_ADC		1
10388447a0Garrett D'Amore#define	PORT_MAX		PORT_ADC
10488447a0Garrett D'Amore
10588447a0Garrett D'Amore	caddr_t			kaddr;
10688447a0Garrett D'Amore	uint32_t		paddr;
10788447a0Garrett D'Amore	ddi_acc_handle_t	acch;
10888447a0Garrett D'Amore	ddi_dma_handle_t	dmah;
10988447a0Garrett D'Amore	int			nchan;
11088447a0Garrett D'Amore	unsigned		nframes;
1115b16275Garrett D'Amore	unsigned		iframes;
11288447a0Garrett D'Amore	unsigned		frameno;
11388447a0Garrett D'Amore	uint64_t		count;
11488447a0Garrett D'Amore
11588447a0Garrett D'Amore	struct audioens_dev	*dev;
1165b16275Garrett D'Amore	audio_engine_t		*engine;
11788447a0Garrett D'Amore} audioens_port_t;
11888447a0Garrett D'Amore
11988447a0Garrett D'Amoretypedef struct audioens_dev
12088447a0Garrett D'Amore{
12188447a0Garrett D'Amore	audio_dev_t		*osdev;
12288447a0Garrett D'Amore	kmutex_t		mutex;
12388447a0Garrett D'Amore	uint16_t		devid;
12488447a0Garrett D'Amore	uint8_t			revision;
12588447a0Garrett D'Amore	dev_info_t		*dip;
12688447a0Garrett D'Amore
12788447a0Garrett D'Amore	audioens_port_t		port[PORT_MAX + 1];
12888447a0Garrett D'Amore
12988447a0Garrett D'Amore	ac97_t			*ac97;
13088447a0Garrett D'Amore
13188447a0Garrett D'Amore	caddr_t			regs;
13288447a0Garrett D'Amore	ddi_acc_handle_t	acch;
1335b16275Garrett D'Amore
1345b16275Garrett D'Amore	boolean_t		suspended;
1355b16275Garrett D'Amore
1365b16275Garrett D'Amore#ifdef __x86
1375b16275Garrett D'Amore	boolean_t		useintr;
1385b16275Garrett D'Amore	ddi_intr_handle_t	intrh;
1395b16275Garrett D'Amore	uint_t			intrpri;
1405b16275Garrett D'Amore#endif
14188447a0Garrett D'Amore} audioens_dev_t;
14288447a0Garrett D'Amore
14388447a0Garrett D'Amorestatic ddi_device_acc_attr_t acc_attr = {
14488447a0Garrett D'Amore	DDI_DEVICE_ATTR_V0,
14588447a0Garrett D'Amore	DDI_STRUCTURE_LE_ACC,
14688447a0Garrett D'Amore	DDI_STRICTORDER_ACC
14788447a0Garrett D'Amore};
14888447a0Garrett D'Amore
14988447a0Garrett D'Amorestatic ddi_device_acc_attr_t buf_attr = {
15088447a0Garrett D'Amore	DDI_DEVICE_ATTR_V0,
15188447a0Garrett D'Amore	DDI_NEVERSWAP_ACC,
15288447a0Garrett D'Amore	DDI_STRICTORDER_ACC
15388447a0Garrett D'Amore};
15488447a0Garrett D'Amore
15588447a0Garrett D'Amorestatic ddi_dma_attr_t dma_attr = {
15688447a0Garrett D'Amore	DMA_ATTR_VERSION,	/* dma_attr_version */
15788447a0Garrett D'Amore	0x0,			/* dma_attr_addr_lo */
158