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);