1139749Simp/*- 2197404Sjoel * Copyright (c) 1999 Russell Cattelan <cattelan@thebarn.com> 3197404Sjoel * Copyright (c) 1998 Joachim Kuebart <joachim.kuebart@gmx.net> 4197404Sjoel * All rights reserved. 550724Scg * 6197404Sjoel * Redistribution and use in source and binary forms, with or without 7197404Sjoel * modification, are permitted provided that the following conditions 8197404Sjoel * are met: 9197404Sjoel * 1. Redistributions of source code must retain the above copyright 10197404Sjoel * notice, this list of conditions and the following disclaimer. 11197404Sjoel * 2. Redistributions in binary form must reproduce the above copyright 12197404Sjoel * notice, this list of conditions and the following disclaimer in the 13197404Sjoel * documentation and/or other materials provided with the distribution. 14197404Sjoel * 15197404Sjoel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16197404Sjoel * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17197404Sjoel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18197404Sjoel * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19197404Sjoel * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20197404Sjoel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21197404Sjoel * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22197404Sjoel * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23197404Sjoel * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24197404Sjoel * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25197404Sjoel * SUCH DAMAGE. 26197404Sjoel */ 27197404Sjoel 28197404Sjoel/*- 29119853Scg * Copyright (c) 1999 Cameron Grant <cg@freebsd.org> 30197404Sjoel * All rights reserved. 3150724Scg * 3250724Scg * Redistribution and use in source and binary forms, with or without 3350724Scg * modification, are permitted provided that the following conditions 3450724Scg * are met: 3550724Scg * 3650724Scg * 1. Redistributions of source code must retain the above copyright 3750724Scg * notice, this list of conditions and the following disclaimer. 3850724Scg * 3950724Scg * 2. Redistributions in binary form must reproduce the above copyright 4050724Scg * notice, this list of conditions and the following disclaimer in 4150724Scg * the documentation and/or other materials provided with the 4250724Scg * distribution. 4350724Scg * 4450724Scg * 3. All advertising materials mentioning features or use of this 4550724Scg * software must display the following acknowledgement: 4650724Scg * This product includes software developed by Joachim Kuebart. 4750724Scg * 4850724Scg * 4. The name of the author may not be used to endorse or promote 4950724Scg * products derived from this software without specific prior 5050724Scg * written permission. 5150724Scg * 5250724Scg * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 5350724Scg * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 5450724Scg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 5550724Scg * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 5650724Scg * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 5750724Scg * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 5850724Scg * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 5950724Scg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 6050724Scg * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 6150724Scg * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 6250724Scg * OF THE POSSIBILITY OF SUCH DAMAGE. 6350724Scg */ 6450724Scg 6553413Sroger/* 66197404Sjoel * Support the ENSONIQ AudioPCI board and Creative Labs SoundBlaster PCI 67197404Sjoel * boards based on the ES1370, ES1371 and ES1373 chips. 68197404Sjoel * 6953413Sroger * Part of this code was heavily inspired by the linux driver from 7053413Sroger * Thomas Sailer (sailer@ife.ee.ethz.ch) 7154831Scg * Just about everything has been touched and reworked in some way but 7254831Scg * the all the underlying sequences/timing/register values are from 7353413Sroger * Thomas' code. 7453413Sroger*/ 7553413Sroger 76193640Sariff#ifdef HAVE_KERNEL_OPTION_HEADERS 77193640Sariff#include "opt_snd.h" 78193640Sariff#endif 79193640Sariff 8053465Scg#include <dev/sound/pcm/sound.h> 8153465Scg#include <dev/sound/pcm/ac97.h> 8253465Scg#include <dev/sound/pci/es137x.h> 8350724Scg 84119287Simp#include <dev/pci/pcireg.h> 85119287Simp#include <dev/pci/pcivar.h> 8650724Scg 8753413Sroger#include <sys/sysctl.h> 8853413Sroger 8970134Scg#include "mixer_if.h" 9070134Scg 9182180ScgSND_DECLARE_FILE("$FreeBSD: releng/11.0/sys/dev/sound/pci/es137x.c 297000 2016-03-18 01:28:41Z jhibbits $"); 9282180Scg 9350724Scg#define MEM_MAP_REG 0x14 9450724Scg 9550724Scg/* PCI IDs of supported chips */ 9650724Scg#define ES1370_PCI_ID 0x50001274 9753413Sroger#define ES1371_PCI_ID 0x13711274 9856154Speter#define ES1371_PCI_ID2 0x13713274 9976086Scg#define CT5880_PCI_ID 0x58801274 100119548Sorion#define CT4730_PCI_ID 0x89381102 10150724Scg 10278033Scg#define ES1371REV_ES1371_A 0x02 10376086Scg#define ES1371REV_ES1371_B 0x09 10476086Scg 10576086Scg#define ES1371REV_ES1373_8 0x08 10676086Scg#define ES1371REV_ES1373_A 0x04 10776086Scg#define ES1371REV_ES1373_B 0x06 10876086Scg 10976086Scg#define ES1371REV_CT5880_A 0x07 11076086Scg 11176086Scg#define CT5880REV_CT5880_C 0x02 11276086Scg#define CT5880REV_CT5880_D 0x03 11395678Scg#define CT5880REV_CT5880_E 0x04 11476086Scg 115119548Sorion#define CT4730REV_CT4730_A 0x00 116119548Sorion 11784658Scg#define ES_DEFAULT_BUFSZ 4096 11859019Scg 119152419Sariff/* 2 DAC for playback, 1 ADC for record */ 120152419Sariff#define ES_DAC1 0 121152419Sariff#define ES_DAC2 1 122152419Sariff#define ES_ADC 2 123152419Sariff#define ES_NCHANS 3 124152419Sariff 125167648Sariff#define ES_DMA_SEGS_MIN 2 126167648Sariff#define ES_DMA_SEGS_MAX 256 127167648Sariff#define ES_BLK_MIN 64 128167648Sariff#define ES_BLK_ALIGN (~(ES_BLK_MIN - 1)) 129167648Sariff 130152419Sariff#define ES1370_DAC1_MINSPEED 5512 131152419Sariff#define ES1370_DAC1_MAXSPEED 44100 132152419Sariff 13350724Scg/* device private data */ 13450724Scgstruct es_info; 13550724Scg 13655209Scgstruct es_chinfo { 13750724Scg struct es_info *parent; 13874763Scg struct pcm_channel *channel; 13974763Scg struct snd_dbuf *buffer; 140152419Sariff struct pcmchan_caps caps; 141152419Sariff int dir, num, index; 142164614Sariff uint32_t fmt, blksz, blkcnt, bufsz; 143164614Sariff uint32_t ptr, prevptr; 144164614Sariff int active; 14555209Scg}; 14650724Scg 147152419Sariff/* 148152419Sariff * 32bit Ensoniq Configuration (es->escfg). 149152419Sariff * ---------------------------------------- 150152419Sariff * 151152419Sariff * +-------+--------+------+------+---------+--------+---------+---------+ 152152419Sariff * len | 16 | 1 | 1 | 1 | 2 | 2 | 1 | 8 | 153152419Sariff * +-------+--------+------+------+---------+--------+---------+---------+ 154152419Sariff * | fixed | single | | | | | is | general | 155152419Sariff * | rate | pcm | DACx | DACy | numplay | numrec | es1370? | purpose | 156152419Sariff * | | mixer | | | | | | | 157152419Sariff * +-------+--------+------+------+---------+--------+---------+---------+ 158152419Sariff */ 159152419Sariff#define ES_FIXED_RATE(cfgv) \ 160152419Sariff (((cfgv) & 0xffff0000) >> 16) 161152419Sariff#define ES_SET_FIXED_RATE(cfgv, nv) \ 162152419Sariff (((cfgv) & ~0xffff0000) | (((nv) & 0xffff) << 16)) 163152419Sariff#define ES_SINGLE_PCM_MIX(cfgv) \ 164152419Sariff (((cfgv) & 0x8000) >> 15) 165152419Sariff#define ES_SET_SINGLE_PCM_MIX(cfgv, nv) \ 166152419Sariff (((cfgv) & ~0x8000) | (((nv) ? 1 : 0) << 15)) 167152419Sariff#define ES_DAC_FIRST(cfgv) \ 168152419Sariff (((cfgv) & 0x4000) >> 14) 169152419Sariff#define ES_SET_DAC_FIRST(cfgv, nv) \ 170152419Sariff (((cfgv) & ~0x4000) | (((nv) & 0x1) << 14)) 171152419Sariff#define ES_DAC_SECOND(cfgv) \ 172152419Sariff (((cfgv) & 0x2000) >> 13) 173152419Sariff#define ES_SET_DAC_SECOND(cfgv, nv) \ 174152419Sariff (((cfgv) & ~0x2000) | (((nv) & 0x1) << 13)) 175152419Sariff#define ES_NUMPLAY(cfgv) \ 176152419Sariff (((cfgv) & 0x1800) >> 11) 177152419Sariff#define ES_SET_NUMPLAY(cfgv, nv) \ 178152419Sariff (((cfgv) & ~0x1800) | (((nv) & 0x3) << 11)) 179152419Sariff#define ES_NUMREC(cfgv) \ 180152419Sariff (((cfgv) & 0x600) >> 9) 181152419Sariff#define ES_SET_NUMREC(cfgv, nv) \ 182152419Sariff (((cfgv) & ~0x600) | (((nv) & 0x3) << 9)) 183152419Sariff#define ES_IS_ES1370(cfgv) \ 184152419Sariff (((cfgv) & 0x100) >> 8) 185152419Sariff#define ES_SET_IS_ES1370(cfgv, nv) \ 186152419Sariff (((cfgv) & ~0x100) | (((nv) ? 1 : 0) << 8)) 187152419Sariff#define ES_GP(cfgv) \ 188152419Sariff ((cfgv) & 0xff) 189152419Sariff#define ES_SET_GP(cfgv, nv) \ 190152419Sariff (((cfgv) & ~0xff) | ((nv) & 0xff)) 191152419Sariff 192152419Sariff#define ES_DAC1_ENABLED(cfgv) \ 193152419Sariff (ES_NUMPLAY(cfgv) > 1 || \ 194152419Sariff (ES_NUMPLAY(cfgv) == 1 && ES_DAC_FIRST(cfgv) == ES_DAC1)) 195152419Sariff#define ES_DAC2_ENABLED(cfgv) \ 196152419Sariff (ES_NUMPLAY(cfgv) > 1 || \ 197152419Sariff (ES_NUMPLAY(cfgv) == 1 && ES_DAC_FIRST(cfgv) == ES_DAC2)) 198152419Sariff 199152419Sariff/* 200152419Sariff * DAC 1/2 configuration through kernel hint - hint.pcm.<unit>.dac="val" 201152419Sariff * 202152419Sariff * 0 = Enable both DACs - Default 203152419Sariff * 1 = Enable single DAC (DAC1) 204152419Sariff * 2 = Enable single DAC (DAC2) 205152419Sariff * 3 = Enable both DACs, swap position (DAC2 comes first instead of DAC1) 206152419Sariff */ 207152419Sariff#define ES_DEFAULT_DAC_CFG 0 208152419Sariff 20955209Scgstruct es_info { 21050724Scg bus_space_tag_t st; 21150724Scg bus_space_handle_t sh; 21250724Scg bus_dma_tag_t parent_dmat; 21350724Scg 21465644Scg struct resource *reg, *irq; 21565644Scg int regtype, regid, irqid; 21665644Scg void *ih; 21765644Scg 21859019Scg device_t dev; 21954831Scg int num; 220164614Sariff unsigned int bufsz, blkcnt; 22184658Scg 22250724Scg /* Contents of board's registers */ 223150832Snetchild uint32_t ctrl; 224150832Snetchild uint32_t sctrl; 225152419Sariff uint32_t escfg; 226152419Sariff struct es_chinfo ch[ES_NCHANS]; 227148591Snetchild struct mtx *lock; 228164614Sariff struct callout poll_timer; 229164614Sariff int poll_ticks, polling; 23055209Scg}; 23150724Scg 232150832Snetchild#define ES_LOCK(sc) snd_mtxlock((sc)->lock) 233150832Snetchild#define ES_UNLOCK(sc) snd_mtxunlock((sc)->lock) 234150832Snetchild#define ES_LOCK_ASSERT(sc) snd_mtxassert((sc)->lock) 23554831Scg 23653413Sroger/* prototypes */ 23754831Scgstatic void es_intr(void *); 238150832Snetchildstatic uint32_t es1371_wait_src_ready(struct es_info *); 239164614Sariffstatic void es1371_src_write(struct es_info *, 240164614Sariff unsigned short, unsigned short); 241164614Sariffstatic unsigned int es1371_adc_rate(struct es_info *, unsigned int, int); 242164614Sariffstatic unsigned int es1371_dac_rate(struct es_info *, unsigned int, int); 243150832Snetchildstatic int es1371_init(struct es_info *); 24454831Scgstatic int es1370_init(struct es_info *); 245164614Sariffstatic int es1370_wrcodec(struct es_info *, unsigned char, unsigned char); 24650724Scg 247164614Sariffstatic uint32_t es_fmt[] = { 248193640Sariff SND_FORMAT(AFMT_U8, 1, 0), 249193640Sariff SND_FORMAT(AFMT_U8, 2, 0), 250193640Sariff SND_FORMAT(AFMT_S16_LE, 1, 0), 251193640Sariff SND_FORMAT(AFMT_S16_LE, 2, 0), 25264881Scg 0 25350724Scg}; 254150832Snetchildstatic struct pcmchan_caps es_caps = {4000, 48000, es_fmt, 0}; 25550724Scg 25650724Scgstatic const struct { 25750724Scg unsigned volidx:4; 25850724Scg unsigned left:4; 25950724Scg unsigned right:4; 26050724Scg unsigned stereo:1; 26150724Scg unsigned recmask:13; 26250724Scg unsigned avail:1; 26350724Scg} mixtable[SOUND_MIXER_NRDEVICES] = { 264152419Sariff [SOUND_MIXER_VOLUME] = { 0, 0x0, 0x1, 1, 0x1f7f, 1 }, 26550724Scg [SOUND_MIXER_PCM] = { 1, 0x2, 0x3, 1, 0x0400, 1 }, 26650724Scg [SOUND_MIXER_SYNTH] = { 2, 0x4, 0x5, 1, 0x0060, 1 }, 26750724Scg [SOUND_MIXER_CD] = { 3, 0x6, 0x7, 1, 0x0006, 1 }, 26850724Scg [SOUND_MIXER_LINE] = { 4, 0x8, 0x9, 1, 0x0018, 1 }, 26950724Scg [SOUND_MIXER_LINE1] = { 5, 0xa, 0xb, 1, 0x1800, 1 }, 27050724Scg [SOUND_MIXER_LINE2] = { 6, 0xc, 0x0, 0, 0x0100, 1 }, 27150724Scg [SOUND_MIXER_LINE3] = { 7, 0xd, 0x0, 0, 0x0200, 1 }, 27250724Scg [SOUND_MIXER_MIC] = { 8, 0xe, 0x0, 0, 0x0001, 1 }, 27354831Scg [SOUND_MIXER_OGAIN] = { 9, 0xf, 0x0, 0, 0x0000, 1 } 27454831Scg}; 27550724Scg 276164614Sariffstatic __inline uint32_t 277148591Snetchildes_rd(struct es_info *es, int regno, int size) 278148591Snetchild{ 279148591Snetchild switch (size) { 280148591Snetchild case 1: 281164614Sariff return (bus_space_read_1(es->st, es->sh, regno)); 282148591Snetchild case 2: 283164614Sariff return (bus_space_read_2(es->st, es->sh, regno)); 284148591Snetchild case 4: 285164614Sariff return (bus_space_read_4(es->st, es->sh, regno)); 286148591Snetchild default: 287164614Sariff return (0xFFFFFFFF); 288148591Snetchild } 289148591Snetchild} 290148591Snetchild 291150832Snetchildstatic __inline void 292164614Sariffes_wr(struct es_info *es, int regno, uint32_t data, int size) 293148591Snetchild{ 294148591Snetchild 295148591Snetchild switch (size) { 296148591Snetchild case 1: 297148591Snetchild bus_space_write_1(es->st, es->sh, regno, data); 298148591Snetchild break; 299148591Snetchild case 2: 300148591Snetchild bus_space_write_2(es->st, es->sh, regno, data); 301148591Snetchild break; 302148591Snetchild case 4: 303148591Snetchild bus_space_write_4(es->st, es->sh, regno, data); 304148591Snetchild break; 305148591Snetchild } 306148591Snetchild} 307148591Snetchild 30870134Scg/* -------------------------------------------------------------------- */ 30970134Scg/* The es1370 mixer interface */ 31070134Scg 31150724Scgstatic int 31274763Scges1370_mixinit(struct snd_mixer *m) 31350724Scg{ 314152419Sariff struct es_info *es; 31550724Scg int i; 316164614Sariff uint32_t v; 31750724Scg 318152419Sariff es = mix_getdevinfo(m); 31950724Scg v = 0; 320164614Sariff for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { 321164614Sariff if (mixtable[i].avail) 322164614Sariff v |= (1 << i); 323164614Sariff } 324152419Sariff /* 325152419Sariff * Each DAC1/2 for ES1370 can be controlled independently 326152419Sariff * DAC1 = controlled by synth 327152419Sariff * DAC2 = controlled by pcm 328152419Sariff * This is indeed can confuse user if DAC1 become primary playback 329152419Sariff * channel. Try to be smart and combine both if necessary. 330152419Sariff */ 331152419Sariff if (ES_SINGLE_PCM_MIX(es->escfg)) 332152419Sariff v &= ~(1 << SOUND_MIXER_SYNTH); 33350724Scg mix_setdevs(m, v); 33450724Scg v = 0; 335164614Sariff for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { 336164614Sariff if (mixtable[i].recmask) 337164614Sariff v |= (1 << i); 338164614Sariff } 339152419Sariff if (ES_SINGLE_PCM_MIX(es->escfg)) /* ditto */ 340152419Sariff v &= ~(1 << SOUND_MIXER_SYNTH); 34150724Scg mix_setrecdevs(m, v); 342164614Sariff return (0); 34350724Scg} 34450724Scg 34550724Scgstatic int 34674763Scges1370_mixset(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) 34750724Scg{ 348150832Snetchild struct es_info *es; 349152419Sariff int l, r, rl, rr, set_dac1; 35050724Scg 351164614Sariff if (!mixtable[dev].avail) 352164614Sariff return (-1); 35350724Scg l = left; 354164614Sariff r = (mixtable[dev].stereo) ? right : l; 355164614Sariff if (mixtable[dev].left == 0xf) 356164614Sariff rl = (l < 2) ? 0x80 : 7 - (l - 2) / 14; 357164614Sariff else 358206033Sjoel rl = (l < 7) ? 0x80 : 31 - (l - 7) / 3; 359150832Snetchild es = mix_getdevinfo(m); 360150832Snetchild ES_LOCK(es); 361152419Sariff if (dev == SOUND_MIXER_PCM && (ES_SINGLE_PCM_MIX(es->escfg)) && 362164614Sariff ES_DAC1_ENABLED(es->escfg)) 363152419Sariff set_dac1 = 1; 364164614Sariff else 365152419Sariff set_dac1 = 0; 36650724Scg if (mixtable[dev].stereo) { 367206033Sjoel rr = (r < 7) ? 0x80 : 31 - (r - 7) / 3; 368150832Snetchild es1370_wrcodec(es, mixtable[dev].right, rr); 369152419Sariff if (set_dac1 && mixtable[SOUND_MIXER_SYNTH].stereo) 370164614Sariff es1370_wrcodec(es, 371164614Sariff mixtable[SOUND_MIXER_SYNTH].right, rr); 37250724Scg } 373150832Snetchild es1370_wrcodec(es, mixtable[dev].left, rl); 374152419Sariff if (set_dac1) 375152419Sariff es1370_wrcodec(es, mixtable[SOUND_MIXER_SYNTH].left, rl); 376150832Snetchild ES_UNLOCK(es); 377150832Snetchild 378164614Sariff return (l | (r << 8)); 37950724Scg} 38050724Scg 381193640Sariffstatic uint32_t 382164614Sariffes1370_mixsetrecsrc(struct snd_mixer *m, uint32_t src) 38350724Scg{ 384150832Snetchild struct es_info *es; 38550724Scg int i, j = 0; 38650724Scg 387150832Snetchild es = mix_getdevinfo(m); 38850724Scg if (src == 0) src = 1 << SOUND_MIXER_MIC; 38950724Scg src &= mix_getrecdevs(m); 39050724Scg for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) 39150724Scg if ((src & (1 << i)) != 0) j |= mixtable[i].recmask; 39250724Scg 393150832Snetchild ES_LOCK(es); 394152419Sariff if ((src & (1 << SOUND_MIXER_PCM)) && ES_SINGLE_PCM_MIX(es->escfg) && 395164614Sariff ES_DAC1_ENABLED(es->escfg)) 396152419Sariff j |= mixtable[SOUND_MIXER_SYNTH].recmask; 397150832Snetchild es1370_wrcodec(es, CODEC_LIMIX1, j & 0x55); 398150832Snetchild es1370_wrcodec(es, CODEC_RIMIX1, j & 0xaa); 399150832Snetchild es1370_wrcodec(es, CODEC_LIMIX2, (j >> 8) & 0x17); 400150832Snetchild es1370_wrcodec(es, CODEC_RIMIX2, (j >> 8) & 0x0f); 401150832Snetchild es1370_wrcodec(es, CODEC_OMIX1, 0x7f); 402150832Snetchild es1370_wrcodec(es, CODEC_OMIX2, 0x3f); 403150832Snetchild ES_UNLOCK(es); 404150832Snetchild 405164614Sariff return (src); 40650724Scg} 40750724Scg 40870134Scgstatic kobj_method_t es1370_mixer_methods[] = { 409164614Sariff KOBJMETHOD(mixer_init, es1370_mixinit), 410164614Sariff KOBJMETHOD(mixer_set, es1370_mixset), 411164614Sariff KOBJMETHOD(mixer_setrecsrc, es1370_mixsetrecsrc), 412193640Sariff KOBJMETHOD_END 41370134Scg}; 41470134ScgMIXER_DECLARE(es1370_mixer); 41570134Scg 41670134Scg/* -------------------------------------------------------------------- */ 41770134Scg 41850724Scgstatic int 419164614Sariffes1370_wrcodec(struct es_info *es, unsigned char i, unsigned char data) 42050724Scg{ 421164614Sariff unsigned int t; 42250724Scg 423150832Snetchild ES_LOCK_ASSERT(es); 424150832Snetchild 425148591Snetchild for (t = 0; t < 0x1000; t++) { 426148591Snetchild if ((es_rd(es, ES1370_REG_STATUS, 4) & 427164614Sariff STAT_CSTAT) == 0) { 428148591Snetchild es_wr(es, ES1370_REG_CODEC, 429164614Sariff ((unsigned short)i << CODEC_INDEX_SHIFT) | data, 2); 430164614Sariff return (0); 43150724Scg } 432148591Snetchild DELAY(1); 433148591Snetchild } 434150832Snetchild device_printf(es->dev, "%s: timed out\n", __func__); 435164614Sariff return (-1); 43650724Scg} 43750724Scg 43850724Scg/* -------------------------------------------------------------------- */ 43950724Scg 44050724Scg/* channel interface */ 44150724Scgstatic void * 442164614Sariffeschan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 443164614Sariff struct pcm_channel *c, int dir) 44450724Scg{ 44550724Scg struct es_info *es = devinfo; 446152419Sariff struct es_chinfo *ch; 447152419Sariff uint32_t index; 44850724Scg 449152419Sariff ES_LOCK(es); 450152419Sariff 451152419Sariff if (dir == PCMDIR_PLAY) { 452152419Sariff index = ES_GP(es->escfg); 453152419Sariff es->escfg = ES_SET_GP(es->escfg, index + 1); 454164614Sariff if (index == 0) 455152419Sariff index = ES_DAC_FIRST(es->escfg); 456164614Sariff else if (index == 1) 457152419Sariff index = ES_DAC_SECOND(es->escfg); 458164614Sariff else { 459164614Sariff device_printf(es->dev, 460164614Sariff "Invalid ES_GP index: %d\n", index); 461152419Sariff ES_UNLOCK(es); 462164614Sariff return (NULL); 463152419Sariff } 464152419Sariff if (!(index == ES_DAC1 || index == ES_DAC2)) { 465164614Sariff device_printf(es->dev, "Unknown DAC: %d\n", index + 1); 466152419Sariff ES_UNLOCK(es); 467164614Sariff return (NULL); 468152419Sariff } 469152419Sariff if (es->ch[index].channel != NULL) { 470152419Sariff device_printf(es->dev, "DAC%d already initialized!\n", 471164614Sariff index + 1); 472152419Sariff ES_UNLOCK(es); 473164614Sariff return (NULL); 474152419Sariff } 475152419Sariff } else 476152419Sariff index = ES_ADC; 477152419Sariff 478152419Sariff ch = &es->ch[index]; 479152419Sariff ch->index = index; 480152419Sariff ch->num = es->num++; 481152419Sariff ch->caps = es_caps; 482152419Sariff if (ES_IS_ES1370(es->escfg)) { 483152419Sariff if (ch->index == ES_DAC1) { 484152419Sariff ch->caps.maxspeed = ES1370_DAC1_MAXSPEED; 485152419Sariff ch->caps.minspeed = ES1370_DAC1_MINSPEED; 486152419Sariff } else { 487152419Sariff uint32_t fixed_rate = ES_FIXED_RATE(es->escfg); 488152419Sariff if (!(fixed_rate < es_caps.minspeed || 489164614Sariff fixed_rate > es_caps.maxspeed)) { 490152419Sariff ch->caps.maxspeed = fixed_rate; 491152419Sariff ch->caps.minspeed = fixed_rate; 492152419Sariff } 493152419Sariff } 494152419Sariff } 49550724Scg ch->parent = es; 49650724Scg ch->channel = c; 49750724Scg ch->buffer = b; 49884658Scg ch->bufsz = es->bufsz; 499164614Sariff ch->blkcnt = es->blkcnt; 500164614Sariff ch->blksz = ch->bufsz / ch->blkcnt; 501150832Snetchild ch->dir = dir; 502152419Sariff ES_UNLOCK(es); 503168847Sariff if (sndbuf_alloc(ch->buffer, es->parent_dmat, 0, ch->bufsz) != 0) 504164614Sariff return (NULL); 505150832Snetchild ES_LOCK(es); 50650724Scg if (dir == PCMDIR_PLAY) { 507152419Sariff if (ch->index == ES_DAC1) { 508164614Sariff es_wr(es, ES1370_REG_MEMPAGE, 509164614Sariff ES1370_REG_DAC1_FRAMEADR >> 8, 1); 510164614Sariff es_wr(es, ES1370_REG_DAC1_FRAMEADR & 0xff, 511164614Sariff sndbuf_getbufaddr(ch->buffer), 4); 512164614Sariff es_wr(es, ES1370_REG_DAC1_FRAMECNT & 0xff, 513164614Sariff (ch->bufsz >> 2) - 1, 4); 514152419Sariff } else { 515164614Sariff es_wr(es, ES1370_REG_MEMPAGE, 516164614Sariff ES1370_REG_DAC2_FRAMEADR >> 8, 1); 517164614Sariff es_wr(es, ES1370_REG_DAC2_FRAMEADR & 0xff, 518164614Sariff sndbuf_getbufaddr(ch->buffer), 4); 519164614Sariff es_wr(es, ES1370_REG_DAC2_FRAMECNT & 0xff, 520164614Sariff (ch->bufsz >> 2) - 1, 4); 521152419Sariff } 52250724Scg } else { 523148591Snetchild es_wr(es, ES1370_REG_MEMPAGE, ES1370_REG_ADC_FRAMEADR >> 8, 1); 524164614Sariff es_wr(es, ES1370_REG_ADC_FRAMEADR & 0xff, 525164614Sariff sndbuf_getbufaddr(ch->buffer), 4); 526164614Sariff es_wr(es, ES1370_REG_ADC_FRAMECNT & 0xff, 527164614Sariff (ch->bufsz >> 2) - 1, 4); 52850724Scg } 529150832Snetchild ES_UNLOCK(es); 530164614Sariff return (ch); 53150724Scg} 53250724Scg 53350724Scgstatic int 534164614Sariffeschan_setformat(kobj_t obj, void *data, uint32_t format) 53550724Scg{ 53650724Scg struct es_chinfo *ch = data; 53750724Scg struct es_info *es = ch->parent; 53850724Scg 539150832Snetchild ES_LOCK(es); 54050724Scg if (ch->dir == PCMDIR_PLAY) { 541152419Sariff if (ch->index == ES_DAC1) { 542152419Sariff es->sctrl &= ~SCTRL_P1FMT; 543164614Sariff if (format & AFMT_S16_LE) 544164614Sariff es->sctrl |= SCTRL_P1SEB; 545193640Sariff if (AFMT_CHANNEL(format) > 1) 546164614Sariff es->sctrl |= SCTRL_P1SMB; 547152419Sariff } else { 548152419Sariff es->sctrl &= ~SCTRL_P2FMT; 549164614Sariff if (format & AFMT_S16_LE) 550164614Sariff es->sctrl |= SCTRL_P2SEB; 551193640Sariff if (AFMT_CHANNEL(format) > 1) 552164614Sariff es->sctrl |= SCTRL_P2SMB; 553152419Sariff } 55450724Scg } else { 55550724Scg es->sctrl &= ~SCTRL_R1FMT; 556164614Sariff if (format & AFMT_S16_LE) 557164614Sariff es->sctrl |= SCTRL_R1SEB; 558193640Sariff if (AFMT_CHANNEL(format) > 1) 559164614Sariff es->sctrl |= SCTRL_R1SMB; 56050724Scg } 561148591Snetchild es_wr(es, ES1370_REG_SERIAL_CONTROL, es->sctrl, 4); 562150832Snetchild ES_UNLOCK(es); 56350724Scg ch->fmt = format; 564164614Sariff return (0); 56550724Scg} 56650724Scg 567193640Sariffstatic uint32_t 568164614Sariffeschan1370_setspeed(kobj_t obj, void *data, uint32_t speed) 56950724Scg{ 57050724Scg struct es_chinfo *ch = data; 57150724Scg struct es_info *es = ch->parent; 57250724Scg 573164614Sariff ES_LOCK(es); 574152419Sariff /* Fixed rate , do nothing. */ 575171250Sariff if (ch->caps.minspeed == ch->caps.maxspeed) { 576171250Sariff ES_UNLOCK(es); 577164614Sariff return (ch->caps.maxspeed); 578171250Sariff } 579152419Sariff if (speed < ch->caps.minspeed) 580152419Sariff speed = ch->caps.minspeed; 581152419Sariff if (speed > ch->caps.maxspeed) 582152419Sariff speed = ch->caps.maxspeed; 583152419Sariff if (ch->index == ES_DAC1) { 584152419Sariff /* 585152419Sariff * DAC1 does not support continuous rate settings. 586152419Sariff * Pick the nearest and use it since FEEDER_RATE will 587218909Sbrucec * do the proper conversion for us. 588152419Sariff */ 589152419Sariff es->ctrl &= ~CTRL_WTSRSEL; 590152419Sariff if (speed < 8268) { 591152419Sariff speed = 5512; 592152419Sariff es->ctrl |= 0 << CTRL_SH_WTSRSEL; 593152419Sariff } else if (speed < 16537) { 594152419Sariff speed = 11025; 595152419Sariff es->ctrl |= 1 << CTRL_SH_WTSRSEL; 596152419Sariff } else if (speed < 33075) { 597152419Sariff speed = 22050; 598152419Sariff es->ctrl |= 2 << CTRL_SH_WTSRSEL; 599152419Sariff } else { 600152419Sariff speed = 44100; 601152419Sariff es->ctrl |= 3 << CTRL_SH_WTSRSEL; 602152419Sariff } 603152419Sariff } else { 604152419Sariff es->ctrl &= ~CTRL_PCLKDIV; 605152419Sariff es->ctrl |= DAC2_SRTODIV(speed) << CTRL_SH_PCLKDIV; 606150832Snetchild } 607148591Snetchild es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4); 608150832Snetchild ES_UNLOCK(es); 609164614Sariff return (speed); 61050724Scg} 61150724Scg 612193640Sariffstatic uint32_t 613164614Sariffeschan1371_setspeed(kobj_t obj, void *data, uint32_t speed) 61454831Scg{ 61554831Scg struct es_chinfo *ch = data; 61654831Scg struct es_info *es = ch->parent; 617152419Sariff uint32_t i; 618152419Sariff int delta; 61954831Scg 620150832Snetchild ES_LOCK(es); 621148591Snetchild if (ch->dir == PCMDIR_PLAY) 622152419Sariff i = es1371_dac_rate(es, speed, ch->index); /* play */ 623148591Snetchild else 624152419Sariff i = es1371_adc_rate(es, speed, ch->index); /* record */ 625150832Snetchild ES_UNLOCK(es); 626164614Sariff delta = (speed > i) ? (speed - i) : (i - speed); 627148591Snetchild if (delta < 2) 628164614Sariff return (speed); 629164614Sariff return (i); 63054831Scg} 63154831Scg 63250724Scgstatic int 633167648Sariffeschan_setfragments(kobj_t obj, void *data, uint32_t blksz, uint32_t blkcnt) 63450724Scg{ 63570321Scg struct es_chinfo *ch = data; 636164614Sariff struct es_info *es = ch->parent; 63770321Scg 638167648Sariff blksz &= ES_BLK_ALIGN; 639164614Sariff 640167648Sariff if (blksz > (sndbuf_getmaxsize(ch->buffer) / ES_DMA_SEGS_MIN)) 641167648Sariff blksz = sndbuf_getmaxsize(ch->buffer) / ES_DMA_SEGS_MIN; 642167648Sariff if (blksz < ES_BLK_MIN) 643167648Sariff blksz = ES_BLK_MIN; 644167648Sariff if (blkcnt > ES_DMA_SEGS_MAX) 645167648Sariff blkcnt = ES_DMA_SEGS_MAX; 646167648Sariff if (blkcnt < ES_DMA_SEGS_MIN) 647167648Sariff blkcnt = ES_DMA_SEGS_MIN; 648164614Sariff 649167648Sariff while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) { 650167648Sariff if ((blkcnt >> 1) >= ES_DMA_SEGS_MIN) 651167648Sariff blkcnt >>= 1; 652167648Sariff else if ((blksz >> 1) >= ES_BLK_MIN) 653167648Sariff blksz >>= 1; 654167648Sariff else 655167648Sariff break; 656167648Sariff } 657167648Sariff 658164614Sariff if ((sndbuf_getblksz(ch->buffer) != blksz || 659167648Sariff sndbuf_getblkcnt(ch->buffer) != blkcnt) && 660167648Sariff sndbuf_resize(ch->buffer, blkcnt, blksz) != 0) 661164614Sariff device_printf(es->dev, "%s: failed blksz=%u blkcnt=%u\n", 662167648Sariff __func__, blksz, blkcnt); 663164614Sariff 664164614Sariff ch->bufsz = sndbuf_getsize(ch->buffer); 665164614Sariff ch->blksz = sndbuf_getblksz(ch->buffer); 666167648Sariff ch->blkcnt = sndbuf_getblkcnt(ch->buffer); 667164614Sariff 668193640Sariff return (0); 669167648Sariff} 670167648Sariff 671193640Sariffstatic uint32_t 672167648Sariffeschan_setblocksize(kobj_t obj, void *data, uint32_t blksz) 673167648Sariff{ 674167648Sariff struct es_chinfo *ch = data; 675167648Sariff struct es_info *es = ch->parent; 676167648Sariff 677167648Sariff eschan_setfragments(obj, data, blksz, es->blkcnt); 678167648Sariff 679164614Sariff return (ch->blksz); 680164614Sariff} 681164614Sariff 682164614Sariff#define es_chan_active(es) ((es)->ch[ES_DAC1].active + \ 683164614Sariff (es)->ch[ES_DAC2].active + \ 684164614Sariff (es)->ch[ES_ADC].active) 685164614Sariff 686164614Sariffstatic __inline int 687164614Sariffes_poll_channel(struct es_chinfo *ch) 688164614Sariff{ 689164614Sariff struct es_info *es; 690164614Sariff uint32_t sz, delta; 691164614Sariff uint32_t reg, ptr; 692164614Sariff 693164614Sariff if (ch == NULL || ch->channel == NULL || ch->active == 0) 694164614Sariff return (0); 695164614Sariff 696164614Sariff es = ch->parent; 697164614Sariff if (ch->dir == PCMDIR_PLAY) { 698164614Sariff if (ch->index == ES_DAC1) 699164614Sariff reg = ES1370_REG_DAC1_FRAMECNT; 700164614Sariff else 701164614Sariff reg = ES1370_REG_DAC2_FRAMECNT; 702164614Sariff } else 703164614Sariff reg = ES1370_REG_ADC_FRAMECNT; 704164614Sariff sz = ch->blksz * ch->blkcnt; 705164614Sariff es_wr(es, ES1370_REG_MEMPAGE, reg >> 8, 4); 706164614Sariff ptr = es_rd(es, reg & 0x000000ff, 4) >> 16; 707164614Sariff ptr <<= 2; 708164614Sariff ch->ptr = ptr; 709164614Sariff ptr %= sz; 710164614Sariff ptr &= ~(ch->blksz - 1); 711164614Sariff delta = (sz + ptr - ch->prevptr) % sz; 712164614Sariff 713164614Sariff if (delta < ch->blksz) 714164614Sariff return (0); 715164614Sariff 716164614Sariff ch->prevptr = ptr; 717164614Sariff 718164614Sariff return (1); 719164614Sariff} 720164614Sariff 721164614Sariffstatic void 722164614Sariffes_poll_callback(void *arg) 723164614Sariff{ 724164614Sariff struct es_info *es = arg; 725164614Sariff uint32_t trigger = 0; 726164614Sariff int i; 727164614Sariff 728164614Sariff if (es == NULL) 729164614Sariff return; 730164614Sariff 731164614Sariff ES_LOCK(es); 732164614Sariff if (es->polling == 0 || es_chan_active(es) == 0) { 733164614Sariff ES_UNLOCK(es); 734164614Sariff return; 735150832Snetchild } 736164614Sariff 737164614Sariff for (i = 0; i < ES_NCHANS; i++) { 738164614Sariff if (es_poll_channel(&es->ch[i]) != 0) 739164614Sariff trigger |= 1 << i; 740164614Sariff } 741164614Sariff 742164614Sariff /* XXX */ 743164614Sariff callout_reset(&es->poll_timer, 1/*es->poll_ticks*/, 744164614Sariff es_poll_callback, es); 745164614Sariff 746164614Sariff ES_UNLOCK(es); 747164614Sariff 748164614Sariff for (i = 0; i < ES_NCHANS; i++) { 749164614Sariff if (trigger & (1 << i)) 750164614Sariff chn_intr(es->ch[i].channel); 751164614Sariff } 75250724Scg} 75350724Scg 75450724Scgstatic int 75570134Scgeschan_trigger(kobj_t obj, void *data, int go) 75650724Scg{ 75750724Scg struct es_chinfo *ch = data; 75850724Scg struct es_info *es = ch->parent; 759152419Sariff uint32_t cnt, b = 0; 76050724Scg 761170521Sariff if (!PCMTRIG_COMMON(go)) 762170521Sariff return 0; 76360958Scg 764164614Sariff ES_LOCK(es); 765193640Sariff cnt = (ch->blksz / sndbuf_getalign(ch->buffer)) - 1; 766152419Sariff if (ch->fmt & AFMT_16BIT) 767152419Sariff b |= 0x02; 768193640Sariff if (AFMT_CHANNEL(ch->fmt) > 1) 769152419Sariff b |= 0x01; 77050724Scg if (ch->dir == PCMDIR_PLAY) { 77150724Scg if (go == PCMTRIG_START) { 772152419Sariff if (ch->index == ES_DAC1) { 773152419Sariff es->ctrl |= CTRL_DAC1_EN; 774164614Sariff es->sctrl &= ~(SCTRL_P1LOOPSEL | 775164614Sariff SCTRL_P1PAUSE | SCTRL_P1SCTRLD); 776164614Sariff if (es->polling == 0) 777164614Sariff es->sctrl |= SCTRL_P1INTEN; 778164614Sariff else 779164614Sariff es->sctrl &= ~SCTRL_P1INTEN; 780164614Sariff es->sctrl |= b; 781152419Sariff es_wr(es, ES1370_REG_DAC1_SCOUNT, cnt, 4); 782152419Sariff /* start at beginning of buffer */ 783164614Sariff es_wr(es, ES1370_REG_MEMPAGE, 784164614Sariff ES1370_REG_DAC1_FRAMECNT >> 8, 4); 785164614Sariff es_wr(es, ES1370_REG_DAC1_FRAMECNT & 0xff, 786164614Sariff (ch->bufsz >> 2) - 1, 4); 787152419Sariff } else { 788152419Sariff es->ctrl |= CTRL_DAC2_EN; 789164614Sariff es->sctrl &= ~(SCTRL_P2ENDINC | SCTRL_P2STINC | 790164614Sariff SCTRL_P2LOOPSEL | SCTRL_P2PAUSE | 791164614Sariff SCTRL_P2DACSEN); 792164614Sariff if (es->polling == 0) 793164614Sariff es->sctrl |= SCTRL_P2INTEN; 794164614Sariff else 795164614Sariff es->sctrl &= ~SCTRL_P2INTEN; 796164614Sariff es->sctrl |= (b << 2) | 797164614Sariff ((((b >> 1) & 1) + 1) << SCTRL_SH_P2ENDINC); 798152419Sariff es_wr(es, ES1370_REG_DAC2_SCOUNT, cnt, 4); 799152419Sariff /* start at beginning of buffer */ 800164614Sariff es_wr(es, ES1370_REG_MEMPAGE, 801164614Sariff ES1370_REG_DAC2_FRAMECNT >> 8, 4); 802164614Sariff es_wr(es, ES1370_REG_DAC2_FRAMECNT & 0xff, 803164614Sariff (ch->bufsz >> 2) - 1, 4); 804152419Sariff } 805164614Sariff } else 806164614Sariff es->ctrl &= ~((ch->index == ES_DAC1) ? 807164614Sariff CTRL_DAC1_EN : CTRL_DAC2_EN); 80850724Scg } else { 80950724Scg if (go == PCMTRIG_START) { 81050724Scg es->ctrl |= CTRL_ADC_EN; 81150724Scg es->sctrl &= ~SCTRL_R1LOOPSEL; 812164614Sariff if (es->polling == 0) 813164614Sariff es->sctrl |= SCTRL_R1INTEN; 814164614Sariff else 815164614Sariff es->sctrl &= ~SCTRL_R1INTEN; 816164614Sariff es->sctrl |= b << 4; 817148591Snetchild es_wr(es, ES1370_REG_ADC_SCOUNT, cnt, 4); 81859323Scg /* start at beginning of buffer */ 819164614Sariff es_wr(es, ES1370_REG_MEMPAGE, 820164614Sariff ES1370_REG_ADC_FRAMECNT >> 8, 4); 821164614Sariff es_wr(es, ES1370_REG_ADC_FRAMECNT & 0xff, 822164614Sariff (ch->bufsz >> 2) - 1, 4); 823164614Sariff } else 824164614Sariff es->ctrl &= ~CTRL_ADC_EN; 82550724Scg } 826148591Snetchild es_wr(es, ES1370_REG_SERIAL_CONTROL, es->sctrl, 4); 827148591Snetchild es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4); 828164614Sariff if (go == PCMTRIG_START) { 829164614Sariff if (es->polling != 0) { 830164614Sariff ch->ptr = 0; 831164614Sariff ch->prevptr = 0; 832164614Sariff if (es_chan_active(es) == 0) { 833164614Sariff es->poll_ticks = 1; 834164614Sariff callout_reset(&es->poll_timer, 1, 835164614Sariff es_poll_callback, es); 836164614Sariff } 837164614Sariff } 838164614Sariff ch->active = 1; 839164614Sariff } else { 840164614Sariff ch->active = 0; 841164614Sariff if (es->polling != 0) { 842164614Sariff if (es_chan_active(es) == 0) { 843164614Sariff callout_stop(&es->poll_timer); 844164614Sariff es->poll_ticks = 1; 845164614Sariff } 846164614Sariff } 847164614Sariff } 848150832Snetchild ES_UNLOCK(es); 849164614Sariff return (0); 85050724Scg} 85150724Scg 852193640Sariffstatic uint32_t 85370134Scgeschan_getptr(kobj_t obj, void *data) 85450724Scg{ 85550724Scg struct es_chinfo *ch = data; 85650724Scg struct es_info *es = ch->parent; 857164614Sariff uint32_t reg, cnt; 85859323Scg 859150832Snetchild ES_LOCK(es); 860164614Sariff if (es->polling != 0) 861164614Sariff cnt = ch->ptr; 862164614Sariff else { 863164614Sariff if (ch->dir == PCMDIR_PLAY) { 864164614Sariff if (ch->index == ES_DAC1) 865164614Sariff reg = ES1370_REG_DAC1_FRAMECNT; 866164614Sariff else 867164614Sariff reg = ES1370_REG_DAC2_FRAMECNT; 868164614Sariff } else 869164614Sariff reg = ES1370_REG_ADC_FRAMECNT; 870164614Sariff es_wr(es, ES1370_REG_MEMPAGE, reg >> 8, 4); 871164614Sariff cnt = es_rd(es, reg & 0x000000ff, 4) >> 16; 872164614Sariff /* cnt is longwords */ 873164614Sariff cnt <<= 2; 874164614Sariff } 875150832Snetchild ES_UNLOCK(es); 876164614Sariff 877167648Sariff cnt &= ES_BLK_ALIGN; 878164614Sariff 879164614Sariff return (cnt); 88050724Scg} 88150724Scg 88274763Scgstatic struct pcmchan_caps * 88370134Scgeschan_getcaps(kobj_t obj, void *data) 88450724Scg{ 88550724Scg struct es_chinfo *ch = data; 886150832Snetchild 887164614Sariff return (&ch->caps); 88850724Scg} 88950724Scg 89070134Scgstatic kobj_method_t eschan1370_methods[] = { 891164614Sariff KOBJMETHOD(channel_init, eschan_init), 892164614Sariff KOBJMETHOD(channel_setformat, eschan_setformat), 893164614Sariff KOBJMETHOD(channel_setspeed, eschan1370_setspeed), 894164614Sariff KOBJMETHOD(channel_setblocksize, eschan_setblocksize), 895167648Sariff KOBJMETHOD(channel_setfragments, eschan_setfragments), 896164614Sariff KOBJMETHOD(channel_trigger, eschan_trigger), 897164614Sariff KOBJMETHOD(channel_getptr, eschan_getptr), 898164614Sariff KOBJMETHOD(channel_getcaps, eschan_getcaps), 899193640Sariff KOBJMETHOD_END 90070134Scg}; 90170134ScgCHANNEL_DECLARE(eschan1370); 90270134Scg 90370134Scgstatic kobj_method_t eschan1371_methods[] = { 904164614Sariff KOBJMETHOD(channel_init, eschan_init), 905164614Sariff KOBJMETHOD(channel_setformat, eschan_setformat), 906164614Sariff KOBJMETHOD(channel_setspeed, eschan1371_setspeed), 907164614Sariff KOBJMETHOD(channel_setblocksize, eschan_setblocksize), 908167648Sariff KOBJMETHOD(channel_setfragments, eschan_setfragments), 909164614Sariff KOBJMETHOD(channel_trigger, eschan_trigger), 910164614Sariff KOBJMETHOD(channel_getptr, eschan_getptr), 911164614Sariff KOBJMETHOD(channel_getcaps, eschan_getcaps), 912193640Sariff KOBJMETHOD_END 91370134Scg}; 91470134ScgCHANNEL_DECLARE(eschan1371); 91570134Scg 91670134Scg/* -------------------------------------------------------------------- */ 91750724Scg/* The interrupt handler */ 91850724Scgstatic void 91954831Scges_intr(void *p) 92050724Scg{ 92150724Scg struct es_info *es = p; 922150832Snetchild uint32_t intsrc, sctrl; 92350724Scg 924150832Snetchild ES_LOCK(es); 925164614Sariff if (es->polling != 0) { 926164614Sariff ES_UNLOCK(es); 927164614Sariff return; 928164614Sariff } 929148591Snetchild intsrc = es_rd(es, ES1370_REG_STATUS, 4); 930148591Snetchild if ((intsrc & STAT_INTR) == 0) { 931150832Snetchild ES_UNLOCK(es); 932148591Snetchild return; 933148591Snetchild } 93450724Scg 93550724Scg sctrl = es->sctrl; 936164614Sariff if (intsrc & STAT_ADC) 937164614Sariff sctrl &= ~SCTRL_R1INTEN; 938164614Sariff if (intsrc & STAT_DAC1) 939164614Sariff sctrl &= ~SCTRL_P1INTEN; 940164614Sariff if (intsrc & STAT_DAC2) 941164614Sariff sctrl &= ~SCTRL_P2INTEN; 94250724Scg 943148591Snetchild es_wr(es, ES1370_REG_SERIAL_CONTROL, sctrl, 4); 944148591Snetchild es_wr(es, ES1370_REG_SERIAL_CONTROL, es->sctrl, 4); 945150832Snetchild ES_UNLOCK(es); 94650724Scg 947164614Sariff if (intsrc & STAT_ADC) 948164614Sariff chn_intr(es->ch[ES_ADC].channel); 949164614Sariff if (intsrc & STAT_DAC1) 950164614Sariff chn_intr(es->ch[ES_DAC1].channel); 951164614Sariff if (intsrc & STAT_DAC2) 952164614Sariff chn_intr(es->ch[ES_DAC2].channel); 95350724Scg} 95450724Scg 95554831Scg/* ES1370 specific */ 95654831Scgstatic int 95754831Scges1370_init(struct es_info *es) 95854831Scg{ 959152419Sariff uint32_t fixed_rate; 960152419Sariff int r, single_pcm; 961150832Snetchild 962152419Sariff /* ES1370 default to fixed rate operation */ 963150832Snetchild if (resource_int_value(device_get_name(es->dev), 964164614Sariff device_get_unit(es->dev), "fixed_rate", &r) == 0) { 965152419Sariff fixed_rate = r; 966152419Sariff if (fixed_rate) { 967152419Sariff if (fixed_rate < es_caps.minspeed) 968152419Sariff fixed_rate = es_caps.minspeed; 969152419Sariff if (fixed_rate > es_caps.maxspeed) 970152419Sariff fixed_rate = es_caps.maxspeed; 971150832Snetchild } 972150832Snetchild } else 973152419Sariff fixed_rate = es_caps.maxspeed; 974152419Sariff 975152419Sariff if (resource_int_value(device_get_name(es->dev), 976164614Sariff device_get_unit(es->dev), "single_pcm_mixer", &r) == 0) 977164614Sariff single_pcm = (r != 0) ? 1 : 0; 978152419Sariff else 979152419Sariff single_pcm = 1; 980152419Sariff 981150832Snetchild ES_LOCK(es); 982152419Sariff if (ES_NUMPLAY(es->escfg) == 1) 983152419Sariff single_pcm = 1; 984152419Sariff /* This is ES1370 */ 985152419Sariff es->escfg = ES_SET_IS_ES1370(es->escfg, 1); 986164614Sariff if (fixed_rate) 987152419Sariff es->escfg = ES_SET_FIXED_RATE(es->escfg, fixed_rate); 988164614Sariff else { 989152419Sariff es->escfg = ES_SET_FIXED_RATE(es->escfg, 0); 990152419Sariff fixed_rate = DSP_DEFAULT_SPEED; 991150832Snetchild } 992164614Sariff if (single_pcm) 993152419Sariff es->escfg = ES_SET_SINGLE_PCM_MIX(es->escfg, 1); 994164614Sariff else 995152419Sariff es->escfg = ES_SET_SINGLE_PCM_MIX(es->escfg, 0); 996152419Sariff es->ctrl = CTRL_CDC_EN | CTRL_JYSTK_EN | CTRL_SERR_DIS | 997164614Sariff (DAC2_SRTODIV(fixed_rate) << CTRL_SH_PCLKDIV); 998152419Sariff es->ctrl |= 3 << CTRL_SH_WTSRSEL; 999148591Snetchild es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4); 100053413Sroger 100154831Scg es->sctrl = 0; 1002148591Snetchild es_wr(es, ES1370_REG_SERIAL_CONTROL, es->sctrl, 4); 100353413Sroger 1004164614Sariff /* No RST, PD */ 1005164614Sariff es1370_wrcodec(es, CODEC_RES_PD, 3); 1006164614Sariff /* 1007164614Sariff * CODEC ADC and CODEC DAC use {LR,B}CLK2 and run off the LRCLK2 PLL; 1008164614Sariff * program DAC_SYNC=0! 1009164614Sariff */ 1010164614Sariff es1370_wrcodec(es, CODEC_CSEL, 0); 1011164614Sariff /* Recording source is mixer */ 1012164614Sariff es1370_wrcodec(es, CODEC_ADSEL, 0); 1013164614Sariff /* MIC amp is 0db */ 1014164614Sariff es1370_wrcodec(es, CODEC_MGAIN, 0); 1015150832Snetchild ES_UNLOCK(es); 101653413Sroger 1017164614Sariff return (0); 101854831Scg} 101953413Sroger 102054831Scg/* ES1371 specific */ 102153413Srogerint 1022150832Snetchildes1371_init(struct es_info *es) 102353413Sroger{ 1024154285Sariff uint32_t cssr, devid, revid, subdev; 102553413Sroger int idx; 102653413Sroger 1027150832Snetchild ES_LOCK(es); 1028152419Sariff /* This is NOT ES1370 */ 1029152419Sariff es->escfg = ES_SET_IS_ES1370(es->escfg, 0); 103054831Scg es->num = 0; 103153413Sroger es->sctrl = 0; 1032148591Snetchild cssr = 0; 1033150832Snetchild devid = pci_get_devid(es->dev); 1034150832Snetchild revid = pci_get_revid(es->dev); 1035164614Sariff subdev = (pci_get_subdevice(es->dev) << 16) | 1036164614Sariff pci_get_subvendor(es->dev); 1037154285Sariff /* 1038154285Sariff * Joyport blacklist. Either we're facing with broken hardware 1039154285Sariff * or because this hardware need special (unknown) initialization 1040154285Sariff * procedures. 1041154285Sariff */ 1042154285Sariff switch (subdev) { 1043154285Sariff case 0x20001274: /* old Ensoniq */ 1044154285Sariff es->ctrl = 0; 1045154285Sariff break; 1046154285Sariff default: 1047154285Sariff es->ctrl = CTRL_JYSTK_EN; 1048154285Sariff break; 1049154285Sariff } 1050148591Snetchild if (devid == CT4730_PCI_ID) { 1051148591Snetchild /* XXX amplifier hack? */ 1052148591Snetchild es->ctrl |= (1 << 16); 1053148591Snetchild } 105453413Sroger /* initialize the chips */ 1055148591Snetchild es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4); 1056148591Snetchild es_wr(es, ES1370_REG_SERIAL_CONTROL, es->sctrl, 4); 1057148591Snetchild es_wr(es, ES1371_REG_LEGACY, 0, 4); 105876086Scg if ((devid == ES1371_PCI_ID && revid == ES1371REV_ES1373_8) || 105976086Scg (devid == ES1371_PCI_ID && revid == ES1371REV_CT5880_A) || 106076086Scg (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_C) || 106195678Scg (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_D) || 1062148591Snetchild (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_E)) { 1063148591Snetchild cssr = 1 << 29; 1064148591Snetchild es_wr(es, ES1370_REG_STATUS, cssr, 4); 106574753Scg DELAY(20000); 106655209Scg } 106753413Sroger /* AC'97 warm reset to start the bitclk */ 1068152419Sariff es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4); 1069152419Sariff es_wr(es, ES1371_REG_LEGACY, ES1371_SYNC_RES, 4); 107053413Sroger DELAY(2000); 1071152419Sariff es_wr(es, ES1370_REG_CONTROL, es->sctrl, 4); 1072148591Snetchild es1371_wait_src_ready(es); 107353413Sroger /* Init the sample rate converter */ 1074148591Snetchild es_wr(es, ES1371_REG_SMPRATE, ES1371_DIS_SRC, 4); 107553413Sroger for (idx = 0; idx < 0x80; idx++) 107654831Scg es1371_src_write(es, idx, 0); 1077164614Sariff es1371_src_write(es, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); 107853413Sroger es1371_src_write(es, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); 1079164614Sariff es1371_src_write(es, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); 108053413Sroger es1371_src_write(es, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); 1081164614Sariff es1371_src_write(es, ES_SMPREG_VOL_ADC, 1 << 12); 1082164614Sariff es1371_src_write(es, ES_SMPREG_VOL_ADC + 1, 1 << 12); 1083164614Sariff es1371_src_write(es, ES_SMPREG_VOL_DAC1, 1 << 12); 1084164614Sariff es1371_src_write(es, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); 1085164614Sariff es1371_src_write(es, ES_SMPREG_VOL_DAC2, 1 << 12); 1086164614Sariff es1371_src_write(es, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); 1087164614Sariff es1371_adc_rate(es, 22050, ES_ADC); 1088164614Sariff es1371_dac_rate(es, 22050, ES_DAC1); 1089164614Sariff es1371_dac_rate(es, 22050, ES_DAC2); 1090164614Sariff /* 1091164614Sariff * WARNING: 109253413Sroger * enabling the sample rate converter without properly programming 109353413Sroger * its parameters causes the chip to lock up (the SRC busy bit will 109453413Sroger * be stuck high, and I've found no way to rectify this other than 109553413Sroger * power cycle) 109653413Sroger */ 1097148591Snetchild es1371_wait_src_ready(es); 1098148591Snetchild es_wr(es, ES1371_REG_SMPRATE, 0, 4); 1099148591Snetchild /* try to reset codec directly */ 1100148591Snetchild es_wr(es, ES1371_REG_CODEC, 0, 4); 1101148591Snetchild es_wr(es, ES1370_REG_STATUS, cssr, 4); 1102150832Snetchild ES_UNLOCK(es); 110353413Sroger 110453413Sroger return (0); 110553413Sroger} 110653413Sroger 110770134Scg/* -------------------------------------------------------------------- */ 110870134Scg 110970134Scgstatic int 1110164614Sariffes1371_wrcd(kobj_t obj, void *s, int addr, uint32_t data) 111153413Sroger{ 1112150832Snetchild uint32_t t, x, orig; 111353413Sroger struct es_info *es = (struct es_info*)s; 111453413Sroger 1115167648Sariff for (t = 0; t < 0x1000; t++) { 1116148591Snetchild if (!es_rd(es, ES1371_REG_CODEC & CODEC_WIP, 4)) 111753413Sroger break; 1118167648Sariff } 111953413Sroger /* save the current state for later */ 1120148591Snetchild x = orig = es_rd(es, ES1371_REG_SMPRATE, 4); 112153413Sroger /* enable SRC state data in SRC mux */ 1122164614Sariff es_wr(es, ES1371_REG_SMPRATE, (x & (ES1371_DIS_SRC | ES1371_DIS_P1 | 1123164614Sariff ES1371_DIS_P2 | ES1371_DIS_R1)) | 0x00010000, 4); 1124148591Snetchild /* busy wait */ 1125164614Sariff for (t = 0; t < 0x1000; t++) { 1126164614Sariff if ((es_rd(es, ES1371_REG_SMPRATE, 4) & 0x00870000) == 1127164614Sariff 0x00000000) 1128148591Snetchild break; 1129164614Sariff } 113053413Sroger /* wait for a SAFE time to write addr/data and then do it, dammit */ 1131164614Sariff for (t = 0; t < 0x1000; t++) { 1132164614Sariff if ((es_rd(es, ES1371_REG_SMPRATE, 4) & 0x00870000) == 1133164614Sariff 0x00010000) 113454831Scg break; 1135164614Sariff } 113654831Scg 1137164614Sariff es_wr(es, ES1371_REG_CODEC, ((addr << CODEC_POADD_SHIFT) & 1138164614Sariff CODEC_POADD_MASK) | ((data << CODEC_PODAT_SHIFT) & 1139164614Sariff CODEC_PODAT_MASK), 4); 114053413Sroger /* restore SRC reg */ 114153413Sroger es1371_wait_src_ready(s); 1142148591Snetchild es_wr(es, ES1371_REG_SMPRATE, orig, 4); 114370134Scg 1144164614Sariff return (0); 114553413Sroger} 114653413Sroger 114770134Scgstatic int 114870134Scges1371_rdcd(kobj_t obj, void *s, int addr) 114953413Sroger{ 1150150832Snetchild uint32_t t, x, orig; 115154831Scg struct es_info *es = (struct es_info *)s; 115253413Sroger 1153164614Sariff for (t = 0; t < 0x1000; t++) { 1154148591Snetchild if (!(x = es_rd(es, ES1371_REG_CODEC, 4) & CODEC_WIP)) 115554831Scg break; 1156164614Sariff } 115753413Sroger 115854831Scg /* save the current state for later */ 1159148591Snetchild x = orig = es_rd(es, ES1371_REG_SMPRATE, 4); 116054831Scg /* enable SRC state data in SRC mux */ 1161164614Sariff es_wr(es, ES1371_REG_SMPRATE, (x & (ES1371_DIS_SRC | ES1371_DIS_P1 | 1162164614Sariff ES1371_DIS_P2 | ES1371_DIS_R1)) | 0x00010000, 4); 1163148591Snetchild /* busy wait */ 1164164614Sariff for (t = 0; t < 0x1000; t++) { 1165164614Sariff if ((x = es_rd(es, ES1371_REG_SMPRATE, 4) & 0x00870000) == 1166164614Sariff 0x00000000) 1167148591Snetchild break; 1168164614Sariff } 116954831Scg /* wait for a SAFE time to write addr/data and then do it, dammit */ 1170164614Sariff for (t = 0; t < 0x1000; t++) { 1171164614Sariff if ((x = es_rd(es, ES1371_REG_SMPRATE, 4) & 0x00870000) == 1172164614Sariff 0x00010000) 117354831Scg break; 1174164614Sariff } 117553413Sroger 1176164614Sariff es_wr(es, ES1371_REG_CODEC, ((addr << CODEC_POADD_SHIFT) & 1177164614Sariff CODEC_POADD_MASK) | CODEC_PORD, 4); 1178148591Snetchild 117954831Scg /* restore SRC reg */ 118054831Scg es1371_wait_src_ready(s); 1181148591Snetchild es_wr(es, ES1371_REG_SMPRATE, orig, 4); 118253413Sroger 118354831Scg /* now wait for the stinkin' data (RDY) */ 1184164614Sariff for (t = 0; t < 0x1000; t++) { 1185148591Snetchild if ((x = es_rd(es, ES1371_REG_CODEC, 4)) & CODEC_RDY) 118654831Scg break; 1187164614Sariff } 1188148591Snetchild 118954831Scg return ((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT); 119053413Sroger} 119153413Sroger 119270134Scgstatic kobj_method_t es1371_ac97_methods[] = { 1193164614Sariff KOBJMETHOD(ac97_read, es1371_rdcd), 1194164614Sariff KOBJMETHOD(ac97_write, es1371_wrcd), 1195193640Sariff KOBJMETHOD_END 119670134Scg}; 119770134ScgAC97_DECLARE(es1371_ac97); 119870134Scg 119970134Scg/* -------------------------------------------------------------------- */ 120070134Scg 1201164614Sariffstatic unsigned int 1202164614Sariffes1371_src_read(struct es_info *es, unsigned short reg) 120354831Scg{ 1204150832Snetchild uint32_t r; 120553413Sroger 1206164614Sariff r = es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P1 | 1207164614Sariff ES1371_DIS_P2 | ES1371_DIS_R1); 120854831Scg r |= ES1371_SRC_RAM_ADDRO(reg); 1209148591Snetchild es_wr(es, ES1371_REG_SMPRATE, r, 4); 1210164614Sariff return (ES1371_SRC_RAM_DATAI(es1371_wait_src_ready(es))); 121153413Sroger} 121253413Sroger 121353413Srogerstatic void 1214164614Sariffes1371_src_write(struct es_info *es, unsigned short reg, unsigned short data) 1215148591Snetchild{ 1216150832Snetchild uint32_t r; 121753413Sroger 1218164614Sariff r = es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P1 | 1219164614Sariff ES1371_DIS_P2 | ES1371_DIS_R1); 122053413Sroger r |= ES1371_SRC_RAM_ADDRO(reg) | ES1371_SRC_RAM_DATAO(data); 1221148591Snetchild es_wr(es, ES1371_REG_SMPRATE, r | ES1371_SRC_RAM_WE, 4); 122253413Sroger} 122353413Sroger 1224164614Sariffstatic unsigned int 1225164614Sariffes1371_adc_rate(struct es_info *es, unsigned int rate, int set) 122654831Scg{ 1227164614Sariff unsigned int n, truncm, freq, result; 122854831Scg 1229150832Snetchild ES_LOCK_ASSERT(es); 1230150832Snetchild 1231164614Sariff if (rate > 48000) 1232164614Sariff rate = 48000; 1233164614Sariff if (rate < 4000) 1234164614Sariff rate = 4000; 123554831Scg n = rate / 3000; 123654831Scg if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9))) 123754831Scg n--; 123854831Scg truncm = (21 * n - 1) | 1; 123954831Scg freq = ((48000UL << 15) / rate) * n; 124054831Scg result = (48000UL << 15) / (freq / n); 124154831Scg if (set) { 124254831Scg if (rate >= 24000) { 1243164614Sariff if (truncm > 239) 1244164614Sariff truncm = 239; 124554831Scg es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N, 1246164614Sariff (((239 - truncm) >> 1) << 9) | (n << 4)); 124754831Scg } else { 1248164614Sariff if (truncm > 119) 1249164614Sariff truncm = 119; 125054831Scg es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N, 1251164614Sariff 0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4)); 125254831Scg } 125354831Scg es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_INT_REGS, 1254164614Sariff (es1371_src_read(es, ES_SMPREG_ADC + ES_SMPREG_INT_REGS) & 1255164614Sariff 0x00ff) | ((freq >> 5) & 0xfc00)); 1256164614Sariff es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, 1257164614Sariff freq & 0x7fff); 125854831Scg es1371_src_write(es, ES_SMPREG_VOL_ADC, n << 8); 125954831Scg es1371_src_write(es, ES_SMPREG_VOL_ADC + 1, n << 8); 126053413Sroger } 1261164614Sariff return (result); 126253413Sroger} 126353413Sroger 1264164614Sariffstatic unsigned int 1265164614Sariffes1371_dac_rate(struct es_info *es, unsigned int rate, int set) 126654831Scg{ 1267164614Sariff unsigned int freq, r, result, dac, dis; 126853413Sroger 1269150832Snetchild ES_LOCK_ASSERT(es); 1270150832Snetchild 1271164614Sariff if (rate > 48000) 1272164614Sariff rate = 48000; 1273164614Sariff if (rate < 4000) 1274164614Sariff rate = 4000; 1275152419Sariff freq = ((rate << 15) + 1500) / 3000; 127654831Scg result = (freq * 3000) >> 15; 1277164614Sariff 1278152419Sariff dac = (set == ES_DAC1) ? ES_SMPREG_DAC1 : ES_SMPREG_DAC2; 1279152419Sariff dis = (set == ES_DAC1) ? ES1371_DIS_P2 : ES1371_DIS_P1; 1280164614Sariff r = (es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P1 | 1281164614Sariff ES1371_DIS_P2 | ES1371_DIS_R1)); 1282152419Sariff es_wr(es, ES1371_REG_SMPRATE, r, 4); 1283152419Sariff es1371_src_write(es, dac + ES_SMPREG_INT_REGS, 1284164614Sariff (es1371_src_read(es, dac + ES_SMPREG_INT_REGS) & 0x00ff) | 1285164614Sariff ((freq >> 5) & 0xfc00)); 1286152419Sariff es1371_src_write(es, dac + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff); 1287164614Sariff r = (es1371_wait_src_ready(es) & 1288164614Sariff (ES1371_DIS_SRC | dis | ES1371_DIS_R1)); 1289152419Sariff es_wr(es, ES1371_REG_SMPRATE, r, 4); 1290164614Sariff return (result); 129153413Sroger} 129253413Sroger 1293150832Snetchildstatic uint32_t 129455209Scges1371_wait_src_ready(struct es_info *es) 129554831Scg{ 1296150832Snetchild uint32_t t, r; 129753413Sroger 1298148591Snetchild for (t = 0; t < 0x1000; t++) { 1299164614Sariff if (!((r = es_rd(es, ES1371_REG_SMPRATE, 4)) & 1300164614Sariff ES1371_SRC_RAM_BUSY)) 1301164614Sariff return (r); 1302148591Snetchild DELAY(1); 130354831Scg } 1304150832Snetchild device_printf(es->dev, "%s: timed out 0x%x [0x%x]\n", __func__, 1305150832Snetchild ES1371_REG_SMPRATE, r); 1306164614Sariff return (0); 130753413Sroger} 130853413Sroger 130950724Scg/* -------------------------------------------------------------------- */ 131050724Scg 131150724Scg/* 131250724Scg * Probe and attach the card 131350724Scg */ 131450724Scg 131550724Scgstatic int 131650724Scges_pci_probe(device_t dev) 131750724Scg{ 131876086Scg switch(pci_get_devid(dev)) { 131976086Scg case ES1370_PCI_ID: 132050724Scg device_set_desc(dev, "AudioPCI ES1370"); 1321164614Sariff return (BUS_PROBE_DEFAULT); 132276086Scg case ES1371_PCI_ID: 132376086Scg switch(pci_get_revid(dev)) { 132478033Scg case ES1371REV_ES1371_A: 132578033Scg device_set_desc(dev, "AudioPCI ES1371-A"); 1326164614Sariff return (BUS_PROBE_DEFAULT); 132776086Scg case ES1371REV_ES1371_B: 132876086Scg device_set_desc(dev, "AudioPCI ES1371-B"); 1329164614Sariff return (BUS_PROBE_DEFAULT); 133076086Scg case ES1371REV_ES1373_A: 133176086Scg device_set_desc(dev, "AudioPCI ES1373-A"); 1332164614Sariff return (BUS_PROBE_DEFAULT); 133376086Scg case ES1371REV_ES1373_B: 133476086Scg device_set_desc(dev, "AudioPCI ES1373-B"); 1335164614Sariff return (BUS_PROBE_DEFAULT); 133676086Scg case ES1371REV_ES1373_8: 133776086Scg device_set_desc(dev, "AudioPCI ES1373-8"); 1338164614Sariff return (BUS_PROBE_DEFAULT); 133976086Scg case ES1371REV_CT5880_A: 134076086Scg device_set_desc(dev, "Creative CT5880-A"); 1341164614Sariff return (BUS_PROBE_DEFAULT); 134276086Scg default: 134376086Scg device_set_desc(dev, "AudioPCI ES1371-?"); 1344164614Sariff device_printf(dev, 1345164614Sariff "unknown revision %d -- please report to " 1346164614Sariff "freebsd-multimedia@freebsd.org\n", 1347164614Sariff pci_get_revid(dev)); 1348164614Sariff return (BUS_PROBE_DEFAULT); 134976086Scg } 135076086Scg case ES1371_PCI_ID2: 135178033Scg device_set_desc(dev, "Strange AudioPCI ES1371-? (vid=3274)"); 1352164614Sariff device_printf(dev, 1353164614Sariff "unknown revision %d -- please report to " 1354164614Sariff "freebsd-multimedia@freebsd.org\n", pci_get_revid(dev)); 1355164614Sariff return (BUS_PROBE_DEFAULT); 1356119548Sorion case CT4730_PCI_ID: 1357119548Sorion switch(pci_get_revid(dev)) { 1358119548Sorion case CT4730REV_CT4730_A: 1359164614Sariff device_set_desc(dev, 1360164614Sariff "Creative SB AudioPCI CT4730/EV1938"); 1361164614Sariff return (BUS_PROBE_DEFAULT); 1362119548Sorion default: 1363119548Sorion device_set_desc(dev, "Creative SB AudioPCI CT4730-?"); 1364164614Sariff device_printf(dev, 1365164614Sariff "unknown revision %d -- please report to " 1366164614Sariff "freebsd-multimedia@freebsd.org\n", 1367164614Sariff pci_get_revid(dev)); 1368164614Sariff return (BUS_PROBE_DEFAULT); 1369119548Sorion } 137076086Scg case CT5880_PCI_ID: 137176086Scg switch(pci_get_revid(dev)) { 137276086Scg case CT5880REV_CT5880_C: 137376086Scg device_set_desc(dev, "Creative CT5880-C"); 1374164614Sariff return (BUS_PROBE_DEFAULT); 137576086Scg case CT5880REV_CT5880_D: 137676086Scg device_set_desc(dev, "Creative CT5880-D"); 1377164614Sariff return (BUS_PROBE_DEFAULT); 137895678Scg case CT5880REV_CT5880_E: 137995678Scg device_set_desc(dev, "Creative CT5880-E"); 1380164614Sariff return (BUS_PROBE_DEFAULT); 138176086Scg default: 138276086Scg device_set_desc(dev, "Creative CT5880-?"); 1383164614Sariff device_printf(dev, 1384164614Sariff "unknown revision %d -- please report to " 1385164614Sariff "freebsd-multimedia@freebsd.org\n", 1386164614Sariff pci_get_revid(dev)); 1387164614Sariff return (BUS_PROBE_DEFAULT); 138876086Scg } 138976086Scg default: 1390164614Sariff return (ENXIO); 139150724Scg } 139250724Scg} 139350724Scg 139450724Scgstatic int 1395150832Snetchildsysctl_es137x_spdif_enable(SYSCTL_HANDLER_ARGS) 1396148591Snetchild{ 1397148591Snetchild struct es_info *es; 1398148591Snetchild device_t dev; 1399150832Snetchild uint32_t r; 1400150832Snetchild int err, new_en; 1401148591Snetchild 1402148591Snetchild dev = oidp->oid_arg1; 1403148591Snetchild es = pcm_getdevinfo(dev); 1404150832Snetchild ES_LOCK(es); 1405150832Snetchild r = es_rd(es, ES1370_REG_STATUS, 4); 1406150832Snetchild ES_UNLOCK(es); 1407150832Snetchild new_en = (r & ENABLE_SPDIF) ? 1 : 0; 1408170289Sdwmalone err = sysctl_handle_int(oidp, &new_en, 0, req); 1409148591Snetchild 1410148591Snetchild if (err || req->newptr == NULL) 1411150832Snetchild return (err); 1412148591Snetchild if (new_en < 0 || new_en > 1) 1413150832Snetchild return (EINVAL); 1414148591Snetchild 1415150832Snetchild ES_LOCK(es); 1416148591Snetchild if (new_en) { 1417148591Snetchild r |= ENABLE_SPDIF; 1418148591Snetchild es->ctrl |= SPDIFEN_B; 1419148591Snetchild es->ctrl |= RECEN_B; 1420148591Snetchild } else { 1421148591Snetchild r &= ~ENABLE_SPDIF; 1422148591Snetchild es->ctrl &= ~SPDIFEN_B; 1423148591Snetchild es->ctrl &= ~RECEN_B; 1424148591Snetchild } 1425148591Snetchild es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4); 1426148591Snetchild es_wr(es, ES1370_REG_STATUS, r, 4); 1427150832Snetchild ES_UNLOCK(es); 1428150832Snetchild 1429150832Snetchild return (0); 1430148591Snetchild} 1431148591Snetchild 1432148591Snetchildstatic int 1433150832Snetchildsysctl_es137x_latency_timer(SYSCTL_HANDLER_ARGS) 1434148591Snetchild{ 1435148591Snetchild struct es_info *es; 1436148591Snetchild device_t dev; 1437150832Snetchild uint32_t val; 1438150832Snetchild int err; 1439148591Snetchild 1440148591Snetchild dev = oidp->oid_arg1; 1441148591Snetchild es = pcm_getdevinfo(dev); 1442150832Snetchild ES_LOCK(es); 1443148591Snetchild val = pci_read_config(dev, PCIR_LATTIMER, 1); 1444150832Snetchild ES_UNLOCK(es); 1445170289Sdwmalone err = sysctl_handle_int(oidp, &val, 0, req); 1446164614Sariff 1447148591Snetchild if (err || req->newptr == NULL) 1448150832Snetchild return (err); 1449150832Snetchild if (val > 255) 1450150832Snetchild return (EINVAL); 1451148591Snetchild 1452150832Snetchild ES_LOCK(es); 1453148591Snetchild pci_write_config(dev, PCIR_LATTIMER, val, 1); 1454150832Snetchild ES_UNLOCK(es); 1455150832Snetchild 1456150832Snetchild return (0); 1457148591Snetchild} 1458150832Snetchild 1459150832Snetchildstatic int 1460150832Snetchildsysctl_es137x_fixed_rate(SYSCTL_HANDLER_ARGS) 1461150832Snetchild{ 1462150832Snetchild struct es_info *es; 1463150832Snetchild device_t dev; 1464150832Snetchild uint32_t val; 1465150832Snetchild int err; 1466150832Snetchild 1467150832Snetchild dev = oidp->oid_arg1; 1468150832Snetchild es = pcm_getdevinfo(dev); 1469150832Snetchild ES_LOCK(es); 1470152419Sariff val = ES_FIXED_RATE(es->escfg); 1471152419Sariff if (val < es_caps.minspeed) 1472150832Snetchild val = 0; 1473150832Snetchild ES_UNLOCK(es); 1474170289Sdwmalone err = sysctl_handle_int(oidp, &val, 0, req); 1475164614Sariff 1476150832Snetchild if (err || req->newptr == NULL) 1477150832Snetchild return (err); 1478150832Snetchild if (val != 0 && (val < es_caps.minspeed || val > es_caps.maxspeed)) 1479150832Snetchild return (EINVAL); 1480150832Snetchild 1481150832Snetchild ES_LOCK(es); 1482152419Sariff if (es->ctrl & (CTRL_DAC2_EN|CTRL_ADC_EN)) { 1483152419Sariff ES_UNLOCK(es); 1484152419Sariff return (EBUSY); 1485152419Sariff } 1486150832Snetchild if (val) { 1487152419Sariff if (val != ES_FIXED_RATE(es->escfg)) { 1488152419Sariff es->escfg = ES_SET_FIXED_RATE(es->escfg, val); 1489152419Sariff es->ch[ES_DAC2].caps.maxspeed = val; 1490152419Sariff es->ch[ES_DAC2].caps.minspeed = val; 1491152419Sariff es->ch[ES_ADC].caps.maxspeed = val; 1492152419Sariff es->ch[ES_ADC].caps.minspeed = val; 1493152419Sariff es->ctrl &= ~CTRL_PCLKDIV; 1494152419Sariff es->ctrl |= DAC2_SRTODIV(val) << CTRL_SH_PCLKDIV; 1495152419Sariff es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4); 1496152419Sariff } 1497150832Snetchild } else { 1498152419Sariff es->escfg = ES_SET_FIXED_RATE(es->escfg, 0); 1499152419Sariff es->ch[ES_DAC2].caps = es_caps; 1500152419Sariff es->ch[ES_ADC].caps = es_caps; 1501150832Snetchild } 1502150832Snetchild ES_UNLOCK(es); 1503150832Snetchild 1504150832Snetchild return (0); 1505150832Snetchild} 1506152419Sariff 1507152419Sariffstatic int 1508152419Sariffsysctl_es137x_single_pcm_mixer(SYSCTL_HANDLER_ARGS) 1509152419Sariff{ 1510152419Sariff struct es_info *es; 1511152419Sariff struct snddev_info *d; 1512152419Sariff struct snd_mixer *m; 1513152419Sariff device_t dev; 1514152419Sariff uint32_t val, set; 1515152419Sariff int recsrc, level, err; 1516152419Sariff 1517152419Sariff dev = oidp->oid_arg1; 1518152419Sariff d = device_get_softc(dev); 1519170815Sariff if (!PCM_REGISTERED(d) || d->mixer_dev == NULL || 1520170815Sariff d->mixer_dev->si_drv1 == NULL) 1521152419Sariff return (EINVAL); 1522152419Sariff es = d->devinfo; 1523152419Sariff if (es == NULL) 1524152419Sariff return (EINVAL); 1525152419Sariff ES_LOCK(es); 1526152419Sariff set = ES_SINGLE_PCM_MIX(es->escfg); 1527152419Sariff val = set; 1528152419Sariff ES_UNLOCK(es); 1529170289Sdwmalone err = sysctl_handle_int(oidp, &val, 0, req); 1530164614Sariff 1531152419Sariff if (err || req->newptr == NULL) 1532152419Sariff return (err); 1533152419Sariff if (!(val == 0 || val == 1)) 1534152419Sariff return (EINVAL); 1535152419Sariff if (val == set) 1536152419Sariff return (0); 1537170815Sariff PCM_ACQUIRE_QUICK(d); 1538170815Sariff m = (d->mixer_dev != NULL) ? d->mixer_dev->si_drv1 : NULL; 1539170815Sariff if (m == NULL) { 1540170815Sariff PCM_RELEASE_QUICK(d); 1541170815Sariff return (ENODEV); 1542170815Sariff } 1543170815Sariff if (mixer_busy(m) != 0) { 1544170815Sariff PCM_RELEASE_QUICK(d); 1545152419Sariff return (EBUSY); 1546170815Sariff } 1547170815Sariff level = mix_get(m, SOUND_MIXER_PCM); 1548170815Sariff recsrc = mix_getrecsrc(m); 1549170815Sariff if (level < 0 || recsrc < 0) { 1550170815Sariff PCM_RELEASE_QUICK(d); 1551170815Sariff return (ENXIO); 1552170815Sariff } 1553152419Sariff 1554152419Sariff ES_LOCK(es); 1555152419Sariff if (es->ctrl & (CTRL_ADC_EN | CTRL_DAC1_EN | CTRL_DAC2_EN)) { 1556152419Sariff ES_UNLOCK(es); 1557170815Sariff PCM_RELEASE_QUICK(d); 1558152419Sariff return (EBUSY); 1559152419Sariff } 1560164614Sariff if (val) 1561152419Sariff es->escfg = ES_SET_SINGLE_PCM_MIX(es->escfg, 1); 1562164614Sariff else 1563152419Sariff es->escfg = ES_SET_SINGLE_PCM_MIX(es->escfg, 0); 1564152419Sariff ES_UNLOCK(es); 1565152419Sariff if (!val) { 1566170815Sariff mix_setdevs(m, mix_getdevs(m) | (1 << SOUND_MIXER_SYNTH)); 1567170815Sariff mix_setrecdevs(m, mix_getrecdevs(m) | (1 << SOUND_MIXER_SYNTH)); 1568170815Sariff err = mix_set(m, SOUND_MIXER_SYNTH, level & 0x7f, 1569170815Sariff (level >> 8) & 0x7f); 1570152419Sariff } else { 1571170815Sariff err = mix_set(m, SOUND_MIXER_SYNTH, level & 0x7f, 1572170815Sariff (level >> 8) & 0x7f); 1573170815Sariff mix_setdevs(m, mix_getdevs(m) & ~(1 << SOUND_MIXER_SYNTH)); 1574170815Sariff mix_setrecdevs(m, mix_getrecdevs(m) & 1575164614Sariff ~(1 << SOUND_MIXER_SYNTH)); 1576152419Sariff } 1577152419Sariff if (!err) { 1578152419Sariff level = recsrc; 1579152419Sariff if (recsrc & (1 << SOUND_MIXER_PCM)) 1580152419Sariff recsrc |= 1 << SOUND_MIXER_SYNTH; 1581152419Sariff else if (recsrc & (1 << SOUND_MIXER_SYNTH)) 1582152419Sariff recsrc |= 1 << SOUND_MIXER_PCM; 1583152419Sariff if (level != recsrc) 1584170815Sariff err = mix_setrecsrc(m, recsrc); 1585152419Sariff } 1586170815Sariff 1587170815Sariff PCM_RELEASE_QUICK(d); 1588170815Sariff 1589152419Sariff return (err); 1590152419Sariff} 1591164614Sariff 1592164614Sariffstatic int 1593164614Sariffsysctl_es_polling(SYSCTL_HANDLER_ARGS) 1594164614Sariff{ 1595164614Sariff struct es_info *es; 1596164614Sariff device_t dev; 1597164614Sariff int err, val; 1598164614Sariff 1599164614Sariff dev = oidp->oid_arg1; 1600164614Sariff es = pcm_getdevinfo(dev); 1601164614Sariff if (es == NULL) 1602164614Sariff return (EINVAL); 1603164614Sariff ES_LOCK(es); 1604164614Sariff val = es->polling; 1605164614Sariff ES_UNLOCK(es); 1606170289Sdwmalone err = sysctl_handle_int(oidp, &val, 0, req); 1607164614Sariff 1608164614Sariff if (err || req->newptr == NULL) 1609164614Sariff return (err); 1610164614Sariff if (val < 0 || val > 1) 1611164614Sariff return (EINVAL); 1612164614Sariff 1613164614Sariff ES_LOCK(es); 1614164614Sariff if (val != es->polling) { 1615164614Sariff if (es_chan_active(es) != 0) 1616164614Sariff err = EBUSY; 1617164614Sariff else if (val == 0) 1618164614Sariff es->polling = 0; 1619164614Sariff else 1620164614Sariff es->polling = 1; 1621164614Sariff } 1622164614Sariff ES_UNLOCK(es); 1623164614Sariff 1624164614Sariff return (err); 1625164614Sariff} 1626148591Snetchild 1627148591Snetchildstatic void 1628148591Snetchildes_init_sysctls(device_t dev) 1629148591Snetchild{ 1630148591Snetchild struct es_info *es; 1631148591Snetchild int r, devid, revid; 1632148591Snetchild 1633148591Snetchild devid = pci_get_devid(dev); 1634148591Snetchild revid = pci_get_revid(dev); 1635148591Snetchild es = pcm_getdevinfo(dev); 1636148591Snetchild if ((devid == ES1371_PCI_ID && revid == ES1371REV_ES1373_8) || 1637167648Sariff (devid == ES1371_PCI_ID && revid == ES1371REV_CT5880_A) || 1638167648Sariff (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_C) || 1639167648Sariff (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_D) || 1640167648Sariff (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_E)) { 1641159732Snetchild /* XXX: an user should be able to set this with a control tool, 1642159732Snetchild if not done before 7.0-RELEASE, this needs to be converted 1643159732Snetchild to a device specific sysctl "dev.pcm.X.yyy" via 1644159732Snetchild device_get_sysctl_*() as discussed on multimedia@ in msg-id 1645159732Snetchild <861wujij2q.fsf@xps.des.no> */ 1646164614Sariff SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 1647164614Sariff SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 1648164614Sariff "spdif_enabled", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 1649164614Sariff sysctl_es137x_spdif_enable, "I", 1650164614Sariff "Enable S/PDIF output on primary playback channel"); 1651150832Snetchild } else if (devid == ES1370_PCI_ID) { 1652152419Sariff /* 1653152419Sariff * Enable fixed rate sysctl if both DAC2 / ADC enabled. 1654152419Sariff */ 1655164614Sariff if (es->ch[ES_DAC2].channel != NULL && 1656164614Sariff es->ch[ES_ADC].channel != NULL) { 1657159732Snetchild /* XXX: an user should be able to set this with a control tool, 1658159732Snetchild if not done before 7.0-RELEASE, this needs to be converted 1659159732Snetchild to a device specific sysctl "dev.pcm.X.yyy" via 1660159732Snetchild device_get_sysctl_*() as discussed on multimedia@ in msg-id 1661159732Snetchild <861wujij2q.fsf@xps.des.no> */ 1662164614Sariff SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 1663164614Sariff SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 1664164614Sariff OID_AUTO, "fixed_rate", CTLTYPE_INT | CTLFLAG_RW, 1665164614Sariff dev, sizeof(dev), sysctl_es137x_fixed_rate, "I", 1666164614Sariff "Enable fixed rate playback/recording"); 1667152419Sariff } 1668152419Sariff /* 1669152419Sariff * Enable single pcm mixer sysctl if both DAC1/2 enabled. 1670152419Sariff */ 1671164614Sariff if (es->ch[ES_DAC1].channel != NULL && 1672164614Sariff es->ch[ES_DAC2].channel != NULL) { 1673159732Snetchild /* XXX: an user should be able to set this with a control tool, 1674159732Snetchild if not done before 7.0-RELEASE, this needs to be converted 1675159732Snetchild to a device specific sysctl "dev.pcm.X.yyy" via 1676159732Snetchild device_get_sysctl_*() as discussed on multimedia@ in msg-id 1677159732Snetchild <861wujij2q.fsf@xps.des.no> */ 1678164614Sariff SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 1679164614Sariff SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 1680164614Sariff OID_AUTO, "single_pcm_mixer", 1681164614Sariff CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 1682164614Sariff sysctl_es137x_single_pcm_mixer, "I", 1683164614Sariff "Single PCM mixer controller for both DAC1/DAC2"); 1684152419Sariff } 1685148591Snetchild } 1686164614Sariff if (resource_int_value(device_get_name(dev), device_get_unit(dev), 1687164614Sariff "latency_timer", &r) == 0 && !(r < 0 || r > 255)) 1688148591Snetchild pci_write_config(dev, PCIR_LATTIMER, r, 1); 1689159732Snetchild /* XXX: this needs to be converted to a device specific sysctl 1690159732Snetchild "dev.pcm.X.yyy" via device_get_sysctl_*() as discussed on 1691159732Snetchild multimedia@ in msg-id <861wujij2q.fsf@xps.des.no> */ 1692164614Sariff SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 1693164614Sariff SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 1694164614Sariff "latency_timer", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 1695164614Sariff sysctl_es137x_latency_timer, "I", 1696164614Sariff "PCI Latency Timer configuration"); 1697164614Sariff SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 1698164614Sariff SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 1699164614Sariff "polling", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 1700164614Sariff sysctl_es_polling, "I", 1701164614Sariff "Enable polling mode"); 1702148591Snetchild} 1703148591Snetchild 1704148591Snetchildstatic int 170550724Scges_pci_attach(device_t dev) 170650724Scg{ 1707150832Snetchild struct es_info *es = NULL; 1708152419Sariff int mapped, i, numplay, dac_cfg; 170950724Scg char status[SND_STATUSLEN]; 1710150832Snetchild struct ac97_info *codec = NULL; 171170134Scg kobj_class_t ct = NULL; 1712150832Snetchild uint32_t devid; 171350724Scg 1714170873Sariff es = malloc(sizeof *es, M_DEVBUF, M_WAITOK | M_ZERO); 1715167608Sariff es->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_es137x softc"); 171659019Scg es->dev = dev; 1717152419Sariff es->escfg = 0; 171850724Scg mapped = 0; 1719150832Snetchild 1720150832Snetchild pci_enable_busmaster(dev); 1721254263Sscottl if (mapped == 0) { 172265644Scg es->regid = MEM_MAP_REG; 172365644Scg es->regtype = SYS_RES_MEMORY; 1724127135Snjl es->reg = bus_alloc_resource_any(dev, es->regtype, &es->regid, 1725164614Sariff RF_ACTIVE); 1726150832Snetchild if (es->reg) 172750724Scg mapped++; 172850724Scg } 1729254263Sscottl if (mapped == 0) { 1730119690Sjhb es->regid = PCIR_BAR(0); 173165644Scg es->regtype = SYS_RES_IOPORT; 1732127135Snjl es->reg = bus_alloc_resource_any(dev, es->regtype, &es->regid, 1733164614Sariff RF_ACTIVE); 1734150832Snetchild if (es->reg) 173550724Scg mapped++; 173650724Scg } 173750724Scg if (mapped == 0) { 173850724Scg device_printf(dev, "unable to map register space\n"); 173950724Scg goto bad; 174050724Scg } 174154831Scg 1742150832Snetchild es->st = rman_get_bustag(es->reg); 1743150832Snetchild es->sh = rman_get_bushandle(es->reg); 1744283291Sjkim callout_init(&es->poll_timer, 1); 1745164614Sariff es->poll_ticks = 1; 1746164614Sariff 1747164614Sariff if (resource_int_value(device_get_name(dev), 1748164614Sariff device_get_unit(dev), "polling", &i) == 0 && i != 0) 1749164614Sariff es->polling = 1; 1750164614Sariff else 1751164614Sariff es->polling = 0; 1752164614Sariff 175384658Scg es->bufsz = pcm_getbuffersize(dev, 4096, ES_DEFAULT_BUFSZ, 65536); 1754164614Sariff if (resource_int_value(device_get_name(dev), 1755164614Sariff device_get_unit(dev), "blocksize", &i) == 0 && i > 0) { 1756167648Sariff i &= ES_BLK_ALIGN; 1757167648Sariff if (i < ES_BLK_MIN) 1758167648Sariff i = ES_BLK_MIN; 1759164614Sariff es->blkcnt = es->bufsz / i; 1760164614Sariff i = 0; 1761164614Sariff while (es->blkcnt >> i) 1762164614Sariff i++; 1763164614Sariff es->blkcnt = 1 << (i - 1); 1764167648Sariff if (es->blkcnt < ES_DMA_SEGS_MIN) 1765167648Sariff es->blkcnt = ES_DMA_SEGS_MIN; 1766167648Sariff else if (es->blkcnt > ES_DMA_SEGS_MAX) 1767167648Sariff es->blkcnt = ES_DMA_SEGS_MAX; 176884658Scg 1769164614Sariff } else 1770164614Sariff es->blkcnt = 2; 1771164614Sariff 1772164614Sariff if (resource_int_value(device_get_name(dev), device_get_unit(dev), 1773164614Sariff "dac", &dac_cfg) == 0) { 1774152419Sariff if (dac_cfg < 0 || dac_cfg > 3) 1775152419Sariff dac_cfg = ES_DEFAULT_DAC_CFG; 1776152419Sariff } else 1777152419Sariff dac_cfg = ES_DEFAULT_DAC_CFG; 1778152419Sariff 1779152419Sariff switch (dac_cfg) { 1780164614Sariff case 0: /* Enable all DAC: DAC1, DAC2 */ 1781164614Sariff numplay = 2; 1782164614Sariff es->escfg = ES_SET_DAC_FIRST(es->escfg, ES_DAC1); 1783164614Sariff es->escfg = ES_SET_DAC_SECOND(es->escfg, ES_DAC2); 1784164614Sariff break; 1785164614Sariff case 1: /* Only DAC1 */ 1786164614Sariff numplay = 1; 1787164614Sariff es->escfg = ES_SET_DAC_FIRST(es->escfg, ES_DAC1); 1788164614Sariff break; 1789164614Sariff case 3: /* Enable all DAC / swap position: DAC2, DAC1 */ 1790164614Sariff numplay = 2; 1791164614Sariff es->escfg = ES_SET_DAC_FIRST(es->escfg, ES_DAC2); 1792164614Sariff es->escfg = ES_SET_DAC_SECOND(es->escfg, ES_DAC1); 1793164614Sariff break; 1794164614Sariff case 2: /* Only DAC2 */ 1795164614Sariff default: 1796164614Sariff numplay = 1; 1797164614Sariff es->escfg = ES_SET_DAC_FIRST(es->escfg, ES_DAC2); 1798164614Sariff break; 1799152419Sariff } 1800152419Sariff es->escfg = ES_SET_NUMPLAY(es->escfg, numplay); 1801152419Sariff es->escfg = ES_SET_NUMREC(es->escfg, 1); 1802152419Sariff 1803148591Snetchild devid = pci_get_devid(dev); 1804150832Snetchild switch (devid) { 1805150832Snetchild case ES1371_PCI_ID: 1806150832Snetchild case ES1371_PCI_ID2: 1807150832Snetchild case CT5880_PCI_ID: 1808150832Snetchild case CT4730_PCI_ID: 1809150832Snetchild es1371_init(es); 1810150832Snetchild codec = AC97_CREATE(dev, es, es1371_ac97); 1811150832Snetchild if (codec == NULL) 181254831Scg goto bad; 181354831Scg /* our init routine does everything for us */ 181454831Scg /* set to NULL; flag mixer_init not to run the ac97_init */ 181554831Scg /* ac97_mixer.init = NULL; */ 1816150832Snetchild if (mixer_init(dev, ac97_getmixerclass(), codec)) 1817150832Snetchild goto bad; 181870134Scg ct = &eschan1371_class; 1819150832Snetchild break; 1820150832Snetchild case ES1370_PCI_ID: 1821150832Snetchild es1370_init(es); 1822152419Sariff /* 1823152419Sariff * Disable fixed rate operation if DAC2 disabled. 1824152419Sariff * This is a special case for es1370 only, where the 1825152419Sariff * speed of both ADC and DAC2 locked together. 1826152419Sariff */ 1827164614Sariff if (!ES_DAC2_ENABLED(es->escfg)) 1828152419Sariff es->escfg = ES_SET_FIXED_RATE(es->escfg, 0); 1829150832Snetchild if (mixer_init(dev, &es1370_mixer_class, es)) 183054831Scg goto bad; 183170134Scg ct = &eschan1370_class; 1832150832Snetchild break; 1833150832Snetchild default: 1834150832Snetchild goto bad; 1835150832Snetchild /* NOTREACHED */ 1836150832Snetchild } 183750724Scg 183865644Scg es->irqid = 0; 1839127135Snjl es->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &es->irqid, 1840164614Sariff RF_ACTIVE | RF_SHAREABLE); 1841164614Sariff if (!es->irq || snd_setup_intr(dev, es->irq, INTR_MPSAFE, es_intr, 1842164614Sariff es, &es->ih)) { 184350724Scg device_printf(dev, "unable to map interrupt\n"); 184450724Scg goto bad; 184550724Scg } 184650724Scg 1847166165Smarius if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), 1848166165Smarius /*alignment*/2, /*boundary*/0, 184950724Scg /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 185050724Scg /*highaddr*/BUS_SPACE_MAXADDR, 185150724Scg /*filter*/NULL, /*filterarg*/NULL, 185284658Scg /*maxsize*/es->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff, 1853148591Snetchild /*flags*/0, /*lockfunc*/NULL, 1854148591Snetchild /*lockarg*/NULL, &es->parent_dmat) != 0) { 185550724Scg device_printf(dev, "unable to create dma tag\n"); 185650724Scg goto bad; 185750724Scg } 185850724Scg 1859297000Sjhibbits snprintf(status, SND_STATUSLEN, "at %s 0x%jx irq %jd %s", 1860164614Sariff (es->regtype == SYS_RES_IOPORT)? "io" : "memory", 1861164614Sariff rman_get_start(es->reg), rman_get_start(es->irq), 1862164614Sariff PCM_KLDSTRING(snd_es137x)); 186350724Scg 1864152419Sariff if (pcm_register(dev, es, numplay, 1)) 1865150832Snetchild goto bad; 1866152419Sariff for (i = 0; i < numplay; i++) 1867152419Sariff pcm_addchan(dev, PCMDIR_PLAY, ct, es); 186854831Scg pcm_addchan(dev, PCMDIR_REC, ct, es); 1869148591Snetchild es_init_sysctls(dev); 187050724Scg pcm_setstatus(dev, status); 1871152419Sariff es->escfg = ES_SET_GP(es->escfg, 0); 1872164614Sariff if (numplay == 1) 1873152419Sariff device_printf(dev, "<Playback: DAC%d / Record: ADC>\n", 1874164614Sariff ES_DAC_FIRST(es->escfg) + 1); 1875164614Sariff else if (numplay == 2) 1876152419Sariff device_printf(dev, "<Playback: DAC%d,DAC%d / Record: ADC>\n", 1877164614Sariff ES_DAC_FIRST(es->escfg) + 1, ES_DAC_SECOND(es->escfg) + 1); 1878164614Sariff return (0); 187950724Scg 1880164614Sariffbad: 1881164614Sariff if (es->parent_dmat) 1882164614Sariff bus_dma_tag_destroy(es->parent_dmat); 1883164614Sariff if (es->ih) 1884164614Sariff bus_teardown_intr(dev, es->irq, es->ih); 1885164614Sariff if (es->irq) 1886164614Sariff bus_release_resource(dev, SYS_RES_IRQ, es->irqid, es->irq); 1887164614Sariff if (codec) 1888164614Sariff ac97_destroy(codec); 1889164614Sariff if (es->reg) 1890164614Sariff bus_release_resource(dev, es->regtype, es->regid, es->reg); 1891164614Sariff if (es->lock) 1892164614Sariff snd_mtxfree(es->lock); 1893164614Sariff if (es) 1894164614Sariff free(es, M_DEVBUF); 1895164614Sariff return (ENXIO); 189650724Scg} 189750724Scg 189865644Scgstatic int 189965644Scges_pci_detach(device_t dev) 190065644Scg{ 190165644Scg int r; 190265644Scg struct es_info *es; 190365644Scg 190465644Scg r = pcm_unregister(dev); 1905164614Sariff if (r) 1906164614Sariff return (r); 190765644Scg 190865644Scg es = pcm_getdevinfo(dev); 1909170721Sariff 1910170721Sariff if (es != NULL && es->num != 0) { 1911170721Sariff ES_LOCK(es); 1912170721Sariff es->polling = 0; 1913170721Sariff callout_stop(&es->poll_timer); 1914170721Sariff ES_UNLOCK(es); 1915170721Sariff callout_drain(&es->poll_timer); 1916170721Sariff } 1917170721Sariff 191865644Scg bus_teardown_intr(dev, es->irq, es->ih); 191965644Scg bus_release_resource(dev, SYS_RES_IRQ, es->irqid, es->irq); 1920148591Snetchild bus_release_resource(dev, es->regtype, es->regid, es->reg); 1921150832Snetchild bus_dma_tag_destroy(es->parent_dmat); 1922148591Snetchild snd_mtxfree(es->lock); 192365644Scg free(es, M_DEVBUF); 192465644Scg 1925164614Sariff return (0); 192665644Scg} 192765644Scg 192850724Scgstatic device_method_t es_methods[] = { 192950724Scg /* Device interface */ 193050724Scg DEVMETHOD(device_probe, es_pci_probe), 193150724Scg DEVMETHOD(device_attach, es_pci_attach), 193265644Scg DEVMETHOD(device_detach, es_pci_detach), 193350724Scg 193450724Scg { 0, 0 } 193550724Scg}; 193650724Scg 193750724Scgstatic driver_t es_driver = { 193850724Scg "pcm", 193950724Scg es_methods, 194082180Scg PCM_SOFTC_SIZE, 194150724Scg}; 194250724Scg 194362483ScgDRIVER_MODULE(snd_es137x, pci, es_driver, pcm_devclass, 0, 0); 1944132236StanimuraMODULE_DEPEND(snd_es137x, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 194562483ScgMODULE_VERSION(snd_es137x, 1); 1946