via8233.c (851a904af5cd8e3633e18f70af19c49672a5f729) | via8233.c (a580b31a54a7d147994d0036c97bba9056c6b38f) |
---|---|
1/*- 2 * Copyright (c) 2002 Orion Hodson <orion@freebsd.org> 3 * Portions of this code derived from via82c686.c: 4 * Copyright (c) 2000 David Jones <dej@ox.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 18 unchanged lines hidden (view full) --- 27 */ 28 29/* 30 * Credits due to: 31 * 32 * Grzybowski Rafal, Russell Davies, Mark Handley, Daniel O'Connor for 33 * comments, machine time, testing patches, and patience. VIA for 34 * providing specs. ALSA for helpful comments and some register poke | 1/*- 2 * Copyright (c) 2002 Orion Hodson <orion@freebsd.org> 3 * Portions of this code derived from via82c686.c: 4 * Copyright (c) 2000 David Jones <dej@ox.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 18 unchanged lines hidden (view full) --- 27 */ 28 29/* 30 * Credits due to: 31 * 32 * Grzybowski Rafal, Russell Davies, Mark Handley, Daniel O'Connor for 33 * comments, machine time, testing patches, and patience. VIA for 34 * providing specs. ALSA for helpful comments and some register poke |
35 * ordering. | 35 * ordering. |
36 */ 37 38#include <dev/sound/pcm/sound.h> 39#include <dev/sound/pcm/ac97.h> 40 41#include <dev/pci/pcireg.h> 42#include <dev/pci/pcivar.h> 43#include <sys/sysctl.h> --- 13 unchanged lines hidden (view full) --- 57#define VIA8233_REV_ID_8251 0x70 58 59#define SEGS_PER_CHAN 2 /* Segments per channel */ 60#define NDXSCHANS 4 /* No of DXS channels */ 61#define NMSGDCHANS 1 /* No of multichannel SGD */ 62#define NWRCHANS 1 /* No of write channels */ 63#define NCHANS (NWRCHANS + NDXSCHANS + NMSGDCHANS) 64#define NSEGS NCHANS * SEGS_PER_CHAN /* Segments in SGD table */ | 36 */ 37 38#include <dev/sound/pcm/sound.h> 39#include <dev/sound/pcm/ac97.h> 40 41#include <dev/pci/pcireg.h> 42#include <dev/pci/pcivar.h> 43#include <sys/sysctl.h> --- 13 unchanged lines hidden (view full) --- 57#define VIA8233_REV_ID_8251 0x70 58 59#define SEGS_PER_CHAN 2 /* Segments per channel */ 60#define NDXSCHANS 4 /* No of DXS channels */ 61#define NMSGDCHANS 1 /* No of multichannel SGD */ 62#define NWRCHANS 1 /* No of write channels */ 63#define NCHANS (NWRCHANS + NDXSCHANS + NMSGDCHANS) 64#define NSEGS NCHANS * SEGS_PER_CHAN /* Segments in SGD table */ |
65#define VIA_SEGS_MIN 2 66#define VIA_SEGS_MAX 128 67#define VIA_SEGS_DEFAULT 2 |
|
65 66#define VIA_DEFAULT_BUFSZ 0x1000 67 68/* we rely on this struct being packed to 64 bits */ 69struct via_dma_op { | 68 69#define VIA_DEFAULT_BUFSZ 0x1000 70 71/* we rely on this struct being packed to 64 bits */ 72struct via_dma_op { |
70 volatile u_int32_t ptr; 71 volatile u_int32_t flags; | 73 volatile uint32_t ptr; 74 volatile uint32_t flags; |
72#define VIA_DMAOP_EOL 0x80000000 73#define VIA_DMAOP_FLAG 0x40000000 74#define VIA_DMAOP_STOP 0x20000000 75#define VIA_DMAOP_COUNT(x) ((x)&0x00FFFFFF) 76}; 77 78struct via_info; 79 80struct via_chinfo { 81 struct via_info *parent; 82 struct pcm_channel *channel; 83 struct snd_dbuf *buffer; 84 struct via_dma_op *sgd_table; 85 bus_addr_t sgd_addr; | 75#define VIA_DMAOP_EOL 0x80000000 76#define VIA_DMAOP_FLAG 0x40000000 77#define VIA_DMAOP_STOP 0x20000000 78#define VIA_DMAOP_COUNT(x) ((x)&0x00FFFFFF) 79}; 80 81struct via_info; 82 83struct via_chinfo { 84 struct via_info *parent; 85 struct pcm_channel *channel; 86 struct snd_dbuf *buffer; 87 struct via_dma_op *sgd_table; 88 bus_addr_t sgd_addr; |
86 int dir, blksz; 87 int rbase; | 89 int dir, rbase, active; 90 unsigned int blksz, blkcnt; 91 unsigned int ptr, prevptr; |
88}; 89 90struct via_info { 91 bus_space_tag_t st; 92 bus_space_handle_t sh; 93 bus_dma_tag_t parent_dmat; 94 bus_dma_tag_t sgd_dmat; 95 bus_dmamap_t sgd_dmamap; 96 bus_addr_t sgd_addr; 97 98 struct resource *reg, *irq; 99 int regid, irqid; 100 void *ih; 101 struct ac97_info *codec; 102 | 92}; 93 94struct via_info { 95 bus_space_tag_t st; 96 bus_space_handle_t sh; 97 bus_dma_tag_t parent_dmat; 98 bus_dma_tag_t sgd_dmat; 99 bus_dmamap_t sgd_dmamap; 100 bus_addr_t sgd_addr; 101 102 struct resource *reg, *irq; 103 int regid, irqid; 104 void *ih; 105 struct ac97_info *codec; 106 |
103 unsigned int bufsz; | 107 unsigned int bufsz, blkcnt; |
104 int dxs_src, dma_eol_wake; 105 106 struct via_chinfo pch[NDXSCHANS + NMSGDCHANS]; 107 struct via_chinfo rch[NWRCHANS]; 108 struct via_dma_op *sgd_table; | 108 int dxs_src, dma_eol_wake; 109 110 struct via_chinfo pch[NDXSCHANS + NMSGDCHANS]; 111 struct via_chinfo rch[NWRCHANS]; 112 struct via_dma_op *sgd_table; |
109 u_int16_t codec_caps; 110 u_int16_t n_dxs_registered; | 113 uint16_t codec_caps; 114 uint16_t n_dxs_registered; |
111 struct mtx *lock; | 115 struct mtx *lock; |
116 struct callout poll_timer; 117 int poll_ticks, polling; |
|
112}; 113 | 118}; 119 |
114static u_int32_t via_fmt[] = { | 120static uint32_t via_fmt[] = { |
115 AFMT_U8, 116 AFMT_STEREO | AFMT_U8, 117 AFMT_S16_LE, 118 AFMT_STEREO | AFMT_S16_LE, 119 0 120}; 121 122static struct pcmchan_caps via_vracaps = { 4000, 48000, via_fmt, 0 }; 123static struct pcmchan_caps via_caps = { 48000, 48000, via_fmt, 0 }; 124 | 121 AFMT_U8, 122 AFMT_STEREO | AFMT_U8, 123 AFMT_S16_LE, 124 AFMT_STEREO | AFMT_S16_LE, 125 0 126}; 127 128static struct pcmchan_caps via_vracaps = { 4000, 48000, via_fmt, 0 }; 129static struct pcmchan_caps via_caps = { 48000, 48000, via_fmt, 0 }; 130 |
131static __inline int 132via_chan_active(struct via_info *via) 133{ 134 int i, ret = 0; 135 136 if (via == NULL) 137 return (0); 138 139 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) 140 ret += via->pch[i].active; 141 142 for (i = 0; i < NWRCHANS; i++) 143 ret += via->rch[i].active; 144 145 return (ret); 146} 147 |
|
125#ifdef SND_DYNSYSCTL 126static int 127sysctl_via8233_spdif_enable(SYSCTL_HANDLER_ARGS) 128{ 129 struct via_info *via; 130 device_t dev; 131 uint32_t r; 132 int err, new_en; 133 134 dev = oidp->oid_arg1; 135 via = pcm_getdevinfo(dev); 136 snd_mtxlock(via->lock); 137 r = pci_read_config(dev, VIA_PCI_SPDIF, 1); 138 snd_mtxunlock(via->lock); 139 new_en = (r & VIA_SPDIF_EN) ? 1 : 0; 140 err = sysctl_handle_int(oidp, &new_en, sizeof(new_en), req); 141 142 if (err || req->newptr == NULL) | 148#ifdef SND_DYNSYSCTL 149static int 150sysctl_via8233_spdif_enable(SYSCTL_HANDLER_ARGS) 151{ 152 struct via_info *via; 153 device_t dev; 154 uint32_t r; 155 int err, new_en; 156 157 dev = oidp->oid_arg1; 158 via = pcm_getdevinfo(dev); 159 snd_mtxlock(via->lock); 160 r = pci_read_config(dev, VIA_PCI_SPDIF, 1); 161 snd_mtxunlock(via->lock); 162 new_en = (r & VIA_SPDIF_EN) ? 1 : 0; 163 err = sysctl_handle_int(oidp, &new_en, sizeof(new_en), req); 164 165 if (err || req->newptr == NULL) |
143 return err; | 166 return (err); |
144 if (new_en < 0 || new_en > 1) | 167 if (new_en < 0 || new_en > 1) |
145 return EINVAL; | 168 return (EINVAL); |
146 147 if (new_en) 148 r |= VIA_SPDIF_EN; 149 else 150 r &= ~VIA_SPDIF_EN; 151 snd_mtxlock(via->lock); 152 pci_write_config(dev, VIA_PCI_SPDIF, r, 1); 153 snd_mtxunlock(via->lock); 154 | 169 170 if (new_en) 171 r |= VIA_SPDIF_EN; 172 else 173 r &= ~VIA_SPDIF_EN; 174 snd_mtxlock(via->lock); 175 pci_write_config(dev, VIA_PCI_SPDIF, r, 1); 176 snd_mtxunlock(via->lock); 177 |
155 return 0; | 178 return (0); |
156} 157 158static int 159sysctl_via8233_dxs_src(SYSCTL_HANDLER_ARGS) 160{ 161 struct via_info *via; 162 device_t dev; 163 int err, val; 164 165 dev = oidp->oid_arg1; 166 via = pcm_getdevinfo(dev); 167 snd_mtxlock(via->lock); 168 val = via->dxs_src; 169 snd_mtxunlock(via->lock); 170 err = sysctl_handle_int(oidp, &val, sizeof(val), req); 171 172 if (err || req->newptr == NULL) | 179} 180 181static int 182sysctl_via8233_dxs_src(SYSCTL_HANDLER_ARGS) 183{ 184 struct via_info *via; 185 device_t dev; 186 int err, val; 187 188 dev = oidp->oid_arg1; 189 via = pcm_getdevinfo(dev); 190 snd_mtxlock(via->lock); 191 val = via->dxs_src; 192 snd_mtxunlock(via->lock); 193 err = sysctl_handle_int(oidp, &val, sizeof(val), req); 194 195 if (err || req->newptr == NULL) |
173 return err; | 196 return (err); |
174 if (val < 0 || val > 1) | 197 if (val < 0 || val > 1) |
175 return EINVAL; | 198 return (EINVAL); |
176 177 snd_mtxlock(via->lock); 178 via->dxs_src = val; 179 snd_mtxunlock(via->lock); 180 | 199 200 snd_mtxlock(via->lock); 201 via->dxs_src = val; 202 snd_mtxunlock(via->lock); 203 |
181 return 0; | 204 return (0); |
182} | 205} |
206 207static int 208sysctl_via_polling(SYSCTL_HANDLER_ARGS) 209{ 210 struct via_info *via; 211 device_t dev; 212 int err, val; 213 214 dev = oidp->oid_arg1; 215 via = pcm_getdevinfo(dev); 216 if (via == NULL) 217 return (EINVAL); 218 snd_mtxlock(via->lock); 219 val = via->polling; 220 snd_mtxunlock(via->lock); 221 err = sysctl_handle_int(oidp, &val, sizeof(val), req); 222 223 if (err || req->newptr == NULL) 224 return (err); 225 if (val < 0 || val > 1) 226 return (EINVAL); 227 228 snd_mtxlock(via->lock); 229 if (val != via->polling) { 230 if (via_chan_active(via) != 0) 231 err = EBUSY; 232 else if (val == 0) 233 via->polling = 0; 234 else 235 via->polling = 1; 236 } 237 snd_mtxunlock(via->lock); 238 239 return (err); 240} |
|
183#endif /* SND_DYNSYSCTL */ 184 185static void 186via_init_sysctls(device_t dev) 187{ 188#ifdef SND_DYNSYSCTL 189 /* XXX: an user should be able to set this with a control tool, 190 if not done before 7.0-RELEASE, this needs to be converted to 191 a device specific sysctl "dev.pcm.X.yyy" via device_get_sysctl_*() 192 as discussed on multimedia@ in msg-id <861wujij2q.fsf@xps.des.no> */ | 241#endif /* SND_DYNSYSCTL */ 242 243static void 244via_init_sysctls(device_t dev) 245{ 246#ifdef SND_DYNSYSCTL 247 /* XXX: an user should be able to set this with a control tool, 248 if not done before 7.0-RELEASE, this needs to be converted to 249 a device specific sysctl "dev.pcm.X.yyy" via device_get_sysctl_*() 250 as discussed on multimedia@ in msg-id <861wujij2q.fsf@xps.des.no> */ |
193 SYSCTL_ADD_PROC(snd_sysctl_tree(dev), 194 SYSCTL_CHILDREN(snd_sysctl_tree_top(dev)), 195 OID_AUTO, "_spdif_enabled", 196 CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 197 sysctl_via8233_spdif_enable, "I", 198 "Enable S/PDIF output on primary playback channel"); 199 SYSCTL_ADD_PROC(snd_sysctl_tree(dev), 200 SYSCTL_CHILDREN(snd_sysctl_tree_top(dev)), 201 OID_AUTO, "_via_dxs_src", 202 CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 203 sysctl_via8233_dxs_src, "I", 204 "Enable VIA DXS Sample Rate Converter"); | 251 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 252 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 253 "spdif_enabled", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 254 sysctl_via8233_spdif_enable, "I", 255 "Enable S/PDIF output on primary playback channel"); 256 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 257 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 258 "dxs_src", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 259 sysctl_via8233_dxs_src, "I", 260 "Enable VIA DXS Sample Rate Converter"); 261 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), 262 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, 263 "polling", CTLTYPE_INT | CTLFLAG_RW, dev, sizeof(dev), 264 sysctl_via_polling, "I", 265 "Enable polling mode"); |
205#endif 206} 207 | 266#endif 267} 268 |
208static __inline u_int32_t | 269static __inline uint32_t |
209via_rd(struct via_info *via, int regno, int size) 210{ 211 switch (size) { 212 case 1: | 270via_rd(struct via_info *via, int regno, int size) 271{ 272 switch (size) { 273 case 1: |
213 return bus_space_read_1(via->st, via->sh, regno); | 274 return (bus_space_read_1(via->st, via->sh, regno)); |
214 case 2: | 275 case 2: |
215 return bus_space_read_2(via->st, via->sh, regno); | 276 return (bus_space_read_2(via->st, via->sh, regno)); |
216 case 4: | 277 case 4: |
217 return bus_space_read_4(via->st, via->sh, regno); | 278 return (bus_space_read_4(via->st, via->sh, regno)); |
218 default: | 279 default: |
219 return 0xFFFFFFFF; | 280 return (0xFFFFFFFF); |
220 } 221} 222 223static __inline void | 281 } 282} 283 284static __inline void |
224via_wr(struct via_info *via, int regno, u_int32_t data, int size) | 285via_wr(struct via_info *via, int regno, uint32_t data, int size) |
225{ 226 227 switch (size) { 228 case 1: 229 bus_space_write_1(via->st, via->sh, regno, data); 230 break; 231 case 2: 232 bus_space_write_2(via->st, via->sh, regno, data); --- 10 unchanged lines hidden (view full) --- 243static int 244via_waitready_codec(struct via_info *via) 245{ 246 int i; 247 248 /* poll until codec not busy */ 249 for (i = 0; i < 1000; i++) { 250 if ((via_rd(via, VIA_AC97_CONTROL, 4) & VIA_AC97_BUSY) == 0) | 286{ 287 288 switch (size) { 289 case 1: 290 bus_space_write_1(via->st, via->sh, regno, data); 291 break; 292 case 2: 293 bus_space_write_2(via->st, via->sh, regno, data); --- 10 unchanged lines hidden (view full) --- 304static int 305via_waitready_codec(struct via_info *via) 306{ 307 int i; 308 309 /* poll until codec not busy */ 310 for (i = 0; i < 1000; i++) { 311 if ((via_rd(via, VIA_AC97_CONTROL, 4) & VIA_AC97_BUSY) == 0) |
251 return 0; | 312 return (0); |
252 DELAY(1); 253 } 254 printf("via: codec busy\n"); | 313 DELAY(1); 314 } 315 printf("via: codec busy\n"); |
255 return 1; | 316 return (1); |
256} 257 258static int 259via_waitvalid_codec(struct via_info *via) 260{ 261 int i; 262 263 /* poll until codec valid */ 264 for (i = 0; i < 1000; i++) { 265 if (via_rd(via, VIA_AC97_CONTROL, 4) & VIA_AC97_CODEC00_VALID) | 317} 318 319static int 320via_waitvalid_codec(struct via_info *via) 321{ 322 int i; 323 324 /* poll until codec valid */ 325 for (i = 0; i < 1000; i++) { 326 if (via_rd(via, VIA_AC97_CONTROL, 4) & VIA_AC97_CODEC00_VALID) |
266 return 0; | 327 return (0); |
267 DELAY(1); 268 } 269 printf("via: codec invalid\n"); | 328 DELAY(1); 329 } 330 printf("via: codec invalid\n"); |
270 return 1; | 331 return (1); |
271} 272 273static int | 332} 333 334static int |
274via_write_codec(kobj_t obj, void *addr, int reg, u_int32_t val) | 335via_write_codec(kobj_t obj, void *addr, int reg, uint32_t val) |
275{ 276 struct via_info *via = addr; 277 | 336{ 337 struct via_info *via = addr; 338 |
278 if (via_waitready_codec(via)) return -1; | 339 if (via_waitready_codec(via)) 340 return (-1); |
279 | 341 |
280 via_wr(via, VIA_AC97_CONTROL, | 342 via_wr(via, VIA_AC97_CONTROL, |
281 VIA_AC97_CODEC00_VALID | VIA_AC97_INDEX(reg) | 282 VIA_AC97_DATA(val), 4); 283 | 343 VIA_AC97_CODEC00_VALID | VIA_AC97_INDEX(reg) | 344 VIA_AC97_DATA(val), 4); 345 |
284 return 0; | 346 return (0); |
285} 286 287static int 288via_read_codec(kobj_t obj, void *addr, int reg) 289{ 290 struct via_info *via = addr; 291 292 if (via_waitready_codec(via)) | 347} 348 349static int 350via_read_codec(kobj_t obj, void *addr, int reg) 351{ 352 struct via_info *via = addr; 353 354 if (via_waitready_codec(via)) |
293 return -1; | 355 return (-1); |
294 | 356 |
295 via_wr(via, VIA_AC97_CONTROL, VIA_AC97_CODEC00_VALID | 296 VIA_AC97_READ | VIA_AC97_INDEX(reg), 4); | 357 via_wr(via, VIA_AC97_CONTROL, VIA_AC97_CODEC00_VALID | 358 VIA_AC97_READ | VIA_AC97_INDEX(reg), 4); |
297 298 if (via_waitready_codec(via)) | 359 360 if (via_waitready_codec(via)) |
299 return -1; | 361 return (-1); |
300 301 if (via_waitvalid_codec(via)) | 362 363 if (via_waitvalid_codec(via)) |
302 return -1; | 364 return (-1); |
303 | 365 |
304 return via_rd(via, VIA_AC97_CONTROL, 2); | 366 return (via_rd(via, VIA_AC97_CONTROL, 2)); |
305} 306 307static kobj_method_t via_ac97_methods[] = { | 367} 368 369static kobj_method_t via_ac97_methods[] = { |
308 KOBJMETHOD(ac97_read, via_read_codec), 309 KOBJMETHOD(ac97_write, via_write_codec), | 370 KOBJMETHOD(ac97_read, via_read_codec), 371 KOBJMETHOD(ac97_write, via_write_codec), |
310 { 0, 0 } 311}; 312AC97_DECLARE(via_ac97); 313 314/* -------------------------------------------------------------------- */ 315 316static int 317via_buildsgdt(struct via_chinfo *ch) 318{ | 372 { 0, 0 } 373}; 374AC97_DECLARE(via_ac97); 375 376/* -------------------------------------------------------------------- */ 377 378static int 379via_buildsgdt(struct via_chinfo *ch) 380{ |
319 u_int32_t phys_addr, flag; 320 int i, seg_size; | 381 uint32_t phys_addr, flag; 382 int i; |
321 | 383 |
322 seg_size = sndbuf_getsize(ch->buffer) / SEGS_PER_CHAN; | |
323 phys_addr = sndbuf_getbufaddr(ch->buffer); 324 | 384 phys_addr = sndbuf_getbufaddr(ch->buffer); 385 |
325 for (i = 0; i < SEGS_PER_CHAN; i++) { 326 flag = (i == SEGS_PER_CHAN - 1) ? VIA_DMAOP_EOL : VIA_DMAOP_FLAG; 327 ch->sgd_table[i].ptr = phys_addr + (i * seg_size); 328 ch->sgd_table[i].flags = flag | seg_size; | 386 for (i = 0; i < ch->blkcnt; i++) { 387 flag = (i == ch->blkcnt - 1) ? VIA_DMAOP_EOL : VIA_DMAOP_FLAG; 388 ch->sgd_table[i].ptr = phys_addr + (i * ch->blksz); 389 ch->sgd_table[i].flags = flag | ch->blksz; |
329 } 330 | 390 } 391 |
331 return 0; | 392 return (0); |
332} 333 334/* -------------------------------------------------------------------- */ 335/* Format setting functions */ 336 337static int | 393} 394 395/* -------------------------------------------------------------------- */ 396/* Format setting functions */ 397 398static int |
338via8233wr_setformat(kobj_t obj, void *data, u_int32_t format) | 399via8233wr_setformat(kobj_t obj, void *data, uint32_t format) |
339{ 340 struct via_chinfo *ch = data; 341 struct via_info *via = ch->parent; 342 | 400{ 401 struct via_chinfo *ch = data; 402 struct via_info *via = ch->parent; 403 |
343 u_int32_t f = WR_FORMAT_STOP_INDEX; | 404 uint32_t f = WR_FORMAT_STOP_INDEX; |
344 345 if (format & AFMT_STEREO) 346 f |= WR_FORMAT_STEREO; 347 if (format & AFMT_S16_LE) 348 f |= WR_FORMAT_16BIT; 349 snd_mtxlock(via->lock); 350 via_wr(via, VIA_WR0_FORMAT, f, 4); 351 snd_mtxunlock(via->lock); 352 | 405 406 if (format & AFMT_STEREO) 407 f |= WR_FORMAT_STEREO; 408 if (format & AFMT_S16_LE) 409 f |= WR_FORMAT_16BIT; 410 snd_mtxlock(via->lock); 411 via_wr(via, VIA_WR0_FORMAT, f, 4); 412 snd_mtxunlock(via->lock); 413 |
353 return 0; | 414 return (0); |
354} 355 356static int | 415} 416 417static int |
357via8233dxs_setformat(kobj_t obj, void *data, u_int32_t format) | 418via8233dxs_setformat(kobj_t obj, void *data, uint32_t format) |
358{ 359 struct via_chinfo *ch = data; 360 struct via_info *via = ch->parent; | 419{ 420 struct via_chinfo *ch = data; 421 struct via_info *via = ch->parent; |
361 u_int32_t r, v; | 422 uint32_t r, v; |
362 363 r = ch->rbase + VIA8233_RP_DXS_RATEFMT; 364 snd_mtxlock(via->lock); 365 v = via_rd(via, r, 4); 366 367 v &= ~(VIA8233_DXS_RATEFMT_STEREO | VIA8233_DXS_RATEFMT_16BIT); 368 if (format & AFMT_STEREO) 369 v |= VIA8233_DXS_RATEFMT_STEREO; | 423 424 r = ch->rbase + VIA8233_RP_DXS_RATEFMT; 425 snd_mtxlock(via->lock); 426 v = via_rd(via, r, 4); 427 428 v &= ~(VIA8233_DXS_RATEFMT_STEREO | VIA8233_DXS_RATEFMT_16BIT); 429 if (format & AFMT_STEREO) 430 v |= VIA8233_DXS_RATEFMT_STEREO; |
370 if (format & AFMT_16BIT) | 431 if (format & AFMT_16BIT) |
371 v |= VIA8233_DXS_RATEFMT_16BIT; 372 via_wr(via, r, v, 4); 373 snd_mtxunlock(via->lock); 374 | 432 v |= VIA8233_DXS_RATEFMT_16BIT; 433 via_wr(via, r, v, 4); 434 snd_mtxunlock(via->lock); 435 |
375 return 0; | 436 return (0); |
376} 377 378static int | 437} 438 439static int |
379via8233msgd_setformat(kobj_t obj, void *data, u_int32_t format) | 440via8233msgd_setformat(kobj_t obj, void *data, uint32_t format) |
380{ 381 struct via_chinfo *ch = data; 382 struct via_info *via = ch->parent; 383 | 441{ 442 struct via_chinfo *ch = data; 443 struct via_info *via = ch->parent; 444 |
384 u_int32_t s = 0xff000000; 385 u_int8_t v = (format & AFMT_S16_LE) ? MC_SGD_16BIT : MC_SGD_8BIT; | 445 uint32_t s = 0xff000000; 446 uint8_t v = (format & AFMT_S16_LE) ? MC_SGD_16BIT : MC_SGD_8BIT; |
386 387 if (format & AFMT_STEREO) { 388 v |= MC_SGD_CHANNELS(2); 389 s |= SLOT3(1) | SLOT4(2); 390 } else { 391 v |= MC_SGD_CHANNELS(1); 392 s |= SLOT3(1) | SLOT4(1); 393 } 394 395 snd_mtxlock(via->lock); 396 via_wr(via, VIA_MC_SLOT_SELECT, s, 4); 397 via_wr(via, VIA_MC_SGD_FORMAT, v, 1); 398 snd_mtxunlock(via->lock); 399 | 447 448 if (format & AFMT_STEREO) { 449 v |= MC_SGD_CHANNELS(2); 450 s |= SLOT3(1) | SLOT4(2); 451 } else { 452 v |= MC_SGD_CHANNELS(1); 453 s |= SLOT3(1) | SLOT4(1); 454 } 455 456 snd_mtxlock(via->lock); 457 via_wr(via, VIA_MC_SLOT_SELECT, s, 4); 458 via_wr(via, VIA_MC_SGD_FORMAT, v, 1); 459 snd_mtxunlock(via->lock); 460 |
400 return 0; | 461 return (0); |
401} 402 403/* -------------------------------------------------------------------- */ 404/* Speed setting functions */ 405 406static int | 462} 463 464/* -------------------------------------------------------------------- */ 465/* Speed setting functions */ 466 467static int |
407via8233wr_setspeed(kobj_t obj, void *data, u_int32_t speed) | 468via8233wr_setspeed(kobj_t obj, void *data, uint32_t speed) |
408{ 409 struct via_chinfo *ch = data; 410 struct via_info *via = ch->parent; 411 412 if (via->codec_caps & AC97_EXTCAP_VRA) | 469{ 470 struct via_chinfo *ch = data; 471 struct via_info *via = ch->parent; 472 473 if (via->codec_caps & AC97_EXTCAP_VRA) |
413 return ac97_setrate(via->codec, AC97_REGEXT_LADCRATE, speed); | 474 return (ac97_setrate(via->codec, AC97_REGEXT_LADCRATE, speed)); |
414 | 475 |
415 return 48000; | 476 return (48000); |
416} 417 418static int | 477} 478 479static int |
419via8233dxs_setspeed(kobj_t obj, void *data, u_int32_t speed) | 480via8233dxs_setspeed(kobj_t obj, void *data, uint32_t speed) |
420{ 421 struct via_chinfo *ch = data; 422 struct via_info *via = ch->parent; | 481{ 482 struct via_chinfo *ch = data; 483 struct via_info *via = ch->parent; |
423 u_int32_t r, v; | 484 uint32_t r, v; |
424 425 r = ch->rbase + VIA8233_RP_DXS_RATEFMT; 426 snd_mtxlock(via->lock); 427 v = via_rd(via, r, 4) & ~VIA8233_DXS_RATEFMT_48K; 428 429 /* Careful to avoid overflow (divide by 48 per vt8233c docs) */ 430 431 v |= VIA8233_DXS_RATEFMT_48K * (speed / 48) / (48000 / 48); 432 via_wr(via, r, v, 4); 433 snd_mtxunlock(via->lock); 434 | 485 486 r = ch->rbase + VIA8233_RP_DXS_RATEFMT; 487 snd_mtxlock(via->lock); 488 v = via_rd(via, r, 4) & ~VIA8233_DXS_RATEFMT_48K; 489 490 /* Careful to avoid overflow (divide by 48 per vt8233c docs) */ 491 492 v |= VIA8233_DXS_RATEFMT_48K * (speed / 48) / (48000 / 48); 493 via_wr(via, r, v, 4); 494 snd_mtxunlock(via->lock); 495 |
435 return speed; | 496 return (speed); |
436} 437 438static int | 497} 498 499static int |
439via8233msgd_setspeed(kobj_t obj, void *data, u_int32_t speed) | 500via8233msgd_setspeed(kobj_t obj, void *data, uint32_t speed) |
440{ 441 struct via_chinfo *ch = data; 442 struct via_info *via = ch->parent; 443 444 if (via->codec_caps & AC97_EXTCAP_VRA) | 501{ 502 struct via_chinfo *ch = data; 503 struct via_info *via = ch->parent; 504 505 if (via->codec_caps & AC97_EXTCAP_VRA) |
445 return ac97_setrate(via->codec, AC97_REGEXT_FDACRATE, speed); | 506 return (ac97_setrate(via->codec, AC97_REGEXT_FDACRATE, speed)); |
446 | 507 |
447 return 48000; | 508 return (48000); |
448} 449 450/* -------------------------------------------------------------------- */ 451/* Format probing functions */ 452 453static struct pcmchan_caps * 454via8233wr_getcaps(kobj_t obj, void *data) 455{ 456 struct via_chinfo *ch = data; 457 struct via_info *via = ch->parent; 458 459 /* Controlled by ac97 registers */ 460 if (via->codec_caps & AC97_EXTCAP_VRA) | 509} 510 511/* -------------------------------------------------------------------- */ 512/* Format probing functions */ 513 514static struct pcmchan_caps * 515via8233wr_getcaps(kobj_t obj, void *data) 516{ 517 struct via_chinfo *ch = data; 518 struct via_info *via = ch->parent; 519 520 /* Controlled by ac97 registers */ 521 if (via->codec_caps & AC97_EXTCAP_VRA) |
461 return &via_vracaps; 462 return &via_caps; | 522 return (&via_vracaps); 523 return (&via_caps); |
463} 464 465static struct pcmchan_caps * 466via8233dxs_getcaps(kobj_t obj, void *data) 467{ 468 struct via_chinfo *ch = data; 469 struct via_info *via = ch->parent; 470 471 /* 472 * Controlled by onboard registers 473 * 474 * Apparently, few boards can do DXS sample rate 475 * conversion. 476 */ 477 if (via->dxs_src) | 524} 525 526static struct pcmchan_caps * 527via8233dxs_getcaps(kobj_t obj, void *data) 528{ 529 struct via_chinfo *ch = data; 530 struct via_info *via = ch->parent; 531 532 /* 533 * Controlled by onboard registers 534 * 535 * Apparently, few boards can do DXS sample rate 536 * conversion. 537 */ 538 if (via->dxs_src) |
478 return &via_vracaps; 479 return &via_caps; | 539 return (&via_vracaps); 540 return (&via_caps); |
480} 481 482static struct pcmchan_caps * 483via8233msgd_getcaps(kobj_t obj, void *data) 484{ 485 struct via_chinfo *ch = data; 486 struct via_info *via = ch->parent; 487 488 /* Controlled by ac97 registers */ 489 if (via->codec_caps & AC97_EXTCAP_VRA) | 541} 542 543static struct pcmchan_caps * 544via8233msgd_getcaps(kobj_t obj, void *data) 545{ 546 struct via_chinfo *ch = data; 547 struct via_info *via = ch->parent; 548 549 /* Controlled by ac97 registers */ 550 if (via->codec_caps & AC97_EXTCAP_VRA) |
490 return &via_vracaps; 491 return &via_caps; | 551 return (&via_vracaps); 552 return (&via_caps); |
492} 493 494/* -------------------------------------------------------------------- */ 495/* Common functions */ 496 497static int | 553} 554 555/* -------------------------------------------------------------------- */ 556/* Common functions */ 557 558static int |
498via8233chan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize) | 559via8233chan_setblocksize(kobj_t obj, void *data, uint32_t blksz) |
499{ 500 struct via_chinfo *ch = data; 501 | 560{ 561 struct via_chinfo *ch = data; 562 |
502 sndbuf_resize(ch->buffer, SEGS_PER_CHAN, blocksize); | 563 if ((blksz * ch->blkcnt) > sndbuf_getmaxsize(ch->buffer)) 564 blksz = sndbuf_getmaxsize(ch->buffer) / ch->blkcnt; 565 566 if ((sndbuf_getblksz(ch->buffer) != blksz || 567 sndbuf_getblkcnt(ch->buffer) != ch->blkcnt) && 568 sndbuf_resize(ch->buffer, ch->blkcnt, blksz) != 0) 569 printf("via: %s: failed blksz=%u blkcnt=%u\n", 570 __func__, blksz, ch->blkcnt); 571 |
503 ch->blksz = sndbuf_getblksz(ch->buffer); | 572 ch->blksz = sndbuf_getblksz(ch->buffer); |
504 return ch->blksz; | 573 574 return (ch->blksz); |
505} 506 507static int 508via8233chan_getptr(kobj_t obj, void *data) 509{ 510 struct via_chinfo *ch = data; 511 struct via_info *via = ch->parent; | 575} 576 577static int 578via8233chan_getptr(kobj_t obj, void *data) 579{ 580 struct via_chinfo *ch = data; 581 struct via_info *via = ch->parent; |
512 u_int32_t v, index, count; | 582 uint32_t v, index, count; |
513 int ptr; 514 515 snd_mtxlock(via->lock); | 583 int ptr; 584 585 snd_mtxlock(via->lock); |
516 v = via_rd(via, ch->rbase + VIA_RP_CURRENT_COUNT, 4); 517 snd_mtxunlock(via->lock); 518 index = v >> 24; /* Last completed buffer */ 519 count = v & 0x00ffffff; /* Bytes remaining */ 520 ptr = (index + 1) * ch->blksz - count; 521 ptr %= SEGS_PER_CHAN * ch->blksz; /* Wrap to available space */ | 586 if (via->polling != 0) { 587 ptr = ch->ptr; 588 snd_mtxunlock(via->lock); 589 } else { 590 v = via_rd(via, ch->rbase + VIA_RP_CURRENT_COUNT, 4); 591 snd_mtxunlock(via->lock); 592 index = v >> 24; /* Last completed buffer */ 593 count = v & 0x00ffffff; /* Bytes remaining */ 594 ptr = (index + 1) * ch->blksz - count; 595 ptr %= ch->blkcnt * ch->blksz; /* Wrap to available space */ 596 } |
522 | 597 |
523 return ptr; | 598 return (ptr); |
524} 525 526static void 527via8233chan_reset(struct via_info *via, struct via_chinfo *ch) 528{ 529 via_wr(via, ch->rbase + VIA_RP_CONTROL, SGD_CONTROL_STOP, 1); 530 via_wr(via, ch->rbase + VIA_RP_CONTROL, 0x00, 1); | 599} 600 601static void 602via8233chan_reset(struct via_info *via, struct via_chinfo *ch) 603{ 604 via_wr(via, ch->rbase + VIA_RP_CONTROL, SGD_CONTROL_STOP, 1); 605 via_wr(via, ch->rbase + VIA_RP_CONTROL, 0x00, 1); |
531 via_wr(via, ch->rbase + VIA_RP_STATUS, 532 SGD_STATUS_EOL | SGD_STATUS_FLAG, 1); | 606 via_wr(via, ch->rbase + VIA_RP_STATUS, 607 SGD_STATUS_EOL | SGD_STATUS_FLAG, 1); |
533} 534 535/* -------------------------------------------------------------------- */ 536/* Channel initialization functions */ 537 538static void 539via8233chan_sgdinit(struct via_info *via, struct via_chinfo *ch, int chnum) 540{ | 608} 609 610/* -------------------------------------------------------------------- */ 611/* Channel initialization functions */ 612 613static void 614via8233chan_sgdinit(struct via_info *via, struct via_chinfo *ch, int chnum) 615{ |
541 ch->sgd_table = &via->sgd_table[chnum * SEGS_PER_CHAN]; 542 ch->sgd_addr = via->sgd_addr + chnum * SEGS_PER_CHAN * sizeof(struct via_dma_op); | 616 ch->sgd_table = &via->sgd_table[chnum * via->blkcnt]; 617 ch->sgd_addr = via->sgd_addr + chnum * via->blkcnt * 618 sizeof(struct via_dma_op); |
543} 544 545static void* 546via8233wr_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, | 619} 620 621static void* 622via8233wr_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, |
547 struct pcm_channel *c, int dir) | 623 struct pcm_channel *c, int dir) |
548{ 549 struct via_info *via = devinfo; 550 struct via_chinfo *ch = &via->rch[c->num]; 551 552 ch->parent = via; 553 ch->channel = c; 554 ch->buffer = b; 555 ch->dir = dir; | 624{ 625 struct via_info *via = devinfo; 626 struct via_chinfo *ch = &via->rch[c->num]; 627 628 ch->parent = via; 629 ch->channel = c; 630 ch->buffer = b; 631 ch->dir = dir; |
632 ch->blkcnt = via->blkcnt; |
|
556 557 ch->rbase = VIA_WR_BASE(c->num); 558 snd_mtxlock(via->lock); 559 via_wr(via, ch->rbase + VIA_WR_RP_SGD_FORMAT, WR_FIFO_ENABLE, 1); 560 snd_mtxunlock(via->lock); 561 562 if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0) | 633 634 ch->rbase = VIA_WR_BASE(c->num); 635 snd_mtxlock(via->lock); 636 via_wr(via, ch->rbase + VIA_WR_RP_SGD_FORMAT, WR_FIFO_ENABLE, 1); 637 snd_mtxunlock(via->lock); 638 639 if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0) |
563 return NULL; | 640 return (NULL); |
564 565 snd_mtxlock(via->lock); 566 via8233chan_sgdinit(via, ch, c->num); 567 via8233chan_reset(via, ch); 568 snd_mtxunlock(via->lock); 569 | 641 642 snd_mtxlock(via->lock); 643 via8233chan_sgdinit(via, ch, c->num); 644 via8233chan_reset(via, ch); 645 snd_mtxunlock(via->lock); 646 |
570 return ch; | 647 return (ch); |
571} 572 573static void* 574via8233dxs_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, | 648} 649 650static void* 651via8233dxs_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, |
575 struct pcm_channel *c, int dir) | 652 struct pcm_channel *c, int dir) |
576{ 577 struct via_info *via = devinfo; 578 struct via_chinfo *ch = &via->pch[c->num]; 579 580 ch->parent = via; 581 ch->channel = c; 582 ch->buffer = b; 583 ch->dir = dir; | 653{ 654 struct via_info *via = devinfo; 655 struct via_chinfo *ch = &via->pch[c->num]; 656 657 ch->parent = via; 658 ch->channel = c; 659 ch->buffer = b; 660 ch->dir = dir; |
661 ch->blkcnt = via->blkcnt; |
|
584 585 /* 586 * All cards apparently support DXS3, but not other DXS 587 * channels. We therefore want to align first DXS channel to 588 * DXS3. 589 */ 590 snd_mtxlock(via->lock); 591 ch->rbase = VIA_DXS_BASE(NDXSCHANS - 1 - via->n_dxs_registered); 592 via->n_dxs_registered++; 593 snd_mtxunlock(via->lock); 594 595 if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0) | 662 663 /* 664 * All cards apparently support DXS3, but not other DXS 665 * channels. We therefore want to align first DXS channel to 666 * DXS3. 667 */ 668 snd_mtxlock(via->lock); 669 ch->rbase = VIA_DXS_BASE(NDXSCHANS - 1 - via->n_dxs_registered); 670 via->n_dxs_registered++; 671 snd_mtxunlock(via->lock); 672 673 if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0) |
596 return NULL; | 674 return (NULL); |
597 598 snd_mtxlock(via->lock); 599 via8233chan_sgdinit(via, ch, NWRCHANS + c->num); 600 via8233chan_reset(via, ch); 601 snd_mtxunlock(via->lock); 602 | 675 676 snd_mtxlock(via->lock); 677 via8233chan_sgdinit(via, ch, NWRCHANS + c->num); 678 via8233chan_reset(via, ch); 679 snd_mtxunlock(via->lock); 680 |
603 return ch; | 681 return (ch); |
604} 605 606static void* 607via8233msgd_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, | 682} 683 684static void* 685via8233msgd_init(kobj_t obj, void *devinfo, struct snd_dbuf *b, |
608 struct pcm_channel *c, int dir) | 686 struct pcm_channel *c, int dir) |
609{ 610 struct via_info *via = devinfo; 611 struct via_chinfo *ch = &via->pch[c->num]; 612 613 ch->parent = via; 614 ch->channel = c; 615 ch->buffer = b; 616 ch->dir = dir; 617 ch->rbase = VIA_MC_SGD_STATUS; | 687{ 688 struct via_info *via = devinfo; 689 struct via_chinfo *ch = &via->pch[c->num]; 690 691 ch->parent = via; 692 ch->channel = c; 693 ch->buffer = b; 694 ch->dir = dir; 695 ch->rbase = VIA_MC_SGD_STATUS; |
696 ch->blkcnt = via->blkcnt; |
|
618 619 if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0) | 697 698 if (sndbuf_alloc(ch->buffer, via->parent_dmat, via->bufsz) != 0) |
620 return NULL; | 699 return (NULL); |
621 622 snd_mtxlock(via->lock); 623 via8233chan_sgdinit(via, ch, NWRCHANS + c->num); 624 via8233chan_reset(via, ch); 625 snd_mtxunlock(via->lock); 626 | 700 701 snd_mtxlock(via->lock); 702 via8233chan_sgdinit(via, ch, NWRCHANS + c->num); 703 via8233chan_reset(via, ch); 704 snd_mtxunlock(via->lock); 705 |
627 return ch; | 706 return (ch); |
628} 629 630static void 631via8233chan_mute(struct via_info *via, struct via_chinfo *ch, int muted) 632{ 633 if (BASE_IS_VIA_DXS_REG(ch->rbase)) { 634 int r; 635 muted = (muted) ? VIA8233_DXS_MUTE : 0; 636 via_wr(via, ch->rbase + VIA8233_RP_DXS_LVOL, muted, 1); 637 via_wr(via, ch->rbase + VIA8233_RP_DXS_RVOL, muted, 1); | 707} 708 709static void 710via8233chan_mute(struct via_info *via, struct via_chinfo *ch, int muted) 711{ 712 if (BASE_IS_VIA_DXS_REG(ch->rbase)) { 713 int r; 714 muted = (muted) ? VIA8233_DXS_MUTE : 0; 715 via_wr(via, ch->rbase + VIA8233_RP_DXS_LVOL, muted, 1); 716 via_wr(via, ch->rbase + VIA8233_RP_DXS_RVOL, muted, 1); |
638 r = via_rd(via, ch->rbase + VIA8233_RP_DXS_LVOL, 1) & VIA8233_DXS_MUTE; | 717 r = via_rd(via, ch->rbase + VIA8233_RP_DXS_LVOL, 1) & 718 VIA8233_DXS_MUTE; |
639 if (r != muted) { 640 printf("via: failed to set dxs volume " 641 "(dxs base 0x%02x).\n", ch->rbase); 642 } 643 } 644} 645 | 719 if (r != muted) { 720 printf("via: failed to set dxs volume " 721 "(dxs base 0x%02x).\n", ch->rbase); 722 } 723 } 724} 725 |
726static __inline int 727via_poll_channel(struct via_chinfo *ch) 728{ 729 struct via_info *via; 730 uint32_t sz, delta; 731 uint32_t v, index, count; 732 int ptr; 733 734 if (ch == NULL || ch->channel == NULL || ch->active == 0) 735 return (0); 736 737 via = ch->parent; 738 sz = ch->blksz * ch->blkcnt; 739 v = via_rd(via, ch->rbase + VIA_RP_CURRENT_COUNT, 4); 740 index = v >> 24; 741 count = v & 0x00ffffff; 742 ptr = ((index + 1) * ch->blksz) - count; 743 ptr %= sz; 744 ptr &= ~(ch->blksz - 1); 745 ch->ptr = ptr; 746 delta = (sz + ptr - ch->prevptr) % sz; 747 748 if (delta < ch->blksz) 749 return (0); 750 751 ch->prevptr = ptr; 752 753 return (1); 754} 755 756static void 757via_poll_callback(void *arg) 758{ 759 struct via_info *via = arg; 760 uint32_t ptrigger = 0, rtrigger = 0; 761 int i; 762 763 if (via == NULL) 764 return; 765 766 snd_mtxlock(via->lock); 767 if (via->polling == 0 || via_chan_active(via) == 0) { 768 snd_mtxunlock(via->lock); 769 return; 770 } 771 772 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) 773 ptrigger |= (via_poll_channel(&via->pch[i]) != 0) ? 774 (1 << i) : 0; 775 776 for (i = 0; i < NWRCHANS; i++) 777 rtrigger |= (via_poll_channel(&via->rch[i]) != 0) ? 778 (1 << i) : 0; 779 780 /* XXX */ 781 callout_reset(&via->poll_timer, 1/*via->poll_ticks*/, 782 via_poll_callback, via); 783 784 snd_mtxunlock(via->lock); 785 786 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { 787 if (ptrigger & (1 << i)) 788 chn_intr(via->pch[i].channel); 789 } 790 for (i = 0; i < NWRCHANS; i++) { 791 if (rtrigger & (1 << i)) 792 chn_intr(via->rch[i].channel); 793 } 794} 795 |
|
646static int | 796static int |
797via_poll_ticks(struct via_info *via) 798{ 799 struct via_chinfo *ch; 800 int i; 801 int ret = hz; 802 int pollticks; 803 804 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { 805 ch = &via->pch[i]; 806 if (ch->channel == NULL || ch->active == 0) 807 continue; 808 pollticks = ((uint64_t)hz * ch->blksz) / 809 ((uint64_t)sndbuf_getbps(ch->buffer) * 810 sndbuf_getspd(ch->buffer)); 811 pollticks >>= 2; 812 if (pollticks > hz) 813 pollticks = hz; 814 if (pollticks < 1) 815 pollticks = 1; 816 if (pollticks < ret) 817 ret = pollticks; 818 } 819 820 for (i = 0; i < NWRCHANS; i++) { 821 ch = &via->rch[i]; 822 if (ch->channel == NULL || ch->active == 0) 823 continue; 824 pollticks = ((uint64_t)hz * ch->blksz) / 825 ((uint64_t)sndbuf_getbps(ch->buffer) * 826 sndbuf_getspd(ch->buffer)); 827 pollticks >>= 2; 828 if (pollticks > hz) 829 pollticks = hz; 830 if (pollticks < 1) 831 pollticks = 1; 832 if (pollticks < ret) 833 ret = pollticks; 834 } 835 836 return (ret); 837} 838 839static int |
|
647via8233chan_trigger(kobj_t obj, void* data, int go) 648{ 649 struct via_chinfo *ch = data; 650 struct via_info *via = ch->parent; | 840via8233chan_trigger(kobj_t obj, void* data, int go) 841{ 842 struct via_chinfo *ch = data; 843 struct via_info *via = ch->parent; |
844 int pollticks; |
|
651 652 snd_mtxlock(via->lock); 653 switch(go) { 654 case PCMTRIG_START: 655 via_buildsgdt(ch); 656 via8233chan_mute(via, ch, 0); 657 via_wr(via, ch->rbase + VIA_RP_TABLE_PTR, ch->sgd_addr, 4); | 845 846 snd_mtxlock(via->lock); 847 switch(go) { 848 case PCMTRIG_START: 849 via_buildsgdt(ch); 850 via8233chan_mute(via, ch, 0); 851 via_wr(via, ch->rbase + VIA_RP_TABLE_PTR, ch->sgd_addr, 4); |
852 if (via->polling != 0) { 853 ch->ptr = 0; 854 ch->prevptr = 0; 855 pollticks = ((uint64_t)hz * ch->blksz) / 856 ((uint64_t)sndbuf_getbps(ch->buffer) * 857 sndbuf_getspd(ch->buffer)); 858 pollticks >>= 2; 859 if (pollticks > hz) 860 pollticks = hz; 861 if (pollticks < 1) 862 pollticks = 1; 863 if (via_chan_active(via) == 0 || 864 pollticks < via->poll_ticks) { 865 if (bootverbose) { 866 if (via_chan_active(via) == 0) 867 printf("%s: pollticks=%d\n", 868 __func__, pollticks); 869 else 870 printf("%s: " 871 "pollticks %d -> %d\n", 872 __func__, via->poll_ticks, 873 pollticks); 874 } 875 via->poll_ticks = pollticks; 876 callout_reset(&via->poll_timer, 1, 877 via_poll_callback, via); 878 } 879 } |
|
658 via_wr(via, ch->rbase + VIA_RP_CONTROL, | 880 via_wr(via, ch->rbase + VIA_RP_CONTROL, |
659 SGD_CONTROL_START | SGD_CONTROL_AUTOSTART | 660 SGD_CONTROL_I_EOL | SGD_CONTROL_I_FLAG, 1); | 881 SGD_CONTROL_START | SGD_CONTROL_AUTOSTART | 882 ((via->polling == 0) ? 883 (SGD_CONTROL_I_EOL | SGD_CONTROL_I_FLAG) : 0), 1); 884 ch->active = 1; |
661 break; 662 case PCMTRIG_STOP: 663 case PCMTRIG_ABORT: 664 via_wr(via, ch->rbase + VIA_RP_CONTROL, SGD_CONTROL_STOP, 1); 665 via8233chan_mute(via, ch, 1); 666 via8233chan_reset(via, ch); | 885 break; 886 case PCMTRIG_STOP: 887 case PCMTRIG_ABORT: 888 via_wr(via, ch->rbase + VIA_RP_CONTROL, SGD_CONTROL_STOP, 1); 889 via8233chan_mute(via, ch, 1); 890 via8233chan_reset(via, ch); |
891 ch->active = 0; 892 if (via->polling != 0) { 893 if (via_chan_active(via) == 0) { 894 callout_stop(&via->poll_timer); 895 via->poll_ticks = 1; 896 } else { 897 pollticks = via_poll_ticks(via); 898 if (pollticks > via->poll_ticks) { 899 if (bootverbose) 900 printf("%s: pollticks " 901 "%d -> %d\n", 902 __func__, via->poll_ticks, 903 pollticks); 904 via->poll_ticks = pollticks; 905 callout_reset(&via->poll_timer, 906 1, via_poll_callback, 907 via); 908 } 909 } 910 } |
|
667 break; | 911 break; |
912 default: 913 break; |
|
668 } 669 snd_mtxunlock(via->lock); | 914 } 915 snd_mtxunlock(via->lock); |
670 return 0; | 916 return (0); |
671} 672 673static kobj_method_t via8233wr_methods[] = { | 917} 918 919static kobj_method_t via8233wr_methods[] = { |
674 KOBJMETHOD(channel_init, via8233wr_init), 675 KOBJMETHOD(channel_setformat, via8233wr_setformat), 676 KOBJMETHOD(channel_setspeed, via8233wr_setspeed), 677 KOBJMETHOD(channel_getcaps, via8233wr_getcaps), 678 KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), 679 KOBJMETHOD(channel_trigger, via8233chan_trigger), 680 KOBJMETHOD(channel_getptr, via8233chan_getptr), | 920 KOBJMETHOD(channel_init, via8233wr_init), 921 KOBJMETHOD(channel_setformat, via8233wr_setformat), 922 KOBJMETHOD(channel_setspeed, via8233wr_setspeed), 923 KOBJMETHOD(channel_getcaps, via8233wr_getcaps), 924 KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), 925 KOBJMETHOD(channel_trigger, via8233chan_trigger), 926 KOBJMETHOD(channel_getptr, via8233chan_getptr), |
681 { 0, 0 } 682}; 683CHANNEL_DECLARE(via8233wr); 684 685static kobj_method_t via8233dxs_methods[] = { | 927 { 0, 0 } 928}; 929CHANNEL_DECLARE(via8233wr); 930 931static kobj_method_t via8233dxs_methods[] = { |
686 KOBJMETHOD(channel_init, via8233dxs_init), 687 KOBJMETHOD(channel_setformat, via8233dxs_setformat), 688 KOBJMETHOD(channel_setspeed, via8233dxs_setspeed), 689 KOBJMETHOD(channel_getcaps, via8233dxs_getcaps), 690 KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), 691 KOBJMETHOD(channel_trigger, via8233chan_trigger), 692 KOBJMETHOD(channel_getptr, via8233chan_getptr), | 932 KOBJMETHOD(channel_init, via8233dxs_init), 933 KOBJMETHOD(channel_setformat, via8233dxs_setformat), 934 KOBJMETHOD(channel_setspeed, via8233dxs_setspeed), 935 KOBJMETHOD(channel_getcaps, via8233dxs_getcaps), 936 KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), 937 KOBJMETHOD(channel_trigger, via8233chan_trigger), 938 KOBJMETHOD(channel_getptr, via8233chan_getptr), |
693 { 0, 0 } 694}; 695CHANNEL_DECLARE(via8233dxs); 696 697static kobj_method_t via8233msgd_methods[] = { | 939 { 0, 0 } 940}; 941CHANNEL_DECLARE(via8233dxs); 942 943static kobj_method_t via8233msgd_methods[] = { |
698 KOBJMETHOD(channel_init, via8233msgd_init), 699 KOBJMETHOD(channel_setformat, via8233msgd_setformat), 700 KOBJMETHOD(channel_setspeed, via8233msgd_setspeed), 701 KOBJMETHOD(channel_getcaps, via8233msgd_getcaps), 702 KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), 703 KOBJMETHOD(channel_trigger, via8233chan_trigger), 704 KOBJMETHOD(channel_getptr, via8233chan_getptr), | 944 KOBJMETHOD(channel_init, via8233msgd_init), 945 KOBJMETHOD(channel_setformat, via8233msgd_setformat), 946 KOBJMETHOD(channel_setspeed, via8233msgd_setspeed), 947 KOBJMETHOD(channel_getcaps, via8233msgd_getcaps), 948 KOBJMETHOD(channel_setblocksize, via8233chan_setblocksize), 949 KOBJMETHOD(channel_trigger, via8233chan_trigger), 950 KOBJMETHOD(channel_getptr, via8233chan_getptr), |
705 { 0, 0 } 706}; 707CHANNEL_DECLARE(via8233msgd); 708 709/* -------------------------------------------------------------------- */ 710 711static void 712via_intr(void *p) 713{ 714 struct via_info *via = p; | 951 { 0, 0 } 952}; 953CHANNEL_DECLARE(via8233msgd); 954 955/* -------------------------------------------------------------------- */ 956 957static void 958via_intr(void *p) 959{ 960 struct via_info *via = p; |
961 uint32_t ptrigger = 0, rtrigger = 0; |
|
715 int i, reg, stat; 716 | 962 int i, reg, stat; 963 |
717 /* Poll playback channels */ | |
718 snd_mtxlock(via->lock); | 964 snd_mtxlock(via->lock); |
965 if (via->polling != 0) { 966 snd_mtxunlock(via->lock); 967 return; 968 } 969 /* Poll playback channels */ |
|
719 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { | 970 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { |
720 if (via->pch[i].channel == NULL) | 971 if (via->pch[i].channel == NULL || via->pch[i].active == 0) |
721 continue; 722 reg = via->pch[i].rbase + VIA_RP_STATUS; 723 stat = via_rd(via, reg, 1); 724 if (stat & SGD_STATUS_INTR) { 725 if (via->dma_eol_wake && ((stat & SGD_STATUS_EOL) || | 972 continue; 973 reg = via->pch[i].rbase + VIA_RP_STATUS; 974 stat = via_rd(via, reg, 1); 975 if (stat & SGD_STATUS_INTR) { 976 if (via->dma_eol_wake && ((stat & SGD_STATUS_EOL) || |
726 !(stat & SGD_STATUS_ACTIVE))) { 727 via_wr(via, 728 via->pch[i].rbase + VIA_RP_CONTROL, 729 SGD_CONTROL_START | 730 SGD_CONTROL_AUTOSTART | 731 SGD_CONTROL_I_EOL | 732 SGD_CONTROL_I_FLAG, 1); 733 } | 977 !(stat & SGD_STATUS_ACTIVE))) 978 via_wr(via, via->pch[i].rbase + VIA_RP_CONTROL, 979 SGD_CONTROL_START | SGD_CONTROL_AUTOSTART | 980 SGD_CONTROL_I_EOL | SGD_CONTROL_I_FLAG, 1); |
734 via_wr(via, reg, stat, 1); | 981 via_wr(via, reg, stat, 1); |
735 snd_mtxunlock(via->lock); 736 chn_intr(via->pch[i].channel); 737 snd_mtxlock(via->lock); | 982 ptrigger |= 1 << i; |
738 } 739 } | 983 } 984 } |
740 | |
741 /* Poll record channels */ 742 for (i = 0; i < NWRCHANS; i++) { | 985 /* Poll record channels */ 986 for (i = 0; i < NWRCHANS; i++) { |
743 if (via->rch[i].channel == NULL) | 987 if (via->rch[i].channel == NULL || via->rch[i].active == 0) |
744 continue; 745 reg = via->rch[i].rbase + VIA_RP_STATUS; 746 stat = via_rd(via, reg, 1); 747 if (stat & SGD_STATUS_INTR) { 748 if (via->dma_eol_wake && ((stat & SGD_STATUS_EOL) || | 988 continue; 989 reg = via->rch[i].rbase + VIA_RP_STATUS; 990 stat = via_rd(via, reg, 1); 991 if (stat & SGD_STATUS_INTR) { 992 if (via->dma_eol_wake && ((stat & SGD_STATUS_EOL) || |
749 !(stat & SGD_STATUS_ACTIVE))) { 750 via_wr(via, 751 via->rch[i].rbase + VIA_RP_CONTROL, 752 SGD_CONTROL_START | 753 SGD_CONTROL_AUTOSTART | 754 SGD_CONTROL_I_EOL | 755 SGD_CONTROL_I_FLAG, 1); 756 } | 993 !(stat & SGD_STATUS_ACTIVE))) 994 via_wr(via, via->rch[i].rbase + VIA_RP_CONTROL, 995 SGD_CONTROL_START | SGD_CONTROL_AUTOSTART | 996 SGD_CONTROL_I_EOL | SGD_CONTROL_I_FLAG, 1); |
757 via_wr(via, reg, stat, 1); | 997 via_wr(via, reg, stat, 1); |
758 snd_mtxunlock(via->lock); 759 chn_intr(via->rch[i].channel); 760 snd_mtxlock(via->lock); | 998 rtrigger |= 1 << i; |
761 } 762 } 763 snd_mtxunlock(via->lock); | 999 } 1000 } 1001 snd_mtxunlock(via->lock); |
1002 1003 for (i = 0; i < NDXSCHANS + NMSGDCHANS; i++) { 1004 if (ptrigger & (1 << i)) 1005 chn_intr(via->pch[i].channel); 1006 } 1007 for (i = 0; i < NWRCHANS; i++) { 1008 if (rtrigger & (1 << i)) 1009 chn_intr(via->rch[i].channel); 1010 } |
|
764} 765 766/* 767 * Probe and attach the card 768 */ 769static int 770via_probe(device_t dev) 771{ 772 switch(pci_get_devid(dev)) { 773 case VIA8233_PCI_ID: 774 switch(pci_get_revid(dev)) { | 1011} 1012 1013/* 1014 * Probe and attach the card 1015 */ 1016static int 1017via_probe(device_t dev) 1018{ 1019 switch(pci_get_devid(dev)) { 1020 case VIA8233_PCI_ID: 1021 switch(pci_get_revid(dev)) { |
775 case VIA8233_REV_ID_8233PRE: | 1022 case VIA8233_REV_ID_8233PRE: |
776 device_set_desc(dev, "VIA VT8233 (pre)"); | 1023 device_set_desc(dev, "VIA VT8233 (pre)"); |
777 return BUS_PROBE_DEFAULT; | 1024 return (BUS_PROBE_DEFAULT); |
778 case VIA8233_REV_ID_8233C: 779 device_set_desc(dev, "VIA VT8233C"); | 1025 case VIA8233_REV_ID_8233C: 1026 device_set_desc(dev, "VIA VT8233C"); |
780 return BUS_PROBE_DEFAULT; | 1027 return (BUS_PROBE_DEFAULT); |
781 case VIA8233_REV_ID_8233: 782 device_set_desc(dev, "VIA VT8233"); | 1028 case VIA8233_REV_ID_8233: 1029 device_set_desc(dev, "VIA VT8233"); |
783 return BUS_PROBE_DEFAULT; | 1030 return (BUS_PROBE_DEFAULT); |
784 case VIA8233_REV_ID_8233A: 785 device_set_desc(dev, "VIA VT8233A"); | 1031 case VIA8233_REV_ID_8233A: 1032 device_set_desc(dev, "VIA VT8233A"); |
786 return BUS_PROBE_DEFAULT; | 1033 return (BUS_PROBE_DEFAULT); |
787 case VIA8233_REV_ID_8235: 788 device_set_desc(dev, "VIA VT8235"); | 1034 case VIA8233_REV_ID_8235: 1035 device_set_desc(dev, "VIA VT8235"); |
789 return BUS_PROBE_DEFAULT; | 1036 return (BUS_PROBE_DEFAULT); |
790 case VIA8233_REV_ID_8237: 791 device_set_desc(dev, "VIA VT8237"); | 1037 case VIA8233_REV_ID_8237: 1038 device_set_desc(dev, "VIA VT8237"); |
792 return BUS_PROBE_DEFAULT; | 1039 return (BUS_PROBE_DEFAULT); |
793 case VIA8233_REV_ID_8251: 794 device_set_desc(dev, "VIA VT8251"); | 1040 case VIA8233_REV_ID_8251: 1041 device_set_desc(dev, "VIA VT8251"); |
795 return BUS_PROBE_DEFAULT; | 1042 return (BUS_PROBE_DEFAULT); |
796 default: 797 device_set_desc(dev, "VIA VT8233X"); /* Unknown */ | 1043 default: 1044 device_set_desc(dev, "VIA VT8233X"); /* Unknown */ |
798 return BUS_PROBE_DEFAULT; 799 } | 1045 return (BUS_PROBE_DEFAULT); 1046 } |
800 } | 1047 } |
801 return ENXIO; | 1048 return (ENXIO); |
802} 803 804static void 805dma_cb(void *p, bus_dma_segment_t *bds, int a, int b) 806{ 807 struct via_info *via = (struct via_info *)p; 808 via->sgd_addr = bds->ds_addr; 809} 810 811static int 812via_chip_init(device_t dev) 813{ | 1049} 1050 1051static void 1052dma_cb(void *p, bus_dma_segment_t *bds, int a, int b) 1053{ 1054 struct via_info *via = (struct via_info *)p; 1055 via->sgd_addr = bds->ds_addr; 1056} 1057 1058static int 1059via_chip_init(device_t dev) 1060{ |
814 u_int32_t data, cnt; | 1061 uint32_t data, cnt; |
815 816 /* Wake up and reset AC97 if necessary */ 817 data = pci_read_config(dev, VIA_PCI_ACLINK_STAT, 1); 818 819 if ((data & VIA_PCI_ACLINK_C00_READY) == 0) { 820 /* Cold reset per ac97r2.3 spec (page 95) */ 821 /* Assert low */ | 1062 1063 /* Wake up and reset AC97 if necessary */ 1064 data = pci_read_config(dev, VIA_PCI_ACLINK_STAT, 1); 1065 1066 if ((data & VIA_PCI_ACLINK_C00_READY) == 0) { 1067 /* Cold reset per ac97r2.3 spec (page 95) */ 1068 /* Assert low */ |
822 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 823 VIA_PCI_ACLINK_EN, 1); | 1069 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1070 VIA_PCI_ACLINK_EN, 1); |
824 /* Wait T_rst_low */ | 1071 /* Wait T_rst_low */ |
825 DELAY(100); | 1072 DELAY(100); |
826 /* Assert high */ | 1073 /* Assert high */ |
827 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 828 VIA_PCI_ACLINK_EN | VIA_PCI_ACLINK_NRST, 1); | 1074 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1075 VIA_PCI_ACLINK_EN | VIA_PCI_ACLINK_NRST, 1); |
829 /* Wait T_rst2clk */ 830 DELAY(5); 831 /* Assert low */ | 1076 /* Wait T_rst2clk */ 1077 DELAY(5); 1078 /* Assert low */ |
832 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 833 VIA_PCI_ACLINK_EN, 1); | 1079 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1080 VIA_PCI_ACLINK_EN, 1); |
834 } else { 835 /* Warm reset */ 836 /* Force no sync */ | 1081 } else { 1082 /* Warm reset */ 1083 /* Force no sync */ |
837 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 838 VIA_PCI_ACLINK_EN, 1); | 1084 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1085 VIA_PCI_ACLINK_EN, 1); |
839 DELAY(100); 840 /* Sync */ | 1086 DELAY(100); 1087 /* Sync */ |
841 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 842 VIA_PCI_ACLINK_EN | VIA_PCI_ACLINK_SYNC, 1); | 1088 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1089 VIA_PCI_ACLINK_EN | VIA_PCI_ACLINK_SYNC, 1); |
843 /* Wait T_sync_high */ 844 DELAY(5); 845 /* Force no sync */ | 1090 /* Wait T_sync_high */ 1091 DELAY(5); 1092 /* Force no sync */ |
846 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 847 VIA_PCI_ACLINK_EN, 1); | 1093 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, 1094 VIA_PCI_ACLINK_EN, 1); |
848 /* Wait T_sync2clk */ 849 DELAY(5); 850 } 851 852 /* Power everything up */ 853 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, VIA_PCI_ACLINK_DESIRED, 1); 854 855 /* Wait for codec to become ready (largest reported delay 310ms) */ 856 for (cnt = 0; cnt < 2000; cnt++) { 857 data = pci_read_config(dev, VIA_PCI_ACLINK_STAT, 1); | 1095 /* Wait T_sync2clk */ 1096 DELAY(5); 1097 } 1098 1099 /* Power everything up */ 1100 pci_write_config(dev, VIA_PCI_ACLINK_CTRL, VIA_PCI_ACLINK_DESIRED, 1); 1101 1102 /* Wait for codec to become ready (largest reported delay 310ms) */ 1103 for (cnt = 0; cnt < 2000; cnt++) { 1104 data = pci_read_config(dev, VIA_PCI_ACLINK_STAT, 1); |
858 if (data & VIA_PCI_ACLINK_C00_READY) { 859 return 0; 860 } | 1105 if (data & VIA_PCI_ACLINK_C00_READY) 1106 return (0); |
861 DELAY(5000); 862 } 863 device_printf(dev, "primary codec not ready (cnt = 0x%02x)\n", cnt); | 1107 DELAY(5000); 1108 } 1109 device_printf(dev, "primary codec not ready (cnt = 0x%02x)\n", cnt); |
864 return ENXIO; | 1110 return (ENXIO); |
865} 866 867static int 868via_attach(device_t dev) 869{ 870 struct via_info *via = 0; 871 char status[SND_STATUSLEN]; 872 int i, via_dxs_disabled, via_dxs_src, via_dxs_chnum, via_sgd_chnum; | 1111} 1112 1113static int 1114via_attach(device_t dev) 1115{ 1116 struct via_info *via = 0; 1117 char status[SND_STATUSLEN]; 1118 int i, via_dxs_disabled, via_dxs_src, via_dxs_chnum, via_sgd_chnum; |
1119 int nsegs; |
|
873 uint32_t revid; 874 875 if ((via = malloc(sizeof *via, M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) { 876 device_printf(dev, "cannot allocate softc\n"); | 1120 uint32_t revid; 1121 1122 if ((via = malloc(sizeof *via, M_DEVBUF, M_NOWAIT | M_ZERO)) == NULL) { 1123 device_printf(dev, "cannot allocate softc\n"); |
877 return ENXIO; | 1124 return (ENXIO); |
878 } 879 via->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc"); 880 | 1125 } 1126 via->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc"); 1127 |
1128 callout_init(&via->poll_timer, CALLOUT_MPSAFE); 1129 via->poll_ticks = 1; 1130 1131 if (resource_int_value(device_get_name(dev), 1132 device_get_unit(dev), "polling", &i) == 0 && i != 0) 1133 via->polling = 1; 1134 else 1135 via->polling = 0; 1136 |
|
881 pci_set_powerstate(dev, PCI_POWERSTATE_D0); 882 pci_enable_busmaster(dev); 883 884 via->regid = PCIR_BAR(0); 885 via->reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &via->regid, 886 RF_ACTIVE); 887 if (!via->reg) { 888 device_printf(dev, "cannot allocate bus resource."); 889 goto bad; 890 } 891 via->st = rman_get_bustag(via->reg); 892 via->sh = rman_get_bushandle(via->reg); 893 | 1137 pci_set_powerstate(dev, PCI_POWERSTATE_D0); 1138 pci_enable_busmaster(dev); 1139 1140 via->regid = PCIR_BAR(0); 1141 via->reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &via->regid, 1142 RF_ACTIVE); 1143 if (!via->reg) { 1144 device_printf(dev, "cannot allocate bus resource."); 1145 goto bad; 1146 } 1147 via->st = rman_get_bustag(via->reg); 1148 via->sh = rman_get_bushandle(via->reg); 1149 |
894 via->bufsz = pcm_getbuffersize(dev, 4096, VIA_DEFAULT_BUFSZ, 65536); 895 | |
896 via->irqid = 0; 897 via->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &via->irqid, | 1150 via->irqid = 0; 1151 via->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &via->irqid, |
898 RF_ACTIVE | RF_SHAREABLE); 899 if (!via->irq || 900 snd_setup_intr(dev, via->irq, INTR_MPSAFE, via_intr, via, &via->ih)) { | 1152 RF_ACTIVE | RF_SHAREABLE); 1153 if (!via->irq || 1154 snd_setup_intr(dev, via->irq, INTR_MPSAFE, 1155 via_intr, via, &via->ih)) { |
901 device_printf(dev, "unable to map interrupt\n"); 902 goto bad; 903 } 904 | 1156 device_printf(dev, "unable to map interrupt\n"); 1157 goto bad; 1158 } 1159 |
905 /* DMA tag for buffers */ 906 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 907 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 908 /*highaddr*/BUS_SPACE_MAXADDR, 909 /*filter*/NULL, /*filterarg*/NULL, 910 /*maxsize*/via->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff, 911 /*flags*/0, /*lockfunc*/NULL, 912 /*lockarg*/NULL, &via->parent_dmat) != 0) { 913 device_printf(dev, "unable to create dma tag\n"); 914 goto bad; 915 } | 1160 via->bufsz = pcm_getbuffersize(dev, 4096, VIA_DEFAULT_BUFSZ, 65536); 1161 if (resource_int_value(device_get_name(dev), 1162 device_get_unit(dev), "blocksize", &i) == 0 && i > 0) { 1163 via->blkcnt = via->bufsz / i; 1164 i = 0; 1165 while (via->blkcnt >> i) 1166 i++; 1167 via->blkcnt = 1 << (i - 1); 1168 if (via->blkcnt < VIA_SEGS_MIN) 1169 via->blkcnt = VIA_SEGS_MIN; 1170 else if (via->blkcnt > VIA_SEGS_MAX) 1171 via->blkcnt = VIA_SEGS_MAX; |
916 | 1172 |
917 /* 918 * DMA tag for SGD table. The 686 uses scatter/gather DMA and 919 * requires a list in memory of work to do. We need only 16 bytes 920 * for this list, and it is wasteful to allocate 16K. 921 */ 922 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 923 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 924 /*highaddr*/BUS_SPACE_MAXADDR, 925 /*filter*/NULL, /*filterarg*/NULL, 926 /*maxsize*/NSEGS * sizeof(struct via_dma_op), 927 /*nsegments*/1, /*maxsegz*/0x3ffff, 928 /*flags*/0, /*lockfunc*/NULL, 929 /*lockarg*/NULL, &via->sgd_dmat) != 0) { 930 device_printf(dev, "unable to create dma tag\n"); 931 goto bad; 932 } | 1173 } else 1174 via->blkcnt = VIA_SEGS_DEFAULT; |
933 | 1175 |
934 if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table, 935 BUS_DMA_NOWAIT, &via->sgd_dmamap) == -1) 936 goto bad; 937 if (bus_dmamap_load(via->sgd_dmat, via->sgd_dmamap, via->sgd_table, 938 NSEGS * sizeof(struct via_dma_op), dma_cb, via, 0)) 939 goto bad; 940 941 if (via_chip_init(dev)) 942 goto bad; 943 944 via->codec = AC97_CREATE(dev, via, via_ac97); 945 if (!via->codec) 946 goto bad; 947 948 mixer_init(dev, ac97_getmixerclass(), via->codec); 949 950 via->codec_caps = ac97_getextcaps(via->codec); 951 952 /* Try to set VRA without generating an error, VRM not reqrd yet */ 953 if (via->codec_caps & 954 (AC97_EXTCAP_VRA | AC97_EXTCAP_VRM | AC97_EXTCAP_DRA)) { 955 u_int16_t ext = ac97_getextmode(via->codec); 956 ext |= (via->codec_caps & 957 (AC97_EXTCAP_VRA | AC97_EXTCAP_VRM)); 958 ext &= ~AC97_EXTCAP_DRA; 959 ac97_setextmode(via->codec, ext); 960 } 961 962 snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld %s", 963 rman_get_start(via->reg), rman_get_start(via->irq),PCM_KLDSTRING(snd_via8233)); 964 | |
965 revid = pci_get_revid(dev); 966 967 /* 968 * VIA8251 lost its interrupt after DMA EOL, and need 969 * a gentle spank on its face within interrupt handler. 970 */ 971 if (revid == VIA8233_REV_ID_8251) 972 via->dma_eol_wake = 1; --- 7 unchanged lines hidden (view full) --- 980 /* 981 * DXS channel is disabled. Reports from multiple users 982 * that it plays at half-speed. Do not see this behaviour 983 * on available 8233C or when emulating 8233A register set 984 * on 8233C (either with or without ac97 VRA). 985 */ 986 via_dxs_disabled = 1; 987 } else if (resource_int_value(device_get_name(dev), | 1176 revid = pci_get_revid(dev); 1177 1178 /* 1179 * VIA8251 lost its interrupt after DMA EOL, and need 1180 * a gentle spank on its face within interrupt handler. 1181 */ 1182 if (revid == VIA8233_REV_ID_8251) 1183 via->dma_eol_wake = 1; --- 7 unchanged lines hidden (view full) --- 1191 /* 1192 * DXS channel is disabled. Reports from multiple users 1193 * that it plays at half-speed. Do not see this behaviour 1194 * on available 8233C or when emulating 8233A register set 1195 * on 8233C (either with or without ac97 VRA). 1196 */ 1197 via_dxs_disabled = 1; 1198 } else if (resource_int_value(device_get_name(dev), |
988 device_get_unit(dev), "via_dxs_disabled", 989 &via_dxs_disabled) == 0) | 1199 device_get_unit(dev), "via_dxs_disabled", 1200 &via_dxs_disabled) == 0) |
990 via_dxs_disabled = (via_dxs_disabled > 0) ? 1 : 0; 991 else 992 via_dxs_disabled = 0; 993 994 if (via_dxs_disabled) { 995 via_dxs_chnum = 0; 996 via_sgd_chnum = 1; 997 } else { 998 if (resource_int_value(device_get_name(dev), | 1201 via_dxs_disabled = (via_dxs_disabled > 0) ? 1 : 0; 1202 else 1203 via_dxs_disabled = 0; 1204 1205 if (via_dxs_disabled) { 1206 via_dxs_chnum = 0; 1207 via_sgd_chnum = 1; 1208 } else { 1209 if (resource_int_value(device_get_name(dev), |
999 device_get_unit(dev), "via_dxs_channels", 1000 &via_dxs_chnum) != 0) | 1210 device_get_unit(dev), "via_dxs_channels", 1211 &via_dxs_chnum) != 0) |
1001 via_dxs_chnum = NDXSCHANS; 1002 if (resource_int_value(device_get_name(dev), | 1212 via_dxs_chnum = NDXSCHANS; 1213 if (resource_int_value(device_get_name(dev), |
1003 device_get_unit(dev), "via_sgd_channels", 1004 &via_sgd_chnum) != 0) | 1214 device_get_unit(dev), "via_sgd_channels", 1215 &via_sgd_chnum) != 0) |
1005 via_sgd_chnum = NMSGDCHANS; 1006 } 1007 if (via_dxs_chnum > NDXSCHANS) 1008 via_dxs_chnum = NDXSCHANS; 1009 else if (via_dxs_chnum < 0) 1010 via_dxs_chnum = 0; 1011 if (via_sgd_chnum > NMSGDCHANS) 1012 via_sgd_chnum = NMSGDCHANS; 1013 else if (via_sgd_chnum < 0) 1014 via_sgd_chnum = 0; 1015 if (via_dxs_chnum + via_sgd_chnum < 1) { 1016 /* Minimalist ? */ 1017 via_dxs_chnum = 1; 1018 via_sgd_chnum = 0; 1019 } 1020 if (via_dxs_chnum > 0 && resource_int_value(device_get_name(dev), | 1216 via_sgd_chnum = NMSGDCHANS; 1217 } 1218 if (via_dxs_chnum > NDXSCHANS) 1219 via_dxs_chnum = NDXSCHANS; 1220 else if (via_dxs_chnum < 0) 1221 via_dxs_chnum = 0; 1222 if (via_sgd_chnum > NMSGDCHANS) 1223 via_sgd_chnum = NMSGDCHANS; 1224 else if (via_sgd_chnum < 0) 1225 via_sgd_chnum = 0; 1226 if (via_dxs_chnum + via_sgd_chnum < 1) { 1227 /* Minimalist ? */ 1228 via_dxs_chnum = 1; 1229 via_sgd_chnum = 0; 1230 } 1231 if (via_dxs_chnum > 0 && resource_int_value(device_get_name(dev), |
1021 device_get_unit(dev), "via_dxs_src", 1022 &via_dxs_src) == 0) | 1232 device_get_unit(dev), "via_dxs_src", &via_dxs_src) == 0) |
1023 via->dxs_src = (via_dxs_src > 0) ? 1 : 0; 1024 else 1025 via->dxs_src = 0; | 1233 via->dxs_src = (via_dxs_src > 0) ? 1 : 0; 1234 else 1235 via->dxs_src = 0; |
1236 1237 nsegs = (via_dxs_chnum + via_sgd_chnum) * via->blkcnt; 1238 1239 /* DMA tag for buffers */ 1240 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 1241 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 1242 /*highaddr*/BUS_SPACE_MAXADDR, 1243 /*filter*/NULL, /*filterarg*/NULL, 1244 /*maxsize*/via->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff, 1245 /*flags*/0, /*lockfunc*/NULL, 1246 /*lockarg*/NULL, &via->parent_dmat) != 0) { 1247 device_printf(dev, "unable to create dma tag\n"); 1248 goto bad; 1249 } 1250 1251 /* 1252 * DMA tag for SGD table. The 686 uses scatter/gather DMA and 1253 * requires a list in memory of work to do. We need only 16 bytes 1254 * for this list, and it is wasteful to allocate 16K. 1255 */ 1256 if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/2, /*boundary*/0, 1257 /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, 1258 /*highaddr*/BUS_SPACE_MAXADDR, 1259 /*filter*/NULL, /*filterarg*/NULL, 1260 /*maxsize*/nsegs * sizeof(struct via_dma_op), 1261 /*nsegments*/1, /*maxsegz*/0x3ffff, 1262 /*flags*/0, /*lockfunc*/NULL, 1263 /*lockarg*/NULL, &via->sgd_dmat) != 0) { 1264 device_printf(dev, "unable to create dma tag\n"); 1265 goto bad; 1266 } 1267 1268 if (bus_dmamem_alloc(via->sgd_dmat, (void **)&via->sgd_table, 1269 BUS_DMA_NOWAIT, &via->sgd_dmamap) == -1) 1270 goto bad; 1271 if (bus_dmamap_load(via->sgd_dmat, via->sgd_dmamap, via->sgd_table, 1272 nsegs * sizeof(struct via_dma_op), dma_cb, via, 0)) 1273 goto bad; 1274 1275 if (via_chip_init(dev)) 1276 goto bad; 1277 1278 via->codec = AC97_CREATE(dev, via, via_ac97); 1279 if (!via->codec) 1280 goto bad; 1281 1282 mixer_init(dev, ac97_getmixerclass(), via->codec); 1283 1284 via->codec_caps = ac97_getextcaps(via->codec); 1285 1286 /* Try to set VRA without generating an error, VRM not reqrd yet */ 1287 if (via->codec_caps & 1288 (AC97_EXTCAP_VRA | AC97_EXTCAP_VRM | AC97_EXTCAP_DRA)) { 1289 uint16_t ext = ac97_getextmode(via->codec); 1290 ext |= (via->codec_caps & 1291 (AC97_EXTCAP_VRA | AC97_EXTCAP_VRM)); 1292 ext &= ~AC97_EXTCAP_DRA; 1293 ac97_setextmode(via->codec, ext); 1294 } 1295 1296 snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld %s", 1297 rman_get_start(via->reg), rman_get_start(via->irq), 1298 PCM_KLDSTRING(snd_via8233)); 1299 |
|
1026 /* Register */ 1027 if (pcm_register(dev, via, via_dxs_chnum + via_sgd_chnum, NWRCHANS)) 1028 goto bad; 1029 for (i = 0; i < via_dxs_chnum; i++) 1030 pcm_addchan(dev, PCMDIR_PLAY, &via8233dxs_class, via); 1031 for (i = 0; i < via_sgd_chnum; i++) 1032 pcm_addchan(dev, PCMDIR_PLAY, &via8233msgd_class, via); 1033 for (i = 0; i < NWRCHANS; i++) 1034 pcm_addchan(dev, PCMDIR_REC, &via8233wr_class, via); 1035 if (via_dxs_chnum > 0) 1036 via_init_sysctls(dev); 1037 device_printf(dev, "<VIA DXS %sabled: DXS%s %d / SGD %d / REC %d>\n", | 1300 /* Register */ 1301 if (pcm_register(dev, via, via_dxs_chnum + via_sgd_chnum, NWRCHANS)) 1302 goto bad; 1303 for (i = 0; i < via_dxs_chnum; i++) 1304 pcm_addchan(dev, PCMDIR_PLAY, &via8233dxs_class, via); 1305 for (i = 0; i < via_sgd_chnum; i++) 1306 pcm_addchan(dev, PCMDIR_PLAY, &via8233msgd_class, via); 1307 for (i = 0; i < NWRCHANS; i++) 1308 pcm_addchan(dev, PCMDIR_REC, &via8233wr_class, via); 1309 if (via_dxs_chnum > 0) 1310 via_init_sysctls(dev); 1311 device_printf(dev, "<VIA DXS %sabled: DXS%s %d / SGD %d / REC %d>\n", |
1038 (via_dxs_chnum > 0) ? "En" : "Dis", 1039 (via->dxs_src) ? "(SRC)" : "", 1040 via_dxs_chnum, via_sgd_chnum, NWRCHANS); | 1312 (via_dxs_chnum > 0) ? "En" : "Dis", (via->dxs_src) ? "(SRC)" : "", 1313 via_dxs_chnum, via_sgd_chnum, NWRCHANS); |
1041 1042 pcm_setstatus(dev, status); 1043 | 1314 1315 pcm_setstatus(dev, status); 1316 |
1044 return 0; | 1317 return (0); |
1045bad: | 1318bad: |
1046 if (via->codec) ac97_destroy(via->codec); 1047 if (via->reg) bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); 1048 if (via->ih) bus_teardown_intr(dev, via->irq, via->ih); 1049 if (via->irq) bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); 1050 if (via->parent_dmat) bus_dma_tag_destroy(via->parent_dmat); 1051 if (via->sgd_dmamap) bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); 1052 if (via->sgd_dmat) bus_dma_tag_destroy(via->sgd_dmat); 1053 if (via->lock) snd_mtxfree(via->lock); 1054 if (via) free(via, M_DEVBUF); 1055 return ENXIO; | 1319 if (via->codec) 1320 ac97_destroy(via->codec); 1321 if (via->reg) 1322 bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); 1323 if (via->ih) 1324 bus_teardown_intr(dev, via->irq, via->ih); 1325 if (via->irq) 1326 bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); 1327 if (via->parent_dmat) 1328 bus_dma_tag_destroy(via->parent_dmat); 1329 if (via->sgd_dmamap) 1330 bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); 1331 if (via->sgd_dmat) 1332 bus_dma_tag_destroy(via->sgd_dmat); 1333 if (via->lock) 1334 snd_mtxfree(via->lock); 1335 if (via) 1336 free(via, M_DEVBUF); 1337 return (ENXIO); |
1056} 1057 1058static int 1059via_detach(device_t dev) 1060{ 1061 int r; 1062 struct via_info *via = 0; 1063 1064 r = pcm_unregister(dev); | 1338} 1339 1340static int 1341via_detach(device_t dev) 1342{ 1343 int r; 1344 struct via_info *via = 0; 1345 1346 r = pcm_unregister(dev); |
1065 if (r) return r; | 1347 if (r) 1348 return (r); |
1066 1067 via = pcm_getdevinfo(dev); 1068 bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); 1069 bus_teardown_intr(dev, via->irq, via->ih); 1070 bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); 1071 bus_dma_tag_destroy(via->parent_dmat); 1072 bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); 1073 bus_dma_tag_destroy(via->sgd_dmat); 1074 snd_mtxfree(via->lock); 1075 free(via, M_DEVBUF); | 1349 1350 via = pcm_getdevinfo(dev); 1351 bus_release_resource(dev, SYS_RES_IOPORT, via->regid, via->reg); 1352 bus_teardown_intr(dev, via->irq, via->ih); 1353 bus_release_resource(dev, SYS_RES_IRQ, via->irqid, via->irq); 1354 bus_dma_tag_destroy(via->parent_dmat); 1355 bus_dmamap_unload(via->sgd_dmat, via->sgd_dmamap); 1356 bus_dma_tag_destroy(via->sgd_dmat); 1357 snd_mtxfree(via->lock); 1358 free(via, M_DEVBUF); |
1076 return 0; | 1359 return (0); |
1077} 1078 1079 1080static device_method_t via_methods[] = { 1081 DEVMETHOD(device_probe, via_probe), 1082 DEVMETHOD(device_attach, via_attach), 1083 DEVMETHOD(device_detach, via_detach), 1084 { 0, 0} 1085}; 1086 1087static driver_t via_driver = { 1088 "pcm", 1089 via_methods, 1090 PCM_SOFTC_SIZE, 1091}; 1092 1093DRIVER_MODULE(snd_via8233, pci, via_driver, pcm_devclass, 0, 0); 1094MODULE_DEPEND(snd_via8233, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 1095MODULE_VERSION(snd_via8233, 1); | 1360} 1361 1362 1363static device_method_t via_methods[] = { 1364 DEVMETHOD(device_probe, via_probe), 1365 DEVMETHOD(device_attach, via_attach), 1366 DEVMETHOD(device_detach, via_detach), 1367 { 0, 0} 1368}; 1369 1370static driver_t via_driver = { 1371 "pcm", 1372 via_methods, 1373 PCM_SOFTC_SIZE, 1374}; 1375 1376DRIVER_MODULE(snd_via8233, pci, via_driver, pcm_devclass, 0, 0); 1377MODULE_DEPEND(snd_via8233, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER); 1378MODULE_VERSION(snd_via8233, 1); |