es137x.c revision 170873
1139749Simp/*- 253413Sroger * Support the ENSONIQ AudioPCI board and Creative Labs SoundBlaster PCI 353413Sroger * boards based on the ES1370, ES1371 and ES1373 chips. 450724Scg * 553413Sroger * Copyright (c) 1999 Russell Cattelan <cattelan@thebarn.com> 6119853Scg * Copyright (c) 1999 Cameron Grant <cg@freebsd.org> 750724Scg * Copyright (c) 1998 by Joachim Kuebart. All rights reserved. 850724Scg * 950724Scg * Redistribution and use in source and binary forms, with or without 1050724Scg * modification, are permitted provided that the following conditions 1150724Scg * are met: 1250724Scg * 1350724Scg * 1. Redistributions of source code must retain the above copyright 1450724Scg * notice, this list of conditions and the following disclaimer. 1550724Scg * 1650724Scg * 2. Redistributions in binary form must reproduce the above copyright 1750724Scg * notice, this list of conditions and the following disclaimer in 1850724Scg * the documentation and/or other materials provided with the 1950724Scg * distribution. 2050724Scg * 2150724Scg * 3. All advertising materials mentioning features or use of this 2250724Scg * software must display the following acknowledgement: 2350724Scg * This product includes software developed by Joachim Kuebart. 2450724Scg * 2550724Scg * 4. The name of the author may not be used to endorse or promote 2650724Scg * products derived from this software without specific prior 2750724Scg * written permission. 2850724Scg * 2950724Scg * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 3050724Scg * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 3150724Scg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 3250724Scg * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 3350724Scg * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 3450724Scg * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 3550724Scg * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3650724Scg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3750724Scg * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3850724Scg * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 3950724Scg * OF THE POSSIBILITY OF SUCH DAMAGE. 4050724Scg */ 4150724Scg 4253413Sroger/* 4353413Sroger * Part of this code was heavily inspired by the linux driver from 4453413Sroger * Thomas Sailer (sailer@ife.ee.ethz.ch) 4554831Scg * Just about everything has been touched and reworked in some way but 4654831Scg * the all the underlying sequences/timing/register values are from 4753413Sroger * Thomas' code. 4853413Sroger * 4953413Sroger*/ 5053413Sroger 5153465Scg#include <dev/sound/pcm/sound.h> 5253465Scg#include <dev/sound/pcm/ac97.h> 5353465Scg#include <dev/sound/pci/es137x.h> 5450724Scg 55119287Simp#include <dev/pci/pcireg.h> 56119287Simp#include <dev/pci/pcivar.h> 5750724Scg 5853413Sroger#include <sys/sysctl.h> 5953413Sroger 6070134Scg#include "mixer_if.h" 6170134Scg 6282180ScgSND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pci/es137x.c 170873 2007-06-17 06:10:43Z ariff $"); 6382180Scg 6450724Scg#define MEM_MAP_REG 0x14 6550724Scg 6650724Scg/* PCI IDs of supported chips */ 6750724Scg#define ES1370_PCI_ID 0x50001274 6853413Sroger#define ES1371_PCI_ID 0x13711274 6956154Speter#define ES1371_PCI_ID2 0x13713274 7076086Scg#define CT5880_PCI_ID 0x58801274 71119548Sorion#define CT4730_PCI_ID 0x89381102 7250724Scg 7378033Scg#define ES1371REV_ES1371_A 0x02 7476086Scg#define ES1371REV_ES1371_B 0x09 7576086Scg 7676086Scg#define ES1371REV_ES1373_8 0x08 7776086Scg#define ES1371REV_ES1373_A 0x04 7876086Scg#define ES1371REV_ES1373_B 0x06 7976086Scg 8076086Scg#define ES1371REV_CT5880_A 0x07 8176086Scg 8276086Scg#define CT5880REV_CT5880_C 0x02 8376086Scg#define CT5880REV_CT5880_D 0x03 8495678Scg#define CT5880REV_CT5880_E 0x04 8576086Scg 86119548Sorion#define CT4730REV_CT4730_A 0x00 87119548Sorion 8884658Scg#define ES_DEFAULT_BUFSZ 4096 8959019Scg 90152419Sariff/* 2 DAC for playback, 1 ADC for record */ 91152419Sariff#define ES_DAC1 0 92152419Sariff#define ES_DAC2 1 93152419Sariff#define ES_ADC 2 94152419Sariff#define ES_NCHANS 3 95152419Sariff 96167648Sariff#define ES_DMA_SEGS_MIN 2 97167648Sariff#define ES_DMA_SEGS_MAX 256 98167648Sariff#define ES_BLK_MIN 64 99167648Sariff#define ES_BLK_ALIGN (~(ES_BLK_MIN - 1)) 100167648Sariff 101152419Sariff#define ES1370_DAC1_MINSPEED 5512 102152419Sariff#define ES1370_DAC1_MAXSPEED 44100 103152419Sariff 10450724Scg/* device private data */ 10550724Scgstruct es_info; 10650724Scg 10755209Scgstruct es_chinfo { 10850724Scg struct es_info *parent; 10974763Scg struct pcm_channel *channel; 11074763Scg struct snd_dbuf *buffer; 111152419Sariff struct pcmchan_caps caps; 112152419Sariff int dir, num, index; 113164614Sariff uint32_t fmt, blksz, blkcnt, bufsz; 114164614Sariff uint32_t ptr, prevptr; 115164614Sariff int active; 11655209Scg}; 11750724Scg 118152419Sariff/* 119152419Sariff * 32bit Ensoniq Configuration (es->escfg). 120152419Sariff * ---------------------------------------- 121152419Sariff * 122152419Sariff * +-------+--------+------+------+---------+--------+---------+---------+ 123152419Sariff * len | 16 | 1 | 1 | 1 | 2 | 2 | 1 | 8 | 124152419Sariff * +-------+--------+------+------+---------+--------+---------+---------+ 125152419Sariff * | fixed | single | | | | | is | general | 126152419Sariff * | rate | pcm | DACx | DACy | numplay | numrec | es1370? | purpose | 127152419Sariff * | | mixer | | | | | | | 128152419Sariff * +-------+--------+------+------+---------+--------+---------+---------+ 129152419Sariff */ 130152419Sariff#define ES_FIXED_RATE(cfgv) \ 131152419Sariff (((cfgv) & 0xffff0000) >> 16) 132152419Sariff#define ES_SET_FIXED_RATE(cfgv, nv) \ 133152419Sariff (((cfgv) & ~0xffff0000) | (((nv) & 0xffff) << 16)) 134152419Sariff#define ES_SINGLE_PCM_MIX(cfgv) \ 135152419Sariff (((cfgv) & 0x8000) >> 15) 136152419Sariff#define ES_SET_SINGLE_PCM_MIX(cfgv, nv) \ 137152419Sariff (((cfgv) & ~0x8000) | (((nv) ? 1 : 0) << 15)) 138152419Sariff#define ES_DAC_FIRST(cfgv) \ 139152419Sariff (((cfgv) & 0x4000) >> 14) 140152419Sariff#define ES_SET_DAC_FIRST(cfgv, nv) \ 141152419Sariff (((cfgv) & ~0x4000) | (((nv) & 0x1) << 14)) 142152419Sariff#define ES_DAC_SECOND(cfgv) \ 143152419Sariff (((cfgv) & 0x2000) >> 13) 144152419Sariff#define ES_SET_DAC_SECOND(cfgv, nv) \ 145152419Sariff (((cfgv) & ~0x2000) | (((nv) & 0x1) << 13)) 146152419Sariff#define ES_NUMPLAY(cfgv) \ 147152419Sariff (((cfgv) & 0x1800) >> 11) 148152419Sariff#define ES_SET_NUMPLAY(cfgv, nv) \ 149152419Sariff (((cfgv) & ~0x1800) | (((nv) & 0x3) << 11)) 150152419Sariff#define ES_NUMREC(cfgv) \ 151152419Sariff (((cfgv) & 0x600) >> 9) 152152419Sariff#define ES_SET_NUMREC(cfgv, nv) \ 153152419Sariff (((cfgv) & ~0x600) | (((nv) & 0x3) << 9)) 154152419Sariff#define ES_IS_ES1370(cfgv) \ 155152419Sariff (((cfgv) & 0x100) >> 8) 156152419Sariff#define ES_SET_IS_ES1370(cfgv, nv) \ 157152419Sariff (((cfgv) & ~0x100) | (((nv) ? 1 : 0) << 8)) 158152419Sariff#define ES_GP(cfgv) \ 159152419Sariff ((cfgv) & 0xff) 160152419Sariff#define ES_SET_GP(cfgv, nv) \ 161152419Sariff (((cfgv) & ~0xff) | ((nv) & 0xff)) 162152419Sariff 163152419Sariff#define ES_DAC1_ENABLED(cfgv) \ 164152419Sariff (ES_NUMPLAY(cfgv) > 1 || \ 165152419Sariff (ES_NUMPLAY(cfgv) == 1 && ES_DAC_FIRST(cfgv) == ES_DAC1)) 166152419Sariff#define ES_DAC2_ENABLED(cfgv) \ 167152419Sariff (ES_NUMPLAY(cfgv) > 1 || \ 168152419Sariff (ES_NUMPLAY(cfgv) == 1 && ES_DAC_FIRST(cfgv) == ES_DAC2)) 169152419Sariff 170152419Sariff/* 171152419Sariff * DAC 1/2 configuration through kernel hint - hint.pcm.<unit>.dac="val" 172152419Sariff * 173152419Sariff * 0 = Enable both DACs - Default 174152419Sariff * 1 = Enable single DAC (DAC1) 175152419Sariff * 2 = Enable single DAC (DAC2) 176152419Sariff * 3 = Enable both DACs, swap position (DAC2 comes first instead of DAC1) 177152419Sariff */ 178152419Sariff#define ES_DEFAULT_DAC_CFG 0 179152419Sariff 18055209Scgstruct es_info { 18150724Scg bus_space_tag_t st; 18250724Scg bus_space_handle_t sh; 18350724Scg bus_dma_tag_t parent_dmat; 18450724Scg 18565644Scg struct resource *reg, *irq; 18665644Scg int regtype, regid, irqid; 18765644Scg void *ih; 18865644Scg 18959019Scg device_t dev; 19054831Scg int num; 191164614Sariff unsigned int bufsz, blkcnt; 19284658Scg 19350724Scg /* Contents of board's registers */ 194150832Snetchild uint32_t ctrl; 195150832Snetchild uint32_t sctrl; 196152419Sariff uint32_t escfg; 197152419Sariff struct es_chinfo ch[ES_NCHANS]; 198148591Snetchild struct mtx *lock; 199164614Sariff struct callout poll_timer; 200164614Sariff int poll_ticks, polling; 20155209Scg}; 20250724Scg 203150832Snetchild#define ES_LOCK(sc) snd_mtxlock((sc)->lock) 204150832Snetchild#define ES_UNLOCK(sc) snd_mtxunlock((sc)->lock) 205150832Snetchild#define ES_LOCK_ASSERT(sc) snd_mtxassert((sc)->lock) 20654831Scg 20753413Sroger/* prototypes */ 20854831Scgstatic void es_intr(void *); 209150832Snetchildstatic uint32_t es1371_wait_src_ready(struct es_info *); 210164614Sariffstatic void es1371_src_write(struct es_info *, 211164614Sariff unsigned short, unsigned short); 212164614Sariffstatic unsigned int es1371_adc_rate(struct es_info *, unsigned int, int); 213164614Sariffstatic unsigned int es1371_dac_rate(struct es_info *, unsigned int, int); 214150832Snetchildstatic int es1371_init(struct es_info *); 21554831Scgstatic int es1370_init(struct es_info *); 216164614Sariffstatic int es1370_wrcodec(struct es_info *, unsigned char, unsigned char); 21750724Scg 218164614Sariffstatic uint32_t es_fmt[] = { 21964881Scg AFMT_U8, 22064881Scg AFMT_STEREO | AFMT_U8, 22164881Scg AFMT_S16_LE, 22264881Scg AFMT_STEREO | AFMT_S16_LE, 22364881Scg 0 22450724Scg}; 225150832Snetchildstatic struct pcmchan_caps es_caps = {4000, 48000, es_fmt, 0}; 22650724Scg 22750724Scgstatic const struct { 22850724Scg unsigned volidx:4; 22950724Scg unsigned left:4; 23050724Scg unsigned right:4; 23150724Scg unsigned stereo:1; 23250724Scg unsigned recmask:13; 23350724Scg unsigned avail:1; 23450724Scg} mixtable[SOUND_MIXER_NRDEVICES] = { 235152419Sariff [SOUND_MIXER_VOLUME] = { 0, 0x0, 0x1, 1, 0x1f7f, 1 }, 23650724Scg [SOUND_MIXER_PCM] = { 1, 0x2, 0x3, 1, 0x0400, 1 }, 23750724Scg [SOUND_MIXER_SYNTH] = { 2, 0x4, 0x5, 1, 0x0060, 1 }, 23850724Scg [SOUND_MIXER_CD] = { 3, 0x6, 0x7, 1, 0x0006, 1 }, 23950724Scg [SOUND_MIXER_LINE] = { 4, 0x8, 0x9, 1, 0x0018, 1 }, 24050724Scg [SOUND_MIXER_LINE1] = { 5, 0xa, 0xb, 1, 0x1800, 1 }, 24150724Scg [SOUND_MIXER_LINE2] = { 6, 0xc, 0x0, 0, 0x0100, 1 }, 24250724Scg [SOUND_MIXER_LINE3] = { 7, 0xd, 0x0, 0, 0x0200, 1 }, 24350724Scg [SOUND_MIXER_MIC] = { 8, 0xe, 0x0, 0, 0x0001, 1 }, 24454831Scg [SOUND_MIXER_OGAIN] = { 9, 0xf, 0x0, 0, 0x0000, 1 } 24554831Scg}; 24650724Scg 247164614Sariffstatic __inline uint32_t 248148591Snetchildes_rd(struct es_info *es, int regno, int size) 249148591Snetchild{ 250148591Snetchild switch (size) { 251148591Snetchild case 1: 252164614Sariff return (bus_space_read_1(es->st, es->sh, regno)); 253148591Snetchild case 2: 254164614Sariff return (bus_space_read_2(es->st, es->sh, regno)); 255148591Snetchild case 4: 256164614Sariff return (bus_space_read_4(es->st, es->sh, regno)); 257148591Snetchild default: 258164614Sariff return (0xFFFFFFFF); 259148591Snetchild } 260148591Snetchild} 261148591Snetchild 262150832Snetchildstatic __inline void 263164614Sariffes_wr(struct es_info *es, int regno, uint32_t data, int size) 264148591Snetchild{ 265148591Snetchild 266148591Snetchild switch (size) { 267148591Snetchild case 1: 268148591Snetchild bus_space_write_1(es->st, es->sh, regno, data); 269148591Snetchild break; 270148591Snetchild case 2: 271148591Snetchild bus_space_write_2(es->st, es->sh, regno, data); 272148591Snetchild break; 273148591Snetchild case 4: 274148591Snetchild bus_space_write_4(es->st, es->sh, regno, data); 275148591Snetchild break; 276148591Snetchild } 277148591Snetchild} 278148591Snetchild 27970134Scg/* -------------------------------------------------------------------- */ 28070134Scg/* The es1370 mixer interface */ 28170134Scg 28250724Scgstatic int 28374763Scges1370_mixinit(struct snd_mixer *m) 28450724Scg{ 285152419Sariff struct es_info *es; 28650724Scg int i; 287164614Sariff uint32_t v; 28850724Scg 289152419Sariff es = mix_getdevinfo(m); 29050724Scg v = 0; 291164614Sariff for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { 292164614Sariff if (mixtable[i].avail) 293164614Sariff v |= (1 << i); 294164614Sariff } 295152419Sariff /* 296152419Sariff * Each DAC1/2 for ES1370 can be controlled independently 297152419Sariff * DAC1 = controlled by synth 298152419Sariff * DAC2 = controlled by pcm 299152419Sariff * This is indeed can confuse user if DAC1 become primary playback 300152419Sariff * channel. Try to be smart and combine both if necessary. 301152419Sariff */ 302152419Sariff if (ES_SINGLE_PCM_MIX(es->escfg)) 303152419Sariff v &= ~(1 << SOUND_MIXER_SYNTH); 30450724Scg mix_setdevs(m, v); 30550724Scg v = 0; 306164614Sariff for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { 307164614Sariff if (mixtable[i].recmask) 308164614Sariff v |= (1 << i); 309164614Sariff } 310152419Sariff if (ES_SINGLE_PCM_MIX(es->escfg)) /* ditto */ 311152419Sariff v &= ~(1 << SOUND_MIXER_SYNTH); 31250724Scg mix_setrecdevs(m, v); 313164614Sariff return (0); 31450724Scg} 31550724Scg 31650724Scgstatic int 31774763Scges1370_mixset(struct snd_mixer *m, unsigned dev, unsigned left, unsigned right) 31850724Scg{ 319150832Snetchild struct es_info *es; 320152419Sariff int l, r, rl, rr, set_dac1; 32150724Scg 322164614Sariff if (!mixtable[dev].avail) 323164614Sariff return (-1); 32450724Scg l = left; 325164614Sariff r = (mixtable[dev].stereo) ? right : l; 326164614Sariff if (mixtable[dev].left == 0xf) 327164614Sariff rl = (l < 2) ? 0x80 : 7 - (l - 2) / 14; 328164614Sariff else 329164614Sariff rl = (l < 10) ? 0x80 : 15 - (l - 10) / 6; 330150832Snetchild es = mix_getdevinfo(m); 331150832Snetchild ES_LOCK(es); 332152419Sariff if (dev == SOUND_MIXER_PCM && (ES_SINGLE_PCM_MIX(es->escfg)) && 333164614Sariff ES_DAC1_ENABLED(es->escfg)) 334152419Sariff set_dac1 = 1; 335164614Sariff else 336152419Sariff set_dac1 = 0; 33750724Scg if (mixtable[dev].stereo) { 338164614Sariff rr = (r < 10) ? 0x80 : 15 - (r - 10) / 6; 339150832Snetchild es1370_wrcodec(es, mixtable[dev].right, rr); 340152419Sariff if (set_dac1 && mixtable[SOUND_MIXER_SYNTH].stereo) 341164614Sariff es1370_wrcodec(es, 342164614Sariff mixtable[SOUND_MIXER_SYNTH].right, rr); 34350724Scg } 344150832Snetchild es1370_wrcodec(es, mixtable[dev].left, rl); 345152419Sariff if (set_dac1) 346152419Sariff es1370_wrcodec(es, mixtable[SOUND_MIXER_SYNTH].left, rl); 347150832Snetchild ES_UNLOCK(es); 348150832Snetchild 349164614Sariff return (l | (r << 8)); 35050724Scg} 35150724Scg 35250724Scgstatic int 353164614Sariffes1370_mixsetrecsrc(struct snd_mixer *m, uint32_t src) 35450724Scg{ 355150832Snetchild struct es_info *es; 35650724Scg int i, j = 0; 35750724Scg 358150832Snetchild es = mix_getdevinfo(m); 35950724Scg if (src == 0) src = 1 << SOUND_MIXER_MIC; 36050724Scg src &= mix_getrecdevs(m); 36150724Scg for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) 36250724Scg if ((src & (1 << i)) != 0) j |= mixtable[i].recmask; 36350724Scg 364150832Snetchild ES_LOCK(es); 365152419Sariff if ((src & (1 << SOUND_MIXER_PCM)) && ES_SINGLE_PCM_MIX(es->escfg) && 366164614Sariff ES_DAC1_ENABLED(es->escfg)) 367152419Sariff j |= mixtable[SOUND_MIXER_SYNTH].recmask; 368150832Snetchild es1370_wrcodec(es, CODEC_LIMIX1, j & 0x55); 369150832Snetchild es1370_wrcodec(es, CODEC_RIMIX1, j & 0xaa); 370150832Snetchild es1370_wrcodec(es, CODEC_LIMIX2, (j >> 8) & 0x17); 371150832Snetchild es1370_wrcodec(es, CODEC_RIMIX2, (j >> 8) & 0x0f); 372150832Snetchild es1370_wrcodec(es, CODEC_OMIX1, 0x7f); 373150832Snetchild es1370_wrcodec(es, CODEC_OMIX2, 0x3f); 374150832Snetchild ES_UNLOCK(es); 375150832Snetchild 376164614Sariff return (src); 37750724Scg} 37850724Scg 37970134Scgstatic kobj_method_t es1370_mixer_methods[] = { 380164614Sariff KOBJMETHOD(mixer_init, es1370_mixinit), 381164614Sariff KOBJMETHOD(mixer_set, es1370_mixset), 382164614Sariff KOBJMETHOD(mixer_setrecsrc, es1370_mixsetrecsrc), 38370134Scg { 0, 0 } 38470134Scg}; 38570134ScgMIXER_DECLARE(es1370_mixer); 38670134Scg 38770134Scg/* -------------------------------------------------------------------- */ 38870134Scg 38950724Scgstatic int 390164614Sariffes1370_wrcodec(struct es_info *es, unsigned char i, unsigned char data) 39150724Scg{ 392164614Sariff unsigned int t; 39350724Scg 394150832Snetchild ES_LOCK_ASSERT(es); 395150832Snetchild 396148591Snetchild for (t = 0; t < 0x1000; t++) { 397148591Snetchild if ((es_rd(es, ES1370_REG_STATUS, 4) & 398164614Sariff STAT_CSTAT) == 0) { 399148591Snetchild es_wr(es, ES1370_REG_CODEC, 400164614Sariff ((unsigned short)i << CODEC_INDEX_SHIFT) | data, 2); 401164614Sariff return (0); 40250724Scg } 403148591Snetchild DELAY(1); 404148591Snetchild } 405150832Snetchild device_printf(es->dev, "%s: timed out\n", __func__); 406164614Sariff return (-1); 40750724Scg} 40850724Scg 40950724Scg/* -------------------------------------------------------------------- */ 41050724Scg 41150724Scg/* channel interface */ 41250724Scgstatic void * 413164614Sariffeschan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, 414164614Sariff struct pcm_channel *c, int dir) 41550724Scg{ 41650724Scg struct es_info *es = devinfo; 417152419Sariff struct es_chinfo *ch; 418152419Sariff uint32_t index; 41950724Scg 420152419Sariff ES_LOCK(es); 421152419Sariff 422152419Sariff if (dir == PCMDIR_PLAY) { 423152419Sariff index = ES_GP(es->escfg); 424152419Sariff es->escfg = ES_SET_GP(es->escfg, index + 1); 425164614Sariff if (index == 0) 426152419Sariff index = ES_DAC_FIRST(es->escfg); 427164614Sariff else if (index == 1) 428152419Sariff index = ES_DAC_SECOND(es->escfg); 429164614Sariff else { 430164614Sariff device_printf(es->dev, 431164614Sariff "Invalid ES_GP index: %d\n", index); 432152419Sariff ES_UNLOCK(es); 433164614Sariff return (NULL); 434152419Sariff } 435152419Sariff if (!(index == ES_DAC1 || index == ES_DAC2)) { 436164614Sariff device_printf(es->dev, "Unknown DAC: %d\n", index + 1); 437152419Sariff ES_UNLOCK(es); 438164614Sariff return (NULL); 439152419Sariff } 440152419Sariff if (es->ch[index].channel != NULL) { 441152419Sariff device_printf(es->dev, "DAC%d already initialized!\n", 442164614Sariff index + 1); 443152419Sariff ES_UNLOCK(es); 444164614Sariff return (NULL); 445152419Sariff } 446152419Sariff } else 447152419Sariff index = ES_ADC; 448152419Sariff 449152419Sariff ch = &es->ch[index]; 450152419Sariff ch->index = index; 451152419Sariff ch->num = es->num++; 452152419Sariff ch->caps = es_caps; 453152419Sariff if (ES_IS_ES1370(es->escfg)) { 454152419Sariff if (ch->index == ES_DAC1) { 455152419Sariff ch->caps.maxspeed = ES1370_DAC1_MAXSPEED; 456152419Sariff ch->caps.minspeed = ES1370_DAC1_MINSPEED; 457152419Sariff } else { 458152419Sariff uint32_t fixed_rate = ES_FIXED_RATE(es->escfg); 459152419Sariff if (!(fixed_rate < es_caps.minspeed || 460164614Sariff fixed_rate > es_caps.maxspeed)) { 461152419Sariff ch->caps.maxspeed = fixed_rate; 462152419Sariff ch->caps.minspeed = fixed_rate; 463152419Sariff } 464152419Sariff } 465152419Sariff } 46650724Scg ch->parent = es; 46750724Scg ch->channel = c; 46850724Scg ch->buffer = b; 46984658Scg ch->bufsz = es->bufsz; 470164614Sariff ch->blkcnt = es->blkcnt; 471164614Sariff ch->blksz = ch->bufsz / ch->blkcnt; 472150832Snetchild ch->dir = dir; 473152419Sariff ES_UNLOCK(es); 474168847Sariff if (sndbuf_alloc(ch->buffer, es->parent_dmat, 0, ch->bufsz) != 0) 475164614Sariff return (NULL); 476150832Snetchild ES_LOCK(es); 47750724Scg if (dir == PCMDIR_PLAY) { 478152419Sariff if (ch->index == ES_DAC1) { 479164614Sariff es_wr(es, ES1370_REG_MEMPAGE, 480164614Sariff ES1370_REG_DAC1_FRAMEADR >> 8, 1); 481164614Sariff es_wr(es, ES1370_REG_DAC1_FRAMEADR & 0xff, 482164614Sariff sndbuf_getbufaddr(ch->buffer), 4); 483164614Sariff es_wr(es, ES1370_REG_DAC1_FRAMECNT & 0xff, 484164614Sariff (ch->bufsz >> 2) - 1, 4); 485152419Sariff } else { 486164614Sariff es_wr(es, ES1370_REG_MEMPAGE, 487164614Sariff ES1370_REG_DAC2_FRAMEADR >> 8, 1); 488164614Sariff es_wr(es, ES1370_REG_DAC2_FRAMEADR & 0xff, 489164614Sariff sndbuf_getbufaddr(ch->buffer), 4); 490164614Sariff es_wr(es, ES1370_REG_DAC2_FRAMECNT & 0xff, 491164614Sariff (ch->bufsz >> 2) - 1, 4); 492152419Sariff } 49350724Scg } else { 494148591Snetchild es_wr(es, ES1370_REG_MEMPAGE, ES1370_REG_ADC_FRAMEADR >> 8, 1); 495164614Sariff es_wr(es, ES1370_REG_ADC_FRAMEADR & 0xff, 496164614Sariff sndbuf_getbufaddr(ch->buffer), 4); 497164614Sariff es_wr(es, ES1370_REG_ADC_FRAMECNT & 0xff, 498164614Sariff (ch->bufsz >> 2) - 1, 4); 49950724Scg } 500150832Snetchild ES_UNLOCK(es); 501164614Sariff return (ch); 50250724Scg} 50350724Scg 50450724Scgstatic int 505164614Sariffeschan_setformat(kobj_t obj, void *data, uint32_t format) 50650724Scg{ 50750724Scg struct es_chinfo *ch = data; 50850724Scg struct es_info *es = ch->parent; 50950724Scg 510150832Snetchild ES_LOCK(es); 51150724Scg if (ch->dir == PCMDIR_PLAY) { 512152419Sariff if (ch->index == ES_DAC1) { 513152419Sariff es->sctrl &= ~SCTRL_P1FMT; 514164614Sariff if (format & AFMT_S16_LE) 515164614Sariff es->sctrl |= SCTRL_P1SEB; 516164614Sariff if (format & AFMT_STEREO) 517164614Sariff es->sctrl |= SCTRL_P1SMB; 518152419Sariff } else { 519152419Sariff es->sctrl &= ~SCTRL_P2FMT; 520164614Sariff if (format & AFMT_S16_LE) 521164614Sariff es->sctrl |= SCTRL_P2SEB; 522164614Sariff if (format & AFMT_STEREO) 523164614Sariff es->sctrl |= SCTRL_P2SMB; 524152419Sariff } 52550724Scg } else { 52650724Scg es->sctrl &= ~SCTRL_R1FMT; 527164614Sariff if (format & AFMT_S16_LE) 528164614Sariff es->sctrl |= SCTRL_R1SEB; 529164614Sariff if (format & AFMT_STEREO) 530164614Sariff es->sctrl |= SCTRL_R1SMB; 53150724Scg } 532148591Snetchild es_wr(es, ES1370_REG_SERIAL_CONTROL, es->sctrl, 4); 533150832Snetchild ES_UNLOCK(es); 53450724Scg ch->fmt = format; 535164614Sariff return (0); 53650724Scg} 53750724Scg 53850724Scgstatic int 539164614Sariffeschan1370_setspeed(kobj_t obj, void *data, uint32_t speed) 54050724Scg{ 54150724Scg struct es_chinfo *ch = data; 54250724Scg struct es_info *es = ch->parent; 54350724Scg 544164614Sariff ES_LOCK(es); 545152419Sariff /* Fixed rate , do nothing. */ 546152419Sariff if (ch->caps.minspeed == ch->caps.maxspeed) 547164614Sariff return (ch->caps.maxspeed); 548152419Sariff if (speed < ch->caps.minspeed) 549152419Sariff speed = ch->caps.minspeed; 550152419Sariff if (speed > ch->caps.maxspeed) 551152419Sariff speed = ch->caps.maxspeed; 552152419Sariff if (ch->index == ES_DAC1) { 553152419Sariff /* 554152419Sariff * DAC1 does not support continuous rate settings. 555152419Sariff * Pick the nearest and use it since FEEDER_RATE will 556152419Sariff * do the the proper conversion for us. 557152419Sariff */ 558152419Sariff es->ctrl &= ~CTRL_WTSRSEL; 559152419Sariff if (speed < 8268) { 560152419Sariff speed = 5512; 561152419Sariff es->ctrl |= 0 << CTRL_SH_WTSRSEL; 562152419Sariff } else if (speed < 16537) { 563152419Sariff speed = 11025; 564152419Sariff es->ctrl |= 1 << CTRL_SH_WTSRSEL; 565152419Sariff } else if (speed < 33075) { 566152419Sariff speed = 22050; 567152419Sariff es->ctrl |= 2 << CTRL_SH_WTSRSEL; 568152419Sariff } else { 569152419Sariff speed = 44100; 570152419Sariff es->ctrl |= 3 << CTRL_SH_WTSRSEL; 571152419Sariff } 572152419Sariff } else { 573152419Sariff es->ctrl &= ~CTRL_PCLKDIV; 574152419Sariff es->ctrl |= DAC2_SRTODIV(speed) << CTRL_SH_PCLKDIV; 575150832Snetchild } 576148591Snetchild es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4); 577150832Snetchild ES_UNLOCK(es); 578164614Sariff return (speed); 57950724Scg} 58050724Scg 58170134Scgstatic int 582164614Sariffeschan1371_setspeed(kobj_t obj, void *data, uint32_t speed) 58354831Scg{ 58454831Scg struct es_chinfo *ch = data; 58554831Scg struct es_info *es = ch->parent; 586152419Sariff uint32_t i; 587152419Sariff int delta; 58854831Scg 589150832Snetchild ES_LOCK(es); 590148591Snetchild if (ch->dir == PCMDIR_PLAY) 591152419Sariff i = es1371_dac_rate(es, speed, ch->index); /* play */ 592148591Snetchild else 593152419Sariff i = es1371_adc_rate(es, speed, ch->index); /* record */ 594150832Snetchild ES_UNLOCK(es); 595164614Sariff delta = (speed > i) ? (speed - i) : (i - speed); 596148591Snetchild if (delta < 2) 597164614Sariff return (speed); 598164614Sariff return (i); 59954831Scg} 60054831Scg 60150724Scgstatic int 602167648Sariffeschan_setfragments(kobj_t obj, void *data, uint32_t blksz, uint32_t blkcnt) 60350724Scg{ 60470321Scg struct es_chinfo *ch = data; 605164614Sariff struct es_info *es = ch->parent; 60670321Scg 607167648Sariff blksz &= ES_BLK_ALIGN; 608164614Sariff 609167648Sariff if (blksz > (sndbuf_getmaxsize(ch->buffer) / ES_DMA_SEGS_MIN)) 610167648Sariff blksz = sndbuf_getmaxsize(ch->buffer) / ES_DMA_SEGS_MIN; 611167648Sariff if (blksz < ES_BLK_MIN) 612167648Sariff blksz = ES_BLK_MIN; 613167648Sariff if (blkcnt > ES_DMA_SEGS_MAX) 614167648Sariff blkcnt = ES_DMA_SEGS_MAX; 615167648Sariff if (blkcnt < ES_DMA_SEGS_MIN) 616167648Sariff blkcnt = ES_DMA_SEGS_MIN; 617164614Sariff 618167648Sariff while ((blksz * blkcnt) > sndbuf_getmaxsize(ch->buffer)) { 619167648Sariff if ((blkcnt >> 1) >= ES_DMA_SEGS_MIN) 620167648Sariff blkcnt >>= 1; 621167648Sariff else if ((blksz >> 1) >= ES_BLK_MIN) 622167648Sariff blksz >>= 1; 623167648Sariff else 624167648Sariff break; 625167648Sariff } 626167648Sariff 627164614Sariff if ((sndbuf_getblksz(ch->buffer) != blksz || 628167648Sariff sndbuf_getblkcnt(ch->buffer) != blkcnt) && 629167648Sariff sndbuf_resize(ch->buffer, blkcnt, blksz) != 0) 630164614Sariff device_printf(es->dev, "%s: failed blksz=%u blkcnt=%u\n", 631167648Sariff __func__, blksz, blkcnt); 632164614Sariff 633164614Sariff ch->bufsz = sndbuf_getsize(ch->buffer); 634164614Sariff ch->blksz = sndbuf_getblksz(ch->buffer); 635167648Sariff ch->blkcnt = sndbuf_getblkcnt(ch->buffer); 636164614Sariff 637167648Sariff return (1); 638167648Sariff} 639167648Sariff 640167648Sariffstatic int 641167648Sariffeschan_setblocksize(kobj_t obj, void *data, uint32_t blksz) 642167648Sariff{ 643167648Sariff struct es_chinfo *ch = data; 644167648Sariff struct es_info *es = ch->parent; 645167648Sariff 646167648Sariff eschan_setfragments(obj, data, blksz, es->blkcnt); 647167648Sariff 648164614Sariff return (ch->blksz); 649164614Sariff} 650164614Sariff 651164614Sariff#define es_chan_active(es) ((es)->ch[ES_DAC1].active + \ 652164614Sariff (es)->ch[ES_DAC2].active + \ 653164614Sariff (es)->ch[ES_ADC].active) 654164614Sariff 655164614Sariffstatic __inline int 656164614Sariffes_poll_channel(struct es_chinfo *ch) 657164614Sariff{ 658164614Sariff struct es_info *es; 659164614Sariff uint32_t sz, delta; 660164614Sariff uint32_t reg, ptr; 661164614Sariff 662164614Sariff if (ch == NULL || ch->channel == NULL || ch->active == 0) 663164614Sariff return (0); 664164614Sariff 665164614Sariff es = ch->parent; 666164614Sariff if (ch->dir == PCMDIR_PLAY) { 667164614Sariff if (ch->index == ES_DAC1) 668164614Sariff reg = ES1370_REG_DAC1_FRAMECNT; 669164614Sariff else 670164614Sariff reg = ES1370_REG_DAC2_FRAMECNT; 671164614Sariff } else 672164614Sariff reg = ES1370_REG_ADC_FRAMECNT; 673164614Sariff sz = ch->blksz * ch->blkcnt; 674164614Sariff es_wr(es, ES1370_REG_MEMPAGE, reg >> 8, 4); 675164614Sariff ptr = es_rd(es, reg & 0x000000ff, 4) >> 16; 676164614Sariff ptr <<= 2; 677164614Sariff ch->ptr = ptr; 678164614Sariff ptr %= sz; 679164614Sariff ptr &= ~(ch->blksz - 1); 680164614Sariff delta = (sz + ptr - ch->prevptr) % sz; 681164614Sariff 682164614Sariff if (delta < ch->blksz) 683164614Sariff return (0); 684164614Sariff 685164614Sariff ch->prevptr = ptr; 686164614Sariff 687164614Sariff return (1); 688164614Sariff} 689164614Sariff 690164614Sariffstatic void 691164614Sariffes_poll_callback(void *arg) 692164614Sariff{ 693164614Sariff struct es_info *es = arg; 694164614Sariff uint32_t trigger = 0; 695164614Sariff int i; 696164614Sariff 697164614Sariff if (es == NULL) 698164614Sariff return; 699164614Sariff 700164614Sariff ES_LOCK(es); 701164614Sariff if (es->polling == 0 || es_chan_active(es) == 0) { 702164614Sariff ES_UNLOCK(es); 703164614Sariff return; 704150832Snetchild } 705164614Sariff 706164614Sariff for (i = 0; i < ES_NCHANS; i++) { 707164614Sariff if (es_poll_channel(&es->ch[i]) != 0) 708164614Sariff trigger |= 1 << i; 709164614Sariff } 710164614Sariff 711164614Sariff /* XXX */ 712164614Sariff callout_reset(&es->poll_timer, 1/*es->poll_ticks*/, 713164614Sariff es_poll_callback, es); 714164614Sariff 715164614Sariff ES_UNLOCK(es); 716164614Sariff 717164614Sariff for (i = 0; i < ES_NCHANS; i++) { 718164614Sariff if (trigger & (1 << i)) 719164614Sariff chn_intr(es->ch[i].channel); 720164614Sariff } 72150724Scg} 72250724Scg 72350724Scgstatic int 72470134Scgeschan_trigger(kobj_t obj, void *data, int go) 72550724Scg{ 72650724Scg struct es_chinfo *ch = data; 72750724Scg struct es_info *es = ch->parent; 728152419Sariff uint32_t cnt, b = 0; 72950724Scg 730170521Sariff if (!PCMTRIG_COMMON(go)) 731170521Sariff return 0; 73260958Scg 733164614Sariff ES_LOCK(es); 73470321Scg cnt = (ch->blksz / sndbuf_getbps(ch->buffer)) - 1; 735152419Sariff if (ch->fmt & AFMT_16BIT) 736152419Sariff b |= 0x02; 737152419Sariff if (ch->fmt & AFMT_STEREO) 738152419Sariff b |= 0x01; 73950724Scg if (ch->dir == PCMDIR_PLAY) { 74050724Scg if (go == PCMTRIG_START) { 741152419Sariff if (ch->index == ES_DAC1) { 742152419Sariff es->ctrl |= CTRL_DAC1_EN; 743164614Sariff es->sctrl &= ~(SCTRL_P1LOOPSEL | 744164614Sariff SCTRL_P1PAUSE | SCTRL_P1SCTRLD); 745164614Sariff if (es->polling == 0) 746164614Sariff es->sctrl |= SCTRL_P1INTEN; 747164614Sariff else 748164614Sariff es->sctrl &= ~SCTRL_P1INTEN; 749164614Sariff es->sctrl |= b; 750152419Sariff es_wr(es, ES1370_REG_DAC1_SCOUNT, cnt, 4); 751152419Sariff /* start at beginning of buffer */ 752164614Sariff es_wr(es, ES1370_REG_MEMPAGE, 753164614Sariff ES1370_REG_DAC1_FRAMECNT >> 8, 4); 754164614Sariff es_wr(es, ES1370_REG_DAC1_FRAMECNT & 0xff, 755164614Sariff (ch->bufsz >> 2) - 1, 4); 756152419Sariff } else { 757152419Sariff es->ctrl |= CTRL_DAC2_EN; 758164614Sariff es->sctrl &= ~(SCTRL_P2ENDINC | SCTRL_P2STINC | 759164614Sariff SCTRL_P2LOOPSEL | SCTRL_P2PAUSE | 760164614Sariff SCTRL_P2DACSEN); 761164614Sariff if (es->polling == 0) 762164614Sariff es->sctrl |= SCTRL_P2INTEN; 763164614Sariff else 764164614Sariff es->sctrl &= ~SCTRL_P2INTEN; 765164614Sariff es->sctrl |= (b << 2) | 766164614Sariff ((((b >> 1) & 1) + 1) << SCTRL_SH_P2ENDINC); 767152419Sariff es_wr(es, ES1370_REG_DAC2_SCOUNT, cnt, 4); 768152419Sariff /* start at beginning of buffer */ 769164614Sariff es_wr(es, ES1370_REG_MEMPAGE, 770164614Sariff ES1370_REG_DAC2_FRAMECNT >> 8, 4); 771164614Sariff es_wr(es, ES1370_REG_DAC2_FRAMECNT & 0xff, 772164614Sariff (ch->bufsz >> 2) - 1, 4); 773152419Sariff } 774164614Sariff } else 775164614Sariff es->ctrl &= ~((ch->index == ES_DAC1) ? 776164614Sariff CTRL_DAC1_EN : CTRL_DAC2_EN); 77750724Scg } else { 77850724Scg if (go == PCMTRIG_START) { 77950724Scg es->ctrl |= CTRL_ADC_EN; 78050724Scg es->sctrl &= ~SCTRL_R1LOOPSEL; 781164614Sariff if (es->polling == 0) 782164614Sariff es->sctrl |= SCTRL_R1INTEN; 783164614Sariff else 784164614Sariff es->sctrl &= ~SCTRL_R1INTEN; 785164614Sariff es->sctrl |= b << 4; 786148591Snetchild es_wr(es, ES1370_REG_ADC_SCOUNT, cnt, 4); 78759323Scg /* start at beginning of buffer */ 788164614Sariff es_wr(es, ES1370_REG_MEMPAGE, 789164614Sariff ES1370_REG_ADC_FRAMECNT >> 8, 4); 790164614Sariff es_wr(es, ES1370_REG_ADC_FRAMECNT & 0xff, 791164614Sariff (ch->bufsz >> 2) - 1, 4); 792164614Sariff } else 793164614Sariff es->ctrl &= ~CTRL_ADC_EN; 79450724Scg } 795148591Snetchild es_wr(es, ES1370_REG_SERIAL_CONTROL, es->sctrl, 4); 796148591Snetchild es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4); 797164614Sariff if (go == PCMTRIG_START) { 798164614Sariff if (es->polling != 0) { 799164614Sariff ch->ptr = 0; 800164614Sariff ch->prevptr = 0; 801164614Sariff if (es_chan_active(es) == 0) { 802164614Sariff es->poll_ticks = 1; 803164614Sariff callout_reset(&es->poll_timer, 1, 804164614Sariff es_poll_callback, es); 805164614Sariff } 806164614Sariff } 807164614Sariff ch->active = 1; 808164614Sariff } else { 809164614Sariff ch->active = 0; 810164614Sariff if (es->polling != 0) { 811164614Sariff if (es_chan_active(es) == 0) { 812164614Sariff callout_stop(&es->poll_timer); 813164614Sariff es->poll_ticks = 1; 814164614Sariff } 815164614Sariff } 816164614Sariff } 817150832Snetchild ES_UNLOCK(es); 818164614Sariff return (0); 81950724Scg} 82050724Scg 82150724Scgstatic int 82270134Scgeschan_getptr(kobj_t obj, void *data) 82350724Scg{ 82450724Scg struct es_chinfo *ch = data; 82550724Scg struct es_info *es = ch->parent; 826164614Sariff uint32_t reg, cnt; 82759323Scg 828150832Snetchild ES_LOCK(es); 829164614Sariff if (es->polling != 0) 830164614Sariff cnt = ch->ptr; 831164614Sariff else { 832164614Sariff if (ch->dir == PCMDIR_PLAY) { 833164614Sariff if (ch->index == ES_DAC1) 834164614Sariff reg = ES1370_REG_DAC1_FRAMECNT; 835164614Sariff else 836164614Sariff reg = ES1370_REG_DAC2_FRAMECNT; 837164614Sariff } else 838164614Sariff reg = ES1370_REG_ADC_FRAMECNT; 839164614Sariff es_wr(es, ES1370_REG_MEMPAGE, reg >> 8, 4); 840164614Sariff cnt = es_rd(es, reg & 0x000000ff, 4) >> 16; 841164614Sariff /* cnt is longwords */ 842164614Sariff cnt <<= 2; 843164614Sariff } 844150832Snetchild ES_UNLOCK(es); 845164614Sariff 846167648Sariff cnt &= ES_BLK_ALIGN; 847164614Sariff 848164614Sariff return (cnt); 84950724Scg} 85050724Scg 85174763Scgstatic struct pcmchan_caps * 85270134Scgeschan_getcaps(kobj_t obj, void *data) 85350724Scg{ 85450724Scg struct es_chinfo *ch = data; 855150832Snetchild 856164614Sariff return (&ch->caps); 85750724Scg} 85850724Scg 85970134Scgstatic kobj_method_t eschan1370_methods[] = { 860164614Sariff KOBJMETHOD(channel_init, eschan_init), 861164614Sariff KOBJMETHOD(channel_setformat, eschan_setformat), 862164614Sariff KOBJMETHOD(channel_setspeed, eschan1370_setspeed), 863164614Sariff KOBJMETHOD(channel_setblocksize, eschan_setblocksize), 864167648Sariff KOBJMETHOD(channel_setfragments, eschan_setfragments), 865164614Sariff KOBJMETHOD(channel_trigger, eschan_trigger), 866164614Sariff KOBJMETHOD(channel_getptr, eschan_getptr), 867164614Sariff KOBJMETHOD(channel_getcaps, eschan_getcaps), 86870134Scg { 0, 0 } 86970134Scg}; 87070134ScgCHANNEL_DECLARE(eschan1370); 87170134Scg 87270134Scgstatic kobj_method_t eschan1371_methods[] = { 873164614Sariff KOBJMETHOD(channel_init, eschan_init), 874164614Sariff KOBJMETHOD(channel_setformat, eschan_setformat), 875164614Sariff KOBJMETHOD(channel_setspeed, eschan1371_setspeed), 876164614Sariff KOBJMETHOD(channel_setblocksize, eschan_setblocksize), 877167648Sariff KOBJMETHOD(channel_setfragments, eschan_setfragments), 878164614Sariff KOBJMETHOD(channel_trigger, eschan_trigger), 879164614Sariff KOBJMETHOD(channel_getptr, eschan_getptr), 880164614Sariff KOBJMETHOD(channel_getcaps, eschan_getcaps), 88170134Scg { 0, 0 } 88270134Scg}; 88370134ScgCHANNEL_DECLARE(eschan1371); 88470134Scg 88570134Scg/* -------------------------------------------------------------------- */ 88650724Scg/* The interrupt handler */ 88750724Scgstatic void 88854831Scges_intr(void *p) 88950724Scg{ 89050724Scg struct es_info *es = p; 891150832Snetchild uint32_t intsrc, sctrl; 89250724Scg 893150832Snetchild ES_LOCK(es); 894164614Sariff if (es->polling != 0) { 895164614Sariff ES_UNLOCK(es); 896164614Sariff return; 897164614Sariff } 898148591Snetchild intsrc = es_rd(es, ES1370_REG_STATUS, 4); 899148591Snetchild if ((intsrc & STAT_INTR) == 0) { 900150832Snetchild ES_UNLOCK(es); 901148591Snetchild return; 902148591Snetchild } 90350724Scg 90450724Scg sctrl = es->sctrl; 905164614Sariff if (intsrc & STAT_ADC) 906164614Sariff sctrl &= ~SCTRL_R1INTEN; 907164614Sariff if (intsrc & STAT_DAC1) 908164614Sariff sctrl &= ~SCTRL_P1INTEN; 909164614Sariff if (intsrc & STAT_DAC2) 910164614Sariff sctrl &= ~SCTRL_P2INTEN; 91150724Scg 912148591Snetchild es_wr(es, ES1370_REG_SERIAL_CONTROL, sctrl, 4); 913148591Snetchild es_wr(es, ES1370_REG_SERIAL_CONTROL, es->sctrl, 4); 914150832Snetchild ES_UNLOCK(es); 91550724Scg 916164614Sariff if (intsrc & STAT_ADC) 917164614Sariff chn_intr(es->ch[ES_ADC].channel); 918164614Sariff if (intsrc & STAT_DAC1) 919164614Sariff chn_intr(es->ch[ES_DAC1].channel); 920164614Sariff if (intsrc & STAT_DAC2) 921164614Sariff chn_intr(es->ch[ES_DAC2].channel); 92250724Scg} 92350724Scg 92454831Scg/* ES1370 specific */ 92554831Scgstatic int 92654831Scges1370_init(struct es_info *es) 92754831Scg{ 928152419Sariff uint32_t fixed_rate; 929152419Sariff int r, single_pcm; 930150832Snetchild 931152419Sariff /* ES1370 default to fixed rate operation */ 932150832Snetchild if (resource_int_value(device_get_name(es->dev), 933164614Sariff device_get_unit(es->dev), "fixed_rate", &r) == 0) { 934152419Sariff fixed_rate = r; 935152419Sariff if (fixed_rate) { 936152419Sariff if (fixed_rate < es_caps.minspeed) 937152419Sariff fixed_rate = es_caps.minspeed; 938152419Sariff if (fixed_rate > es_caps.maxspeed) 939152419Sariff fixed_rate = es_caps.maxspeed; 940150832Snetchild } 941150832Snetchild } else 942152419Sariff fixed_rate = es_caps.maxspeed; 943152419Sariff 944152419Sariff if (resource_int_value(device_get_name(es->dev), 945164614Sariff device_get_unit(es->dev), "single_pcm_mixer", &r) == 0) 946164614Sariff single_pcm = (r != 0) ? 1 : 0; 947152419Sariff else 948152419Sariff single_pcm = 1; 949152419Sariff 950150832Snetchild ES_LOCK(es); 951152419Sariff if (ES_NUMPLAY(es->escfg) == 1) 952152419Sariff single_pcm = 1; 953152419Sariff /* This is ES1370 */ 954152419Sariff es->escfg = ES_SET_IS_ES1370(es->escfg, 1); 955164614Sariff if (fixed_rate) 956152419Sariff es->escfg = ES_SET_FIXED_RATE(es->escfg, fixed_rate); 957164614Sariff else { 958152419Sariff es->escfg = ES_SET_FIXED_RATE(es->escfg, 0); 959152419Sariff fixed_rate = DSP_DEFAULT_SPEED; 960150832Snetchild } 961164614Sariff if (single_pcm) 962152419Sariff es->escfg = ES_SET_SINGLE_PCM_MIX(es->escfg, 1); 963164614Sariff else 964152419Sariff es->escfg = ES_SET_SINGLE_PCM_MIX(es->escfg, 0); 965152419Sariff es->ctrl = CTRL_CDC_EN | CTRL_JYSTK_EN | CTRL_SERR_DIS | 966164614Sariff (DAC2_SRTODIV(fixed_rate) << CTRL_SH_PCLKDIV); 967152419Sariff es->ctrl |= 3 << CTRL_SH_WTSRSEL; 968148591Snetchild es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4); 96953413Sroger 97054831Scg es->sctrl = 0; 971148591Snetchild es_wr(es, ES1370_REG_SERIAL_CONTROL, es->sctrl, 4); 97253413Sroger 973164614Sariff /* No RST, PD */ 974164614Sariff es1370_wrcodec(es, CODEC_RES_PD, 3); 975164614Sariff /* 976164614Sariff * CODEC ADC and CODEC DAC use {LR,B}CLK2 and run off the LRCLK2 PLL; 977164614Sariff * program DAC_SYNC=0! 978164614Sariff */ 979164614Sariff es1370_wrcodec(es, CODEC_CSEL, 0); 980164614Sariff /* Recording source is mixer */ 981164614Sariff es1370_wrcodec(es, CODEC_ADSEL, 0); 982164614Sariff /* MIC amp is 0db */ 983164614Sariff es1370_wrcodec(es, CODEC_MGAIN, 0); 984150832Snetchild ES_UNLOCK(es); 98553413Sroger 986164614Sariff return (0); 98754831Scg} 98853413Sroger 98954831Scg/* ES1371 specific */ 99053413Srogerint 991150832Snetchildes1371_init(struct es_info *es) 99253413Sroger{ 993154285Sariff uint32_t cssr, devid, revid, subdev; 99453413Sroger int idx; 99553413Sroger 996150832Snetchild ES_LOCK(es); 997152419Sariff /* This is NOT ES1370 */ 998152419Sariff es->escfg = ES_SET_IS_ES1370(es->escfg, 0); 99954831Scg es->num = 0; 100053413Sroger es->sctrl = 0; 1001148591Snetchild cssr = 0; 1002150832Snetchild devid = pci_get_devid(es->dev); 1003150832Snetchild revid = pci_get_revid(es->dev); 1004164614Sariff subdev = (pci_get_subdevice(es->dev) << 16) | 1005164614Sariff pci_get_subvendor(es->dev); 1006154285Sariff /* 1007154285Sariff * Joyport blacklist. Either we're facing with broken hardware 1008154285Sariff * or because this hardware need special (unknown) initialization 1009154285Sariff * procedures. 1010154285Sariff */ 1011154285Sariff switch (subdev) { 1012154285Sariff case 0x20001274: /* old Ensoniq */ 1013154285Sariff es->ctrl = 0; 1014154285Sariff break; 1015154285Sariff default: 1016154285Sariff es->ctrl = CTRL_JYSTK_EN; 1017154285Sariff break; 1018154285Sariff } 1019148591Snetchild if (devid == CT4730_PCI_ID) { 1020148591Snetchild /* XXX amplifier hack? */ 1021148591Snetchild es->ctrl |= (1 << 16); 1022148591Snetchild } 102353413Sroger /* initialize the chips */ 1024148591Snetchild es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4); 1025148591Snetchild es_wr(es, ES1370_REG_SERIAL_CONTROL, es->sctrl, 4); 1026148591Snetchild es_wr(es, ES1371_REG_LEGACY, 0, 4); 102776086Scg if ((devid == ES1371_PCI_ID && revid == ES1371REV_ES1373_8) || 102876086Scg (devid == ES1371_PCI_ID && revid == ES1371REV_CT5880_A) || 102976086Scg (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_C) || 103095678Scg (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_D) || 1031148591Snetchild (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_E)) { 1032148591Snetchild cssr = 1 << 29; 1033148591Snetchild es_wr(es, ES1370_REG_STATUS, cssr, 4); 103474753Scg DELAY(20000); 103555209Scg } 103653413Sroger /* AC'97 warm reset to start the bitclk */ 1037152419Sariff es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4); 1038152419Sariff es_wr(es, ES1371_REG_LEGACY, ES1371_SYNC_RES, 4); 103953413Sroger DELAY(2000); 1040152419Sariff es_wr(es, ES1370_REG_CONTROL, es->sctrl, 4); 1041148591Snetchild es1371_wait_src_ready(es); 104253413Sroger /* Init the sample rate converter */ 1043148591Snetchild es_wr(es, ES1371_REG_SMPRATE, ES1371_DIS_SRC, 4); 104453413Sroger for (idx = 0; idx < 0x80; idx++) 104554831Scg es1371_src_write(es, idx, 0); 1046164614Sariff es1371_src_write(es, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4); 104753413Sroger es1371_src_write(es, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10); 1048164614Sariff es1371_src_write(es, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4); 104953413Sroger es1371_src_write(es, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10); 1050164614Sariff es1371_src_write(es, ES_SMPREG_VOL_ADC, 1 << 12); 1051164614Sariff es1371_src_write(es, ES_SMPREG_VOL_ADC + 1, 1 << 12); 1052164614Sariff es1371_src_write(es, ES_SMPREG_VOL_DAC1, 1 << 12); 1053164614Sariff es1371_src_write(es, ES_SMPREG_VOL_DAC1 + 1, 1 << 12); 1054164614Sariff es1371_src_write(es, ES_SMPREG_VOL_DAC2, 1 << 12); 1055164614Sariff es1371_src_write(es, ES_SMPREG_VOL_DAC2 + 1, 1 << 12); 1056164614Sariff es1371_adc_rate(es, 22050, ES_ADC); 1057164614Sariff es1371_dac_rate(es, 22050, ES_DAC1); 1058164614Sariff es1371_dac_rate(es, 22050, ES_DAC2); 1059164614Sariff /* 1060164614Sariff * WARNING: 106153413Sroger * enabling the sample rate converter without properly programming 106253413Sroger * its parameters causes the chip to lock up (the SRC busy bit will 106353413Sroger * be stuck high, and I've found no way to rectify this other than 106453413Sroger * power cycle) 106553413Sroger */ 1066148591Snetchild es1371_wait_src_ready(es); 1067148591Snetchild es_wr(es, ES1371_REG_SMPRATE, 0, 4); 1068148591Snetchild /* try to reset codec directly */ 1069148591Snetchild es_wr(es, ES1371_REG_CODEC, 0, 4); 1070148591Snetchild es_wr(es, ES1370_REG_STATUS, cssr, 4); 1071150832Snetchild ES_UNLOCK(es); 107253413Sroger 107353413Sroger return (0); 107453413Sroger} 107553413Sroger 107670134Scg/* -------------------------------------------------------------------- */ 107770134Scg 107870134Scgstatic int 1079164614Sariffes1371_wrcd(kobj_t obj, void *s, int addr, uint32_t data) 108053413Sroger{ 1081150832Snetchild uint32_t t, x, orig; 108253413Sroger struct es_info *es = (struct es_info*)s; 108353413Sroger 1084167648Sariff for (t = 0; t < 0x1000; t++) { 1085148591Snetchild if (!es_rd(es, ES1371_REG_CODEC & CODEC_WIP, 4)) 108653413Sroger break; 1087167648Sariff } 108853413Sroger /* save the current state for later */ 1089148591Snetchild x = orig = es_rd(es, ES1371_REG_SMPRATE, 4); 109053413Sroger /* enable SRC state data in SRC mux */ 1091164614Sariff es_wr(es, ES1371_REG_SMPRATE, (x & (ES1371_DIS_SRC | ES1371_DIS_P1 | 1092164614Sariff ES1371_DIS_P2 | ES1371_DIS_R1)) | 0x00010000, 4); 1093148591Snetchild /* busy wait */ 1094164614Sariff for (t = 0; t < 0x1000; t++) { 1095164614Sariff if ((es_rd(es, ES1371_REG_SMPRATE, 4) & 0x00870000) == 1096164614Sariff 0x00000000) 1097148591Snetchild break; 1098164614Sariff } 109953413Sroger /* wait for a SAFE time to write addr/data and then do it, dammit */ 1100164614Sariff for (t = 0; t < 0x1000; t++) { 1101164614Sariff if ((es_rd(es, ES1371_REG_SMPRATE, 4) & 0x00870000) == 1102164614Sariff 0x00010000) 110354831Scg break; 1104164614Sariff } 110554831Scg 1106164614Sariff es_wr(es, ES1371_REG_CODEC, ((addr << CODEC_POADD_SHIFT) & 1107164614Sariff CODEC_POADD_MASK) | ((data << CODEC_PODAT_SHIFT) & 1108164614Sariff CODEC_PODAT_MASK), 4); 110953413Sroger /* restore SRC reg */ 111053413Sroger es1371_wait_src_ready(s); 1111148591Snetchild es_wr(es, ES1371_REG_SMPRATE, orig, 4); 111270134Scg 1113164614Sariff return (0); 111453413Sroger} 111553413Sroger 111670134Scgstatic int 111770134Scges1371_rdcd(kobj_t obj, void *s, int addr) 111853413Sroger{ 1119150832Snetchild uint32_t t, x, orig; 112054831Scg struct es_info *es = (struct es_info *)s; 112153413Sroger 1122164614Sariff for (t = 0; t < 0x1000; t++) { 1123148591Snetchild if (!(x = es_rd(es, ES1371_REG_CODEC, 4) & CODEC_WIP)) 112454831Scg break; 1125164614Sariff } 112653413Sroger 112754831Scg /* save the current state for later */ 1128148591Snetchild x = orig = es_rd(es, ES1371_REG_SMPRATE, 4); 112954831Scg /* enable SRC state data in SRC mux */ 1130164614Sariff es_wr(es, ES1371_REG_SMPRATE, (x & (ES1371_DIS_SRC | ES1371_DIS_P1 | 1131164614Sariff ES1371_DIS_P2 | ES1371_DIS_R1)) | 0x00010000, 4); 1132148591Snetchild /* busy wait */ 1133164614Sariff for (t = 0; t < 0x1000; t++) { 1134164614Sariff if ((x = es_rd(es, ES1371_REG_SMPRATE, 4) & 0x00870000) == 1135164614Sariff 0x00000000) 1136148591Snetchild break; 1137164614Sariff } 113854831Scg /* wait for a SAFE time to write addr/data and then do it, dammit */ 1139164614Sariff for (t = 0; t < 0x1000; t++) { 1140164614Sariff if ((x = es_rd(es, ES1371_REG_SMPRATE, 4) & 0x00870000) == 1141164614Sariff 0x00010000) 114254831Scg break; 1143164614Sariff } 114453413Sroger 1145164614Sariff es_wr(es, ES1371_REG_CODEC, ((addr << CODEC_POADD_SHIFT) & 1146164614Sariff CODEC_POADD_MASK) | CODEC_PORD, 4); 1147148591Snetchild 114854831Scg /* restore SRC reg */ 114954831Scg es1371_wait_src_ready(s); 1150148591Snetchild es_wr(es, ES1371_REG_SMPRATE, orig, 4); 115153413Sroger 115254831Scg /* now wait for the stinkin' data (RDY) */ 1153164614Sariff for (t = 0; t < 0x1000; t++) { 1154148591Snetchild if ((x = es_rd(es, ES1371_REG_CODEC, 4)) & CODEC_RDY) 115554831Scg break; 1156164614Sariff } 1157148591Snetchild 115854831Scg return ((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT); 115953413Sroger} 116053413Sroger 116170134Scgstatic kobj_method_t es1371_ac97_methods[] = { 1162164614Sariff KOBJMETHOD(ac97_read, es1371_rdcd), 1163164614Sariff KOBJMETHOD(ac97_write, es1371_wrcd), 116470134Scg { 0, 0 } 116570134Scg}; 116670134ScgAC97_DECLARE(es1371_ac97); 116770134Scg 116870134Scg/* -------------------------------------------------------------------- */ 116970134Scg 1170164614Sariffstatic unsigned int 1171164614Sariffes1371_src_read(struct es_info *es, unsigned short reg) 117254831Scg{ 1173150832Snetchild uint32_t r; 117453413Sroger 1175164614Sariff r = es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P1 | 1176164614Sariff ES1371_DIS_P2 | ES1371_DIS_R1); 117754831Scg r |= ES1371_SRC_RAM_ADDRO(reg); 1178148591Snetchild es_wr(es, ES1371_REG_SMPRATE, r, 4); 1179164614Sariff return (ES1371_SRC_RAM_DATAI(es1371_wait_src_ready(es))); 118053413Sroger} 118153413Sroger 118253413Srogerstatic void 1183164614Sariffes1371_src_write(struct es_info *es, unsigned short reg, unsigned short data) 1184148591Snetchild{ 1185150832Snetchild uint32_t r; 118653413Sroger 1187164614Sariff r = es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P1 | 1188164614Sariff ES1371_DIS_P2 | ES1371_DIS_R1); 118953413Sroger r |= ES1371_SRC_RAM_ADDRO(reg) | ES1371_SRC_RAM_DATAO(data); 1190148591Snetchild es_wr(es, ES1371_REG_SMPRATE, r | ES1371_SRC_RAM_WE, 4); 119153413Sroger} 119253413Sroger 1193164614Sariffstatic unsigned int 1194164614Sariffes1371_adc_rate(struct es_info *es, unsigned int rate, int set) 119554831Scg{ 1196164614Sariff unsigned int n, truncm, freq, result; 119754831Scg 1198150832Snetchild ES_LOCK_ASSERT(es); 1199150832Snetchild 1200164614Sariff if (rate > 48000) 1201164614Sariff rate = 48000; 1202164614Sariff if (rate < 4000) 1203164614Sariff rate = 4000; 120454831Scg n = rate / 3000; 120554831Scg if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9))) 120654831Scg n--; 120754831Scg truncm = (21 * n - 1) | 1; 120854831Scg freq = ((48000UL << 15) / rate) * n; 120954831Scg result = (48000UL << 15) / (freq / n); 121054831Scg if (set) { 121154831Scg if (rate >= 24000) { 1212164614Sariff if (truncm > 239) 1213164614Sariff truncm = 239; 121454831Scg es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N, 1215164614Sariff (((239 - truncm) >> 1) << 9) | (n << 4)); 121654831Scg } else { 1217164614Sariff if (truncm > 119) 1218164614Sariff truncm = 119; 121954831Scg es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N, 1220164614Sariff 0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4)); 122154831Scg } 122254831Scg es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_INT_REGS, 1223164614Sariff (es1371_src_read(es, ES_SMPREG_ADC + ES_SMPREG_INT_REGS) & 1224164614Sariff 0x00ff) | ((freq >> 5) & 0xfc00)); 1225164614Sariff es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, 1226164614Sariff freq & 0x7fff); 122754831Scg es1371_src_write(es, ES_SMPREG_VOL_ADC, n << 8); 122854831Scg es1371_src_write(es, ES_SMPREG_VOL_ADC + 1, n << 8); 122953413Sroger } 1230164614Sariff return (result); 123153413Sroger} 123253413Sroger 1233164614Sariffstatic unsigned int 1234164614Sariffes1371_dac_rate(struct es_info *es, unsigned int rate, int set) 123554831Scg{ 1236164614Sariff unsigned int freq, r, result, dac, dis; 123753413Sroger 1238150832Snetchild ES_LOCK_ASSERT(es); 1239150832Snetchild 1240164614Sariff if (rate > 48000) 1241164614Sariff rate = 48000; 1242164614Sariff if (rate < 4000) 1243164614Sariff rate = 4000; 1244152419Sariff freq = ((rate << 15) + 1500) / 3000; 124554831Scg result = (freq * 3000) >> 15; 1246164614Sariff 1247152419Sariff dac = (set == ES_DAC1) ? ES_SMPREG_DAC1 : ES_SMPREG_DAC2; 1248152419Sariff dis = (set == ES_DAC1) ? ES1371_DIS_P2 : ES1371_DIS_P1; 1249164614Sariff r = (es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P1 | 1250164614Sariff ES1371_DIS_P2 | ES1371_DIS_R1)); 1251152419Sariff es_wr(es, ES1371_REG_SMPRATE, r, 4); 1252152419Sariff es1371_src_write(es, dac + ES_SMPREG_INT_REGS, 1253164614Sariff (es1371_src_read(es, dac + ES_SMPREG_INT_REGS) & 0x00ff) | 1254164614Sariff ((freq >> 5) & 0xfc00)); 1255152419Sariff es1371_src_write(es, dac + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff); 1256164614Sariff r = (es1371_wait_src_ready(es) & 1257164614Sariff (ES1371_DIS_SRC | dis | ES1371_DIS_R1)); 1258152419Sariff es_wr(es, ES1371_REG_SMPRATE, r, 4); 1259164614Sariff return (result); 126053413Sroger} 126153413Sroger 1262150832Snetchildstatic uint32_t 126355209Scges1371_wait_src_ready(struct es_info *es) 126454831Scg{ 1265150832Snetchild uint32_t t, r; 126653413Sroger 1267148591Snetchild for (t = 0; t < 0x1000; t++) { 1268164614Sariff if (!((r = es_rd(es, ES1371_REG_SMPRATE, 4)) & 1269164614Sariff ES1371_SRC_RAM_BUSY)) 1270164614Sariff return (r); 1271148591Snetchild DELAY(1); 127254831Scg } 1273150832Snetchild device_printf(es->dev, "%s: timed out 0x%x [0x%x]\n", __func__, 1274150832Snetchild ES1371_REG_SMPRATE, r); 1275164614Sariff return (0); 127653413Sroger} 127753413Sroger 127850724Scg/* -------------------------------------------------------------------- */ 127950724Scg 128050724Scg/* 128150724Scg * Probe and attach the card 128250724Scg */ 128350724Scg 128450724Scgstatic int 128550724Scges_pci_probe(device_t dev) 128650724Scg{ 128776086Scg switch(pci_get_devid(dev)) { 128876086Scg case ES1370_PCI_ID: 128950724Scg device_set_desc(dev, "AudioPCI ES1370"); 1290164614Sariff return (BUS_PROBE_DEFAULT); 129176086Scg case ES1371_PCI_ID: 129276086Scg switch(pci_get_revid(dev)) { 129378033Scg case ES1371REV_ES1371_A: 129478033Scg device_set_desc(dev, "AudioPCI ES1371-A"); 1295164614Sariff return (BUS_PROBE_DEFAULT); 129676086Scg case ES1371REV_ES1371_B: 129776086Scg device_set_desc(dev, "AudioPCI ES1371-B"); 1298164614Sariff return (BUS_PROBE_DEFAULT); 129976086Scg case ES1371REV_ES1373_A: 130076086Scg device_set_desc(dev, "AudioPCI ES1373-A"); 1301164614Sariff return (BUS_PROBE_DEFAULT); 130276086Scg case ES1371REV_ES1373_B: 130376086Scg device_set_desc(dev, "AudioPCI ES1373-B"); 1304164614Sariff return (BUS_PROBE_DEFAULT); 130576086Scg case ES1371REV_ES1373_8: 130676086Scg device_set_desc(dev, "AudioPCI ES1373-8"); 1307164614Sariff return (BUS_PROBE_DEFAULT); 130876086Scg case ES1371REV_CT5880_A: 130976086Scg device_set_desc(dev, "Creative CT5880-A"); 1310164614Sariff return (BUS_PROBE_DEFAULT); 131176086Scg default: 131276086Scg device_set_desc(dev, "AudioPCI ES1371-?"); 1313164614Sariff device_printf(dev, 1314164614Sariff "unknown revision %d -- please report to " 1315164614Sariff "freebsd-multimedia@freebsd.org\n", 1316164614Sariff pci_get_revid(dev)); 1317164614Sariff return (BUS_PROBE_DEFAULT); 131876086Scg } 131976086Scg case ES1371_PCI_ID2: 132078033Scg device_set_desc(dev, "Strange AudioPCI ES1371-? (vid=3274)"); 1321164614Sariff device_printf(dev, 1322164614Sariff "unknown revision %d -- please report to " 1323164614Sariff "freebsd-multimedia@freebsd.org\n", pci_get_revid(dev)); 1324164614Sariff return (BUS_PROBE_DEFAULT); 1325119548Sorion case CT4730_PCI_ID: 1326119548Sorion switch(pci_get_revid(dev)) { 1327119548Sorion case CT4730REV_CT4730_A: 1328164614Sariff device_set_desc(dev, 1329164614Sariff "Creative SB AudioPCI CT4730/EV1938"); 1330164614Sariff return (BUS_PROBE_DEFAULT); 1331119548Sorion default: 1332119548Sorion device_set_desc(dev, "Creative SB AudioPCI CT4730-?"); 1333164614Sariff device_printf(dev, 1334164614Sariff "unknown revision %d -- please report to " 1335164614Sariff "freebsd-multimedia@freebsd.org\n", 1336164614Sariff pci_get_revid(dev)); 1337164614Sariff return (BUS_PROBE_DEFAULT); 1338119548Sorion } 133976086Scg case CT5880_PCI_ID: 134076086Scg switch(pci_get_revid(dev)) { 134176086Scg case CT5880REV_CT5880_C: 134276086Scg device_set_desc(dev, "Creative CT5880-C"); 1343164614Sariff return (BUS_PROBE_DEFAULT); 134476086Scg case CT5880REV_CT5880_D: 134576086Scg device_set_desc(dev, "Creative CT5880-D"); 1346164614Sariff return (BUS_PROBE_DEFAULT); 134795678Scg case CT5880REV_CT5880_E: 134895678Scg device_set_desc(dev, "Creative CT5880-E"); 1349164614Sariff return (BUS_PROBE_DEFAULT); 135076086Scg default: 135176086Scg device_set_desc(dev, "Creative CT5880-?"); 1352164614Sariff device_printf(dev, 1353164614Sariff "unknown revision %d -- please report to " 1354164614Sariff "freebsd-multimedia@freebsd.org\n", 1355164614Sariff pci_get_revid(dev)); 1356164614Sariff return (BUS_PROBE_DEFAULT); 135776086Scg } 135876086Scg default: 1359164614Sariff return (ENXIO); 136050724Scg } 136150724Scg} 136250724Scg 1363148591Snetchild#ifdef SND_DYNSYSCTL 136450724Scgstatic int 1365150832Snetchildsysctl_es137x_spdif_enable(SYSCTL_HANDLER_ARGS) 1366148591Snetchild{ 1367148591Snetchild struct es_info *es; 1368148591Snetchild device_t dev; 1369150832Snetchild uint32_t r; 1370150832Snetchild int err, new_en; 1371148591Snetchild 1372148591Snetchild dev = oidp->oid_arg1; 1373148591Snetchild es = pcm_getdevinfo(dev); 1374150832Snetchild ES_LOCK(es); 1375150832Snetchild r = es_rd(es, ES1370_REG_STATUS, 4); 1376150832Snetchild ES_UNLOCK(es); 1377150832Snetchild new_en = (r & ENABLE_SPDIF) ? 1 : 0; 1378170289Sdwmalone err = sysctl_handle_int(oidp, &new_en, 0, req); 1379148591Snetchild 1380148591Snetchild if (err || req->newptr == NULL) 1381150832Snetchild return (err); 1382148591Snetchild if (new_en < 0 || new_en > 1) 1383150832Snetchild return (EINVAL); 1384148591Snetchild 1385150832Snetchild ES_LOCK(es); 1386148591Snetchild if (new_en) { 1387148591Snetchild r |= ENABLE_SPDIF; 1388148591Snetchild es->ctrl |= SPDIFEN_B; 1389148591Snetchild es->ctrl |= RECEN_B; 1390148591Snetchild } else { 1391148591Snetchild r &= ~ENABLE_SPDIF; 1392148591Snetchild es->ctrl &= ~SPDIFEN_B; 1393148591Snetchild es->ctrl &= ~RECEN_B; 1394148591Snetchild } 1395148591Snetchild es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4); 1396148591Snetchild es_wr(es, ES1370_REG_STATUS, r, 4); 1397150832Snetchild ES_UNLOCK(es); 1398150832Snetchild 1399150832Snetchild return (0); 1400148591Snetchild} 1401148591Snetchild 1402148591Snetchildstatic int 1403150832Snetchildsysctl_es137x_latency_timer(SYSCTL_HANDLER_ARGS) 1404148591Snetchild{ 1405148591Snetchild struct es_info *es; 1406148591Snetchild device_t dev; 1407150832Snetchild uint32_t val; 1408150832Snetchild int err; 1409148591Snetchild 1410148591Snetchild dev = oidp->oid_arg1; 1411148591Snetchild es = pcm_getdevinfo(dev); 1412150832Snetchild ES_LOCK(es); 1413148591Snetchild val = pci_read_config(dev, PCIR_LATTIMER, 1); 1414150832Snetchild ES_UNLOCK(es); 1415170289Sdwmalone err = sysctl_handle_int(oidp, &val, 0, req); 1416164614Sariff 1417148591Snetchild if (err || req->newptr == NULL) 1418150832Snetchild return (err); 1419150832Snetchild if (val > 255) 1420150832Snetchild return (EINVAL); 1421148591Snetchild 1422150832Snetchild ES_LOCK(es); 1423148591Snetchild pci_write_config(dev, PCIR_LATTIMER, val, 1); 1424150832Snetchild ES_UNLOCK(es); 1425150832Snetchild 1426150832Snetchild return (0); 1427148591Snetchild} 1428150832Snetchild 1429150832Snetchildstatic int 1430150832Snetchildsysctl_es137x_fixed_rate(SYSCTL_HANDLER_ARGS) 1431150832Snetchild{ 1432150832Snetchild struct es_info *es; 1433150832Snetchild device_t dev; 1434150832Snetchild uint32_t val; 1435150832Snetchild int err; 1436150832Snetchild 1437150832Snetchild dev = oidp->oid_arg1; 1438150832Snetchild es = pcm_getdevinfo(dev); 1439150832Snetchild ES_LOCK(es); 1440152419Sariff val = ES_FIXED_RATE(es->escfg); 1441152419Sariff if (val < es_caps.minspeed) 1442150832Snetchild val = 0; 1443150832Snetchild ES_UNLOCK(es); 1444170289Sdwmalone err = sysctl_handle_int(oidp, &val, 0, req); 1445164614Sariff 1446150832Snetchild if (err || req->newptr == NULL) 1447150832Snetchild return (err); 1448150832Snetchild if (val != 0 && (val < es_caps.minspeed || val > es_caps.maxspeed)) 1449150832Snetchild return (EINVAL); 1450150832Snetchild 1451150832Snetchild ES_LOCK(es); 1452152419Sariff if (es->ctrl & (CTRL_DAC2_EN|CTRL_ADC_EN)) { 1453152419Sariff ES_UNLOCK(es); 1454152419Sariff return (EBUSY); 1455152419Sariff } 1456150832Snetchild if (val) { 1457152419Sariff if (val != ES_FIXED_RATE(es->escfg)) { 1458152419Sariff es->escfg = ES_SET_FIXED_RATE(es->escfg, val); 1459152419Sariff es->ch[ES_DAC2].caps.maxspeed = val; 1460152419Sariff es->ch[ES_DAC2].caps.minspeed = val; 1461152419Sariff es->ch[ES_ADC].caps.maxspeed = val; 1462152419Sariff es->ch[ES_ADC].caps.minspeed = val; 1463152419Sariff es->ctrl &= ~CTRL_PCLKDIV; 1464152419Sariff es->ctrl |= DAC2_SRTODIV(val) << CTRL_SH_PCLKDIV; 1465152419Sariff es_wr(es, ES1370_REG_CONTROL, es->ctrl, 4); 1466152419Sariff } 1467150832Snetchild } else { 1468152419Sariff es->escfg = ES_SET_FIXED_RATE(es->escfg, 0); 1469152419Sariff es->ch[ES_DAC2].caps = es_caps; 1470152419Sariff es->ch[ES_ADC].caps = es_caps; 1471150832Snetchild } 1472150832Snetchild ES_UNLOCK(es); 1473150832Snetchild 1474150832Snetchild return (0); 1475150832Snetchild} 1476152419Sariff 1477152419Sariffstatic int 1478152419Sariffsysctl_es137x_single_pcm_mixer(SYSCTL_HANDLER_ARGS) 1479152419Sariff{ 1480152419Sariff struct es_info *es; 1481152419Sariff struct snddev_info *d; 1482152419Sariff struct snd_mixer *m; 1483152419Sariff device_t dev; 1484152419Sariff uint32_t val, set; 1485152419Sariff int recsrc, level, err; 1486152419Sariff 1487152419Sariff dev = oidp->oid_arg1; 1488152419Sariff d = device_get_softc(dev); 1489170815Sariff if (!PCM_REGISTERED(d) || d->mixer_dev == NULL || 1490170815Sariff d->mixer_dev->si_drv1 == NULL) 1491152419Sariff return (EINVAL); 1492152419Sariff es = d->devinfo; 1493152419Sariff if (es == NULL) 1494152419Sariff return (EINVAL); 1495152419Sariff ES_LOCK(es); 1496152419Sariff set = ES_SINGLE_PCM_MIX(es->escfg); 1497152419Sariff val = set; 1498152419Sariff ES_UNLOCK(es); 1499170289Sdwmalone err = sysctl_handle_int(oidp, &val, 0, req); 1500164614Sariff 1501152419Sariff if (err || req->newptr == NULL) 1502152419Sariff return (err); 1503152419Sariff if (!(val == 0 || val == 1)) 1504152419Sariff return (EINVAL); 1505152419Sariff if (val == set) 1506152419Sariff return (0); 1507170815Sariff PCM_ACQUIRE_QUICK(d); 1508170815Sariff m = (d->mixer_dev != NULL) ? d->mixer_dev->si_drv1 : NULL; 1509170815Sariff if (m == NULL) { 1510170815Sariff PCM_RELEASE_QUICK(d); 1511170815Sariff return (ENODEV); 1512170815Sariff } 1513170815Sariff if (mixer_busy(m) != 0) { 1514170815Sariff PCM_RELEASE_QUICK(d); 1515152419Sariff return (EBUSY); 1516170815Sariff } 1517170815Sariff level = mix_get(m, SOUND_MIXER_PCM); 1518170815Sariff recsrc = mix_getrecsrc(m); 1519170815Sariff if (level < 0 || recsrc < 0) { 1520170815Sariff PCM_RELEASE_QUICK(d); 1521170815Sariff return (ENXIO); 1522170815Sariff } 1523152419Sariff 1524152419Sariff ES_LOCK(es); 1525152419Sariff if (es->ctrl & (CTRL_ADC_EN | CTRL_DAC1_EN | CTRL_DAC2_EN)) { 1526152419Sariff ES_UNLOCK(es); 1527170815Sariff PCM_RELEASE_QUICK(d); 1528152419Sariff return (EBUSY); 1529152419Sariff } 1530164614Sariff if (val) 1531152419Sariff es->escfg = ES_SET_SINGLE_PCM_MIX(es->escfg, 1); 1532164614Sariff else 1533152419Sariff es->escfg = ES_SET_SINGLE_PCM_MIX(es->escfg, 0); 1534152419Sariff ES_UNLOCK(es); 1535152419Sariff if (!val) { 1536170815Sariff mix_setdevs(m, mix_getdevs(m) | (1 << SOUND_MIXER_SYNTH)); 1537170815Sariff mix_setrecdevs(m, mix_getrecdevs(m) | (1 << SOUND_MIXER_SYNTH)); 1538170815Sariff err = mix_set(m, SOUND_MIXER_SYNTH, level & 0x7f, 1539170815Sariff (level >> 8) & 0x7f); 1540152419Sariff } else { 1541170815Sariff err = mix_set(m, SOUND_MIXER_SYNTH, level & 0x7f, 1542170815Sariff (level >> 8) & 0x7f); 1543170815Sariff mix_setdevs(m, mix_getdevs(m) & ~(1 << SOUND_MIXER_SYNTH)); 1544170815Sariff mix_setrecdevs(m, mix_getrecdevs(m) & 1545164614Sariff ~(1 << SOUND_MIXER_SYNTH)); 1546152419Sariff } 1547152419Sariff if (!err) { 1548152419Sariff level = recsrc; 1549152419Sariff if (recsrc & (1 << SOUND_MIXER_PCM)) 1550152419Sariff recsrc |= 1 << SOUND_MIXER_SYNTH; 1551152419Sariff else if (recsrc & (1 << SOUND_MIXER_SYNTH)) 1552152419Sariff recsrc |= 1 << SOUND_MIXER_PCM; 1553152419Sariff if (level != recsrc) 1554170815Sariff err = mix_setrecsrc(m, recsrc); 1555152419Sariff } 1556170815Sariff 1557170815Sariff PCM_RELEASE_QUICK(d); 1558170815Sariff 1559152419Sariff return (err); 1560152419Sariff} 1561164614Sariff 1562164614Sariffstatic int 1563164614Sariffsysctl_es_polling(SYSCTL_HANDLER_ARGS) 1564164614Sariff{ 1565164614Sariff struct es_info *es; 1566164614Sariff device_t dev; 1567164614Sariff int err, val; 1568164614Sariff 1569164614Sariff dev = oidp->oid_arg1; 1570164614Sariff es = pcm_getdevinfo(dev); 1571164614Sariff if (es == NULL) 1572164614Sariff return (EINVAL); 1573164614Sariff ES_LOCK(es); 1574164614Sariff val = es->polling; 1575164614Sariff ES_UNLOCK(es); 1576170289Sdwmalone err = sysctl_handle_int(oidp, &val, 0, req); 1577164614Sariff 1578164614Sariff if (err || req->newptr == NULL) 1579164614Sariff return (err); 1580164614Sariff if (val < 0 || val > 1) 1581164614Sariff return (EINVAL); 1582164614Sariff 1583164614Sariff ES_LOCK(es); 1584164614Sariff if (val != es->polling) { 1585164614Sariff if (es_chan_active(es) != 0) 1586164614Sariff err = EBUSY; 1587164614Sariff else if (val == 0) 1588164614Sariff es->polling = 0; 1589164614Sariff else 1590164614Sariff es->polling = 1; 1591164614Sariff } 1592164614Sariff ES_UNLOCK(es); 1593164614Sariff 1594164614Sariff return (err); 1595164614Sariff} 1596148591Snetchild#endif /* SND_DYNSYSCTL */ 1597148591Snetchild 1598148591Snetchildstatic void 1599148591Snetchildes_init_sysctls(device_t dev) 1600148591Snetchild{ 1601148591Snetchild#ifdef SND_DYNSYSCTL 1602148591Snetchild struct es_info *es; 1603148591Snetchild int r, devid, revid; 1604148591Snetchild 1605148591Snetchild devid = pci_get_devid(dev); 1606148591Snetchild revid = pci_get_revid(dev); 1607148591Snetchild es = pcm_getdevinfo(dev); 1608148591Snetchild if ((devid == ES1371_PCI_ID && revid == ES1371REV_ES1373_8) || 1609167648Sariff (devid == ES1371_PCI_ID && revid == ES1371REV_CT5880_A) || 1610167648Sariff (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_C) || 1611167648Sariff (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_D) || 1612167648Sariff (devid == CT5880_PCI_ID && revid == CT5880REV_CT5880_E)) { 1613159732Snetchild /* XXX: an user should be able to set this with a control tool, 1614159732Snetchild if not done before 7.0-RELEASE, this needs to be converted 1615159732Snetchild to a device specific sysctl "dev.pcm.X.yyy" via 1616159732Snetchild device_get_sysctl_*() as discussed on multimedia@ in msg-id 1617159732Snetchild <861wujij2q.fsf@xps.des.no> */ 1618164614Sariff SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 1619164614Sariff SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 1620164614Sariff "spdif_enabled", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 1621164614Sariff sysctl_es137x_spdif_enable, "I", 1622164614Sariff "Enable S/PDIF output on primary playback channel"); 1623150832Snetchild } else if (devid == ES1370_PCI_ID) { 1624152419Sariff /* 1625152419Sariff * Enable fixed rate sysctl if both DAC2 / ADC enabled. 1626152419Sariff */ 1627164614Sariff if (es->ch[ES_DAC2].channel != NULL && 1628164614Sariff es->ch[ES_ADC].channel != NULL) { 1629159732Snetchild /* XXX: an user should be able to set this with a control tool, 1630159732Snetchild if not done before 7.0-RELEASE, this needs to be converted 1631159732Snetchild to a device specific sysctl "dev.pcm.X.yyy" via 1632159732Snetchild device_get_sysctl_*() as discussed on multimedia@ in msg-id 1633159732Snetchild <861wujij2q.fsf@xps.des.no> */ 1634164614Sariff SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 1635164614Sariff SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 1636164614Sariff OID_AUTO, "fixed_rate", CTLTYPE_INT | CTLFLAG_RW, 1637164614Sariff dev, sizeof(dev), sysctl_es137x_fixed_rate, "I", 1638164614Sariff "Enable fixed rate playback/recording"); 1639152419Sariff } 1640152419Sariff /* 1641152419Sariff * Enable single pcm mixer sysctl if both DAC1/2 enabled. 1642152419Sariff */ 1643164614Sariff if (es->ch[ES_DAC1].channel != NULL && 1644164614Sariff es->ch[ES_DAC2].channel != NULL) { 1645159732Snetchild /* XXX: an user should be able to set this with a control tool, 1646159732Snetchild if not done before 7.0-RELEASE, this needs to be converted 1647159732Snetchild to a device specific sysctl "dev.pcm.X.yyy" via 1648159732Snetchild device_get_sysctl_*() as discussed on multimedia@ in msg-id 1649159732Snetchild <861wujij2q.fsf@xps.des.no> */ 1650164614Sariff SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 1651164614Sariff SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), 1652164614Sariff OID_AUTO, "single_pcm_mixer", 1653164614Sariff CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 1654164614Sariff sysctl_es137x_single_pcm_mixer, "I", 1655164614Sariff "Single PCM mixer controller for both DAC1/DAC2"); 1656152419Sariff } 1657148591Snetchild } 1658164614Sariff if (resource_int_value(device_get_name(dev), device_get_unit(dev), 1659164614Sariff "latency_timer", &r) == 0 && !(r < 0 || r > 255)) 1660148591Snetchild pci_write_config(dev, PCIR_LATTIMER, r, 1); 1661159732Snetchild /* XXX: this needs to be converted to a device specific sysctl 1662159732Snetchild "dev.pcm.X.yyy" via device_get_sysctl_*() as discussed on 1663159732Snetchild multimedia@ in msg-id <861wujij2q.fsf@xps.des.no> */ 1664164614Sariff SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 1665164614Sariff SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 1666164614Sariff "latency_timer", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 1667164614Sariff sysctl_es137x_latency_timer, "I", 1668164614Sariff "PCI Latency Timer configuration"); 1669164614Sariff SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 1670164614Sariff SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 1671164614Sariff "polling", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 1672164614Sariff sysctl_es_polling, "I", 1673164614Sariff "Enable polling mode"); 1674148591Snetchild#endif /* SND_DYNSYSCTL */ 1675148591Snetchild} 1676148591Snetchild 1677148591Snetchildstatic int 167850724Scges_pci_attach(device_t dev) 167950724Scg{ 1680164614Sariff uint32_t data; 1681150832Snetchild struct es_info *es = NULL; 1682152419Sariff int mapped, i, numplay, dac_cfg; 168350724Scg char status[SND_STATUSLEN]; 1684150832Snetchild struct ac97_info *codec = NULL; 168570134Scg kobj_class_t ct = NULL; 1686150832Snetchild uint32_t devid; 168750724Scg 1688170873Sariff es = malloc(sizeof *es, M_DEVBUF, M_WAITOK | M_ZERO); 1689167608Sariff es->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_es137x softc"); 169059019Scg es->dev = dev; 1691152419Sariff es->escfg = 0; 169250724Scg mapped = 0; 1693150832Snetchild 1694150832Snetchild pci_enable_busmaster(dev); 169550724Scg data = pci_read_config(dev, PCIR_COMMAND, 2); 1696150832Snetchild data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN); 169755426Scg pci_write_config(dev, PCIR_COMMAND, data, 2); 169855426Scg data = pci_read_config(dev, PCIR_COMMAND, 2); 169950724Scg if (mapped == 0 && (data & PCIM_CMD_MEMEN)) { 170065644Scg es->regid = MEM_MAP_REG; 170165644Scg es->regtype = SYS_RES_MEMORY; 1702127135Snjl es->reg = bus_alloc_resource_any(dev, es->regtype, &es->regid, 1703164614Sariff RF_ACTIVE); 1704150832Snetchild if (es->reg) 170550724Scg mapped++; 170650724Scg } 170750724Scg if (mapped == 0 && (data & PCIM_CMD_PORTEN)) { 1708119690Sjhb es->regid = PCIR_BAR(0); 170965644Scg es->regtype = SYS_RES_IOPORT; 1710127135Snjl es->reg = bus_alloc_resource_any(dev, es->regtype, &es->regid, 1711164614Sariff RF_ACTIVE); 1712150832Snetchild if (es->reg) 171350724Scg mapped++; 171450724Scg } 171550724Scg if (mapped == 0) { 171650724Scg device_printf(dev, "unable to map register space\n"); 171750724Scg goto bad; 171850724Scg } 171954831Scg 1720150832Snetchild es->st = rman_get_bustag(es->reg); 1721150832Snetchild es->sh = rman_get_bushandle(es->reg); 1722164614Sariff callout_init(&es->poll_timer, CALLOUT_MPSAFE); 1723164614Sariff es->poll_ticks = 1; 1724164614Sariff 1725164614Sariff if (resource_int_value(device_get_name(dev), 1726164614Sariff device_get_unit(dev), "polling", &i) == 0 && i != 0) 1727164614Sariff es->polling = 1; 1728164614Sariff else 1729164614Sariff es->polling = 0; 1730164614Sariff 173184658Scg es->bufsz = pcm_getbuffersize(dev, 4096, ES_DEFAULT_BUFSZ, 65536); 1732164614Sariff if (resource_int_value(device_get_name(dev), 1733164614Sariff device_get_unit(dev), "blocksize", &i) == 0 && i > 0) { 1734167648Sariff i &= ES_BLK_ALIGN; 1735167648Sariff if (i < ES_BLK_MIN) 1736167648Sariff i = ES_BLK_MIN; 1737164614Sariff es->blkcnt = es->bufsz / i; 1738164614Sariff i = 0; 1739164614Sariff while (es->blkcnt >> i) 1740164614Sariff i++; 1741164614Sariff es->blkcnt = 1 << (i - 1); 1742167648Sariff if (es->blkcnt < ES_DMA_SEGS_MIN) 1743167648Sariff es->blkcnt = ES_DMA_SEGS_MIN; 1744167648Sariff else if (es->blkcnt > ES_DMA_SEGS_MAX) 1745167648Sariff es->blkcnt = ES_DMA_SEGS_MAX; 174684658Scg 1747164614Sariff } else 1748164614Sariff es->blkcnt = 2; 1749164614Sariff 1750164614Sariff if (resource_int_value(device_get_name(dev), device_get_unit(dev), 1751164614Sariff "dac", &dac_cfg) == 0) { 1752152419Sariff if (dac_cfg < 0 || dac_cfg > 3) 1753152419Sariff dac_cfg = ES_DEFAULT_DAC_CFG; 1754152419Sariff } else 1755152419Sariff dac_cfg = ES_DEFAULT_DAC_CFG; 1756152419Sariff 1757152419Sariff switch (dac_cfg) { 1758164614Sariff case 0: /* Enable all DAC: DAC1, DAC2 */ 1759164614Sariff numplay = 2; 1760164614Sariff es->escfg = ES_SET_DAC_FIRST(es->escfg, ES_DAC1); 1761164614Sariff es->escfg = ES_SET_DAC_SECOND(es->escfg, ES_DAC2); 1762164614Sariff break; 1763164614Sariff case 1: /* Only DAC1 */ 1764164614Sariff numplay = 1; 1765164614Sariff es->escfg = ES_SET_DAC_FIRST(es->escfg, ES_DAC1); 1766164614Sariff break; 1767164614Sariff case 3: /* Enable all DAC / swap position: DAC2, DAC1 */ 1768164614Sariff numplay = 2; 1769164614Sariff es->escfg = ES_SET_DAC_FIRST(es->escfg, ES_DAC2); 1770164614Sariff es->escfg = ES_SET_DAC_SECOND(es->escfg, ES_DAC1); 1771164614Sariff break; 1772164614Sariff case 2: /* Only DAC2 */ 1773164614Sariff default: 1774164614Sariff numplay = 1; 1775164614Sariff es->escfg = ES_SET_DAC_FIRST(es->escfg, ES_DAC2); 1776164614Sariff break; 1777152419Sariff } 1778152419Sariff es->escfg = ES_SET_NUMPLAY(es->escfg, numplay); 1779152419Sariff es->escfg = ES_SET_NUMREC(es->escfg, 1); 1780152419Sariff 1781148591Snetchild devid = pci_get_devid(dev); 1782150832Snetchild switch (devid) { 1783150832Snetchild case ES1371_PCI_ID: 1784150832Snetchild case ES1371_PCI_ID2: 1785150832Snetchild case CT5880_PCI_ID: 1786150832Snetchild case CT4730_PCI_ID: 1787150832Snetchild es1371_init(es); 1788150832Snetchild codec = AC97_CREATE(dev, es, es1371_ac97); 1789150832Snetchild if (codec == NULL) 179054831Scg goto bad; 179154831Scg /* our init routine does everything for us */ 179254831Scg /* set to NULL; flag mixer_init not to run the ac97_init */ 179354831Scg /* ac97_mixer.init = NULL; */ 1794150832Snetchild if (mixer_init(dev, ac97_getmixerclass(), codec)) 1795150832Snetchild goto bad; 179670134Scg ct = &eschan1371_class; 1797150832Snetchild break; 1798150832Snetchild case ES1370_PCI_ID: 1799150832Snetchild es1370_init(es); 1800152419Sariff /* 1801152419Sariff * Disable fixed rate operation if DAC2 disabled. 1802152419Sariff * This is a special case for es1370 only, where the 1803152419Sariff * speed of both ADC and DAC2 locked together. 1804152419Sariff */ 1805164614Sariff if (!ES_DAC2_ENABLED(es->escfg)) 1806152419Sariff es->escfg = ES_SET_FIXED_RATE(es->escfg, 0); 1807150832Snetchild if (mixer_init(dev, &es1370_mixer_class, es)) 180854831Scg goto bad; 180970134Scg ct = &eschan1370_class; 1810150832Snetchild break; 1811150832Snetchild default: 1812150832Snetchild goto bad; 1813150832Snetchild /* NOTREACHED */ 1814150832Snetchild } 181550724Scg 181665644Scg es->irqid = 0; 1817127135Snjl es->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &es->irqid, 1818164614Sariff RF_ACTIVE | RF_SHAREABLE); 1819164614Sariff if (!es->irq || snd_setup_intr(dev, es->irq, INTR_MPSAFE, es_intr, 1820164614Sariff es, &es->ih)) { 182150724Scg device_printf(dev, "unable to map interrupt\n"); 182250724Scg goto bad; 182350724Scg } 182450724Scg 1825166165Smarius if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), 1826166165Smarius /*alignment*/2, /*boundary*/0, 182750724Scg /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 182850724Scg /*highaddr*/BUS_SPACE_MAXADDR, 182950724Scg /*filter*/NULL, /*filterarg*/NULL, 183084658Scg /*maxsize*/es->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff, 1831148591Snetchild /*flags*/0, /*lockfunc*/NULL, 1832148591Snetchild /*lockarg*/NULL, &es->parent_dmat) != 0) { 183350724Scg device_printf(dev, "unable to create dma tag\n"); 183450724Scg goto bad; 183550724Scg } 183650724Scg 1837126695Smatk snprintf(status, SND_STATUSLEN, "at %s 0x%lx irq %ld %s", 1838164614Sariff (es->regtype == SYS_RES_IOPORT)? "io" : "memory", 1839164614Sariff rman_get_start(es->reg), rman_get_start(es->irq), 1840164614Sariff PCM_KLDSTRING(snd_es137x)); 184150724Scg 1842152419Sariff if (pcm_register(dev, es, numplay, 1)) 1843150832Snetchild goto bad; 1844152419Sariff for (i = 0; i < numplay; i++) 1845152419Sariff pcm_addchan(dev, PCMDIR_PLAY, ct, es); 184654831Scg pcm_addchan(dev, PCMDIR_REC, ct, es); 1847148591Snetchild es_init_sysctls(dev); 184850724Scg pcm_setstatus(dev, status); 1849152419Sariff es->escfg = ES_SET_GP(es->escfg, 0); 1850164614Sariff if (numplay == 1) 1851152419Sariff device_printf(dev, "<Playback: DAC%d / Record: ADC>\n", 1852164614Sariff ES_DAC_FIRST(es->escfg) + 1); 1853164614Sariff else if (numplay == 2) 1854152419Sariff device_printf(dev, "<Playback: DAC%d,DAC%d / Record: ADC>\n", 1855164614Sariff ES_DAC_FIRST(es->escfg) + 1, ES_DAC_SECOND(es->escfg) + 1); 1856164614Sariff return (0); 185750724Scg 1858164614Sariffbad: 1859164614Sariff if (es->parent_dmat) 1860164614Sariff bus_dma_tag_destroy(es->parent_dmat); 1861164614Sariff if (es->ih) 1862164614Sariff bus_teardown_intr(dev, es->irq, es->ih); 1863164614Sariff if (es->irq) 1864164614Sariff bus_release_resource(dev, SYS_RES_IRQ, es->irqid, es->irq); 1865164614Sariff if (codec) 1866164614Sariff ac97_destroy(codec); 1867164614Sariff if (es->reg) 1868164614Sariff bus_release_resource(dev, es->regtype, es->regid, es->reg); 1869164614Sariff if (es->lock) 1870164614Sariff snd_mtxfree(es->lock); 1871164614Sariff if (es) 1872164614Sariff free(es, M_DEVBUF); 1873164614Sariff return (ENXIO); 187450724Scg} 187550724Scg 187665644Scgstatic int 187765644Scges_pci_detach(device_t dev) 187865644Scg{ 187965644Scg int r; 188065644Scg struct es_info *es; 188165644Scg 188265644Scg r = pcm_unregister(dev); 1883164614Sariff if (r) 1884164614Sariff return (r); 188565644Scg 188665644Scg es = pcm_getdevinfo(dev); 1887170721Sariff 1888170721Sariff if (es != NULL && es->num != 0) { 1889170721Sariff ES_LOCK(es); 1890170721Sariff es->polling = 0; 1891170721Sariff callout_stop(&es->poll_timer); 1892170721Sariff ES_UNLOCK(es); 1893170721Sariff callout_drain(&es->poll_timer); 1894170721Sariff } 1895170721Sariff 189665644Scg bus_teardown_intr(dev, es->irq, es->ih); 189765644Scg bus_release_resource(dev, SYS_RES_IRQ, es->irqid, es->irq); 1898148591Snetchild bus_release_resource(dev, es->regtype, es->regid, es->reg); 1899150832Snetchild bus_dma_tag_destroy(es->parent_dmat); 1900148591Snetchild snd_mtxfree(es->lock); 190165644Scg free(es, M_DEVBUF); 190265644Scg 1903164614Sariff return (0); 190465644Scg} 190565644Scg 190650724Scgstatic device_method_t es_methods[] = { 190750724Scg /* Device interface */ 190850724Scg DEVMETHOD(device_probe, es_pci_probe), 190950724Scg DEVMETHOD(device_attach, es_pci_attach), 191065644Scg DEVMETHOD(device_detach, es_pci_detach), 191150724Scg 191250724Scg { 0, 0 } 191350724Scg}; 191450724Scg 191550724Scgstatic driver_t es_driver = { 191650724Scg "pcm", 191750724Scg es_methods, 191882180Scg PCM_SOFTC_SIZE, 191950724Scg}; 192050724Scg 192162483ScgDRIVER_MODULE(snd_es137x, pci, es_driver, pcm_devclass, 0, 0); 1922132236StanimuraMODULE_DEPEND(snd_es137x, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 192362483ScgMODULE_VERSION(snd_es137x, 1); 1924