1/* 2 * Copyright (c) 1999 Seigo Tanimura 3 * All rights reserved. 4 * 5 * Portions of this source are based on cwcealdr.cpp and dhwiface.cpp in 6 * cwcealdr1.zip, the sample sources by Crystal Semiconductor. 7 * Copyright (c) 1996-1998 Crystal Semiconductor Corp. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 *
| 1/* 2 * Copyright (c) 1999 Seigo Tanimura 3 * All rights reserved. 4 * 5 * Portions of this source are based on cwcealdr.cpp and dhwiface.cpp in 6 * cwcealdr1.zip, the sample sources by Crystal Semiconductor. 7 * Copyright (c) 1996-1998 Crystal Semiconductor Corp. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 *
|
30 * $FreeBSD: head/sys/dev/sound/pci/csapcm.c 65644 2000-09-09 19:21:04Z cg $
| 30 * $FreeBSD: head/sys/dev/sound/pci/csapcm.c 70134 2000-12-18 01:36:41Z cg $
|
31 */ 32 33#include <sys/soundcard.h> 34#include <dev/sound/pcm/sound.h> 35#include <dev/sound/pcm/ac97.h> 36#include <dev/sound/chip.h> 37#include <dev/sound/pci/csareg.h> 38#include <dev/sound/pci/csavar.h> 39 40#include <pci/pcireg.h> 41#include <pci/pcivar.h> 42 43/* device private data */ 44struct csa_info; 45 46struct csa_chinfo { 47 struct csa_info *parent; 48 pcm_channel *channel; 49 snd_dbuf *buffer; 50 int dir; 51 u_int32_t fmt; 52 int dma; 53}; 54 55struct csa_info { 56 csa_res res; /* resource */ 57 void *ih; /* Interrupt cookie */ 58 bus_dma_tag_t parent_dmat; /* DMA tag */ 59 struct csa_bridgeinfo *binfo; /* The state of the parent. */ 60 61 /* Contents of board's registers */ 62 u_long pfie; 63 u_long pctl; 64 u_long cctl; 65 struct csa_chinfo pch, rch; 66}; 67 68/* -------------------------------------------------------------------- */ 69 70/* prototypes */ 71static int csa_init(struct csa_info *); 72static void csa_intr(void *); 73static void csa_setplaysamplerate(csa_res *resp, u_long ulInRate); 74static void csa_setcapturesamplerate(csa_res *resp, u_long ulOutRate); 75static void csa_startplaydma(struct csa_info *csa); 76static void csa_startcapturedma(struct csa_info *csa); 77static void csa_stopplaydma(struct csa_info *csa); 78static void csa_stopcapturedma(struct csa_info *csa); 79static void csa_powerupadc(csa_res *resp); 80static void csa_powerupdac(csa_res *resp); 81static int csa_startdsp(csa_res *resp); 82static int csa_allocres(struct csa_info *scp, device_t dev); 83static void csa_releaseres(struct csa_info *scp, device_t dev); 84
| 31 */ 32 33#include <sys/soundcard.h> 34#include <dev/sound/pcm/sound.h> 35#include <dev/sound/pcm/ac97.h> 36#include <dev/sound/chip.h> 37#include <dev/sound/pci/csareg.h> 38#include <dev/sound/pci/csavar.h> 39 40#include <pci/pcireg.h> 41#include <pci/pcivar.h> 42 43/* device private data */ 44struct csa_info; 45 46struct csa_chinfo { 47 struct csa_info *parent; 48 pcm_channel *channel; 49 snd_dbuf *buffer; 50 int dir; 51 u_int32_t fmt; 52 int dma; 53}; 54 55struct csa_info { 56 csa_res res; /* resource */ 57 void *ih; /* Interrupt cookie */ 58 bus_dma_tag_t parent_dmat; /* DMA tag */ 59 struct csa_bridgeinfo *binfo; /* The state of the parent. */ 60 61 /* Contents of board's registers */ 62 u_long pfie; 63 u_long pctl; 64 u_long cctl; 65 struct csa_chinfo pch, rch; 66}; 67 68/* -------------------------------------------------------------------- */ 69 70/* prototypes */ 71static int csa_init(struct csa_info *); 72static void csa_intr(void *); 73static void csa_setplaysamplerate(csa_res *resp, u_long ulInRate); 74static void csa_setcapturesamplerate(csa_res *resp, u_long ulOutRate); 75static void csa_startplaydma(struct csa_info *csa); 76static void csa_startcapturedma(struct csa_info *csa); 77static void csa_stopplaydma(struct csa_info *csa); 78static void csa_stopcapturedma(struct csa_info *csa); 79static void csa_powerupadc(csa_res *resp); 80static void csa_powerupdac(csa_res *resp); 81static int csa_startdsp(csa_res *resp); 82static int csa_allocres(struct csa_info *scp, device_t dev); 83static void csa_releaseres(struct csa_info *scp, device_t dev); 84
|
85/* talk to the codec - called from ac97.c */ 86static u_int32_t csa_rdcd(void *, int); 87static void csa_wrcd(void *, int, u_int32_t); 88 89/* channel interface */ 90static void *csachan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir); 91static int csachan_setdir(void *data, int dir); 92static int csachan_setformat(void *data, u_int32_t format); 93static int csachan_setspeed(void *data, u_int32_t speed); 94static int csachan_setblocksize(void *data, u_int32_t blocksize); 95static int csachan_trigger(void *data, int go); 96static int csachan_getptr(void *data); 97static pcmchan_caps *csachan_getcaps(void *data); 98
| |
99static u_int32_t csa_playfmt[] = { 100 AFMT_U8, 101 AFMT_STEREO | AFMT_U8, 102 AFMT_S8, 103 AFMT_STEREO | AFMT_S8, 104 AFMT_S16_LE, 105 AFMT_STEREO | AFMT_S16_LE, 106 AFMT_S16_BE, 107 AFMT_STEREO | AFMT_S16_BE, 108 0 109}; 110static pcmchan_caps csa_playcaps = {8000, 48000, csa_playfmt, 0}; 111 112static u_int32_t csa_recfmt[] = { 113 AFMT_S16_LE, 114 AFMT_STEREO | AFMT_S16_LE, 115 0 116}; 117static pcmchan_caps csa_reccaps = {11025, 48000, csa_recfmt, 0}; 118
| 85static u_int32_t csa_playfmt[] = { 86 AFMT_U8, 87 AFMT_STEREO | AFMT_U8, 88 AFMT_S8, 89 AFMT_STEREO | AFMT_S8, 90 AFMT_S16_LE, 91 AFMT_STEREO | AFMT_S16_LE, 92 AFMT_S16_BE, 93 AFMT_STEREO | AFMT_S16_BE, 94 0 95}; 96static pcmchan_caps csa_playcaps = {8000, 48000, csa_playfmt, 0}; 97 98static u_int32_t csa_recfmt[] = { 99 AFMT_S16_LE, 100 AFMT_STEREO | AFMT_S16_LE, 101 0 102}; 103static pcmchan_caps csa_reccaps = {11025, 48000, csa_recfmt, 0}; 104
|
119static pcm_channel csa_chantemplate = { 120 csachan_init, 121 csachan_setdir, 122 csachan_setformat, 123 csachan_setspeed, 124 csachan_setblocksize, 125 csachan_trigger, 126 csachan_getptr, 127 csachan_getcaps, 128 NULL, /* free */ 129 NULL, /* nop1 */ 130 NULL, /* nop2 */ 131 NULL, /* nop3 */ 132 NULL, /* nop4 */ 133 NULL, /* nop5 */ 134 NULL, /* nop6 */ 135 NULL, /* nop7 */ 136}; 137
| |
138/* -------------------------------------------------------------------- */
| 105/* -------------------------------------------------------------------- */
|
| 106/* ac97 codec */
|
139
| 107
|
140/* channel interface */ 141static void * 142csachan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) 143{ 144 struct csa_info *csa = devinfo; 145 struct csa_chinfo *ch = (dir == PCMDIR_PLAY)? &csa->pch : &csa->rch; 146 147 ch->parent = csa; 148 ch->channel = c; 149 ch->buffer = b; 150 ch->buffer->bufsize = CS461x_BUFFSIZE; 151 if (chn_allocbuf(ch->buffer, csa->parent_dmat) == -1) return NULL; 152 return ch; 153} 154
| |
155static int
| 108static int
|
156csachan_setdir(void *data, int dir)
| 109csa_rdcd(kobj_t obj, void *devinfo, int regno)
|
157{
| 110{
|
158 struct csa_chinfo *ch = data; 159 struct csa_info *csa = ch->parent; 160 csa_res *resp;
| 111 u_int32_t data; 112 struct csa_info *csa = (struct csa_info *)devinfo;
|
161
| 113
|
162 resp = &csa->res;
| 114 if (csa_readcodec(&csa->res, regno + BA0_AC97_RESET, &data)) 115 data = 0;
|
163
| 116
|
164 if (dir == PCMDIR_PLAY) 165 csa_writemem(resp, BA1_PBA, vtophys(ch->buffer->buf)); 166 else 167 csa_writemem(resp, BA1_CBA, vtophys(ch->buffer->buf)); 168 ch->dir = dir; 169 return 0;
| 117 return data;
|
170} 171 172static int
| 118} 119 120static int
|
173csachan_setformat(void *data, u_int32_t format)
| 121csa_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data)
|
174{
| 122{
|
175 struct csa_chinfo *ch = data; 176 struct csa_info *csa = ch->parent; 177 u_long pdtc; 178 csa_res *resp;
| 123 struct csa_info *csa = (struct csa_info *)devinfo;
|
179
| 124
|
180 resp = &csa->res;
| 125 csa_writecodec(&csa->res, regno + BA0_AC97_RESET, data);
|
181
| 126
|
182 if (ch->dir == PCMDIR_REC) 183 csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001); 184 else { 185 csa->pfie = csa_readmem(resp, BA1_PFIE) & ~0x0000f03f; 186 if (format & AFMT_U8 || format & AFMT_U16_LE || format & AFMT_U16_BE) 187 csa->pfie |= 0x8000; 188 if (format & AFMT_S16_BE || format & AFMT_U16_BE) 189 csa->pfie |= 0x4000; 190 if (!(format & AFMT_STEREO)) 191 csa->pfie |= 0x2000; 192 if (format & AFMT_U8 || format & AFMT_S8) 193 csa->pfie |= 0x1000; 194 csa_writemem(resp, BA1_PFIE, csa->pfie); 195 pdtc = csa_readmem(resp, BA1_PDTC) & ~0x000003ff; 196 if ((format & AFMT_S16_BE || format & AFMT_U16_BE || format & AFMT_S16_LE || format & AFMT_U16_LE) && (format & AFMT_STEREO)) 197 pdtc |= 0x00f; 198 else if ((format & AFMT_S16_BE || format & AFMT_U16_BE || format & AFMT_S16_LE || format & AFMT_U16_LE) || (format & AFMT_STEREO)) 199 pdtc |= 0x007; 200 else 201 pdtc |= 0x003; 202 csa_writemem(resp, BA1_PDTC, pdtc); 203 } 204 ch->fmt = format;
| |
205 return 0; 206} 207
| 127 return 0; 128} 129
|
208static int 209csachan_setspeed(void *data, u_int32_t speed) 210{ 211 struct csa_chinfo *ch = data; 212 struct csa_info *csa = ch->parent; 213 csa_res *resp;
| 130static kobj_method_t csa_ac97_methods[] = { 131 KOBJMETHOD(ac97_read, csa_rdcd), 132 KOBJMETHOD(ac97_write, csa_wrcd), 133 { 0, 0 } 134}; 135AC97_DECLARE(csa_ac97);
|
214
| 136
|
215 resp = &csa->res; 216 217 if (ch->dir == PCMDIR_PLAY) 218 csa_setplaysamplerate(resp, speed); 219 else if (ch->dir == PCMDIR_REC) 220 csa_setcapturesamplerate(resp, speed); 221 222 /* rec/play speeds locked together - should indicate in flags */ 223#if 0 224 if (ch->direction == PCMDIR_PLAY) d->rec[0].speed = speed; 225 else d->play[0].speed = speed; 226#endif 227 return speed; /* XXX calc real speed */ 228} 229
| |
230static void 231csa_setplaysamplerate(csa_res *resp, u_long ulInRate) 232{ 233 u_long ulTemp1, ulTemp2; 234 u_long ulPhiIncr; 235 u_long ulCorrectionPerGOF, ulCorrectionPerSec; 236 u_long ulOutRate; 237 238 ulOutRate = 48000; 239 240 /* 241 * Compute the values used to drive the actual sample rate conversion. 242 * The following formulas are being computed, using inline assembly 243 * since we need to use 64 bit arithmetic to compute the values: 244 * 245 * ulPhiIncr = floor((Fs,in * 2^26) / Fs,out) 246 * ulCorrectionPerGOF = floor((Fs,in * 2^26 - Fs,out * ulPhiIncr) / 247 * GOF_PER_SEC) 248 * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr - 249 * GOF_PER_SEC * ulCorrectionPerGOF 250 * 251 * i.e. 252 * 253 * ulPhiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out) 254 * ulCorrectionPerGOF:ulCorrectionPerSec = 255 * dividend:remainder(ulOther / GOF_PER_SEC) 256 */ 257 ulTemp1 = ulInRate << 16; 258 ulPhiIncr = ulTemp1 / ulOutRate; 259 ulTemp1 -= ulPhiIncr * ulOutRate; 260 ulTemp1 <<= 10; 261 ulPhiIncr <<= 10; 262 ulTemp2 = ulTemp1 / ulOutRate; 263 ulPhiIncr += ulTemp2; 264 ulTemp1 -= ulTemp2 * ulOutRate; 265 ulCorrectionPerGOF = ulTemp1 / GOF_PER_SEC; 266 ulTemp1 -= ulCorrectionPerGOF * GOF_PER_SEC; 267 ulCorrectionPerSec = ulTemp1; 268 269 /* 270 * Fill in the SampleRateConverter control block. 271 */ 272 csa_writemem(resp, BA1_PSRC, ((ulCorrectionPerSec << 16) & 0xFFFF0000) | (ulCorrectionPerGOF & 0xFFFF)); 273 csa_writemem(resp, BA1_PPI, ulPhiIncr); 274} 275 276static void 277csa_setcapturesamplerate(csa_res *resp, u_long ulOutRate) 278{ 279 u_long ulPhiIncr, ulCoeffIncr, ulTemp1, ulTemp2; 280 u_long ulCorrectionPerGOF, ulCorrectionPerSec, ulInitialDelay; 281 u_long dwFrameGroupLength, dwCnt; 282 u_long ulInRate; 283 284 ulInRate = 48000; 285 286 /* 287 * We can only decimate by up to a factor of 1/9th the hardware rate. 288 * Return an error if an attempt is made to stray outside that limit. 289 */ 290 if((ulOutRate * 9) < ulInRate) 291 return; 292 293 /* 294 * We can not capture at at rate greater than the Input Rate (48000). 295 * Return an error if an attempt is made to stray outside that limit. 296 */ 297 if(ulOutRate > ulInRate) 298 return; 299 300 /* 301 * Compute the values used to drive the actual sample rate conversion. 302 * The following formulas are being computed, using inline assembly 303 * since we need to use 64 bit arithmetic to compute the values: 304 * 305 * ulCoeffIncr = -floor((Fs,out * 2^23) / Fs,in) 306 * ulPhiIncr = floor((Fs,in * 2^26) / Fs,out) 307 * ulCorrectionPerGOF = floor((Fs,in * 2^26 - Fs,out * ulPhiIncr) / 308 * GOF_PER_SEC) 309 * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr - 310 * GOF_PER_SEC * ulCorrectionPerGOF 311 * ulInitialDelay = ceil((24 * Fs,in) / Fs,out) 312 * 313 * i.e. 314 * 315 * ulCoeffIncr = neg(dividend((Fs,out * 2^23) / Fs,in)) 316 * ulPhiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out) 317 * ulCorrectionPerGOF:ulCorrectionPerSec = 318 * dividend:remainder(ulOther / GOF_PER_SEC) 319 * ulInitialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out) 320 */ 321 ulTemp1 = ulOutRate << 16; 322 ulCoeffIncr = ulTemp1 / ulInRate; 323 ulTemp1 -= ulCoeffIncr * ulInRate; 324 ulTemp1 <<= 7; 325 ulCoeffIncr <<= 7; 326 ulCoeffIncr += ulTemp1 / ulInRate; 327 ulCoeffIncr ^= 0xFFFFFFFF; 328 ulCoeffIncr++; 329 ulTemp1 = ulInRate << 16; 330 ulPhiIncr = ulTemp1 / ulOutRate; 331 ulTemp1 -= ulPhiIncr * ulOutRate; 332 ulTemp1 <<= 10; 333 ulPhiIncr <<= 10; 334 ulTemp2 = ulTemp1 / ulOutRate; 335 ulPhiIncr += ulTemp2; 336 ulTemp1 -= ulTemp2 * ulOutRate; 337 ulCorrectionPerGOF = ulTemp1 / GOF_PER_SEC; 338 ulTemp1 -= ulCorrectionPerGOF * GOF_PER_SEC; 339 ulCorrectionPerSec = ulTemp1; 340 ulInitialDelay = ((ulInRate * 24) + ulOutRate - 1) / ulOutRate; 341 342 /* 343 * Fill in the VariDecimate control block. 344 */ 345 csa_writemem(resp, BA1_CSRC, 346 ((ulCorrectionPerSec << 16) & 0xFFFF0000) | (ulCorrectionPerGOF & 0xFFFF)); 347 csa_writemem(resp, BA1_CCI, ulCoeffIncr); 348 csa_writemem(resp, BA1_CD, 349 (((BA1_VARIDEC_BUF_1 + (ulInitialDelay << 2)) << 16) & 0xFFFF0000) | 0x80); 350 csa_writemem(resp, BA1_CPI, ulPhiIncr); 351 352 /* 353 * Figure out the frame group length for the write back task. Basically, 354 * this is just the factors of 24000 (2^6*3*5^3) that are not present in 355 * the output sample rate. 356 */ 357 dwFrameGroupLength = 1; 358 for(dwCnt = 2; dwCnt <= 64; dwCnt *= 2) 359 { 360 if(((ulOutRate / dwCnt) * dwCnt) != 361 ulOutRate) 362 { 363 dwFrameGroupLength *= 2; 364 } 365 } 366 if(((ulOutRate / 3) * 3) != 367 ulOutRate) 368 { 369 dwFrameGroupLength *= 3; 370 } 371 for(dwCnt = 5; dwCnt <= 125; dwCnt *= 5) 372 { 373 if(((ulOutRate / dwCnt) * dwCnt) != 374 ulOutRate) 375 { 376 dwFrameGroupLength *= 5; 377 } 378 } 379 380 /* 381 * Fill in the WriteBack control block. 382 */ 383 csa_writemem(resp, BA1_CFG1, dwFrameGroupLength); 384 csa_writemem(resp, BA1_CFG2, (0x00800000 | dwFrameGroupLength)); 385 csa_writemem(resp, BA1_CCST, 0x0000FFFF); 386 csa_writemem(resp, BA1_CSPB, ((65536 * ulOutRate) / 24000)); 387 csa_writemem(resp, (BA1_CSPB + 4), 0x0000FFFF); 388} 389
| 137static void 138csa_setplaysamplerate(csa_res *resp, u_long ulInRate) 139{ 140 u_long ulTemp1, ulTemp2; 141 u_long ulPhiIncr; 142 u_long ulCorrectionPerGOF, ulCorrectionPerSec; 143 u_long ulOutRate; 144 145 ulOutRate = 48000; 146 147 /* 148 * Compute the values used to drive the actual sample rate conversion. 149 * The following formulas are being computed, using inline assembly 150 * since we need to use 64 bit arithmetic to compute the values: 151 * 152 * ulPhiIncr = floor((Fs,in * 2^26) / Fs,out) 153 * ulCorrectionPerGOF = floor((Fs,in * 2^26 - Fs,out * ulPhiIncr) / 154 * GOF_PER_SEC) 155 * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr - 156 * GOF_PER_SEC * ulCorrectionPerGOF 157 * 158 * i.e. 159 * 160 * ulPhiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out) 161 * ulCorrectionPerGOF:ulCorrectionPerSec = 162 * dividend:remainder(ulOther / GOF_PER_SEC) 163 */ 164 ulTemp1 = ulInRate << 16; 165 ulPhiIncr = ulTemp1 / ulOutRate; 166 ulTemp1 -= ulPhiIncr * ulOutRate; 167 ulTemp1 <<= 10; 168 ulPhiIncr <<= 10; 169 ulTemp2 = ulTemp1 / ulOutRate; 170 ulPhiIncr += ulTemp2; 171 ulTemp1 -= ulTemp2 * ulOutRate; 172 ulCorrectionPerGOF = ulTemp1 / GOF_PER_SEC; 173 ulTemp1 -= ulCorrectionPerGOF * GOF_PER_SEC; 174 ulCorrectionPerSec = ulTemp1; 175 176 /* 177 * Fill in the SampleRateConverter control block. 178 */ 179 csa_writemem(resp, BA1_PSRC, ((ulCorrectionPerSec << 16) & 0xFFFF0000) | (ulCorrectionPerGOF & 0xFFFF)); 180 csa_writemem(resp, BA1_PPI, ulPhiIncr); 181} 182 183static void 184csa_setcapturesamplerate(csa_res *resp, u_long ulOutRate) 185{ 186 u_long ulPhiIncr, ulCoeffIncr, ulTemp1, ulTemp2; 187 u_long ulCorrectionPerGOF, ulCorrectionPerSec, ulInitialDelay; 188 u_long dwFrameGroupLength, dwCnt; 189 u_long ulInRate; 190 191 ulInRate = 48000; 192 193 /* 194 * We can only decimate by up to a factor of 1/9th the hardware rate. 195 * Return an error if an attempt is made to stray outside that limit. 196 */ 197 if((ulOutRate * 9) < ulInRate) 198 return; 199 200 /* 201 * We can not capture at at rate greater than the Input Rate (48000). 202 * Return an error if an attempt is made to stray outside that limit. 203 */ 204 if(ulOutRate > ulInRate) 205 return; 206 207 /* 208 * Compute the values used to drive the actual sample rate conversion. 209 * The following formulas are being computed, using inline assembly 210 * since we need to use 64 bit arithmetic to compute the values: 211 * 212 * ulCoeffIncr = -floor((Fs,out * 2^23) / Fs,in) 213 * ulPhiIncr = floor((Fs,in * 2^26) / Fs,out) 214 * ulCorrectionPerGOF = floor((Fs,in * 2^26 - Fs,out * ulPhiIncr) / 215 * GOF_PER_SEC) 216 * ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr - 217 * GOF_PER_SEC * ulCorrectionPerGOF 218 * ulInitialDelay = ceil((24 * Fs,in) / Fs,out) 219 * 220 * i.e. 221 * 222 * ulCoeffIncr = neg(dividend((Fs,out * 2^23) / Fs,in)) 223 * ulPhiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out) 224 * ulCorrectionPerGOF:ulCorrectionPerSec = 225 * dividend:remainder(ulOther / GOF_PER_SEC) 226 * ulInitialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out) 227 */ 228 ulTemp1 = ulOutRate << 16; 229 ulCoeffIncr = ulTemp1 / ulInRate; 230 ulTemp1 -= ulCoeffIncr * ulInRate; 231 ulTemp1 <<= 7; 232 ulCoeffIncr <<= 7; 233 ulCoeffIncr += ulTemp1 / ulInRate; 234 ulCoeffIncr ^= 0xFFFFFFFF; 235 ulCoeffIncr++; 236 ulTemp1 = ulInRate << 16; 237 ulPhiIncr = ulTemp1 / ulOutRate; 238 ulTemp1 -= ulPhiIncr * ulOutRate; 239 ulTemp1 <<= 10; 240 ulPhiIncr <<= 10; 241 ulTemp2 = ulTemp1 / ulOutRate; 242 ulPhiIncr += ulTemp2; 243 ulTemp1 -= ulTemp2 * ulOutRate; 244 ulCorrectionPerGOF = ulTemp1 / GOF_PER_SEC; 245 ulTemp1 -= ulCorrectionPerGOF * GOF_PER_SEC; 246 ulCorrectionPerSec = ulTemp1; 247 ulInitialDelay = ((ulInRate * 24) + ulOutRate - 1) / ulOutRate; 248 249 /* 250 * Fill in the VariDecimate control block. 251 */ 252 csa_writemem(resp, BA1_CSRC, 253 ((ulCorrectionPerSec << 16) & 0xFFFF0000) | (ulCorrectionPerGOF & 0xFFFF)); 254 csa_writemem(resp, BA1_CCI, ulCoeffIncr); 255 csa_writemem(resp, BA1_CD, 256 (((BA1_VARIDEC_BUF_1 + (ulInitialDelay << 2)) << 16) & 0xFFFF0000) | 0x80); 257 csa_writemem(resp, BA1_CPI, ulPhiIncr); 258 259 /* 260 * Figure out the frame group length for the write back task. Basically, 261 * this is just the factors of 24000 (2^6*3*5^3) that are not present in 262 * the output sample rate. 263 */ 264 dwFrameGroupLength = 1; 265 for(dwCnt = 2; dwCnt <= 64; dwCnt *= 2) 266 { 267 if(((ulOutRate / dwCnt) * dwCnt) != 268 ulOutRate) 269 { 270 dwFrameGroupLength *= 2; 271 } 272 } 273 if(((ulOutRate / 3) * 3) != 274 ulOutRate) 275 { 276 dwFrameGroupLength *= 3; 277 } 278 for(dwCnt = 5; dwCnt <= 125; dwCnt *= 5) 279 { 280 if(((ulOutRate / dwCnt) * dwCnt) != 281 ulOutRate) 282 { 283 dwFrameGroupLength *= 5; 284 } 285 } 286 287 /* 288 * Fill in the WriteBack control block. 289 */ 290 csa_writemem(resp, BA1_CFG1, dwFrameGroupLength); 291 csa_writemem(resp, BA1_CFG2, (0x00800000 | dwFrameGroupLength)); 292 csa_writemem(resp, BA1_CCST, 0x0000FFFF); 293 csa_writemem(resp, BA1_CSPB, ((65536 * ulOutRate) / 24000)); 294 csa_writemem(resp, (BA1_CSPB + 4), 0x0000FFFF); 295} 296
|
390static int 391csachan_setblocksize(void *data, u_int32_t blocksize) 392{ 393#if notdef 394 return blocksize; 395#else 396 struct csa_chinfo *ch = data; 397 return ch->buffer->bufsize / 2; 398#endif /* notdef */ 399} 400 401static int 402csachan_trigger(void *data, int go) 403{ 404 struct csa_chinfo *ch = data; 405 struct csa_info *csa = ch->parent; 406 407 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) 408 return 0; 409 410 if (ch->dir == PCMDIR_PLAY) { 411 if (go == PCMTRIG_START) 412 csa_startplaydma(csa); 413 else 414 csa_stopplaydma(csa); 415 } else { 416 if (go == PCMTRIG_START) 417 csa_startcapturedma(csa); 418 else 419 csa_stopcapturedma(csa); 420 } 421 return 0; 422} 423
| |
424static void 425csa_startplaydma(struct csa_info *csa) 426{ 427 csa_res *resp; 428 u_long ul; 429 430 if (!csa->pch.dma) { 431 resp = &csa->res; 432 ul = csa_readmem(resp, BA1_PCTL); 433 ul &= 0x0000ffff; 434 csa_writemem(resp, BA1_PCTL, ul | csa->pctl); 435 csa_writemem(resp, BA1_PVOL, 0x80008000); 436 csa->pch.dma = 1; 437 } 438} 439 440static void 441csa_startcapturedma(struct csa_info *csa) 442{ 443 csa_res *resp; 444 u_long ul; 445 446 if (!csa->rch.dma) { 447 resp = &csa->res; 448 ul = csa_readmem(resp, BA1_CCTL); 449 ul &= 0xffff0000; 450 csa_writemem(resp, BA1_CCTL, ul | csa->cctl); 451 csa_writemem(resp, BA1_CVOL, 0x80008000); 452 csa->rch.dma = 1; 453 } 454} 455 456static void 457csa_stopplaydma(struct csa_info *csa) 458{ 459 csa_res *resp; 460 u_long ul; 461 462 if (csa->pch.dma) { 463 resp = &csa->res; 464 ul = csa_readmem(resp, BA1_PCTL); 465 csa->pctl = ul & 0xffff0000; 466 csa_writemem(resp, BA1_PCTL, ul & 0x0000ffff); 467 csa_writemem(resp, BA1_PVOL, 0xffffffff); 468 csa->pch.dma = 0; 469 470 /* 471 * The bitwise pointer of the serial FIFO in the DSP 472 * seems to make an error upon starting or stopping the 473 * DSP. Clear the FIFO and correct the pointer if we 474 * are not capturing. 475 */ 476 if (!csa->rch.dma) { 477 csa_clearserialfifos(resp); 478 csa_writeio(resp, BA0_SERBSP, 0); 479 } 480 } 481} 482 483static void 484csa_stopcapturedma(struct csa_info *csa) 485{ 486 csa_res *resp; 487 u_long ul; 488 489 if (csa->rch.dma) { 490 resp = &csa->res; 491 ul = csa_readmem(resp, BA1_CCTL); 492 csa->cctl = ul & 0x0000ffff; 493 csa_writemem(resp, BA1_CCTL, ul & 0xffff0000); 494 csa_writemem(resp, BA1_CVOL, 0xffffffff); 495 csa->rch.dma = 0; 496 497 /* 498 * The bitwise pointer of the serial FIFO in the DSP 499 * seems to make an error upon starting or stopping the 500 * DSP. Clear the FIFO and correct the pointer if we 501 * are not playing. 502 */ 503 if (!csa->pch.dma) { 504 csa_clearserialfifos(resp); 505 csa_writeio(resp, BA0_SERBSP, 0); 506 } 507 } 508} 509 510static void 511csa_powerupdac(csa_res *resp) 512{ 513 int i; 514 u_long ul; 515 516 /* 517 * Power on the DACs on the AC97 codec. We turn off the DAC 518 * powerdown bit and write the new value of the power control 519 * register. 520 */ 521 ul = csa_readio(resp, BA0_AC97_POWERDOWN); 522 ul &= 0xfdff; 523 csa_writeio(resp, BA0_AC97_POWERDOWN, ul); 524 525 /* 526 * Now, we wait until we sample a DAC ready state. 527 */ 528 for (i = 0 ; i < 32 ; i++) { 529 /* 530 * First, lets wait a short while to let things settle out a 531 * bit, and to prevent retrying the read too quickly. 532 */ 533 DELAY(125); 534 535 /* 536 * Read the current state of the power control register. 537 */ 538 ul = csa_readio(resp, BA0_AC97_POWERDOWN); 539 540 /* 541 * If the DAC ready state bit is set, then stop waiting. 542 */ 543 if ((ul & 0x2) != 0) 544 break; 545 } 546 /* 547 * The DACs are now calibrated, so we can unmute the DAC output. 548 */ 549 csa_writeio(resp, BA0_AC97_PCM_OUT_VOLUME, 0x0808); 550} 551 552static void 553csa_powerupadc(csa_res *resp) 554{ 555 int i; 556 u_long ul; 557 558 /* 559 * Power on the ADCs on the AC97 codec. We turn off the ADC 560 * powerdown bit and write the new value of the power control 561 * register. 562 */ 563 ul = csa_readio(resp, BA0_AC97_POWERDOWN); 564 ul &= 0xfeff; 565 csa_writeio(resp, BA0_AC97_POWERDOWN, ul); 566 567 /* 568 * Now, we wait until we sample a ADC ready state. 569 */ 570 for (i = 0 ; i < 32 ; i++) { 571 /* 572 * First, lets wait a short while to let things settle out a 573 * bit, and to prevent retrying the read too quickly. 574 */ 575 DELAY(125); 576 577 /* 578 * Read the current state of the power control register. 579 */ 580 ul = csa_readio(resp, BA0_AC97_POWERDOWN); 581 582 /* 583 * If the ADC ready state bit is set, then stop waiting. 584 */ 585 if ((ul & 0x1) != 0) 586 break; 587 } 588} 589 590static int 591csa_startdsp(csa_res *resp) 592{ 593 int i; 594 u_long ul; 595 596 /* 597 * Set the frame timer to reflect the number of cycles per frame. 598 */ 599 csa_writemem(resp, BA1_FRMT, 0xadf); 600 601 /* 602 * Turn on the run, run at frame, and DMA enable bits in the local copy of 603 * the SP control register. 604 */ 605 csa_writemem(resp, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN); 606 607 /* 608 * Wait until the run at frame bit resets itself in the SP control 609 * register. 610 */ 611 ul = 0; 612 for (i = 0 ; i < 25 ; i++) { 613 /* 614 * Wait a little bit, so we don't issue PCI reads too frequently. 615 */ 616#if notdef 617 DELAY(1000); 618#else 619 DELAY(125); 620#endif /* notdef */ 621 /* 622 * Fetch the current value of the SP status register. 623 */ 624 ul = csa_readmem(resp, BA1_SPCR); 625 626 /* 627 * If the run at frame bit has reset, then stop waiting. 628 */ 629 if((ul & SPCR_RUNFR) == 0) 630 break; 631 } 632 /* 633 * If the run at frame bit never reset, then return an error. 634 */ 635 if((ul & SPCR_RUNFR) != 0) 636 return (EAGAIN); 637 638 return (0); 639} 640
| 297static void 298csa_startplaydma(struct csa_info *csa) 299{ 300 csa_res *resp; 301 u_long ul; 302 303 if (!csa->pch.dma) { 304 resp = &csa->res; 305 ul = csa_readmem(resp, BA1_PCTL); 306 ul &= 0x0000ffff; 307 csa_writemem(resp, BA1_PCTL, ul | csa->pctl); 308 csa_writemem(resp, BA1_PVOL, 0x80008000); 309 csa->pch.dma = 1; 310 } 311} 312 313static void 314csa_startcapturedma(struct csa_info *csa) 315{ 316 csa_res *resp; 317 u_long ul; 318 319 if (!csa->rch.dma) { 320 resp = &csa->res; 321 ul = csa_readmem(resp, BA1_CCTL); 322 ul &= 0xffff0000; 323 csa_writemem(resp, BA1_CCTL, ul | csa->cctl); 324 csa_writemem(resp, BA1_CVOL, 0x80008000); 325 csa->rch.dma = 1; 326 } 327} 328 329static void 330csa_stopplaydma(struct csa_info *csa) 331{ 332 csa_res *resp; 333 u_long ul; 334 335 if (csa->pch.dma) { 336 resp = &csa->res; 337 ul = csa_readmem(resp, BA1_PCTL); 338 csa->pctl = ul & 0xffff0000; 339 csa_writemem(resp, BA1_PCTL, ul & 0x0000ffff); 340 csa_writemem(resp, BA1_PVOL, 0xffffffff); 341 csa->pch.dma = 0; 342 343 /* 344 * The bitwise pointer of the serial FIFO in the DSP 345 * seems to make an error upon starting or stopping the 346 * DSP. Clear the FIFO and correct the pointer if we 347 * are not capturing. 348 */ 349 if (!csa->rch.dma) { 350 csa_clearserialfifos(resp); 351 csa_writeio(resp, BA0_SERBSP, 0); 352 } 353 } 354} 355 356static void 357csa_stopcapturedma(struct csa_info *csa) 358{ 359 csa_res *resp; 360 u_long ul; 361 362 if (csa->rch.dma) { 363 resp = &csa->res; 364 ul = csa_readmem(resp, BA1_CCTL); 365 csa->cctl = ul & 0x0000ffff; 366 csa_writemem(resp, BA1_CCTL, ul & 0xffff0000); 367 csa_writemem(resp, BA1_CVOL, 0xffffffff); 368 csa->rch.dma = 0; 369 370 /* 371 * The bitwise pointer of the serial FIFO in the DSP 372 * seems to make an error upon starting or stopping the 373 * DSP. Clear the FIFO and correct the pointer if we 374 * are not playing. 375 */ 376 if (!csa->pch.dma) { 377 csa_clearserialfifos(resp); 378 csa_writeio(resp, BA0_SERBSP, 0); 379 } 380 } 381} 382 383static void 384csa_powerupdac(csa_res *resp) 385{ 386 int i; 387 u_long ul; 388 389 /* 390 * Power on the DACs on the AC97 codec. We turn off the DAC 391 * powerdown bit and write the new value of the power control 392 * register. 393 */ 394 ul = csa_readio(resp, BA0_AC97_POWERDOWN); 395 ul &= 0xfdff; 396 csa_writeio(resp, BA0_AC97_POWERDOWN, ul); 397 398 /* 399 * Now, we wait until we sample a DAC ready state. 400 */ 401 for (i = 0 ; i < 32 ; i++) { 402 /* 403 * First, lets wait a short while to let things settle out a 404 * bit, and to prevent retrying the read too quickly. 405 */ 406 DELAY(125); 407 408 /* 409 * Read the current state of the power control register. 410 */ 411 ul = csa_readio(resp, BA0_AC97_POWERDOWN); 412 413 /* 414 * If the DAC ready state bit is set, then stop waiting. 415 */ 416 if ((ul & 0x2) != 0) 417 break; 418 } 419 /* 420 * The DACs are now calibrated, so we can unmute the DAC output. 421 */ 422 csa_writeio(resp, BA0_AC97_PCM_OUT_VOLUME, 0x0808); 423} 424 425static void 426csa_powerupadc(csa_res *resp) 427{ 428 int i; 429 u_long ul; 430 431 /* 432 * Power on the ADCs on the AC97 codec. We turn off the ADC 433 * powerdown bit and write the new value of the power control 434 * register. 435 */ 436 ul = csa_readio(resp, BA0_AC97_POWERDOWN); 437 ul &= 0xfeff; 438 csa_writeio(resp, BA0_AC97_POWERDOWN, ul); 439 440 /* 441 * Now, we wait until we sample a ADC ready state. 442 */ 443 for (i = 0 ; i < 32 ; i++) { 444 /* 445 * First, lets wait a short while to let things settle out a 446 * bit, and to prevent retrying the read too quickly. 447 */ 448 DELAY(125); 449 450 /* 451 * Read the current state of the power control register. 452 */ 453 ul = csa_readio(resp, BA0_AC97_POWERDOWN); 454 455 /* 456 * If the ADC ready state bit is set, then stop waiting. 457 */ 458 if ((ul & 0x1) != 0) 459 break; 460 } 461} 462 463static int 464csa_startdsp(csa_res *resp) 465{ 466 int i; 467 u_long ul; 468 469 /* 470 * Set the frame timer to reflect the number of cycles per frame. 471 */ 472 csa_writemem(resp, BA1_FRMT, 0xadf); 473 474 /* 475 * Turn on the run, run at frame, and DMA enable bits in the local copy of 476 * the SP control register. 477 */ 478 csa_writemem(resp, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN); 479 480 /* 481 * Wait until the run at frame bit resets itself in the SP control 482 * register. 483 */ 484 ul = 0; 485 for (i = 0 ; i < 25 ; i++) { 486 /* 487 * Wait a little bit, so we don't issue PCI reads too frequently. 488 */ 489#if notdef 490 DELAY(1000); 491#else 492 DELAY(125); 493#endif /* notdef */ 494 /* 495 * Fetch the current value of the SP status register. 496 */ 497 ul = csa_readmem(resp, BA1_SPCR); 498 499 /* 500 * If the run at frame bit has reset, then stop waiting. 501 */ 502 if((ul & SPCR_RUNFR) == 0) 503 break; 504 } 505 /* 506 * If the run at frame bit never reset, then return an error. 507 */ 508 if((ul & SPCR_RUNFR) != 0) 509 return (EAGAIN); 510 511 return (0); 512} 513
|
| 514/* -------------------------------------------------------------------- */ 515/* channel interface */ 516 517static void * 518csachan_init(kobj_t obj, void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) 519{ 520 struct csa_info *csa = devinfo; 521 struct csa_chinfo *ch = (dir == PCMDIR_PLAY)? &csa->pch : &csa->rch; 522 523 ch->parent = csa; 524 ch->channel = c; 525 ch->buffer = b; 526 ch->buffer->bufsize = CS461x_BUFFSIZE; 527 if (chn_allocbuf(ch->buffer, csa->parent_dmat) == -1) return NULL; 528 return ch; 529} 530
|
641static int
| 531static int
|
642csachan_getptr(void *data)
| 532csachan_setdir(kobj_t obj, void *data, int dir)
|
643{ 644 struct csa_chinfo *ch = data; 645 struct csa_info *csa = ch->parent; 646 csa_res *resp;
| 533{ 534 struct csa_chinfo *ch = data; 535 struct csa_info *csa = ch->parent; 536 csa_res *resp;
|
| 537 538 resp = &csa->res; 539 540 if (dir == PCMDIR_PLAY) 541 csa_writemem(resp, BA1_PBA, vtophys(ch->buffer->buf)); 542 else 543 csa_writemem(resp, BA1_CBA, vtophys(ch->buffer->buf)); 544 ch->dir = dir; 545 return 0; 546} 547 548static int 549csachan_setformat(kobj_t obj, void *data, u_int32_t format) 550{ 551 struct csa_chinfo *ch = data; 552 struct csa_info *csa = ch->parent; 553 u_long pdtc; 554 csa_res *resp; 555 556 resp = &csa->res; 557 558 if (ch->dir == PCMDIR_REC) 559 csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001); 560 else { 561 csa->pfie = csa_readmem(resp, BA1_PFIE) & ~0x0000f03f; 562 if (format & AFMT_U8 || format & AFMT_U16_LE || format & AFMT_U16_BE) 563 csa->pfie |= 0x8000; 564 if (format & AFMT_S16_BE || format & AFMT_U16_BE) 565 csa->pfie |= 0x4000; 566 if (!(format & AFMT_STEREO)) 567 csa->pfie |= 0x2000; 568 if (format & AFMT_U8 || format & AFMT_S8) 569 csa->pfie |= 0x1000; 570 csa_writemem(resp, BA1_PFIE, csa->pfie); 571 pdtc = csa_readmem(resp, BA1_PDTC) & ~0x000003ff; 572 if ((format & AFMT_S16_BE || format & AFMT_U16_BE || format & AFMT_S16_LE || format & AFMT_U16_LE) && (format & AFMT_STEREO)) 573 pdtc |= 0x00f; 574 else if ((format & AFMT_S16_BE || format & AFMT_U16_BE || format & AFMT_S16_LE || format & AFMT_U16_LE) || (format & AFMT_STEREO)) 575 pdtc |= 0x007; 576 else 577 pdtc |= 0x003; 578 csa_writemem(resp, BA1_PDTC, pdtc); 579 } 580 ch->fmt = format; 581 return 0; 582} 583 584static int 585csachan_setspeed(kobj_t obj, void *data, u_int32_t speed) 586{ 587 struct csa_chinfo *ch = data; 588 struct csa_info *csa = ch->parent; 589 csa_res *resp; 590 591 resp = &csa->res; 592 593 if (ch->dir == PCMDIR_PLAY) 594 csa_setplaysamplerate(resp, speed); 595 else if (ch->dir == PCMDIR_REC) 596 csa_setcapturesamplerate(resp, speed); 597 598 /* rec/play speeds locked together - should indicate in flags */ 599#if 0 600 if (ch->direction == PCMDIR_PLAY) d->rec[0].speed = speed; 601 else d->play[0].speed = speed; 602#endif 603 return speed; /* XXX calc real speed */ 604} 605 606static int 607csachan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) 608{ 609#if notdef 610 return blocksize; 611#else 612 struct csa_chinfo *ch = data; 613 return ch->buffer->bufsize / 2; 614#endif /* notdef */ 615} 616 617static int 618csachan_trigger(kobj_t obj, void *data, int go) 619{ 620 struct csa_chinfo *ch = data; 621 struct csa_info *csa = ch->parent; 622 623 if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD) 624 return 0; 625 626 if (ch->dir == PCMDIR_PLAY) { 627 if (go == PCMTRIG_START) 628 csa_startplaydma(csa); 629 else 630 csa_stopplaydma(csa); 631 } else { 632 if (go == PCMTRIG_START) 633 csa_startcapturedma(csa); 634 else 635 csa_stopcapturedma(csa); 636 } 637 return 0; 638} 639 640static int 641csachan_getptr(kobj_t obj, void *data) 642{ 643 struct csa_chinfo *ch = data; 644 struct csa_info *csa = ch->parent; 645 csa_res *resp;
|
647 int ptr; 648 649 resp = &csa->res; 650 651 if (ch->dir == PCMDIR_PLAY) { 652 ptr = csa_readmem(resp, BA1_PBA) - vtophys(ch->buffer->buf); 653 if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0) 654 ptr >>= 1; 655 } else { 656 ptr = csa_readmem(resp, BA1_CBA) - vtophys(ch->buffer->buf); 657 if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0) 658 ptr >>= 1; 659 } 660 661 return (ptr); 662} 663 664static pcmchan_caps *
| 646 int ptr; 647 648 resp = &csa->res; 649 650 if (ch->dir == PCMDIR_PLAY) { 651 ptr = csa_readmem(resp, BA1_PBA) - vtophys(ch->buffer->buf); 652 if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0) 653 ptr >>= 1; 654 } else { 655 ptr = csa_readmem(resp, BA1_CBA) - vtophys(ch->buffer->buf); 656 if ((ch->fmt & AFMT_U8) != 0 || (ch->fmt & AFMT_S8) != 0) 657 ptr >>= 1; 658 } 659 660 return (ptr); 661} 662 663static pcmchan_caps *
|
665csachan_getcaps(void *data)
| 664csachan_getcaps(kobj_t obj, void *data)
|
666{ 667 struct csa_chinfo *ch = data; 668 return (ch->dir == PCMDIR_PLAY)? &csa_playcaps : &csa_reccaps; 669} 670
| 665{ 666 struct csa_chinfo *ch = data; 667 return (ch->dir == PCMDIR_PLAY)? &csa_playcaps : &csa_reccaps; 668} 669
|
| 670static kobj_method_t csachan_methods[] = { 671 KOBJMETHOD(channel_init, csachan_init), 672 KOBJMETHOD(channel_setdir, csachan_setdir), 673 KOBJMETHOD(channel_setformat, csachan_setformat), 674 KOBJMETHOD(channel_setspeed, csachan_setspeed), 675 KOBJMETHOD(channel_setblocksize, csachan_setblocksize), 676 KOBJMETHOD(channel_trigger, csachan_trigger), 677 KOBJMETHOD(channel_getptr, csachan_getptr), 678 KOBJMETHOD(channel_getcaps, csachan_getcaps), 679 { 0, 0 } 680}; 681CHANNEL_DECLARE(csachan); 682 683/* -------------------------------------------------------------------- */
|
671/* The interrupt handler */ 672static void 673csa_intr (void *p) 674{ 675 struct csa_info *csa = p; 676 677 if ((csa->binfo->hisr & HISR_VC0) != 0) 678 chn_intr(csa->pch.channel); 679 if ((csa->binfo->hisr & HISR_VC1) != 0) 680 chn_intr(csa->rch.channel); 681} 682 683/* -------------------------------------------------------------------- */ 684 685/* 686 * Probe and attach the card 687 */ 688 689static int 690csa_init(struct csa_info *csa) 691{ 692 csa_res *resp; 693 694 resp = &csa->res; 695 696 csa->pfie = 0; 697 csa_stopplaydma(csa); 698 csa_stopcapturedma(csa); 699 700 /* Crank up the power on the DAC and ADC. */ 701 csa_powerupadc(resp); 702 csa_powerupdac(resp); 703 704 csa_setplaysamplerate(resp, 8000); 705 csa_setcapturesamplerate(resp, 8000); 706 707 if (csa_startdsp(resp)) 708 return (1); 709 710 return 0; 711} 712 713/* Allocates resources. */ 714static int 715csa_allocres(struct csa_info *csa, device_t dev) 716{ 717 csa_res *resp; 718 719 resp = &csa->res; 720 if (resp->io == NULL) { 721 resp->io = bus_alloc_resource(dev, SYS_RES_MEMORY, &resp->io_rid, 0, ~0, CS461x_IO_SIZE, RF_ACTIVE); 722 if (resp->io == NULL) 723 return (1); 724 } 725 if (resp->mem == NULL) { 726 resp->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &resp->mem_rid, 0, ~0, CS461x_MEM_SIZE, RF_ACTIVE); 727 if (resp->mem == NULL) 728 return (1); 729 } 730 if (resp->irq == NULL) { 731 resp->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &resp->irq_rid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); 732 if (resp->irq == NULL) 733 return (1); 734 } 735 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/CS461x_BUFFSIZE, /*boundary*/CS461x_BUFFSIZE, 736 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 737 /*highaddr*/BUS_SPACE_MAXADDR, 738 /*filter*/NULL, /*filterarg*/NULL, 739 /*maxsize*/CS461x_BUFFSIZE, /*nsegments*/1, /*maxsegz*/0x3ffff, 740 /*flags*/0, &csa->parent_dmat) != 0) 741 return (1); 742 743 return (0); 744} 745 746/* Releases resources. */ 747static void 748csa_releaseres(struct csa_info *csa, device_t dev) 749{ 750 csa_res *resp; 751 752 resp = &csa->res; 753 if (resp->irq != NULL) { 754 if (csa->ih) 755 bus_teardown_intr(dev, resp->irq, csa->ih); 756 bus_release_resource(dev, SYS_RES_IRQ, resp->irq_rid, resp->irq); 757 resp->irq = NULL; 758 } 759 if (resp->io != NULL) { 760 bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); 761 resp->io = NULL; 762 } 763 if (resp->mem != NULL) { 764 bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem); 765 resp->mem = NULL; 766 } 767 if (csa->parent_dmat != NULL) { 768 bus_dma_tag_destroy(csa->parent_dmat); 769 csa->parent_dmat = NULL; 770 } 771 if (csa != NULL) { 772 free(csa, M_DEVBUF); 773 csa = NULL; 774 } 775} 776 777static int pcmcsa_probe(device_t dev); 778static int pcmcsa_attach(device_t dev); 779 780static int 781pcmcsa_probe(device_t dev) 782{ 783 char *s; 784 struct sndcard_func *func; 785 786 /* The parent device has already been probed. */ 787 788 func = device_get_ivars(dev); 789 if (func == NULL || func->func != SCF_PCM) 790 return (ENXIO); 791 792 s = "CS461x PCM Audio"; 793 794 device_set_desc(dev, s); 795 return (0); 796} 797 798static int 799pcmcsa_attach(device_t dev) 800{ 801 struct csa_info *csa; 802 csa_res *resp; 803 int unit; 804 char status[SND_STATUSLEN]; 805 struct ac97_info *codec; 806 struct sndcard_func *func; 807 808 csa = malloc(sizeof(*csa), M_DEVBUF, M_NOWAIT); 809 if (csa == NULL) 810 return (ENOMEM); 811 bzero(csa, sizeof(*csa)); 812 unit = device_get_unit(dev); 813 func = device_get_ivars(dev); 814 csa->binfo = func->varinfo; 815 /* 816 * Fake the status of DMA so that the initial value of 817 * PCTL and CCTL can be stored into csa->pctl and csa->cctl, 818 * respectively. 819 */ 820 csa->pch.dma = csa->rch.dma = 1; 821 822 /* Allocate the resources. */ 823 resp = &csa->res; 824 resp->io_rid = CS461x_IO_OFFSET; 825 resp->mem_rid = CS461x_MEM_OFFSET; 826 resp->irq_rid = 0; 827 if (csa_allocres(csa, dev)) { 828 csa_releaseres(csa, dev); 829 return (ENXIO); 830 } 831 832 if (csa_init(csa)) { 833 csa_releaseres(csa, dev); 834 return (ENXIO); 835 }
| 684/* The interrupt handler */ 685static void 686csa_intr (void *p) 687{ 688 struct csa_info *csa = p; 689 690 if ((csa->binfo->hisr & HISR_VC0) != 0) 691 chn_intr(csa->pch.channel); 692 if ((csa->binfo->hisr & HISR_VC1) != 0) 693 chn_intr(csa->rch.channel); 694} 695 696/* -------------------------------------------------------------------- */ 697 698/* 699 * Probe and attach the card 700 */ 701 702static int 703csa_init(struct csa_info *csa) 704{ 705 csa_res *resp; 706 707 resp = &csa->res; 708 709 csa->pfie = 0; 710 csa_stopplaydma(csa); 711 csa_stopcapturedma(csa); 712 713 /* Crank up the power on the DAC and ADC. */ 714 csa_powerupadc(resp); 715 csa_powerupdac(resp); 716 717 csa_setplaysamplerate(resp, 8000); 718 csa_setcapturesamplerate(resp, 8000); 719 720 if (csa_startdsp(resp)) 721 return (1); 722 723 return 0; 724} 725 726/* Allocates resources. */ 727static int 728csa_allocres(struct csa_info *csa, device_t dev) 729{ 730 csa_res *resp; 731 732 resp = &csa->res; 733 if (resp->io == NULL) { 734 resp->io = bus_alloc_resource(dev, SYS_RES_MEMORY, &resp->io_rid, 0, ~0, CS461x_IO_SIZE, RF_ACTIVE); 735 if (resp->io == NULL) 736 return (1); 737 } 738 if (resp->mem == NULL) { 739 resp->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &resp->mem_rid, 0, ~0, CS461x_MEM_SIZE, RF_ACTIVE); 740 if (resp->mem == NULL) 741 return (1); 742 } 743 if (resp->irq == NULL) { 744 resp->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &resp->irq_rid, 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); 745 if (resp->irq == NULL) 746 return (1); 747 } 748 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/CS461x_BUFFSIZE, /*boundary*/CS461x_BUFFSIZE, 749 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 750 /*highaddr*/BUS_SPACE_MAXADDR, 751 /*filter*/NULL, /*filterarg*/NULL, 752 /*maxsize*/CS461x_BUFFSIZE, /*nsegments*/1, /*maxsegz*/0x3ffff, 753 /*flags*/0, &csa->parent_dmat) != 0) 754 return (1); 755 756 return (0); 757} 758 759/* Releases resources. */ 760static void 761csa_releaseres(struct csa_info *csa, device_t dev) 762{ 763 csa_res *resp; 764 765 resp = &csa->res; 766 if (resp->irq != NULL) { 767 if (csa->ih) 768 bus_teardown_intr(dev, resp->irq, csa->ih); 769 bus_release_resource(dev, SYS_RES_IRQ, resp->irq_rid, resp->irq); 770 resp->irq = NULL; 771 } 772 if (resp->io != NULL) { 773 bus_release_resource(dev, SYS_RES_MEMORY, resp->io_rid, resp->io); 774 resp->io = NULL; 775 } 776 if (resp->mem != NULL) { 777 bus_release_resource(dev, SYS_RES_MEMORY, resp->mem_rid, resp->mem); 778 resp->mem = NULL; 779 } 780 if (csa->parent_dmat != NULL) { 781 bus_dma_tag_destroy(csa->parent_dmat); 782 csa->parent_dmat = NULL; 783 } 784 if (csa != NULL) { 785 free(csa, M_DEVBUF); 786 csa = NULL; 787 } 788} 789 790static int pcmcsa_probe(device_t dev); 791static int pcmcsa_attach(device_t dev); 792 793static int 794pcmcsa_probe(device_t dev) 795{ 796 char *s; 797 struct sndcard_func *func; 798 799 /* The parent device has already been probed. */ 800 801 func = device_get_ivars(dev); 802 if (func == NULL || func->func != SCF_PCM) 803 return (ENXIO); 804 805 s = "CS461x PCM Audio"; 806 807 device_set_desc(dev, s); 808 return (0); 809} 810 811static int 812pcmcsa_attach(device_t dev) 813{ 814 struct csa_info *csa; 815 csa_res *resp; 816 int unit; 817 char status[SND_STATUSLEN]; 818 struct ac97_info *codec; 819 struct sndcard_func *func; 820 821 csa = malloc(sizeof(*csa), M_DEVBUF, M_NOWAIT); 822 if (csa == NULL) 823 return (ENOMEM); 824 bzero(csa, sizeof(*csa)); 825 unit = device_get_unit(dev); 826 func = device_get_ivars(dev); 827 csa->binfo = func->varinfo; 828 /* 829 * Fake the status of DMA so that the initial value of 830 * PCTL and CCTL can be stored into csa->pctl and csa->cctl, 831 * respectively. 832 */ 833 csa->pch.dma = csa->rch.dma = 1; 834 835 /* Allocate the resources. */ 836 resp = &csa->res; 837 resp->io_rid = CS461x_IO_OFFSET; 838 resp->mem_rid = CS461x_MEM_OFFSET; 839 resp->irq_rid = 0; 840 if (csa_allocres(csa, dev)) { 841 csa_releaseres(csa, dev); 842 return (ENXIO); 843 } 844 845 if (csa_init(csa)) { 846 csa_releaseres(csa, dev); 847 return (ENXIO); 848 }
|
836 codec = ac97_create(dev, csa, NULL, csa_rdcd, csa_wrcd);
| 849 codec = AC97_CREATE(dev, csa, csa_ac97);
|
837 if (codec == NULL) { 838 csa_releaseres(csa, dev); 839 return (ENXIO); 840 }
| 850 if (codec == NULL) { 851 csa_releaseres(csa, dev); 852 return (ENXIO); 853 }
|
841 if (mixer_init(dev, &ac97_mixer, codec) == -1) {
| 854 if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) {
|
842 ac97_destroy(codec); 843 csa_releaseres(csa, dev); 844 return (ENXIO); 845 } 846 847 snprintf(status, SND_STATUSLEN, "at irq %ld", rman_get_start(resp->irq)); 848 849 /* Enable interrupt. */ 850 if (bus_setup_intr(dev, resp->irq, INTR_TYPE_TTY, csa_intr, csa, &csa->ih)) { 851 ac97_destroy(codec); 852 csa_releaseres(csa, dev); 853 return (ENXIO); 854 } 855 csa_writemem(resp, BA1_PFIE, csa_readmem(resp, BA1_PFIE) & ~0x0000f03f); 856 csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001); 857 858 if (pcm_register(dev, csa, 1, 1)) { 859 ac97_destroy(codec); 860 csa_releaseres(csa, dev); 861 return (ENXIO); 862 }
| 855 ac97_destroy(codec); 856 csa_releaseres(csa, dev); 857 return (ENXIO); 858 } 859 860 snprintf(status, SND_STATUSLEN, "at irq %ld", rman_get_start(resp->irq)); 861 862 /* Enable interrupt. */ 863 if (bus_setup_intr(dev, resp->irq, INTR_TYPE_TTY, csa_intr, csa, &csa->ih)) { 864 ac97_destroy(codec); 865 csa_releaseres(csa, dev); 866 return (ENXIO); 867 } 868 csa_writemem(resp, BA1_PFIE, csa_readmem(resp, BA1_PFIE) & ~0x0000f03f); 869 csa_writemem(resp, BA1_CIE, (csa_readmem(resp, BA1_CIE) & ~0x0000003f) | 0x00000001); 870 871 if (pcm_register(dev, csa, 1, 1)) { 872 ac97_destroy(codec); 873 csa_releaseres(csa, dev); 874 return (ENXIO); 875 }
|
863 pcm_addchan(dev, PCMDIR_REC, &csa_chantemplate, csa); 864 pcm_addchan(dev, PCMDIR_PLAY, &csa_chantemplate, csa);
| 876 pcm_addchan(dev, PCMDIR_REC, &csachan_class, csa); 877 pcm_addchan(dev, PCMDIR_PLAY, &csachan_class, csa);
|
865 pcm_setstatus(dev, status); 866 867 return (0); 868} 869 870static int 871pcmcsa_detach(device_t dev) 872{ 873 int r; 874 struct csa_info *csa; 875 876 r = pcm_unregister(dev); 877 if (r) 878 return r; 879 880 csa = pcm_getdevinfo(dev); 881 csa_releaseres(csa, dev); 882 883 return 0; 884} 885
| 878 pcm_setstatus(dev, status); 879 880 return (0); 881} 882 883static int 884pcmcsa_detach(device_t dev) 885{ 886 int r; 887 struct csa_info *csa; 888 889 r = pcm_unregister(dev); 890 if (r) 891 return r; 892 893 csa = pcm_getdevinfo(dev); 894 csa_releaseres(csa, dev); 895 896 return 0; 897} 898
|
886/* ac97 codec */ 887 888static u_int32_t 889csa_rdcd(void *devinfo, int regno) 890{ 891 u_int32_t data; 892 struct csa_info *csa = (struct csa_info *)devinfo; 893 894 if (csa_readcodec(&csa->res, regno + BA0_AC97_RESET, &data)) 895 data = 0; 896 897 return data; 898} 899 900static void 901csa_wrcd(void *devinfo, int regno, u_int32_t data) 902{ 903 struct csa_info *csa = (struct csa_info *)devinfo; 904 905 csa_writecodec(&csa->res, regno + BA0_AC97_RESET, data); 906} 907
| |
908static device_method_t pcmcsa_methods[] = { 909 /* Device interface */ 910 DEVMETHOD(device_probe , pcmcsa_probe ), 911 DEVMETHOD(device_attach, pcmcsa_attach), 912 DEVMETHOD(device_detach, pcmcsa_detach), 913 914 { 0, 0 }, 915}; 916 917static driver_t pcmcsa_driver = { 918 "pcm", 919 pcmcsa_methods, 920 sizeof(snddev_info), 921}; 922 923static devclass_t pcm_devclass; 924 925DRIVER_MODULE(snd_csapcm, csa, pcmcsa_driver, pcm_devclass, 0, 0); 926MODULE_DEPEND(snd_csapcm, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER); 927MODULE_DEPEND(snd_csapcm, snd_csa, 1, 1, 1); 928MODULE_VERSION(snd_csapcm, 1);
| 899static device_method_t pcmcsa_methods[] = { 900 /* Device interface */ 901 DEVMETHOD(device_probe , pcmcsa_probe ), 902 DEVMETHOD(device_attach, pcmcsa_attach), 903 DEVMETHOD(device_detach, pcmcsa_detach), 904 905 { 0, 0 }, 906}; 907 908static driver_t pcmcsa_driver = { 909 "pcm", 910 pcmcsa_methods, 911 sizeof(snddev_info), 912}; 913 914static devclass_t pcm_devclass; 915 916DRIVER_MODULE(snd_csapcm, csa, pcmcsa_driver, pcm_devclass, 0, 0); 917MODULE_DEPEND(snd_csapcm, snd_pcm, PCM_MINVER, PCM_PREFVER, PCM_MAXVER); 918MODULE_DEPEND(snd_csapcm, snd_csa, 1, 1, 1); 919MODULE_VERSION(snd_csapcm, 1);
|