/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Purpose: Definitions for the Creative Audigy LS driver */ /* * This file is part of Open Sound System * * Copyright (C) 4Front Technologies 1996-2009. * * This software is released under CDDL 1.0 source license. * See the COPYING file included in the main directory of this source * distribution for the license terms and conditions. */ #ifndef AUDIGYLS_H #define AUDIGYLS_H #define AUDIGYLS_NAME "audiols" #define AUDIGYLS_NUM_PORT 2 #define AUDIGYLS_PLAY_PORT 0 #define AUDIGYLS_REC_PORT 1 /* * Number of fragments must be multiple of 2 because the * hardware supports only full and half buffer interrupts. In * addition it looks like 8 fragments is the minimum. */ #define AUDIGYLS_NUM_FRAGS (8*2) #define PCI_VENDOR_ID_CREATIVE 0x1102 #define PCI_DEVICE_ID_CREATIVE_AUDIGYLS 0x0007 #define AUDIGYLS_MAX_INTRS 256 #define AUDIGYLS_MIN_INTRS 24 #define AUDIGYLS_INTRS 100 /* * PCI registers */ #define PR 0x00 #define DR 0x04 #define IPR 0x08 #define IER 0x0C #define INTR_PCI (1 << 0) #define INTR_TXA (1 << 1) /* midi-a tx */ #define INTR_RXA (1 << 2) /* midi-a rx */ #define INTR_IT2 (1 << 3) /* timer 2, 44.1 kHz */ #define INTR_IT1 (1 << 4) /* timer 1, 192 kHz */ #define INTR_SS_ (1 << 5) /* spdif status */ #define INTR_SRT (1 << 6) /* sample rate status */ #define INTR_GP (1 << 7) #define INTR_AI (1 << 8) /* audio pending interrupt */ #define INTR_I2CDAC (1 << 9) #define INTR_I2CEE (1 << 10) #define INTR_SPI (1 << 11) #define INTR_SPF (1 << 12) #define INTR_SUO (1 << 13) #define INTR_SUI (1 << 14) #define INTR_TXB (1 << 16) /* midi-b tx */ #define INTR_RXB (1 << 17) /* midi-b rx */ #define HC 0x14 #define HC_PF (1 << 11) /* play fmt 1 = 32b, 0 = 16b */ #define HC_RF (1 << 10) /* rec fmt 1 = 32b, 0 = 16b */ #define HC_AC97 (1 << 3) #define HC_AEN (1 << 0) /* audio enable */ #define GPIO 0x18 #define AC97D 0x1C #define AC97A 0x1E /* * Indirect registers */ #define PTBA 0x000 /* gather play table base address */ #define PTBS 0x001 /* gather play table buffer size */ #define PTCA 0x002 /* gather play table current addr ptr */ #define PFBA 0x004 /* play fifo base address */ #define PFBS 0x005 /* play fifo buffer size */ #define CPFA 0x006 /* current play fifo address */ #define PFEA 0x007 /* play fifo end address */ #define CPCAV 0x008 /* current play fifo offset/cache sz valid */ #define RFBA 0x010 /* record fifo base address */ #define RFBS 0x011 /* record fifo buffer size */ #define CRFA 0x012 /* current record fifo address */ #define CRCAV 0x013 /* current record fifo offset/cache sz valid */ #define CDL 0x020 /* play fifo cache data, 0x20-0x2f */ #define SA 0x040 /* start audio */ #define SCS3 0x041 #define SCS0 0x042 #define SCS1 0x043 #define SCS2 0x044 #define SPC 0x045 /* spdif output control */ #define WMARK 0x046 /* test purposes only */ #define SPSC 0x049 /* spdif input control */ #define RCD 0x050 /* record cache data, 0x50-0x5f */ #define P17RECSEL 0x060 /* record fifo map address */ #define P17RECVOLL 0x061 /* record fifo volume control (lo) */ #define P17RECVOLH 0x062 /* record fifo volume control (hi) */ #define HMIXMAP_SPDIF 0x063 /* spdif router map address */ #define SMIXMAP_SPDIF 0x064 /* spdif router map address */ #define MIXCTL_SPDIF 0x065 /* spdif mixer control */ #define MIXVOL_SPDIF 0x066 /* spdif mixer input volume control */ #define HMIXMAP_I2S 0x067 /* i2s router map address */ #define SMIXMAP_I2S 0x068 /* i2s router map address */ #define MIXCTL_I2S 0x069 /* i2s mixer control */ #define MIXVOL_I2S 0x06a /* i2s mixer input volume control */ /* MIDI UART */ #define MUDATA 0x06c /* midi uart a data */ #define MUCMDA 0x06d /* midi uart a command/status */ #define MUDATB 0x06e /* midi uart b data */ #define MUCMDB 0x06f /* midi uart b command/status */ #define SRT 0x070 /* sample rate tracker status */ #define SRCTL 0x071 /* sample rate control */ #define AUDCTL 0x072 /* audio output control */ #define CHIP_ID 0x074 /* chip id */ #define AIE 0x075 /* audio interrupt enable */ #define AIP 0x076 /* audio interrupt */ #define WALL192 0x077 /* wall clock @ 192 kHz */ #define WALL441 0x078 /* wall clock @ 44.1 kHz */ #define IT 0x079 /* interval timer */ #define SPI 0x07a /* spi interface */ #define I2C_A 0x07b /* i2c address */ #define I2C_0 0x07c /* i2c data */ #define I2C_1 0x07d /* i2c data */ /* * Audio interrupt bits */ #define AI_PFH 0x00000001 /* playback fifo half loop */ #define AI_PFF 0x00000010 /* playback fifo loop */ #define AI_TFH 0x00000100 /* playback table half loop */ #define AI_TFF 0x00001000 /* playback table loop */ #define AI_RFH 0x00010000 /* capture table half loop */ #define AI_RFF 0x00100000 /* capture fifo loop */ #define AI_EAI 0x01000000 /* enables audio end interrupt */ #define SA_48K 0 #define SA_44K 1 #define SA_96K 2 #define SA_192K 3 #define SA_MIX_OUT_EN(ch) (1 << ((ch) + 28)) #define SA_MIX_IN_EN(ch) (1 << ((ch) + 24)) #define SA_PLAY_RATE(ch, rate) ((rate) << (((ch) * 2) + 16)) #define SA_PLAY_START(ch) (1 << (ch)) #define SA_RECORD_START(ch) (1 << ((ch) + 8)) #define SA_SPA(ch) (1U << (ch)) #define SA_SRA(ch) (1U << ((ch) + 8)) #define RECSEL_SPDIFOUT 0 #define RECSEL_I2SOUT 1 #define RECSEL_SPDIFIN 2 #define RECSEL_I2SIN 3 #define RECSEL_AC97 4 #define RECSEL_SRC 5 typedef struct _audigyls_dev_t audigyls_dev_t; typedef struct _audigyls_port_t audigyls_port_t; typedef enum { CTL_FRONT = 0, CTL_SURROUND, CTL_CENTER, CTL_LFE, CTL_RECORDVOL, CTL_MONGAIN, CTL_RECSRC, CTL_SPREAD, CTL_LOOP, CTL_NUM /* must be last */ } audigyls_ctrl_num_t; typedef struct audigyls_ctrl { audigyls_dev_t *dev; audio_ctrl_t *ctrl; audigyls_ctrl_num_t num; uint64_t val; } audigyls_ctrl_t; struct _audigyls_port_t { audigyls_dev_t *dev; audio_engine_t *engine; int direction; int started; boolean_t active; unsigned fragfr; unsigned fragsz; unsigned nchan; ddi_dma_handle_t buf_dmah; /* dma for buffers */ ddi_acc_handle_t buf_acch; uint32_t buf_paddr; caddr_t buf_kaddr; uint32_t buf_size; uint32_t buf_frames; /* Buffer size in frames */ uint32_t offset; int syncdir; uint64_t count; }; struct _audigyls_dev_t { dev_info_t *dip; audio_dev_t *adev; ac97_t *ac97; kstat_t *ksp; unsigned intrs; unsigned timer; int nactive; /* Num active ports */ char digital_enable; /* Orange combo-jack mode */ boolean_t suspended; ddi_acc_handle_t pcih; ddi_acc_handle_t regsh; caddr_t base; kmutex_t mutex; /* For normal locking */ kmutex_t low_mutex; /* For low level routines */ ddi_intr_handle_t ih; audigyls_port_t *port[AUDIGYLS_NUM_PORT]; audigyls_ctrl_t controls[CTL_NUM]; ac97_ctrl_t *ac97_recgain; ac97_ctrl_t *ac97_recsrc; uint64_t recmask; }; #define INB(dev, reg) \ ddi_get8(dev->regsh, (void *)(dev->base + reg)) #define OUTB(dev, reg, val) \ ddi_put8(dev->regsh, (void *)(dev->base + reg), (val)) #define INW(dev, reg) \ ddi_get16(dev->regsh, (void *)(dev->base + reg)) #define OUTW(dev, reg, val) \ ddi_put16(dev->regsh, (void *)(dev->base + reg), (val)) #define INL(dev, reg) \ ddi_get32(dev->regsh, (void *)(dev->base + reg)) #define OUTL(dev, reg, val) \ ddi_put32(dev->regsh, (void *)(dev->base + reg), (val)) #define AUDIGYLS_KIOP(X) ((kstat_intr_t *)(X->ksp->ks_data)) #endif /* AUDIGYLS_H */