29 */ 30 31#include "pci.h" 32#include "pcm.h" 33 34#include <dev/sound/pcm/sound.h> 35#include <dev/sound/pcm/ac97.h> 36#include <dev/sound/pci/neomagic.h> 37#include <dev/sound/pci/neomagic-coeff.h> 38 39#include <pci/pcireg.h> 40#include <pci/pcivar.h> 41 42/* -------------------------------------------------------------------- */ 43 44#define NM_BUFFSIZE 16384 45 46#define NM256AV_PCI_ID 0x800510c8 47#define NM256ZX_PCI_ID 0x800610c8 48 49struct sc_info; 50 51/* channel registers */ 52struct sc_chinfo { 53 int spd, dir, fmt; 54 snd_dbuf *buffer; 55 pcm_channel *channel; 56 struct sc_info *parent; 57}; 58 59/* device private data */ 60struct sc_info { 61 device_t dev; 62 u_int32_t type; 63 64 struct resource *reg, *irq, *buf; 65 int regid, irqid, bufid; 66 void *ih; 67 68 u_int32_t ac97_base, ac97_status, ac97_busy; 69 u_int32_t buftop, pbuf, rbuf, cbuf, acbuf; 70 u_int32_t playint, recint, misc1int, misc2int; 71 u_int32_t irsz, badintr; 72 73 struct sc_chinfo pch, rch; 74}; 75 76/* -------------------------------------------------------------------- */ 77 78/* 79 * prototypes 80 */ 81 82/* channel interface */ 83static void *nmchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir); 84static int nmchan_setdir(void *data, int dir); 85static int nmchan_setformat(void *data, u_int32_t format); 86static int nmchan_setspeed(void *data, u_int32_t speed); 87static int nmchan_setblocksize(void *data, u_int32_t blocksize); 88static int nmchan_trigger(void *data, int go); 89static int nmchan_getptr(void *data); 90static pcmchan_caps *nmchan_getcaps(void *data); 91 92static int nm_waitcd(struct sc_info *sc); 93/* talk to the codec - called from ac97.c */ 94static u_int32_t nm_rdcd(void *, int); 95static void nm_wrcd(void *, int, u_int32_t); 96 97/* stuff */ 98static int nm_loadcoeff(struct sc_info *sc, int dir, int num); 99static int nm_setch(struct sc_chinfo *ch); 100static int nm_init(struct sc_info *); 101static void nm_intr(void *); 102 103/* talk to the card */ 104static u_int32_t nm_rd(struct sc_info *, int, int); 105static void nm_wr(struct sc_info *, int, u_int32_t, int); 106static u_int32_t nm_rdbuf(struct sc_info *, int, int); 107static void nm_wrbuf(struct sc_info *, int, u_int32_t, int); 108 109/* The actual rates supported by the card. */ 110static int samplerates[9] = { 111 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 99999999 112}; 113 114/* -------------------------------------------------------------------- */ 115 116static pcmchan_caps nm_caps = { 117 4000, 48000, 118 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE, 119 AFMT_STEREO | AFMT_S16_LE 120}; 121 122static pcm_channel nm_chantemplate = { 123 nmchan_init, 124 nmchan_setdir, 125 nmchan_setformat, 126 nmchan_setspeed, 127 nmchan_setblocksize, 128 nmchan_trigger, 129 nmchan_getptr, 130 nmchan_getcaps, 131}; 132 133/* -------------------------------------------------------------------- */ 134 135/* Hardware */ 136static u_int32_t 137nm_rd(struct sc_info *sc, int regno, int size) 138{ 139 bus_space_tag_t st = rman_get_bustag(sc->reg); 140 bus_space_handle_t sh = rman_get_bushandle(sc->reg); 141 142 switch (size) { 143 case 1: 144 return bus_space_read_1(st, sh, regno); 145 case 2: 146 return bus_space_read_2(st, sh, regno); 147 case 4: 148 return bus_space_read_4(st, sh, regno); 149 default: 150 return 0xffffffff; 151 } 152} 153 154static void 155nm_wr(struct sc_info *sc, int regno, u_int32_t data, int size) 156{ 157 bus_space_tag_t st = rman_get_bustag(sc->reg); 158 bus_space_handle_t sh = rman_get_bushandle(sc->reg); 159 160 switch (size) { 161 case 1: 162 bus_space_write_1(st, sh, regno, data); 163 break; 164 case 2: 165 bus_space_write_2(st, sh, regno, data); 166 break; 167 case 4: 168 bus_space_write_4(st, sh, regno, data); 169 break; 170 } 171} 172 173static u_int32_t 174nm_rdbuf(struct sc_info *sc, int regno, int size) 175{ 176 bus_space_tag_t st = rman_get_bustag(sc->buf); 177 bus_space_handle_t sh = rman_get_bushandle(sc->buf); 178 179 switch (size) { 180 case 1: 181 return bus_space_read_1(st, sh, regno); 182 case 2: 183 return bus_space_read_2(st, sh, regno); 184 case 4: 185 return bus_space_read_4(st, sh, regno); 186 default: 187 return 0xffffffff; 188 } 189} 190 191static void 192nm_wrbuf(struct sc_info *sc, int regno, u_int32_t data, int size) 193{ 194 bus_space_tag_t st = rman_get_bustag(sc->buf); 195 bus_space_handle_t sh = rman_get_bushandle(sc->buf); 196 197 switch (size) { 198 case 1: 199 bus_space_write_1(st, sh, regno, data); 200 break; 201 case 2: 202 bus_space_write_2(st, sh, regno, data); 203 break; 204 case 4: 205 bus_space_write_4(st, sh, regno, data); 206 break; 207 } 208} 209 210/* ac97 codec */ 211static int 212nm_waitcd(struct sc_info *sc) 213{ 214 int cnt = 10; 215 216 while (cnt-- > 0) { 217 if (nm_rd(sc, sc->ac97_status, 2) & sc->ac97_busy) 218 DELAY(100); 219 else 220 break; 221 } 222 return (nm_rd(sc, sc->ac97_status, 2) & sc->ac97_busy); 223} 224 225static u_int32_t 226nm_rdcd(void *devinfo, int regno) 227{ 228 struct sc_info *sc = (struct sc_info *)devinfo; 229 u_int32_t x; 230 231 if (!nm_waitcd(sc)) { 232 x = nm_rd(sc, sc->ac97_base + regno, 2); 233 DELAY(1000); 234 return x; 235 } else { 236 device_printf(sc->dev, "ac97 codec not ready\n"); 237 return 0xffffffff; 238 } 239} 240 241static void 242nm_wrcd(void *devinfo, int regno, u_int32_t data) 243{ 244 struct sc_info *sc = (struct sc_info *)devinfo; 245 int cnt = 3; 246 247 if (!nm_waitcd(sc)) { 248 while (cnt-- > 0) { 249 nm_wr(sc, sc->ac97_base + regno, data, 2); 250 if (!nm_waitcd(sc)) { 251 DELAY(1000); 252 return; 253 } 254 } 255 } 256 device_printf(sc->dev, "ac97 codec not ready\n"); 257} 258 259static void 260nm_ackint(struct sc_info *sc, u_int32_t num) 261{ 262 if (sc->type == NM256AV_PCI_ID) { 263 nm_wr(sc, NM_INT_REG, num << 1, 2); 264 } else if (sc->type == NM256ZX_PCI_ID) { 265 nm_wr(sc, NM_INT_REG, num, 4); 266 } 267} 268 269static int 270nm_loadcoeff(struct sc_info *sc, int dir, int num) 271{ 272 int ofs, sz, i; 273 u_int32_t addr; 274 275 addr = (dir == PCMDIR_PLAY)? 0x01c : 0x21c; 276 if (dir == PCMDIR_REC) 277 num += 8; 278 sz = coefficientSizes[num]; 279 ofs = 0; 280 while (num-- > 0) 281 ofs+= coefficientSizes[num]; 282 for (i = 0; i < sz; i++) 283 nm_wrbuf(sc, sc->cbuf + i, coefficients[ofs + i], 1); 284 nm_wr(sc, addr, sc->cbuf, 4); 285 if (dir == PCMDIR_PLAY) 286 sz--; 287 nm_wr(sc, addr + 4, sc->cbuf + sz, 4); 288 return 0; 289} 290 291static int 292nm_setch(struct sc_chinfo *ch) 293{ 294 struct sc_info *sc = ch->parent; 295 u_int32_t base; 296 u_int8_t x; 297 298 for (x = 0; x < 8; x++) 299 if (ch->spd < (samplerates[x] + samplerates[x + 1]) / 2) 300 break; 301 302 if (x == 8) return 1; 303 304 ch->spd = samplerates[x]; 305 nm_loadcoeff(sc, ch->dir, x); 306 307 x <<= 4; 308 x &= NM_RATE_MASK; 309 if (ch->fmt & AFMT_16BIT) x |= NM_RATE_BITS_16; 310 if (ch->fmt & AFMT_STEREO) x |= NM_RATE_STEREO; 311 312 base = (ch->dir == PCMDIR_PLAY)? NM_PLAYBACK_REG_OFFSET : NM_RECORD_REG_OFFSET; 313 nm_wr(sc, base + NM_RATE_REG_OFFSET, x, 1); 314 return 0; 315} 316 317/* channel interface */ 318static void * 319nmchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) 320{ 321 struct sc_info *sc = devinfo; 322 struct sc_chinfo *ch; 323 u_int32_t chnbuf; 324 325 chnbuf = (dir == PCMDIR_PLAY)? sc->pbuf : sc->rbuf; 326 ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch; 327 ch->buffer = b; 328 ch->buffer->bufsize = NM_BUFFSIZE; 329 ch->buffer->buf = (u_int8_t *)(rman_get_bushandle(sc->buf) + chnbuf); 330 device_printf(sc->dev, "%s buf %p\n", (dir == PCMDIR_PLAY)? "play" : "rec", ch->buffer->buf); 331 ch->parent = sc; 332 ch->channel = c; 333 ch->dir = dir; 334 return ch; 335} 336 337static int 338nmchan_setdir(void *data, int dir) 339{ 340 return 0; 341} 342 343static int 344nmchan_setformat(void *data, u_int32_t format) 345{ 346 struct sc_chinfo *ch = data; 347 348 ch->fmt = format; 349 return nm_setch(ch); 350} 351 352static int 353nmchan_setspeed(void *data, u_int32_t speed) 354{ 355 struct sc_chinfo *ch = data; 356 357 ch->spd = speed; 358 return nm_setch(ch)? 0 : ch->spd; 359} 360 361static int 362nmchan_setblocksize(void *data, u_int32_t blocksize) 363{ 364 return blocksize; 365} 366 367static int 368nmchan_trigger(void *data, int go) 369{ 370 struct sc_chinfo *ch = data; 371 struct sc_info *sc = ch->parent; 372 int ssz; 373 374 if (go == PCMTRIG_EMLDMAWR) return 0; 375 376 ssz = (ch->fmt & AFMT_16BIT)? 2 : 1; 377 if (ch->fmt & AFMT_STEREO) 378 ssz <<= 1; 379 380 if (ch->dir == PCMDIR_PLAY) { 381 if (go == PCMTRIG_START) { 382 nm_wr(sc, NM_PBUFFER_START, sc->pbuf, 4); 383 nm_wr(sc, NM_PBUFFER_END, sc->pbuf + NM_BUFFSIZE - ssz, 4); 384 nm_wr(sc, NM_PBUFFER_CURRP, sc->pbuf, 4); 385 nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + NM_BUFFSIZE / 2, 4); 386 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN | 387 NM_PLAYBACK_ENABLE_FLAG, 1); 388 nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2); 389 } else { 390 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, 0, 1); 391 nm_wr(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH, 2); 392 } 393 } else { 394 if (go == PCMTRIG_START) { 395 nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN | 396 NM_RECORD_ENABLE_FLAG, 1); 397 nm_wr(sc, NM_RBUFFER_START, sc->rbuf, 4); 398 nm_wr(sc, NM_RBUFFER_END, sc->rbuf + NM_BUFFSIZE, 4); 399 nm_wr(sc, NM_RBUFFER_CURRP, sc->rbuf, 4); 400 nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + NM_BUFFSIZE / 2, 4); 401 } else { 402 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 403 } 404 } 405 return 0; 406} 407 408static int 409nmchan_getptr(void *data) 410{ 411 struct sc_chinfo *ch = data; 412 struct sc_info *sc = ch->parent; 413 414 if (ch->dir == PCMDIR_PLAY) 415 return nm_rd(sc, NM_PBUFFER_CURRP, 4) - sc->pbuf; 416 else 417 return nm_rd(sc, NM_RBUFFER_CURRP, 4) - sc->rbuf; 418} 419 420static pcmchan_caps * 421nmchan_getcaps(void *data) 422{ 423 return &nm_caps; 424} 425 426/* The interrupt handler */ 427static void 428nm_intr(void *p) 429{ 430 struct sc_info *sc = (struct sc_info *)p;
| 29 */ 30 31#include "pci.h" 32#include "pcm.h" 33 34#include <dev/sound/pcm/sound.h> 35#include <dev/sound/pcm/ac97.h> 36#include <dev/sound/pci/neomagic.h> 37#include <dev/sound/pci/neomagic-coeff.h> 38 39#include <pci/pcireg.h> 40#include <pci/pcivar.h> 41 42/* -------------------------------------------------------------------- */ 43 44#define NM_BUFFSIZE 16384 45 46#define NM256AV_PCI_ID 0x800510c8 47#define NM256ZX_PCI_ID 0x800610c8 48 49struct sc_info; 50 51/* channel registers */ 52struct sc_chinfo { 53 int spd, dir, fmt; 54 snd_dbuf *buffer; 55 pcm_channel *channel; 56 struct sc_info *parent; 57}; 58 59/* device private data */ 60struct sc_info { 61 device_t dev; 62 u_int32_t type; 63 64 struct resource *reg, *irq, *buf; 65 int regid, irqid, bufid; 66 void *ih; 67 68 u_int32_t ac97_base, ac97_status, ac97_busy; 69 u_int32_t buftop, pbuf, rbuf, cbuf, acbuf; 70 u_int32_t playint, recint, misc1int, misc2int; 71 u_int32_t irsz, badintr; 72 73 struct sc_chinfo pch, rch; 74}; 75 76/* -------------------------------------------------------------------- */ 77 78/* 79 * prototypes 80 */ 81 82/* channel interface */ 83static void *nmchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir); 84static int nmchan_setdir(void *data, int dir); 85static int nmchan_setformat(void *data, u_int32_t format); 86static int nmchan_setspeed(void *data, u_int32_t speed); 87static int nmchan_setblocksize(void *data, u_int32_t blocksize); 88static int nmchan_trigger(void *data, int go); 89static int nmchan_getptr(void *data); 90static pcmchan_caps *nmchan_getcaps(void *data); 91 92static int nm_waitcd(struct sc_info *sc); 93/* talk to the codec - called from ac97.c */ 94static u_int32_t nm_rdcd(void *, int); 95static void nm_wrcd(void *, int, u_int32_t); 96 97/* stuff */ 98static int nm_loadcoeff(struct sc_info *sc, int dir, int num); 99static int nm_setch(struct sc_chinfo *ch); 100static int nm_init(struct sc_info *); 101static void nm_intr(void *); 102 103/* talk to the card */ 104static u_int32_t nm_rd(struct sc_info *, int, int); 105static void nm_wr(struct sc_info *, int, u_int32_t, int); 106static u_int32_t nm_rdbuf(struct sc_info *, int, int); 107static void nm_wrbuf(struct sc_info *, int, u_int32_t, int); 108 109/* The actual rates supported by the card. */ 110static int samplerates[9] = { 111 8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 99999999 112}; 113 114/* -------------------------------------------------------------------- */ 115 116static pcmchan_caps nm_caps = { 117 4000, 48000, 118 AFMT_STEREO | AFMT_U8 | AFMT_S16_LE, 119 AFMT_STEREO | AFMT_S16_LE 120}; 121 122static pcm_channel nm_chantemplate = { 123 nmchan_init, 124 nmchan_setdir, 125 nmchan_setformat, 126 nmchan_setspeed, 127 nmchan_setblocksize, 128 nmchan_trigger, 129 nmchan_getptr, 130 nmchan_getcaps, 131}; 132 133/* -------------------------------------------------------------------- */ 134 135/* Hardware */ 136static u_int32_t 137nm_rd(struct sc_info *sc, int regno, int size) 138{ 139 bus_space_tag_t st = rman_get_bustag(sc->reg); 140 bus_space_handle_t sh = rman_get_bushandle(sc->reg); 141 142 switch (size) { 143 case 1: 144 return bus_space_read_1(st, sh, regno); 145 case 2: 146 return bus_space_read_2(st, sh, regno); 147 case 4: 148 return bus_space_read_4(st, sh, regno); 149 default: 150 return 0xffffffff; 151 } 152} 153 154static void 155nm_wr(struct sc_info *sc, int regno, u_int32_t data, int size) 156{ 157 bus_space_tag_t st = rman_get_bustag(sc->reg); 158 bus_space_handle_t sh = rman_get_bushandle(sc->reg); 159 160 switch (size) { 161 case 1: 162 bus_space_write_1(st, sh, regno, data); 163 break; 164 case 2: 165 bus_space_write_2(st, sh, regno, data); 166 break; 167 case 4: 168 bus_space_write_4(st, sh, regno, data); 169 break; 170 } 171} 172 173static u_int32_t 174nm_rdbuf(struct sc_info *sc, int regno, int size) 175{ 176 bus_space_tag_t st = rman_get_bustag(sc->buf); 177 bus_space_handle_t sh = rman_get_bushandle(sc->buf); 178 179 switch (size) { 180 case 1: 181 return bus_space_read_1(st, sh, regno); 182 case 2: 183 return bus_space_read_2(st, sh, regno); 184 case 4: 185 return bus_space_read_4(st, sh, regno); 186 default: 187 return 0xffffffff; 188 } 189} 190 191static void 192nm_wrbuf(struct sc_info *sc, int regno, u_int32_t data, int size) 193{ 194 bus_space_tag_t st = rman_get_bustag(sc->buf); 195 bus_space_handle_t sh = rman_get_bushandle(sc->buf); 196 197 switch (size) { 198 case 1: 199 bus_space_write_1(st, sh, regno, data); 200 break; 201 case 2: 202 bus_space_write_2(st, sh, regno, data); 203 break; 204 case 4: 205 bus_space_write_4(st, sh, regno, data); 206 break; 207 } 208} 209 210/* ac97 codec */ 211static int 212nm_waitcd(struct sc_info *sc) 213{ 214 int cnt = 10; 215 216 while (cnt-- > 0) { 217 if (nm_rd(sc, sc->ac97_status, 2) & sc->ac97_busy) 218 DELAY(100); 219 else 220 break; 221 } 222 return (nm_rd(sc, sc->ac97_status, 2) & sc->ac97_busy); 223} 224 225static u_int32_t 226nm_rdcd(void *devinfo, int regno) 227{ 228 struct sc_info *sc = (struct sc_info *)devinfo; 229 u_int32_t x; 230 231 if (!nm_waitcd(sc)) { 232 x = nm_rd(sc, sc->ac97_base + regno, 2); 233 DELAY(1000); 234 return x; 235 } else { 236 device_printf(sc->dev, "ac97 codec not ready\n"); 237 return 0xffffffff; 238 } 239} 240 241static void 242nm_wrcd(void *devinfo, int regno, u_int32_t data) 243{ 244 struct sc_info *sc = (struct sc_info *)devinfo; 245 int cnt = 3; 246 247 if (!nm_waitcd(sc)) { 248 while (cnt-- > 0) { 249 nm_wr(sc, sc->ac97_base + regno, data, 2); 250 if (!nm_waitcd(sc)) { 251 DELAY(1000); 252 return; 253 } 254 } 255 } 256 device_printf(sc->dev, "ac97 codec not ready\n"); 257} 258 259static void 260nm_ackint(struct sc_info *sc, u_int32_t num) 261{ 262 if (sc->type == NM256AV_PCI_ID) { 263 nm_wr(sc, NM_INT_REG, num << 1, 2); 264 } else if (sc->type == NM256ZX_PCI_ID) { 265 nm_wr(sc, NM_INT_REG, num, 4); 266 } 267} 268 269static int 270nm_loadcoeff(struct sc_info *sc, int dir, int num) 271{ 272 int ofs, sz, i; 273 u_int32_t addr; 274 275 addr = (dir == PCMDIR_PLAY)? 0x01c : 0x21c; 276 if (dir == PCMDIR_REC) 277 num += 8; 278 sz = coefficientSizes[num]; 279 ofs = 0; 280 while (num-- > 0) 281 ofs+= coefficientSizes[num]; 282 for (i = 0; i < sz; i++) 283 nm_wrbuf(sc, sc->cbuf + i, coefficients[ofs + i], 1); 284 nm_wr(sc, addr, sc->cbuf, 4); 285 if (dir == PCMDIR_PLAY) 286 sz--; 287 nm_wr(sc, addr + 4, sc->cbuf + sz, 4); 288 return 0; 289} 290 291static int 292nm_setch(struct sc_chinfo *ch) 293{ 294 struct sc_info *sc = ch->parent; 295 u_int32_t base; 296 u_int8_t x; 297 298 for (x = 0; x < 8; x++) 299 if (ch->spd < (samplerates[x] + samplerates[x + 1]) / 2) 300 break; 301 302 if (x == 8) return 1; 303 304 ch->spd = samplerates[x]; 305 nm_loadcoeff(sc, ch->dir, x); 306 307 x <<= 4; 308 x &= NM_RATE_MASK; 309 if (ch->fmt & AFMT_16BIT) x |= NM_RATE_BITS_16; 310 if (ch->fmt & AFMT_STEREO) x |= NM_RATE_STEREO; 311 312 base = (ch->dir == PCMDIR_PLAY)? NM_PLAYBACK_REG_OFFSET : NM_RECORD_REG_OFFSET; 313 nm_wr(sc, base + NM_RATE_REG_OFFSET, x, 1); 314 return 0; 315} 316 317/* channel interface */ 318static void * 319nmchan_init(void *devinfo, snd_dbuf *b, pcm_channel *c, int dir) 320{ 321 struct sc_info *sc = devinfo; 322 struct sc_chinfo *ch; 323 u_int32_t chnbuf; 324 325 chnbuf = (dir == PCMDIR_PLAY)? sc->pbuf : sc->rbuf; 326 ch = (dir == PCMDIR_PLAY)? &sc->pch : &sc->rch; 327 ch->buffer = b; 328 ch->buffer->bufsize = NM_BUFFSIZE; 329 ch->buffer->buf = (u_int8_t *)(rman_get_bushandle(sc->buf) + chnbuf); 330 device_printf(sc->dev, "%s buf %p\n", (dir == PCMDIR_PLAY)? "play" : "rec", ch->buffer->buf); 331 ch->parent = sc; 332 ch->channel = c; 333 ch->dir = dir; 334 return ch; 335} 336 337static int 338nmchan_setdir(void *data, int dir) 339{ 340 return 0; 341} 342 343static int 344nmchan_setformat(void *data, u_int32_t format) 345{ 346 struct sc_chinfo *ch = data; 347 348 ch->fmt = format; 349 return nm_setch(ch); 350} 351 352static int 353nmchan_setspeed(void *data, u_int32_t speed) 354{ 355 struct sc_chinfo *ch = data; 356 357 ch->spd = speed; 358 return nm_setch(ch)? 0 : ch->spd; 359} 360 361static int 362nmchan_setblocksize(void *data, u_int32_t blocksize) 363{ 364 return blocksize; 365} 366 367static int 368nmchan_trigger(void *data, int go) 369{ 370 struct sc_chinfo *ch = data; 371 struct sc_info *sc = ch->parent; 372 int ssz; 373 374 if (go == PCMTRIG_EMLDMAWR) return 0; 375 376 ssz = (ch->fmt & AFMT_16BIT)? 2 : 1; 377 if (ch->fmt & AFMT_STEREO) 378 ssz <<= 1; 379 380 if (ch->dir == PCMDIR_PLAY) { 381 if (go == PCMTRIG_START) { 382 nm_wr(sc, NM_PBUFFER_START, sc->pbuf, 4); 383 nm_wr(sc, NM_PBUFFER_END, sc->pbuf + NM_BUFFSIZE - ssz, 4); 384 nm_wr(sc, NM_PBUFFER_CURRP, sc->pbuf, 4); 385 nm_wr(sc, NM_PBUFFER_WMARK, sc->pbuf + NM_BUFFSIZE / 2, 4); 386 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, NM_PLAYBACK_FREERUN | 387 NM_PLAYBACK_ENABLE_FLAG, 1); 388 nm_wr(sc, NM_AUDIO_MUTE_REG, 0, 2); 389 } else { 390 nm_wr(sc, NM_PLAYBACK_ENABLE_REG, 0, 1); 391 nm_wr(sc, NM_AUDIO_MUTE_REG, NM_AUDIO_MUTE_BOTH, 2); 392 } 393 } else { 394 if (go == PCMTRIG_START) { 395 nm_wr(sc, NM_RECORD_ENABLE_REG, NM_RECORD_FREERUN | 396 NM_RECORD_ENABLE_FLAG, 1); 397 nm_wr(sc, NM_RBUFFER_START, sc->rbuf, 4); 398 nm_wr(sc, NM_RBUFFER_END, sc->rbuf + NM_BUFFSIZE, 4); 399 nm_wr(sc, NM_RBUFFER_CURRP, sc->rbuf, 4); 400 nm_wr(sc, NM_RBUFFER_WMARK, sc->rbuf + NM_BUFFSIZE / 2, 4); 401 } else { 402 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 403 } 404 } 405 return 0; 406} 407 408static int 409nmchan_getptr(void *data) 410{ 411 struct sc_chinfo *ch = data; 412 struct sc_info *sc = ch->parent; 413 414 if (ch->dir == PCMDIR_PLAY) 415 return nm_rd(sc, NM_PBUFFER_CURRP, 4) - sc->pbuf; 416 else 417 return nm_rd(sc, NM_RBUFFER_CURRP, 4) - sc->rbuf; 418} 419 420static pcmchan_caps * 421nmchan_getcaps(void *data) 422{ 423 return &nm_caps; 424} 425 426/* The interrupt handler */ 427static void 428nm_intr(void *p) 429{ 430 struct sc_info *sc = (struct sc_info *)p;
|
510 sc->badintr = 0; 511 ofs = sc->buftop - 0x0400; 512 sc->buftop -= 0x1400; 513 514 if ((nm_rdbuf(sc, ofs, 4) & NM_SIG_MASK) == NM_SIGNATURE) { 515 i = nm_rdbuf(sc, ofs + 4, 4); 516 if (i != 0 && i != 0xffffffff) 517 sc->buftop = i; 518 } 519 520 sc->cbuf = sc->buftop - NM_MAX_COEFFICIENT; 521 sc->rbuf = sc->cbuf - NM_BUFFSIZE; 522 sc->pbuf = sc->rbuf - NM_BUFFSIZE; 523 sc->acbuf = sc->pbuf - (NM_TOTAL_COEFF_COUNT * 4); 524 525 nm_wr(sc, 0, 0x11, 1); 526 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 527 nm_wr(sc, 0x214, 0, 2); 528 529 return 0; 530} 531 532static int 533nm_pci_probe(device_t dev) 534{ 535 char *s = NULL; 536 537 switch (pci_get_devid(dev)) { 538 case NM256AV_PCI_ID: 539 s = "NeoMagic 256AV"; 540 break; 541 542 case NM256ZX_PCI_ID: 543 s = "NeoMagic 256ZX"; 544 break; 545 } 546 547 if (s) device_set_desc(dev, s); 548 return s? 0 : ENXIO; 549} 550 551static int 552nm_pci_attach(device_t dev) 553{ 554 snddev_info *d; 555 u_int32_t data; 556 struct sc_info *sc; 557 struct ac97_info *codec; 558 char status[SND_STATUSLEN]; 559 560 d = device_get_softc(dev); 561 if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) { 562 device_printf(dev, "cannot allocate softc\n"); 563 return ENXIO; 564 } 565 566 bzero(sc, sizeof(*sc)); 567 sc->dev = dev; 568 sc->type = pci_get_devid(dev); 569 570 data = pci_read_config(dev, PCIR_COMMAND, 2); 571 data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); 572 pci_write_config(dev, PCIR_COMMAND, data, 2); 573 data = pci_read_config(dev, PCIR_COMMAND, 2); 574 575 sc->bufid = PCIR_MAPS; 576 sc->buf = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->bufid, 577 0, ~0, 1, RF_ACTIVE); 578 sc->regid = PCIR_MAPS + 4; 579 sc->reg = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->regid, 580 0, ~0, 1, RF_ACTIVE); 581 582 if (!sc->buf || !sc->reg) { 583 device_printf(dev, "unable to map register space\n"); 584 goto bad; 585 } 586 587 if (nm_init(sc) == -1) { 588 device_printf(dev, "unable to initialize the card\n"); 589 goto bad; 590 } 591 592 codec = ac97_create(sc, nm_rdcd, nm_wrcd); 593 if (codec == NULL) goto bad; 594 mixer_init(d, &ac97_mixer, codec); 595 596 sc->irqid = 0; 597 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 598 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); 599 if (!sc->irq || 600 bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, nm_intr, sc, &sc->ih)) { 601 device_printf(dev, "unable to map interrupt\n"); 602 goto bad; 603 } 604 605 snprintf(status, SND_STATUSLEN, "at memory 0x%lx, 0x%lx irq %ld", 606 rman_get_start(sc->buf), rman_get_start(sc->reg), 607 rman_get_start(sc->irq)); 608 609 if (pcm_register(dev, sc, 1, 1)) goto bad; 610 pcm_addchan(dev, PCMDIR_REC, &nm_chantemplate, sc); 611 pcm_addchan(dev, PCMDIR_PLAY, &nm_chantemplate, sc); 612 pcm_setstatus(dev, status); 613 614 return 0; 615 616bad: 617 if (sc->buf) bus_release_resource(dev, SYS_RES_MEMORY, sc->bufid, sc->buf); 618 if (sc->reg) bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg); 619 if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih); 620 if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 621 free(sc, M_DEVBUF); 622 return ENXIO; 623} 624 625static device_method_t nm_methods[] = { 626 /* Device interface */ 627 DEVMETHOD(device_probe, nm_pci_probe), 628 DEVMETHOD(device_attach, nm_pci_attach), 629 630 { 0, 0 } 631}; 632 633static driver_t nm_driver = { 634 "pcm", 635 nm_methods, 636 sizeof(snddev_info), 637}; 638 639static devclass_t pcm_devclass; 640 641DRIVER_MODULE(nm, pci, nm_driver, pcm_devclass, 0, 0);
| 511 sc->badintr = 0; 512 ofs = sc->buftop - 0x0400; 513 sc->buftop -= 0x1400; 514 515 if ((nm_rdbuf(sc, ofs, 4) & NM_SIG_MASK) == NM_SIGNATURE) { 516 i = nm_rdbuf(sc, ofs + 4, 4); 517 if (i != 0 && i != 0xffffffff) 518 sc->buftop = i; 519 } 520 521 sc->cbuf = sc->buftop - NM_MAX_COEFFICIENT; 522 sc->rbuf = sc->cbuf - NM_BUFFSIZE; 523 sc->pbuf = sc->rbuf - NM_BUFFSIZE; 524 sc->acbuf = sc->pbuf - (NM_TOTAL_COEFF_COUNT * 4); 525 526 nm_wr(sc, 0, 0x11, 1); 527 nm_wr(sc, NM_RECORD_ENABLE_REG, 0, 1); 528 nm_wr(sc, 0x214, 0, 2); 529 530 return 0; 531} 532 533static int 534nm_pci_probe(device_t dev) 535{ 536 char *s = NULL; 537 538 switch (pci_get_devid(dev)) { 539 case NM256AV_PCI_ID: 540 s = "NeoMagic 256AV"; 541 break; 542 543 case NM256ZX_PCI_ID: 544 s = "NeoMagic 256ZX"; 545 break; 546 } 547 548 if (s) device_set_desc(dev, s); 549 return s? 0 : ENXIO; 550} 551 552static int 553nm_pci_attach(device_t dev) 554{ 555 snddev_info *d; 556 u_int32_t data; 557 struct sc_info *sc; 558 struct ac97_info *codec; 559 char status[SND_STATUSLEN]; 560 561 d = device_get_softc(dev); 562 if ((sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT)) == NULL) { 563 device_printf(dev, "cannot allocate softc\n"); 564 return ENXIO; 565 } 566 567 bzero(sc, sizeof(*sc)); 568 sc->dev = dev; 569 sc->type = pci_get_devid(dev); 570 571 data = pci_read_config(dev, PCIR_COMMAND, 2); 572 data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN); 573 pci_write_config(dev, PCIR_COMMAND, data, 2); 574 data = pci_read_config(dev, PCIR_COMMAND, 2); 575 576 sc->bufid = PCIR_MAPS; 577 sc->buf = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->bufid, 578 0, ~0, 1, RF_ACTIVE); 579 sc->regid = PCIR_MAPS + 4; 580 sc->reg = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->regid, 581 0, ~0, 1, RF_ACTIVE); 582 583 if (!sc->buf || !sc->reg) { 584 device_printf(dev, "unable to map register space\n"); 585 goto bad; 586 } 587 588 if (nm_init(sc) == -1) { 589 device_printf(dev, "unable to initialize the card\n"); 590 goto bad; 591 } 592 593 codec = ac97_create(sc, nm_rdcd, nm_wrcd); 594 if (codec == NULL) goto bad; 595 mixer_init(d, &ac97_mixer, codec); 596 597 sc->irqid = 0; 598 sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irqid, 599 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); 600 if (!sc->irq || 601 bus_setup_intr(dev, sc->irq, INTR_TYPE_TTY, nm_intr, sc, &sc->ih)) { 602 device_printf(dev, "unable to map interrupt\n"); 603 goto bad; 604 } 605 606 snprintf(status, SND_STATUSLEN, "at memory 0x%lx, 0x%lx irq %ld", 607 rman_get_start(sc->buf), rman_get_start(sc->reg), 608 rman_get_start(sc->irq)); 609 610 if (pcm_register(dev, sc, 1, 1)) goto bad; 611 pcm_addchan(dev, PCMDIR_REC, &nm_chantemplate, sc); 612 pcm_addchan(dev, PCMDIR_PLAY, &nm_chantemplate, sc); 613 pcm_setstatus(dev, status); 614 615 return 0; 616 617bad: 618 if (sc->buf) bus_release_resource(dev, SYS_RES_MEMORY, sc->bufid, sc->buf); 619 if (sc->reg) bus_release_resource(dev, SYS_RES_MEMORY, sc->regid, sc->reg); 620 if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih); 621 if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, sc->irqid, sc->irq); 622 free(sc, M_DEVBUF); 623 return ENXIO; 624} 625 626static device_method_t nm_methods[] = { 627 /* Device interface */ 628 DEVMETHOD(device_probe, nm_pci_probe), 629 DEVMETHOD(device_attach, nm_pci_attach), 630 631 { 0, 0 } 632}; 633 634static driver_t nm_driver = { 635 "pcm", 636 nm_methods, 637 sizeof(snddev_info), 638}; 639 640static devclass_t pcm_devclass; 641 642DRIVER_MODULE(nm, pci, nm_driver, pcm_devclass, 0, 0);
|