Deleted Added
full compact
2,3c2,3
< * Support the ENSONIQ AudioPCI board based on the ES1370 and Codec
< * AK4531.
---
> * Support the ENSONIQ AudioPCI board and Creative Labs SoundBlaster PCI
> * boards based on the ES1370, ES1371 and ES1373 chips.
4a5
> * Copyright (c) 1999 Russell Cattelan <cattelan@thebarn.com>
40c41
< * $FreeBSD: head/sys/dev/sound/pci/es137x.c 52046 1999-10-09 03:50:27Z imp $
---
> * $FreeBSD: head/sys/dev/sound/pci/es137x.c 53413 1999-11-19 07:29:10Z roger $
42a44,52
> /*
> * Part of this code was heavily inspired by the linux driver from
> * Thomas Sailer (sailer@ife.ee.ethz.ch)
> * Just about everything has been touched and reworked in some way but
> * the all the underlying sequences/timing/register values are from
> * Thomas' code.
> *
> */
>
47c57,58
< #include <dev/pcm/pci/es1370.h>
---
> #include <dev/pcm/ac97.h>
> #include <dev/pcm/pci/es137x.h>
51a63,64
> #include <sys/sysctl.h>
>
53a67,69
> static int debug = 0;
> SYSCTL_INT(_debug, OID_AUTO, es_debug, CTLFLAG_RW, &debug, 0, "");
>
57a74
> #define ES1371_PCI_ID 0x13711274
62c79
< struct es_chinfo {
---
> typedef struct es_chinfo {
68c85
< };
---
> } es_chinfo_t;
70c87
< struct es_info {
---
> typedef struct es_info {
79c96
< };
---
> } es_info_t;
82d98
<
83a100,110
>
> static u_int es1371_wait_src_ready(es_info_t *);
> static void es1371_src_write(es_info_t *, u_short, unsigned short);
> static u_int es1371_adc_rate (es_info_t *, u_int, int);
> static u_int es1371_dac1_rate(es_info_t *, u_int, int);
> static u_int es1371_dac2_rate(es_info_t *, u_int, int);
> static void es1371_wrcodec(void *, int, u_int32_t);
> static u_int32_t es1371_rdcodec(void *, u_int32_t);
> static int es1371_init(es_info_t *es);
> static int eschan1371_setspeed(void *data, u_int32_t speed);
>
90,95c117,122
< static int eschan_setdir(void *data, int dir);
< static int eschan_setformat(void *data, u_int32_t format);
< static int eschan_setspeed(void *data, u_int32_t speed);
< static int eschan_setblocksize(void *data, u_int32_t blocksize);
< static int eschan_trigger(void *data, int go);
< static int eschan_getptr(void *data);
---
> static int eschan_setdir(void *data, int dir);
> static int eschan_setformat(void *data, u_int32_t format);
> static int eschan_setspeed(void *data, u_int32_t speed);
> static int eschan_setblocksize(void *data, u_int32_t blocksize);
> static int eschan_trigger(void *data, int go);
> static int eschan_getptr(void *data);
393a421,745
>
> /* ES1371 specific code */
>
> #define CODEC_ID_SESHIFT 10
> #define CODEC_ID_SEMASK 0x1f
>
> #define CODEC_PIRD 0x00800000 /* 0 = write AC97 register */
> #define CODEC_PIADD_MASK 0x007f0000
> #define CODEC_PIADD_SHIFT 16
> #define CODEC_PIDAT_MASK 0x0000ffff
> #define CODEC_PIDAT_SHIFT 0
>
> #define CODEC_PORD 0x00800000 /* 0 = write AC97 register */
> #define CODEC_POADD_MASK 0x007f0000
> #define CODEC_POADD_SHIFT 16
> #define CODEC_PODAT_MASK 0x0000ffff
> #define CODEC_PODAT_SHIFT 0
>
> #define CODEC_RDY 0x80000000 /* AC97 read data valid */
> #define CODEC_WIP 0x40000000 /* AC97 write in progress */
>
> #define ES1370_REG_CONTROL 0x00
> #define ES1370_REG_SERIAL_CONTROL 0x20
> #define ES1371_REG_CODEC 0x14
> #define ES1371_REG_LEGACY 0x18 /* W/R: Legacy control/status register */
> #define ES1371_REG_SMPRATE 0x10 /* W/R: Codec rate converter interface register */
>
> #define ES1371_SYNC_RES (1<<14) /* Warm AC97 reset */
> #define ES1371_DIS_R1 (1<<19) /* record channel accumulator update disable */
> #define ES1371_DIS_P2 (1<<20) /* playback channel 2 accumulator update disable */
> #define ES1371_DIS_P1 (1<<21) /* playback channel 1 accumulator update disable */
> #define ES1371_DIS_SRC (1<<22) /* sample rate converter disable */
> #define ES1371_SRC_RAM_BUSY (1<<23) /* R/O: sample rate memory is busy */
> #define ES1371_SRC_RAM_WE (1<<24) /* R/W: read/write control for sample rate converter */
> #define ES1371_SRC_RAM_ADDRO(o) (((o)&0x7f)<<25) /* address of the sample rate converter */
> #define ES1371_SRC_RAM_DATAO(o) (((o)&0xffff)<<0) /* current value of the sample rate converter */
> #define ES1371_SRC_RAM_DATAI(i) (((i)>>0)&0xffff) /* current value of the sample rate converter */
>
> /*
> * Sample rate converter addresses
> */
>
> #define ES_SMPREG_DAC1 0x70
> #define ES_SMPREG_DAC2 0x74
> #define ES_SMPREG_ADC 0x78
> #define ES_SMPREG_TRUNC_N 0x00
> #define ES_SMPREG_INT_REGS 0x01
> #define ES_SMPREG_VFREQ_FRAC 0x03
> #define ES_SMPREG_VOL_ADC 0x6c
> #define ES_SMPREG_VOL_DAC1 0x7c
> #define ES_SMPREG_VOL_DAC2 0x7e
>
>
> int
> es1371_init(struct es_info *es)
> {
> int idx;
>
> if(debug > 0) printf("es_init\n");
>
> es->ctrl = 0;
> es->sctrl = 0;
> /* initialize the chips */
> bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
> bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl);
> bus_space_write_4(es->st, es->sh, ES1371_REG_LEGACY, 0);
> /* AC'97 warm reset to start the bitclk */
> bus_space_write_4(es->st, es->sh, ES1371_REG_LEGACY, es->ctrl | ES1371_SYNC_RES);
> DELAY(2000);
> bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL,es->ctrl);
> /* Init the sample rate converter */
> bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE, ES1371_DIS_SRC);
> for (idx = 0; idx < 0x80; idx++)
> es1371_src_write(es, idx, 0);
> es1371_src_write(es, ES_SMPREG_DAC1 + ES_SMPREG_TRUNC_N, 16 << 4);
> es1371_src_write(es, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, 16 << 10);
> es1371_src_write(es, ES_SMPREG_DAC2 + ES_SMPREG_TRUNC_N, 16 << 4);
> es1371_src_write(es, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, 16 << 10);
> es1371_src_write(es, ES_SMPREG_VOL_ADC, 1 << 12);
> es1371_src_write(es, ES_SMPREG_VOL_ADC + 1, 1 << 12);
> es1371_src_write(es, ES_SMPREG_VOL_DAC1, 1 << 12);
> es1371_src_write(es, ES_SMPREG_VOL_DAC1 + 1, 1 << 12);
> es1371_src_write(es, ES_SMPREG_VOL_DAC2, 1 << 12);
> es1371_src_write(es, ES_SMPREG_VOL_DAC2 + 1, 1 << 12);
> es1371_adc_rate (es, 22050, 1);
> es1371_dac1_rate(es, 22050, 1);
> es1371_dac2_rate(es, 22050, 1);
> /* WARNING:
> * enabling the sample rate converter without properly programming
> * its parameters causes the chip to lock up (the SRC busy bit will
> * be stuck high, and I've found no way to rectify this other than
> * power cycle)
> */
> bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE, 0);
>
> return (0);
> }
>
> void
> es1371_wrcodec(void *s, int addr, u_int32_t data)
> {
> /* unsigned long flags; */
> int sl;
> unsigned t, x;
> struct es_info *es = (struct es_info*)s;
>
> if(debug > 0) printf("wrcodec addr 0x%x data 0x%x\n",addr,data);
>
> for (t = 0; t < 0x1000; t++)
> if(!(bus_space_read_4(es->st, es->sh,(ES1371_REG_CODEC & CODEC_WIP))))
> break;
> sl = spltty();
> /* save the current state for later */
> x = bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE);
> /* enable SRC state data in SRC mux */
> bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE,
> (es1371_wait_src_ready(s) &
> (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1)));
> /* wait for a SAFE time to write addr/data and then do it, dammit */
> for (t = 0; t < 0x1000; t++)
> if (( bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE) & 0x00070000) == 0x00010000)
> break;
>
> if(debug > 2) printf("one b_s_w: 0x%x 0x%x 0x%x\n",es->sh,ES1371_REG_CODEC,
> ((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) |
> ((data << CODEC_PODAT_SHIFT) & CODEC_PODAT_MASK));
>
> bus_space_write_4(es->st, es->sh,ES1371_REG_CODEC,
> ((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) |
> ((data << CODEC_PODAT_SHIFT) & CODEC_PODAT_MASK));
> /* restore SRC reg */
> es1371_wait_src_ready(s);
> if(debug > 2) printf("two b_s_w: 0x%x 0x%x 0x%x\n",es->sh,ES1371_REG_SMPRATE,x);
> bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,x);
> splx(sl);
> }
>
> u_int32_t
> es1371_rdcodec(void *s, u_int32_t addr)
> {
> /* unsigned long flags; */
> int sl;
> unsigned t, x;
>
> struct es_info *es = (struct es_info *)s;
>
> if(debug > 0) printf("rdcodec addr 0x%x ... ",addr);
>
> for (t = 0; t < 0x1000; t++)
> if (!(x = bus_space_read_4(es->st,es->sh,ES1371_REG_CODEC) & CODEC_WIP))
> break;
> if(debug >0) printf("loop 1 t 0x%x x 0x%x ",t,x);
>
> sl = spltty();
>
> /* save the current state for later */
> x = bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE);
> /* enable SRC state data in SRC mux */
> bus_space_write_4(es->st, es->sh, ES1371_REG_SMPRATE,
> (es1371_wait_src_ready(s) &
> (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1)));
> /* wait for a SAFE time to write addr/data and then do it, dammit */
> for (t = 0; t < 0x5000; t++)
> if (( x = bus_space_read_4(es->st, es->sh, ES1371_REG_SMPRATE) & 0x00070000) == 0x00010000)
> break;
> if(debug >0) printf("loop 2 t 0x%x x 0x%x ",t,x);
> bus_space_write_4(es->st, es->sh,ES1371_REG_CODEC,
> ((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) | CODEC_PORD);
>
> /* restore SRC reg */
> es1371_wait_src_ready(s);
> bus_space_write_4(es->st,es->sh,ES1371_REG_SMPRATE,x);
>
> splx(sl);
>
> /* now wait for the stinkin' data (RDY) */
> for (t = 0; t < 0x1000; t++)
> if ((x = bus_space_read_4(es->st,es->sh,ES1371_REG_CODEC)) & CODEC_RDY)
> break;
> if(debug > 0) printf("loop 3 t 0x%x 0x%x ret 0x%x\n",t,x,((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT));
> return ((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT);
> }
>
>
>
>
> static u_int
> es1371_src_read(es_info_t *es, u_short reg){
>
> unsigned int r;
>
> r = es1371_wait_src_ready(es) &
> (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1);
> r |= ES1371_SRC_RAM_ADDRO(reg);
> bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r);
> return ES1371_SRC_RAM_DATAI(es1371_wait_src_ready(es));
> }
>
> static void
> es1371_src_write(es_info_t *es, u_short reg, u_short data){
> u_int r;
>
> r = es1371_wait_src_ready(es) &
> (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1);
> r |= ES1371_SRC_RAM_ADDRO(reg) | ES1371_SRC_RAM_DATAO(data);
> /* printf("es1371_src_write 0x%x 0x%x\n",ES1371_REG_SMPRATE,r | ES1371_SRC_RAM_WE); */
> bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r | ES1371_SRC_RAM_WE);
> }
>
> static u_int
> es1371_adc_rate(es_info_t *es, u_int rate, int set){
> u_int n, truncm, freq, result;
>
> if (rate > 48000)
> rate = 48000;
> if (rate < 4000)
> rate = 4000;
> n = rate / 3000;
> if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9)))
> n--;
> truncm = (21 * n - 1) | 1;
> freq = ((48000UL << 15) / rate) * n;
> result = (48000UL << 15) / (freq / n);
> if (set) {
> if (rate >= 24000) {
> if (truncm > 239)
> truncm = 239;
> es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
> (((239 - truncm) >> 1) << 9) | (n << 4));
> } else {
> if (truncm > 119)
> truncm = 119;
> es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N,
> 0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4));
> }
> es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_INT_REGS,
> (es1371_src_read(es, ES_SMPREG_ADC + ES_SMPREG_INT_REGS) &
> 0x00ff) | ((freq >> 5) & 0xfc00));
> es1371_src_write(es, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
> es1371_src_write(es, ES_SMPREG_VOL_ADC, n << 8);
> es1371_src_write(es, ES_SMPREG_VOL_ADC + 1, n << 8);
> }
> return result;
> }
>
> static u_int
> es1371_dac1_rate(es_info_t *es, u_int rate, int set){
> u_int freq, r, result;
>
> if (rate > 48000)
> rate = 48000;
> if (rate < 4000)
> rate = 4000;
> freq = (rate << 15) / 3000;
> result = (freq * 3000) >> 15;
> if (set) {
> r = (es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1));
> bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r);
> es1371_src_write(es, ES_SMPREG_DAC1 +
> ES_SMPREG_INT_REGS,
> (es1371_src_read(es,
> ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS) & 0x00ff) | ((freq >> 5) & 0xfc00));
> es1371_src_write(es, ES_SMPREG_DAC1 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
> r = (es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P2 | ES1371_DIS_R1));
> bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r);
> }
> return result;
> }
>
> static u_int
> es1371_dac2_rate(es_info_t *es, u_int rate, int set){
> u_int freq, r, result;
>
> if (rate > 48000)
> rate = 48000;
> if (rate < 4000)
> rate = 4000;
> freq = (rate << 15) / 3000;
> result = (freq * 3000) >> 15;
> if (set) {
> r = (es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_P2 | ES1371_DIS_R1));
> bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r);
> /* if(debug > 0) printf("dac2_rate 0x%x\n",bus_space_read_4(es->st, es->sh,ES1371_REG_SMPRATE)); */
> es1371_src_write(es, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS,
> (es1371_src_read(es, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS) &
> 0x00ff) | ((freq >> 5) & 0xfc00));
> es1371_src_write(es, ES_SMPREG_DAC2 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff);
> r = (es1371_wait_src_ready(es) & (ES1371_DIS_SRC | ES1371_DIS_P1 | ES1371_DIS_R1));
> bus_space_write_4(es->st, es->sh,ES1371_REG_SMPRATE,r);
> /* if(debug > 0) printf("dac2_rate 0x%x\n",bus_space_read_4(es->st, es->sh,ES1371_REG_SMPRATE)); */
> }
> return result;
> }
>
>
> static u_int
> es1371_wait_src_ready(es_info_t *es){
> u_int t, r;
>
> for (t = 0; t < 500; t++) {
> if (!((r = bus_space_read_4(es->st, es->sh,ES1371_REG_SMPRATE)) & ES1371_SRC_RAM_BUSY)){
> return r;
> }
> DELAY(1000);
> }
> printf("es1371: wait source ready timeout 0x%x [0x%x]\n", ES1371_REG_SMPRATE, r);
> return 0;
> }
>
>
> int
> eschan1371_setspeed(void *data, u_int32_t speed)
> {
> struct es_chinfo *ch = data;
> struct es_info *es = ch->parent;
>
> /* rec/play speeds locked together - should indicate in flags */
> es1371_dac2_rate(es, speed, 1); /* play */
> es1371_adc_rate (es, speed, 1); /* record */
>
> return speed; /* XXX calc real speed */
> }
>
>
>
425a778,780
> } else if (pci_get_devid(dev) == ES1371_PCI_ID) {
> device_set_desc(dev, "AudioPCI ES1371");
> return 0;
443a799
> struct ac97_info *codec;
480,481c836,838
<
< if (es_init(es) == -1) {
---
>
> if (pci_get_devid(dev) == ES1371_PCI_ID) {
> if(-1 == es1371_init(es)){
482a840,852
> goto bad;
> }
> codec = ac97_create(es,(ac97_read *)es1371_rdcodec,(ac97_write *)es1371_wrcodec);
> if (codec == NULL) goto bad;
> /* our init routine does everything for us */
> /* set to NULL; flag mixer_init not to run the ac97_init */
> /* ac97_mixer.init = NULL; */
> mixer_init(d, &ac97_mixer, codec);
> /* change the routine for setting speed */
> es_chantemplate.setspeed = eschan1371_setspeed;
> } else if (pci_get_devid(dev) == ES1370_PCI_ID) {
> if (-1 == es_init(es)){
> device_printf(dev, "unable to initialize the card\n");
483a854,855
> }
> mixer_init(d, &es_mixer, es);
485c857
< mixer_init(d, &es_mixer, es);
---
>
542a915
>