Bug Summary

File:dev/pci/yds.c
Warning:line 402, column 2
Value stored to 'ecs' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name yds.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -target-feature +retpoline-external-thunk -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D SUSPEND -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/dev/pci/yds.c
1/* $OpenBSD: yds.c,v 1.63 2022/10/26 20:19:08 kn Exp $ */
2/* $NetBSD: yds.c,v 1.5 2001/05/21 23:55:04 minoura Exp $ */
3
4/*
5 * Copyright (c) 2000, 2001 Kazuki Sakamoto and Minoura Makoto.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * Yamaha YMF724[B-F]/740[B-C]/744/754
31 *
32 * Documentation links:
33 * - ftp://ftp.alsa-project.org/pub/manuals/yamaha/
34 * - ftp://ftp.alsa-project.org/pub/manuals/yamaha/pci/
35 *
36 * TODO:
37 * - FM synth volume (difficult: mixed before ac97)
38 * - Digital in/out (SPDIF) support
39 * - Effect??
40 */
41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/kernel.h>
45#include <sys/fcntl.h>
46#include <sys/malloc.h>
47#include <sys/device.h>
48#include <sys/queue.h>
49
50#include <dev/pci/pcidevs.h>
51#include <dev/pci/pcireg.h>
52#include <dev/pci/pcivar.h>
53
54#include <sys/audioio.h>
55#include <dev/audio_if.h>
56#include <dev/midi_if.h>
57#include <dev/ic/ac97.h>
58
59#include <machine/bus.h>
60#include <machine/intr.h>
61
62#include <dev/pci/ydsreg.h>
63#include <dev/pci/ydsvar.h>
64
65/* Debug */
66#undef YDS_USE_REC_SLOT
67#define YDS_USE_P44
68
69#ifdef AUDIO_DEBUG
70# define DPRINTF(x) if (ydsdebug) printf x
71# define DPRINTFN(n,x) if (ydsdebug>(n)) printf x
72int ydsdebug = 0;
73#else
74# define DPRINTF(x)
75# define DPRINTFN(n,x)
76#endif
77#ifdef YDS_USE_REC_SLOT
78# define YDS_INPUT_SLOT1 0 /* REC slot = ADC + loopbacks */
79#else
80# define YDS_INPUT_SLOT1 1 /* ADC slot */
81#endif
82
83static int ac97_id2;
84
85int yds_match(struct device *, void *, void *);
86void yds_attach(struct device *, struct device *, void *);
87int yds_activate(struct device *, int);
88int yds_intr(void *);
89
90static void nswaph(u_int32_t *p, int wcount);
91
92#define DMAADDR(p)((p)->map->dm_segs[0].ds_addr) ((p)->map->dm_segs[0].ds_addr)
93#define KERNADDR(p)((void *)((p)->addr)) ((void *)((p)->addr))
94
95int yds_allocmem(struct yds_softc *, size_t, size_t,
96 struct yds_dma *);
97int yds_freemem(struct yds_softc *, struct yds_dma *);
98
99#ifndef AUDIO_DEBUG
100#define YWRITE1(sc, r, x)(((sc)->memt)->write_1(((sc)->memh), ((r)), ((x)))) bus_space_write_1((sc)->memt, (sc)->memh, (r), (x))(((sc)->memt)->write_1(((sc)->memh), ((r)), ((x))))
101#define YWRITE2(sc, r, x)(((sc)->memt)->write_2(((sc)->memh), ((r)), ((x)))) bus_space_write_2((sc)->memt, (sc)->memh, (r), (x))(((sc)->memt)->write_2(((sc)->memh), ((r)), ((x))))
102#define YWRITE4(sc, r, x)(((sc)->memt)->write_4(((sc)->memh), ((r)), ((x)))) bus_space_write_4((sc)->memt, (sc)->memh, (r), (x))(((sc)->memt)->write_4(((sc)->memh), ((r)), ((x))))
103#define YREAD1(sc, r)(((sc)->memt)->read_1(((sc)->memh), ((r)))) bus_space_read_1((sc)->memt, (sc)->memh, (r))(((sc)->memt)->read_1(((sc)->memh), ((r))))
104#define YREAD2(sc, r)(((sc)->memt)->read_2(((sc)->memh), ((r)))) bus_space_read_2((sc)->memt, (sc)->memh, (r))(((sc)->memt)->read_2(((sc)->memh), ((r))))
105#define YREAD4(sc, r)(((sc)->memt)->read_4(((sc)->memh), ((r)))) bus_space_read_4((sc)->memt, (sc)->memh, (r))(((sc)->memt)->read_4(((sc)->memh), ((r))))
106#else
107
108u_int16_t YREAD2(struct yds_softc *sc,bus_size_t r)(((struct yds_softc *sc)->memt)->read_2(((struct yds_softc
*sc)->memh), ((bus_size_t r))))
;
109u_int32_t YREAD4(struct yds_softc *sc,bus_size_t r)(((struct yds_softc *sc)->memt)->read_4(((struct yds_softc
*sc)->memh), ((bus_size_t r))))
;
110void YWRITE1(struct yds_softc *sc,bus_size_t r,u_int8_t x)(((struct yds_softc *sc)->memt)->write_1(((struct yds_softc
*sc)->memh), ((bus_size_t r)), ((u_int8_t x))))
;
111void YWRITE2(struct yds_softc *sc,bus_size_t r,u_int16_t x)(((struct yds_softc *sc)->memt)->write_2(((struct yds_softc
*sc)->memh), ((bus_size_t r)), ((u_int16_t x))))
;
112void YWRITE4(struct yds_softc *sc,bus_size_t r,u_int32_t x)(((struct yds_softc *sc)->memt)->write_4(((struct yds_softc
*sc)->memh), ((bus_size_t r)), ((u_int32_t x))))
;
113
114u_int16_t YREAD2(struct yds_softc *sc,bus_size_t r)(((struct yds_softc *sc)->memt)->read_2(((struct yds_softc
*sc)->memh), ((bus_size_t r))))
115{
116 DPRINTFN(5, (" YREAD2(0x%lX)\n",(unsigned long)r));
117 return bus_space_read_2(sc->memt,sc->memh,r)((sc->memt)->read_2((sc->memh), (r)));
118}
119u_int32_t YREAD4(struct yds_softc *sc,bus_size_t r)(((struct yds_softc *sc)->memt)->read_4(((struct yds_softc
*sc)->memh), ((bus_size_t r))))
120{
121 DPRINTFN(5, (" YREAD4(0x%lX)\n",(unsigned long)r));
122 return bus_space_read_4(sc->memt,sc->memh,r)((sc->memt)->read_4((sc->memh), (r)));
123}
124void YWRITE1(struct yds_softc *sc,bus_size_t r,u_int8_t x)(((struct yds_softc *sc)->memt)->write_1(((struct yds_softc
*sc)->memh), ((bus_size_t r)), ((u_int8_t x))))
125{
126 DPRINTFN(5, (" YWRITE1(0x%lX,0x%lX)\n",(unsigned long)r,(unsigned long)x));
127 bus_space_write_1(sc->memt,sc->memh,r,x)((sc->memt)->write_1((sc->memh), (r), (x)));
128}
129void YWRITE2(struct yds_softc *sc,bus_size_t r,u_int16_t x)(((struct yds_softc *sc)->memt)->write_2(((struct yds_softc
*sc)->memh), ((bus_size_t r)), ((u_int16_t x))))
130{
131 DPRINTFN(5, (" YWRITE2(0x%lX,0x%lX)\n",(unsigned long)r,(unsigned long)x));
132 bus_space_write_2(sc->memt,sc->memh,r,x)((sc->memt)->write_2((sc->memh), (r), (x)));
133}
134void YWRITE4(struct yds_softc *sc,bus_size_t r,u_int32_t x)(((struct yds_softc *sc)->memt)->write_4(((struct yds_softc
*sc)->memh), ((bus_size_t r)), ((u_int32_t x))))
135{
136 DPRINTFN(5, (" YWRITE4(0x%lX,0x%lX)\n",(unsigned long)r,(unsigned long)x));
137 bus_space_write_4(sc->memt,sc->memh,r,x)((sc->memt)->write_4((sc->memh), (r), (x)));
138}
139#endif
140
141#define YWRITEREGION4(sc, r, x, c)(((sc)->memt)->write_region_4(((sc)->memh), ((r)), (
(x)), ((c) / 4)))
\
142 bus_space_write_region_4((sc)->memt, (sc)->memh, (r), (x), (c) / 4)(((sc)->memt)->write_region_4(((sc)->memh), ((r)), (
(x)), ((c) / 4)))
143
144const struct cfattach yds_ca = {
145 sizeof(struct yds_softc), yds_match, yds_attach, NULL((void *)0),
146 yds_activate
147};
148
149struct cfdriver yds_cd = {
150 NULL((void *)0), "yds", DV_DULL
151};
152
153int yds_open(void *, int);
154void yds_close(void *);
155int yds_set_params(void *, int, int,
156 struct audio_params *, struct audio_params *);
157int yds_round_blocksize(void *, int);
158int yds_trigger_output(void *, void *, void *, int, void (*)(void *),
159 void *, struct audio_params *);
160int yds_trigger_input(void *, void *, void *, int, void (*)(void *),
161 void *, struct audio_params *);
162int yds_halt_output(void *);
163int yds_halt_input(void *);
164int yds_mixer_set_port(void *, mixer_ctrl_t *);
165int yds_mixer_get_port(void *, mixer_ctrl_t *);
166void *yds_malloc(void *, int, size_t, int, int);
167void yds_free(void *, void *, int);
168size_t yds_round_buffersize(void *, int, size_t);
169int yds_query_devinfo(void *addr, mixer_devinfo_t *dip);
170
171int yds_attach_codec(void *sc, struct ac97_codec_if *);
172int yds_read_codec(void *sc, u_int8_t a, u_int16_t *d);
173int yds_write_codec(void *sc, u_int8_t a, u_int16_t d);
174void yds_reset_codec(void *sc);
175int yds_get_portnum_by_name(struct yds_softc *, char *, char *,
176 char *);
177
178static u_int yds_get_dstype(int);
179static int yds_download_mcode(struct yds_softc *);
180static int yds_allocate_slots(struct yds_softc *, int);
181static void yds_configure_legacy(struct yds_softc *arg);
182static void yds_enable_dsp(struct yds_softc *);
183static int yds_disable_dsp(struct yds_softc *);
184static int yds_ready_codec(struct yds_codec_softc *);
185static int yds_halt(struct yds_softc *);
186static u_int32_t yds_get_lpfq(u_int);
187static u_int32_t yds_get_lpfk(u_int);
188static struct yds_dma *yds_find_dma(struct yds_softc *, void *);
189
190int yds_init(struct yds_softc *, int);
191void yds_attachhook(struct device *);
192
193#ifdef AUDIO_DEBUG
194static void yds_dump_play_slot(struct yds_softc *, int);
195#define YDS_DUMP_PLAY_SLOT(n,sc,bank) \
196 if (ydsdebug > (n)) yds_dump_play_slot(sc, bank)
197#else
198#define YDS_DUMP_PLAY_SLOT(n,sc,bank)
199#endif /* AUDIO_DEBUG */
200
201static const struct audio_hw_if yds_hw_if = {
202 .open = yds_open,
203 .close = yds_close,
204 .set_params = yds_set_params,
205 .round_blocksize = yds_round_blocksize,
206 .halt_output = yds_halt_output,
207 .halt_input = yds_halt_input,
208 .set_port = yds_mixer_set_port,
209 .get_port = yds_mixer_get_port,
210 .query_devinfo = yds_query_devinfo,
211 .allocm = yds_malloc,
212 .freem = yds_free,
213 .round_buffersize = yds_round_buffersize,
214 .trigger_output = yds_trigger_output,
215 .trigger_input = yds_trigger_input,
216};
217
218static const struct {
219 u_int id;
220 u_int flags;
221#define YDS_CAP_MCODE_10x0001 0x0001
222#define YDS_CAP_MCODE_1E0x0002 0x0002
223#define YDS_CAP_LEGACY_SELECTABLE0x0004 0x0004
224#define YDS_CAP_LEGACY_FLEXIBLE0x0008 0x0008
225#define YDS_CAP_HAS_P440x0010 0x0010
226#define YDS_CAP_LEGACY_SMOD_DISABLE0x1000 0x1000
227} yds_chip_capability_list[] = {
228 { PCI_PRODUCT_YAMAHA_YMF7240x0004,
229 YDS_CAP_MCODE_10x0001|YDS_CAP_LEGACY_SELECTABLE0x0004 },
230 /* 740[C] has only 32 slots. But anyway we use only 2 */
231 { PCI_PRODUCT_YAMAHA_YMF7400x000a,
232 YDS_CAP_MCODE_10x0001|YDS_CAP_LEGACY_SELECTABLE0x0004 }, /* XXX NOT TESTED */
233 { PCI_PRODUCT_YAMAHA_YMF740C0x000c,
234 YDS_CAP_MCODE_1E0x0002|YDS_CAP_LEGACY_SELECTABLE0x0004 },
235 { PCI_PRODUCT_YAMAHA_YMF724F0x000d,
236 YDS_CAP_MCODE_1E0x0002|YDS_CAP_LEGACY_SELECTABLE0x0004 },
237 { PCI_PRODUCT_YAMAHA_YMF7440x0010,
238 YDS_CAP_MCODE_1E0x0002|YDS_CAP_LEGACY_FLEXIBLE0x0008 },
239 { PCI_PRODUCT_YAMAHA_YMF7540x0012,
240 YDS_CAP_MCODE_1E0x0002|YDS_CAP_LEGACY_FLEXIBLE0x0008|YDS_CAP_HAS_P440x0010 },
241 /* How about 734/737/738?? */
242 { 0, 0 }
243};
244#ifdef AUDIO_DEBUG
245#define YDS_CAP_BITS "\020\005P44\004LEGFLEX\003LEGSEL\002MCODE1E\001MCODE1"
246#endif
247
248#ifdef AUDIO_DEBUG
249static void
250yds_dump_play_slot(struct yds_softc *sc, int bank)
251{
252 int i, j;
253 u_int32_t *p;
254 u_int32_t num;
255 struct yds_dma *dma;
256
257 for (i = 0; i < N_PLAY_SLOTS2; i++) {
258 printf("pbankp[%d] = %p,", i*2, sc->pbankp[i*2]);
259 printf("pbankp[%d] = %p\n", i*2+1, sc->pbankp[i*2+1]);
260 }
261
262 p = (u_int32_t*)sc->ptbl;
263 for (i = 0; i < N_PLAY_SLOTS2+1; i++) {
264 printf("ptbl + %d:0x%x\n", i, *p);
265 p++;
266 }
267
268 num = *(u_int32_t*)sc->ptbl;
269 printf("num = %d\n", num);
270
271 for (i = 0; i < num; i++) {
272
273 p = (u_int32_t *)sc->pbankp[i];
274
275 dma = yds_find_dma(sc,(void *)p);
276
277 for (j = 0; j < sizeof(struct play_slot_ctrl_bank) /
278 sizeof(u_int32_t); j++) {
279 printf(" 0x%02x: 0x%08x\n",
280 (unsigned) (j * sizeof(u_int32_t)),
281 (unsigned) *p++);
282 }
283 /*
284 p = (u_int32_t *)sc->pbankp[i*2 + 1];
285 printf(" pbankp[%d] : %p\n", i*2 + 1, p);
286 for (j = 0; j < sizeof(struct play_slot_ctrl_bank) /
287 sizeof(u_int32_t); j++) {
288 printf(" 0x%02x: 0x%08x\n",
289 j * sizeof(u_int32_t), *p++);
290 delay(1);
291 }
292 */
293 }
294}
295#endif /* AUDIO_DEBUG */
296
297static u_int
298yds_get_dstype(int id)
299{
300 int i;
301
302 for (i = 0; yds_chip_capability_list[i].id; i++) {
303 if (PCI_PRODUCT(id)(((id) >> 16) & 0xffff) == yds_chip_capability_list[i].id)
304 return yds_chip_capability_list[i].flags;
305 }
306
307 return -1;
308}
309
310static void
311nswaph(u_int32_t *p, int wcount)
312{
313 for (; wcount; wcount -=4) {
314 *p = ntohl(*p)(__uint32_t)(__builtin_constant_p(*p) ? (__uint32_t)(((__uint32_t
)(*p) & 0xff) << 24 | ((__uint32_t)(*p) & 0xff00
) << 8 | ((__uint32_t)(*p) & 0xff0000) >> 8 |
((__uint32_t)(*p) & 0xff000000) >> 24) : __swap32md
(*p))
;
315 p++;
316 }
317}
318
319static int
320yds_download_mcode(struct yds_softc *sc)
321{
322 u_int ctrl;
323 const u_int32_t *p;
324 size_t size;
325 u_char *buf;
326 size_t buflen;
327 int error;
328 struct yds_firmware *yf;
329
330 error = loadfirmware("yds", &buf, &buflen);
331 if (error)
332 return 1;
333 yf = (struct yds_firmware *)buf;
334
335 if (sc->sc_flags & YDS_CAP_MCODE_10x0001) {
336 p = (u_int32_t *)&yf->data[ntohl(yf->dsplen)(__uint32_t)(__builtin_constant_p(yf->dsplen) ? (__uint32_t
)(((__uint32_t)(yf->dsplen) & 0xff) << 24 | ((__uint32_t
)(yf->dsplen) & 0xff00) << 8 | ((__uint32_t)(yf->
dsplen) & 0xff0000) >> 8 | ((__uint32_t)(yf->dsplen
) & 0xff000000) >> 24) : __swap32md(yf->dsplen))
];
337 size = ntohl(yf->ds1len)(__uint32_t)(__builtin_constant_p(yf->ds1len) ? (__uint32_t
)(((__uint32_t)(yf->ds1len) & 0xff) << 24 | ((__uint32_t
)(yf->ds1len) & 0xff00) << 8 | ((__uint32_t)(yf->
ds1len) & 0xff0000) >> 8 | ((__uint32_t)(yf->ds1len
) & 0xff000000) >> 24) : __swap32md(yf->ds1len))
;
338 } else if (sc->sc_flags & YDS_CAP_MCODE_1E0x0002) {
339 p = (u_int32_t *)&yf->data[ntohl(yf->dsplen)(__uint32_t)(__builtin_constant_p(yf->dsplen) ? (__uint32_t
)(((__uint32_t)(yf->dsplen) & 0xff) << 24 | ((__uint32_t
)(yf->dsplen) & 0xff00) << 8 | ((__uint32_t)(yf->
dsplen) & 0xff0000) >> 8 | ((__uint32_t)(yf->dsplen
) & 0xff000000) >> 24) : __swap32md(yf->dsplen))
+ ntohl(yf->ds1len)(__uint32_t)(__builtin_constant_p(yf->ds1len) ? (__uint32_t
)(((__uint32_t)(yf->ds1len) & 0xff) << 24 | ((__uint32_t
)(yf->ds1len) & 0xff00) << 8 | ((__uint32_t)(yf->
ds1len) & 0xff0000) >> 8 | ((__uint32_t)(yf->ds1len
) & 0xff000000) >> 24) : __swap32md(yf->ds1len))
];
340 size = ntohl(yf->ds1elen)(__uint32_t)(__builtin_constant_p(yf->ds1elen) ? (__uint32_t
)(((__uint32_t)(yf->ds1elen) & 0xff) << 24 | ((__uint32_t
)(yf->ds1elen) & 0xff00) << 8 | ((__uint32_t)(yf
->ds1elen) & 0xff0000) >> 8 | ((__uint32_t)(yf->
ds1elen) & 0xff000000) >> 24) : __swap32md(yf->ds1elen
))
;
341 } else {
342 free(buf, M_DEVBUF2, buflen);
343 return 1; /* unknown */
344 }
345
346 if (size > buflen) {
347 printf("%s: old firmware file, update please\n",
348 sc->sc_dev.dv_xname);
349 free(buf, M_DEVBUF2, buflen);
350 return 1;
351 }
352
353 if (yds_disable_dsp(sc)) {
354 free(buf, M_DEVBUF2, buflen);
355 return 1;
356 }
357
358 /* Software reset */
359 YWRITE4(sc, YDS_MODE, YDS_MODE_RESET)(((sc)->memt)->write_4(((sc)->memh), ((0x0108)), ((0x00010000
))))
;
360 YWRITE4(sc, YDS_MODE, 0)(((sc)->memt)->write_4(((sc)->memh), ((0x0108)), ((0
))))
;
361
362 YWRITE4(sc, YDS_MAPOF_REC, 0)(((sc)->memt)->write_4(((sc)->memh), ((0x0150)), ((0
))))
;
363 YWRITE4(sc, YDS_MAPOF_EFFECT, 0)(((sc)->memt)->write_4(((sc)->memh), ((0x0154)), ((0
))))
;
364 YWRITE4(sc, YDS_PLAY_CTRLBASE, 0)(((sc)->memt)->write_4(((sc)->memh), ((0x0158)), ((0
))))
;
365 YWRITE4(sc, YDS_REC_CTRLBASE, 0)(((sc)->memt)->write_4(((sc)->memh), ((0x015c)), ((0
))))
;
366 YWRITE4(sc, YDS_EFFECT_CTRLBASE, 0)(((sc)->memt)->write_4(((sc)->memh), ((0x0160)), ((0
))))
;
367 YWRITE4(sc, YDS_WORK_BASE, 0)(((sc)->memt)->write_4(((sc)->memh), ((0x0164)), ((0
))))
;
368
369 ctrl = YREAD2(sc, YDS_GLOBAL_CONTROL)(((sc)->memt)->read_2(((sc)->memh), ((0x0008))));
370 YWRITE2(sc, YDS_GLOBAL_CONTROL, ctrl & ~0x0007)(((sc)->memt)->write_2(((sc)->memh), ((0x0008)), ((ctrl
& ~0x0007))))
;
371
372 /* Download DSP microcode. */
373 nswaph((u_int32_t *)&yf->data[0], ntohl(yf->dsplen)(__uint32_t)(__builtin_constant_p(yf->dsplen) ? (__uint32_t
)(((__uint32_t)(yf->dsplen) & 0xff) << 24 | ((__uint32_t
)(yf->dsplen) & 0xff00) << 8 | ((__uint32_t)(yf->
dsplen) & 0xff0000) >> 8 | ((__uint32_t)(yf->dsplen
) & 0xff000000) >> 24) : __swap32md(yf->dsplen))
);
374 YWRITEREGION4(sc, YDS_DSP_INSTRAM, (u_int32_t *)&yf->data[0],(((sc)->memt)->write_region_4(((sc)->memh), ((0x1000
)), (((u_int32_t *)&yf->data[0])), (((__uint32_t)(__builtin_constant_p
(yf->dsplen) ? (__uint32_t)(((__uint32_t)(yf->dsplen) &
0xff) << 24 | ((__uint32_t)(yf->dsplen) & 0xff00
) << 8 | ((__uint32_t)(yf->dsplen) & 0xff0000) >>
8 | ((__uint32_t)(yf->dsplen) & 0xff000000) >> 24
) : __swap32md(yf->dsplen))) / 4)))
375 ntohl(yf->dsplen))(((sc)->memt)->write_region_4(((sc)->memh), ((0x1000
)), (((u_int32_t *)&yf->data[0])), (((__uint32_t)(__builtin_constant_p
(yf->dsplen) ? (__uint32_t)(((__uint32_t)(yf->dsplen) &
0xff) << 24 | ((__uint32_t)(yf->dsplen) & 0xff00
) << 8 | ((__uint32_t)(yf->dsplen) & 0xff0000) >>
8 | ((__uint32_t)(yf->dsplen) & 0xff000000) >> 24
) : __swap32md(yf->dsplen))) / 4)))
;
376
377 /* Download CONTROL microcode. */
378 nswaph((u_int32_t *)p, size);
379 YWRITEREGION4(sc, YDS_CTRL_INSTRAM, p, size)(((sc)->memt)->write_region_4(((sc)->memh), ((0x4000
)), ((p)), ((size) / 4)))
;
380
381 yds_enable_dsp(sc);
382 delay(10*1000)(*delay_func)(10*1000); /* necessary on my 724F (??) */
383
384 free(buf, M_DEVBUF2, buflen);
385 return 0;
386}
387
388static int
389yds_allocate_slots(struct yds_softc *sc, int resuming)
390{
391 size_t pcs, rcs, ecs, ws, memsize;
392 void *mp;
393 u_int32_t da; /* DMA address */
394 char *va; /* KVA */
395 off_t cb;
396 int i;
397 struct yds_dma *p;
398
399 /* Alloc DSP Control Data */
400 pcs = YREAD4(sc, YDS_PLAY_CTRLSIZE)(((sc)->memt)->read_4(((sc)->memh), ((0x0140)))) * sizeof(u_int32_t);
401 rcs = YREAD4(sc, YDS_REC_CTRLSIZE)(((sc)->memt)->read_4(((sc)->memh), ((0x0144)))) * sizeof(u_int32_t);
402 ecs = YREAD4(sc, YDS_EFFECT_CTRLSIZE)(((sc)->memt)->read_4(((sc)->memh), ((0x0148)))) * sizeof(u_int32_t);
Value stored to 'ecs' is never read
403 ws = WORK_SIZE0x0400;
404 YWRITE4(sc, YDS_WORK_SIZE, ws / sizeof(u_int32_t))(((sc)->memt)->write_4(((sc)->memh), ((0x014c)), ((ws
/ sizeof(u_int32_t)))))
;
405
406 DPRINTF(("play control size : %d\n", (unsigned int)pcs));
407 DPRINTF(("rec control size : %d\n", (unsigned int)rcs));
408 DPRINTF(("eff control size : %d\n", (unsigned int)ecs));
409 DPRINTF(("work size : %d\n", (unsigned int)ws));
410#ifdef DIAGNOSTIC1
411 if (pcs != sizeof(struct play_slot_ctrl_bank)) {
412 printf("%s: invalid play slot ctrldata %d != %d\n",
413 sc->sc_dev.dv_xname, (unsigned int)pcs,
414 (unsigned int)sizeof(struct play_slot_ctrl_bank));
415 }
416 if (rcs != sizeof(struct rec_slot_ctrl_bank)) {
417 printf("%s: invalid rec slot ctrldata %d != %d\n",
418 sc->sc_dev.dv_xname, (unsigned int)rcs,
419 (unsigned int)sizeof(struct rec_slot_ctrl_bank));
420 }
421#endif
422
423 memsize = N_PLAY_SLOTS2*N_PLAY_SLOT_CTRL_BANK2*pcs +
424 N_REC_SLOT_CTRL2*N_REC_SLOT_CTRL_BANK2*rcs + ws;
425 memsize += (N_PLAY_SLOTS2+1)*sizeof(u_int32_t);
426
427 p = &sc->sc_ctrldata;
428 if (!resuming) {
429 i = yds_allocmem(sc, memsize, 16, p);
430 if (i) {
431 printf("%s: couldn't alloc/map DSP DMA buffer, reason %d\n",
432 sc->sc_dev.dv_xname, i);
433 return 1;
434 }
435 }
436 mp = KERNADDR(p)((void *)((p)->addr));
437 da = DMAADDR(p)((p)->map->dm_segs[0].ds_addr);
438
439 DPRINTF(("mp:%p, DMA addr:%p\n",
440 mp, (void *) sc->sc_ctrldata.map->dm_segs[0].ds_addr));
441
442 bzero(mp, memsize)__builtin_bzero((mp), (memsize));
443
444 /* Work space */
445 cb = 0;
446 va = (u_int8_t*)mp;
447 YWRITE4(sc, YDS_WORK_BASE, da + cb)(((sc)->memt)->write_4(((sc)->memh), ((0x0164)), ((da
+ cb))))
;
448 cb += ws;
449
450 /* Play control data table */
451 sc->ptbl = (u_int32_t *)(va + cb);
452 sc->ptbloff = cb;
453 YWRITE4(sc, YDS_PLAY_CTRLBASE, da + cb)(((sc)->memt)->write_4(((sc)->memh), ((0x0158)), ((da
+ cb))))
;
454 cb += (N_PLAY_SLOT_CTRL2 + 1) * sizeof(u_int32_t);
455
456 /* Record slot control data */
457 sc->rbank = (struct rec_slot_ctrl_bank *)(va + cb);
458 YWRITE4(sc, YDS_REC_CTRLBASE, da + cb)(((sc)->memt)->write_4(((sc)->memh), ((0x015c)), ((da
+ cb))))
;
459 sc->rbankoff = cb;
460 cb += N_REC_SLOT_CTRL2 * N_REC_SLOT_CTRL_BANK2 * rcs;
461
462#if 0
463 /* Effect slot control data -- unused */
464 YWRITE4(sc, YDS_EFFECT_CTRLBASE, da + cb)(((sc)->memt)->write_4(((sc)->memh), ((0x0160)), ((da
+ cb))))
;
465 cb += N_EFFECT_SLOT_CTRL * N_EFFECT_SLOT_CTRL_BANK * ecs;
466#endif
467
468 /* Play slot control data */
469 sc->pbankoff = da + cb;
470 for (i=0; i<N_PLAY_SLOT_CTRL2; i++) {
471 sc->pbankp[i*2] = (struct play_slot_ctrl_bank *)(va + cb);
472 *(sc->ptbl + i+1) = da + cb;
473 cb += pcs;
474
475 sc->pbankp[i*2+1] = (struct play_slot_ctrl_bank *)(va + cb);
476 cb += pcs;
477 }
478 /* Sync play control data table */
479 bus_dmamap_sync(sc->sc_dmatag, p->map,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (p
->map), (sc->ptbloff), ((2 +1) * sizeof(u_int32_t)), (0x04
))
480 sc->ptbloff, (N_PLAY_SLOT_CTRL+1) * sizeof(u_int32_t),(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (p
->map), (sc->ptbloff), ((2 +1) * sizeof(u_int32_t)), (0x04
))
481 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (p
->map), (sc->ptbloff), ((2 +1) * sizeof(u_int32_t)), (0x04
))
;
482
483 return 0;
484}
485
486static void
487yds_enable_dsp(struct yds_softc *sc)
488{
489 YWRITE4(sc, YDS_CONFIG, YDS_DSP_SETUP)(((sc)->memt)->write_4(((sc)->memh), ((0x0114)), ((0x00000001
))))
;
490}
491
492static int
493yds_disable_dsp(struct yds_softc *sc)
494{
495 int to;
496 u_int32_t data;
497
498 data = YREAD4(sc, YDS_CONFIG)(((sc)->memt)->read_4(((sc)->memh), ((0x0114))));
499 if (data)
500 YWRITE4(sc, YDS_CONFIG, YDS_DSP_DISABLE)(((sc)->memt)->write_4(((sc)->memh), ((0x0114)), ((0
))))
;
501
502 for (to = 0; to < YDS_WORK_TIMEOUT250000; to++) {
503 if ((YREAD4(sc, YDS_STATUS)(((sc)->memt)->read_4(((sc)->memh), ((0x0100)))) & YDS_STAT_WORK0x00000002) == 0)
504 return 0;
505 delay(1)(*delay_func)(1);
506 }
507
508 return 1;
509}
510
511int
512yds_match(struct device *parent, void *match, void *aux)
513{
514 struct pci_attach_args *pa = (struct pci_attach_args *) aux;
515
516 switch (PCI_VENDOR(pa->pa_id)(((pa->pa_id) >> 0) & 0xffff)) {
517 case PCI_VENDOR_YAMAHA0x1073:
518 switch (PCI_PRODUCT(pa->pa_id)(((pa->pa_id) >> 16) & 0xffff)) {
519 case PCI_PRODUCT_YAMAHA_YMF7240x0004:
520 case PCI_PRODUCT_YAMAHA_YMF7400x000a:
521 case PCI_PRODUCT_YAMAHA_YMF740C0x000c:
522 case PCI_PRODUCT_YAMAHA_YMF724F0x000d:
523 case PCI_PRODUCT_YAMAHA_YMF7440x0010:
524 case PCI_PRODUCT_YAMAHA_YMF7540x0012:
525 /* 734, 737, 738?? */
526 return (1);
527 }
528 break;
529 }
530
531 return (0);
532}
533
534/*
535 * This routine is called after all the ISA devices are configured,
536 * to avoid conflict.
537 */
538static void
539yds_configure_legacy(struct yds_softc *sc)
540#define FLEXIBLE (sc->sc_flags & YDS_CAP_LEGACY_FLEXIBLE0x0008)
541#define SELECTABLE (sc->sc_flags & YDS_CAP_LEGACY_SELECTABLE0x0004)
542{
543 pcireg_t reg;
544 struct device *dev;
545 int i;
546 bus_addr_t opl_addrs[] = {0x388, 0x398, 0x3A0, 0x3A8};
547 bus_addr_t mpu_addrs[] = {0x330, 0x300, 0x332, 0x334};
548
549 if (!FLEXIBLE && !SELECTABLE)
550 return;
551
552 reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY0x40);
553 reg &= ~0x8133c03f; /* these bits are out of interest */
554 reg |= (YDS_PCI_EX_LEGACY_IMOD(0x8000 << 16) | YDS_PCI_LEGACY_FMEN0x0002 |
555 YDS_PCI_LEGACY_MEN0x0008 /*| YDS_PCI_LEGACY_MIEN*/);
556 if (sc->sc_flags & YDS_CAP_LEGACY_SMOD_DISABLE0x1000)
557 reg |= YDS_PCI_EX_LEGACY_SMOD_DISABLE(0x0800 << 16);
558 if (FLEXIBLE) {
559 pci_conf_write(sc->sc_pc, sc->sc_pcitag, YDS_PCI_LEGACY0x40, reg);
560 delay(100*1000)(*delay_func)(100*1000);
561 }
562
563 /* Look for OPL */
564 dev = 0;
565 for (i = 0; i < sizeof(opl_addrs) / sizeof (bus_addr_t); i++) {
566 if (SELECTABLE) {
567 pci_conf_write(sc->sc_pc, sc->sc_pcitag,
568 YDS_PCI_LEGACY0x40, reg | (i << (0+16)));
569 delay(100*1000)(*delay_func)(100*1000); /* wait 100ms */
570 } else
571 pci_conf_write(sc->sc_pc, sc->sc_pcitag,
572 YDS_PCI_FM_BA0x60, opl_addrs[i]);
573 if (bus_space_map(sc->sc_opl_iotsc_legacy_iot,
574 opl_addrs[i], 4, 0, &sc->sc_opl_ioh) == 0) {
575 struct audio_attach_args aa;
576
577 aa.type = AUDIODEV_TYPE_OPL2;
578 aa.hwif = aa.hdl = NULL((void *)0);
579 dev = config_found(&sc->sc_dev, &aa, audioprint)config_found_sm((&sc->sc_dev), (&aa), (audioprint)
, ((void *)0))
;
580 if (dev == 0)
581 bus_space_unmap(sc->sc_opl_iotsc_legacy_iot,
582 sc->sc_opl_ioh, 4);
583 else {
584 if (SELECTABLE)
585 reg |= (i << (0+16));
586 break;
587 }
588 }
589 }
590 if (dev == 0) {
591 reg &= ~YDS_PCI_LEGACY_FMEN0x0002;
592 pci_conf_write(sc->sc_pc, sc->sc_pcitag,
593 YDS_PCI_LEGACY0x40, reg);
594 } else {
595 /* Max. volume */
596 YWRITE4(sc, YDS_LEGACY_OUT_VOLUME, 0x3fff3fff)(((sc)->memt)->write_4(((sc)->memh), ((0x0080)), ((0x3fff3fff
))))
;
597 YWRITE4(sc, YDS_LEGACY_REC_VOLUME, 0x3fff3fff)(((sc)->memt)->write_4(((sc)->memh), ((0x0094)), ((0x3fff3fff
))))
;
598 }
599
600 /* Look for MPU */
601 dev = 0;
602 for (i = 0; i < sizeof(mpu_addrs) / sizeof (bus_addr_t); i++) {
603 if (SELECTABLE)
604 pci_conf_write(sc->sc_pc, sc->sc_pcitag,
605 YDS_PCI_LEGACY0x40, reg | (i << (4+16)));
606 else
607 pci_conf_write(sc->sc_pc, sc->sc_pcitag,
608 YDS_PCI_MPU_BA0x64, mpu_addrs[i]);
609 if (bus_space_map(sc->sc_mpu_iotsc_legacy_iot,
610 mpu_addrs[i], 2, 0, &sc->sc_mpu_ioh) == 0) {
611 struct audio_attach_args aa;
612
613 aa.type = AUDIODEV_TYPE_MPU3;
614 aa.hwif = aa.hdl = NULL((void *)0);
615 dev = config_found(&sc->sc_dev, &aa, audioprint)config_found_sm((&sc->sc_dev), (&aa), (audioprint)
, ((void *)0))
;
616 if (dev == 0)
617 bus_space_unmap(sc->sc_mpu_iotsc_legacy_iot,
618 sc->sc_mpu_ioh, 2);
619 else {
620 if (SELECTABLE)
621 reg |= (i << (4+16));
622 break;
623 }
624 }
625 }
626 if (dev == 0) {
627 reg &= ~(YDS_PCI_LEGACY_MEN0x0008 | YDS_PCI_LEGACY_MIEN0x0010);
628 pci_conf_write(sc->sc_pc, sc->sc_pcitag,
629 YDS_PCI_LEGACY0x40, reg);
630 }
631 sc->sc_mpu = dev;
632}
633#undef FLEXIBLE
634#undef SELECTABLE
635
636void
637yds_attach(struct device *parent, struct device *self, void *aux)
638{
639 struct yds_softc *sc = (struct yds_softc *)self;
640 struct pci_attach_args *pa = (struct pci_attach_args *)aux;
641 pci_chipset_tag_t pc = pa->pa_pc;
642 char const *intrstr;
643 pci_intr_handle_t ih;
644 bus_size_t size;
645 pcireg_t reg;
646 int i;
647
648 /* Map register to memory */
649 if (pci_mapreg_map(pa, YDS_PCI_MBA0x10, PCI_MAPREG_TYPE_MEM0x00000000, 0,
650 &sc->memt, &sc->memh, NULL((void *)0), &size, 0)) {
651 printf(": can't map mem space\n");
652 return;
653 }
654
655 /* Map and establish the interrupt. */
656 if (pci_intr_map(pa, &ih)) {
657 printf(": couldn't map interrupt\n");
658 bus_space_unmap(sc->memt, sc->memh, size);
659 return;
660 }
661 intrstr = pci_intr_string(pc, ih);
662 sc->sc_ih = pci_intr_establish(pc, ih, IPL_AUDIO0xb | IPL_MPSAFE0x100,
663 yds_intr, sc, self->dv_xname);
664 if (sc->sc_ih == NULL((void *)0)) {
665 printf(": couldn't establish interrupt");
666 if (intrstr != NULL((void *)0))
667 printf(" at %s", intrstr);
668 printf("\n");
669 bus_space_unmap(sc->memt, sc->memh, size);
670 return;
671 }
672 printf(": %s\n", intrstr);
673
674 sc->sc_dmatag = pa->pa_dmat;
675 sc->sc_pc = pc;
676 sc->sc_pcitag = pa->pa_tag;
677 sc->sc_id = pa->pa_id;
678 sc->sc_revision = PCI_REVISION(pa->pa_class)(((pa->pa_class) >> 0) & 0xff);
679 sc->sc_flags = yds_get_dstype(sc->sc_id);
680 if (sc->sc_dev.dv_cfdata->cf_flags & YDS_CAP_LEGACY_SMOD_DISABLE0x1000)
681 sc->sc_flags |= YDS_CAP_LEGACY_SMOD_DISABLE0x1000;
682#ifdef AUDIO_DEBUG
683 if (ydsdebug)
684 printf("%s: chip has %b\n", sc->sc_dev.dv_xname,
685 sc->sc_flags, YDS_CAP_BITS);
686#endif
687
688 /* Disable legacy mode */
689 reg = pci_conf_read(pc, pa->pa_tag, YDS_PCI_LEGACY0x40);
690 pci_conf_write(pc, pa->pa_tag, YDS_PCI_LEGACY0x40,
691 reg & YDS_PCI_LEGACY_LAD0x8000);
692
693 /* Mute all volumes */
694 for (i = 0x80; i < 0xc0; i += 2)
695 YWRITE2(sc, i, 0)(((sc)->memt)->write_2(((sc)->memh), ((i)), ((0))));
696
697 sc->sc_legacy_iot = pa->pa_iot;
698 config_mountroot(self, yds_attachhook);
699}
700
701void
702yds_attachhook(struct device *self)
703{
704 struct yds_softc *sc = (struct yds_softc *)self;
705 struct yds_codec_softc *codec;
706 mixer_ctrl_t ctl;
707 int r, i;
708
709 /* Initialize the device */
710 if (yds_init(sc, 0) == -1)
711 return;
712
713 /*
714 * Attach ac97 codec
715 */
716 for (i = 0; i < 2; i++) {
717 static struct {
718 int data;
719 int addr;
720 } statregs[] = {
721 {AC97_STAT_DATA10x0064, AC97_STAT_ADDR10x0066},
722 {AC97_STAT_DATA20x0068, AC97_STAT_ADDR20x006a},
723 };
724
725 if (i == 1 && ac97_id2 == -1)
726 break; /* secondary ac97 not available */
727
728 codec = &sc->sc_codec[i];
729 memcpy(&codec->sc_dev, &sc->sc_dev, sizeof(codec->sc_dev))__builtin_memcpy((&codec->sc_dev), (&sc->sc_dev
), (sizeof(codec->sc_dev)))
;
730 codec->sc = sc;
731 codec->id = i == 1 ? ac97_id2 : 0;
732 codec->status_data = statregs[i].data;
733 codec->status_addr = statregs[i].addr;
734 codec->host_if.arg = codec;
735 codec->host_if.attach = yds_attach_codec;
736 codec->host_if.read = yds_read_codec;
737 codec->host_if.write = yds_write_codec;
738 codec->host_if.reset = yds_reset_codec;
739
740 if ((r = ac97_attach(&codec->host_if)) != 0) {
741 printf("%s: can't attach codec (error 0x%X)\n",
742 sc->sc_dev.dv_xname, r);
743 return;
744 }
745 }
746
747 /* Just enable the DAC and master volumes by default */
748 ctl.type = AUDIO_MIXER_ENUM1;
749 ctl.un.ord = 0; /* off */
750 ctl.dev = yds_get_portnum_by_name(sc, AudioCoutputs"outputs",
751 AudioNmaster"master", AudioNmute"mute");
752 yds_mixer_set_port(sc, &ctl);
753 ctl.dev = yds_get_portnum_by_name(sc, AudioCinputs"inputs",
754 AudioNdac"dac", AudioNmute"mute");
755 yds_mixer_set_port(sc, &ctl);
756 ctl.dev = yds_get_portnum_by_name(sc, AudioCinputs"inputs",
757 AudioNcd"cd", AudioNmute"mute");
758 yds_mixer_set_port(sc, &ctl);
759 ctl.dev = yds_get_portnum_by_name(sc, AudioCrecord"record",
760 AudioNvolume"volume", AudioNmute"mute");
761 yds_mixer_set_port(sc, &ctl);
762
763 ctl.dev = yds_get_portnum_by_name(sc, AudioCrecord"record",
764 AudioNsource"source", NULL((void *)0));
765 ctl.type = AUDIO_MIXER_ENUM1;
766 ctl.un.ord = 0;
767 yds_mixer_set_port(sc, &ctl);
768
769 /* Set a reasonable default volume */
770 ctl.type = AUDIO_MIXER_VALUE3;
771 ctl.un.value.num_channels = 2;
772 ctl.un.value.level[AUDIO_MIXER_LEVEL_LEFT0] =
773 ctl.un.value.level[AUDIO_MIXER_LEVEL_RIGHT1] = 127;
774
775 ctl.dev = sc->sc_codec[0].codec_if->vtbl->get_portnum_by_name(
776 sc->sc_codec[0].codec_if, AudioCoutputs"outputs", AudioNmaster"master", NULL((void *)0));
777 yds_mixer_set_port(sc, &ctl);
778
779 audio_attach_mi(&yds_hw_if, sc, NULL((void *)0), &sc->sc_dev);
780
781 /* Watch for power changes */
782 sc->suspend = DVACT_RESUME4;
783 yds_configure_legacy(sc);
784}
785
786int
787yds_attach_codec(void *sc_, struct ac97_codec_if *codec_if)
788{
789 struct yds_codec_softc *sc = sc_;
790
791 sc->codec_if = codec_if;
792 return 0;
793}
794
795static int
796yds_ready_codec(struct yds_codec_softc *sc)
797{
798 int to;
799
800 for (to = 0; to < AC97_TIMEOUT1000; to++) {
801 if ((YREAD2(sc->sc, sc->status_addr)(((sc->sc)->memt)->read_2(((sc->sc)->memh), ((
sc->status_addr))))
& AC97_BUSY0x8000) == 0)
802 return 0;
803 delay(1)(*delay_func)(1);
804 }
805
806 return 1;
807}
808
809int
810yds_read_codec(void *sc_, u_int8_t reg, u_int16_t *data)
811{
812 struct yds_codec_softc *sc = sc_;
813
814 YWRITE2(sc->sc, AC97_CMD_ADDR, AC97_CMD_READ | AC97_ID(sc->id) | reg)(((sc->sc)->memt)->write_2(((sc->sc)->memh), (
(0x0062)), ((0x8000 | ((sc->id) << 8) | reg))))
;
815
816 if (yds_ready_codec(sc)) {
817 printf("%s: yds_read_codec timeout\n",
818 sc->sc->sc_dev.dv_xname);
819 return EIO5;
820 }
821
822 if (PCI_PRODUCT(sc->sc->sc_id)(((sc->sc->sc_id) >> 16) & 0xffff) == PCI_PRODUCT_YAMAHA_YMF7440x0010 &&
823 sc->sc->sc_revision < 2) {
824 int i;
825
826 for (i = 0; i < 600; i++)
827 YREAD2(sc->sc, sc->status_data)(((sc->sc)->memt)->read_2(((sc->sc)->memh), ((
sc->status_data))))
;
828 }
829 *data = YREAD2(sc->sc, sc->status_data)(((sc->sc)->memt)->read_2(((sc->sc)->memh), ((
sc->status_data))))
;
830
831 return 0;
832}
833
834int
835yds_write_codec(void *sc_, u_int8_t reg, u_int16_t data)
836{
837 struct yds_codec_softc *sc = sc_;
838
839 YWRITE2(sc->sc, AC97_CMD_ADDR, AC97_CMD_WRITE | AC97_ID(sc->id) | reg)(((sc->sc)->memt)->write_2(((sc->sc)->memh), (
(0x0062)), ((0x0000 | ((sc->id) << 8) | reg))))
;
840 YWRITE2(sc->sc, AC97_CMD_DATA, data)(((sc->sc)->memt)->write_2(((sc->sc)->memh), (
(0x0060)), ((data))))
;
841
842 if (yds_ready_codec(sc)) {
843 printf("%s: yds_write_codec timeout\n",
844 sc->sc->sc_dev.dv_xname);
845 return EIO5;
846 }
847
848 return 0;
849}
850
851/*
852 * XXX: Must handle the secondary differently!!
853 */
854void
855yds_reset_codec(void *sc_)
856{
857 struct yds_codec_softc *codec = sc_;
858 struct yds_softc *sc = codec->sc;
859 pcireg_t reg;
860
861 /* reset AC97 codec */
862 reg = pci_conf_read(sc->sc_pc, sc->sc_pcitag, YDS_PCI_DSCTRL0x48);
863 if (reg & 0x03) {
864 pci_conf_write(sc->sc_pc, sc->sc_pcitag,
865 YDS_PCI_DSCTRL0x48, reg & ~0x03);
866 pci_conf_write(sc->sc_pc, sc->sc_pcitag,
867 YDS_PCI_DSCTRL0x48, reg | 0x03);
868 pci_conf_write(sc->sc_pc, sc->sc_pcitag,
869 YDS_PCI_DSCTRL0x48, reg & ~0x03);
870 delay(50000)(*delay_func)(50000);
871 }
872
873 yds_ready_codec(sc_);
874}
875
876int
877yds_intr(void *p)
878{
879 struct yds_softc *sc = p;
880 u_int status;
881
882 mtx_enter(&audio_lock);
883 status = YREAD4(sc, YDS_STATUS)(((sc)->memt)->read_4(((sc)->memh), ((0x0100))));
884 DPRINTFN(1, ("yds_intr: status=%08x\n", status));
885 if ((status & (YDS_STAT_INT0x80000000|YDS_STAT_TINT0x00008000)) == 0) {
886#if 0
887 if (sc->sc_mpu)
888 return mpu_intr(sc->sc_mpu);
889#endif
890 mtx_leave(&audio_lock);
891 return 0;
892 }
893
894 if (status & YDS_STAT_TINT0x00008000) {
895 YWRITE4(sc, YDS_STATUS, YDS_STAT_TINT)(((sc)->memt)->write_4(((sc)->memh), ((0x0100)), ((0x00008000
))))
;
896 printf ("yds_intr: timeout!\n");
897 }
898
899 if (status & YDS_STAT_INT0x80000000) {
900 int nbank = (YREAD4(sc, YDS_CONTROL_SELECT)(((sc)->memt)->read_4(((sc)->memh), ((0x0104)))) == 0);
901
902 /* Clear interrupt flag */
903 YWRITE4(sc, YDS_STATUS, YDS_STAT_INT)(((sc)->memt)->write_4(((sc)->memh), ((0x0100)), ((0x80000000
))))
;
904
905 /* Buffer for the next frame is always ready. */
906 YWRITE4(sc, YDS_MODE, YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV2)(((sc)->memt)->write_4(((sc)->memh), ((0x0108)), (((
((sc)->memt)->read_4(((sc)->memh), ((0x0108)))) | 0x00000002
))))
;
907
908 if (sc->sc_play.intr) {
909 u_int dma, cpu, blk, len;
910
911 /* Sync play slot control data */
912 bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->pbankoff), (sizeof(struct play_slot_ctrl_bank
)* (*sc->ptbl)* 2), (0x08| 0x02))
913 sc->pbankoff,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->pbankoff), (sizeof(struct play_slot_ctrl_bank
)* (*sc->ptbl)* 2), (0x08| 0x02))
914 sizeof(struct play_slot_ctrl_bank)*(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->pbankoff), (sizeof(struct play_slot_ctrl_bank
)* (*sc->ptbl)* 2), (0x08| 0x02))
915 (*sc->ptbl)*(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->pbankoff), (sizeof(struct play_slot_ctrl_bank
)* (*sc->ptbl)* 2), (0x08| 0x02))
916 N_PLAY_SLOT_CTRL_BANK,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->pbankoff), (sizeof(struct play_slot_ctrl_bank
)* (*sc->ptbl)* 2), (0x08| 0x02))
917 BUS_DMASYNC_POSTWRITE|(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->pbankoff), (sizeof(struct play_slot_ctrl_bank
)* (*sc->ptbl)* 2), (0x08| 0x02))
918 BUS_DMASYNC_POSTREAD)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->pbankoff), (sizeof(struct play_slot_ctrl_bank
)* (*sc->ptbl)* 2), (0x08| 0x02))
;
919 dma = sc->pbankp[nbank]->pgstart;
920 cpu = sc->sc_play.offset;
921 blk = sc->sc_play.blksize;
922 len = sc->sc_play.length;
923
924 if (((dma > cpu) && (dma - cpu > blk * 2)) ||
925 ((cpu > dma) && (dma + len - cpu > blk * 2))) {
926 /* We can fill the next block */
927 /* Sync ring buffer for previous write */
928 bus_dmamap_sync(sc->sc_dmatag,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_play.dma->map), (cpu), (blk), (0x08))
929 sc->sc_play.dma->map,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_play.dma->map), (cpu), (blk), (0x08))
930 cpu, blk,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_play.dma->map), (cpu), (blk), (0x08))
931 BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_play.dma->map), (cpu), (blk), (0x08))
;
932 sc->sc_play.intr(sc->sc_play.intr_arg);
933 sc->sc_play.offset += blk;
934 if (sc->sc_play.offset >= len) {
935 sc->sc_play.offset -= len;
936#ifdef DIAGNOSTIC1
937 if (sc->sc_play.offset != 0)
938 printf ("Audio ringbuffer botch\n");
939#endif
940 }
941 /* Sync ring buffer for next write */
942 bus_dmamap_sync(sc->sc_dmatag,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_play.dma->map), (cpu), (blk), (0x04))
943 sc->sc_play.dma->map,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_play.dma->map), (cpu), (blk), (0x04))
944 cpu, blk,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_play.dma->map), (cpu), (blk), (0x04))
945 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_play.dma->map), (cpu), (blk), (0x04))
;
946 }
947 }
948 if (sc->sc_rec.intr) {
949 u_int dma, cpu, blk, len;
950
951 /* Sync rec slot control data */
952 bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2* 2), (0x08| 0x02))
953 sc->rbankoff,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2* 2), (0x08| 0x02))
954 sizeof(struct rec_slot_ctrl_bank)*(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2* 2), (0x08| 0x02))
955 N_REC_SLOT_CTRL*(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2* 2), (0x08| 0x02))
956 N_REC_SLOT_CTRL_BANK,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2* 2), (0x08| 0x02))
957 BUS_DMASYNC_POSTWRITE|(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2* 2), (0x08| 0x02))
958 BUS_DMASYNC_POSTREAD)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2* 2), (0x08| 0x02))
;
959 dma = sc->rbank[YDS_INPUT_SLOT1*2 + nbank].pgstartadr;
960 cpu = sc->sc_rec.offset;
961 blk = sc->sc_rec.blksize;
962 len = sc->sc_rec.length;
963
964 if (((dma > cpu) && (dma - cpu > blk * 2)) ||
965 ((cpu > dma) && (dma + len - cpu > blk * 2))) {
966 /* We can drain the current block */
967 /* Sync ring buffer first */
968 bus_dmamap_sync(sc->sc_dmatag,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_rec.dma->map), (cpu), (blk), (0x02))
969 sc->sc_rec.dma->map,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_rec.dma->map), (cpu), (blk), (0x02))
970 cpu, blk,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_rec.dma->map), (cpu), (blk), (0x02))
971 BUS_DMASYNC_POSTREAD)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_rec.dma->map), (cpu), (blk), (0x02))
;
972 sc->sc_rec.intr(sc->sc_rec.intr_arg);
973 sc->sc_rec.offset += blk;
974 if (sc->sc_rec.offset >= len) {
975 sc->sc_rec.offset -= len;
976#ifdef DIAGNOSTIC1
977 if (sc->sc_rec.offset != 0)
978 printf ("Audio ringbuffer botch\n");
979#endif
980 }
981 /* Sync ring buffer for next read */
982 bus_dmamap_sync(sc->sc_dmatag,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_rec.dma->map), (cpu), (blk), (0x01))
983 sc->sc_rec.dma->map,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_rec.dma->map), (cpu), (blk), (0x01))
984 cpu, blk,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_rec.dma->map), (cpu), (blk), (0x01))
985 BUS_DMASYNC_PREREAD)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_rec.dma->map), (cpu), (blk), (0x01))
;
986 }
987 }
988 }
989 mtx_leave(&audio_lock);
990 return 1;
991}
992
993int
994yds_allocmem(struct yds_softc *sc, size_t size, size_t align, struct yds_dma *p)
995{
996 int error;
997
998 p->size = size;
999 error = bus_dmamem_alloc(sc->sc_dmatag, p->size, align, 0,(*(sc->sc_dmatag)->_dmamem_alloc)((sc->sc_dmatag), (
p->size), (align), (0), (p->segs), ((sizeof((p->segs
)) / sizeof((p->segs)[0]))), (&p->nsegs), (0x0001))
1000 p->segs, nitems(p->segs),(*(sc->sc_dmatag)->_dmamem_alloc)((sc->sc_dmatag), (
p->size), (align), (0), (p->segs), ((sizeof((p->segs
)) / sizeof((p->segs)[0]))), (&p->nsegs), (0x0001))
1001 &p->nsegs, BUS_DMA_NOWAIT)(*(sc->sc_dmatag)->_dmamem_alloc)((sc->sc_dmatag), (
p->size), (align), (0), (p->segs), ((sizeof((p->segs
)) / sizeof((p->segs)[0]))), (&p->nsegs), (0x0001))
;
1002 if (error)
1003 return (error);
1004
1005 error = bus_dmamem_map(sc->sc_dmatag, p->segs, p->nsegs, p->size,(*(sc->sc_dmatag)->_dmamem_map)((sc->sc_dmatag), (p->
segs), (p->nsegs), (p->size), (&p->addr), (0x0001
|0x0004))
1006 &p->addr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT)(*(sc->sc_dmatag)->_dmamem_map)((sc->sc_dmatag), (p->
segs), (p->nsegs), (p->size), (&p->addr), (0x0001
|0x0004))
;
1007 if (error)
1008 goto free;
1009
1010 error = bus_dmamap_create(sc->sc_dmatag, p->size, 1, p->size,(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), (
p->size), (1), (p->size), (0), (0x0001), (&p->map
))
1011 0, BUS_DMA_NOWAIT, &p->map)(*(sc->sc_dmatag)->_dmamap_create)((sc->sc_dmatag), (
p->size), (1), (p->size), (0), (0x0001), (&p->map
))
;
1012 if (error)
1013 goto unmap;
1014
1015 error = bus_dmamap_load(sc->sc_dmatag, p->map, p->addr, p->size, NULL,(*(sc->sc_dmatag)->_dmamap_load)((sc->sc_dmatag), (p
->map), (p->addr), (p->size), (((void *)0)), (0x0001
))
1016 BUS_DMA_NOWAIT)(*(sc->sc_dmatag)->_dmamap_load)((sc->sc_dmatag), (p
->map), (p->addr), (p->size), (((void *)0)), (0x0001
))
;
1017 if (error)
1018 goto destroy;
1019 return (0);
1020
1021destroy:
1022 bus_dmamap_destroy(sc->sc_dmatag, p->map)(*(sc->sc_dmatag)->_dmamap_destroy)((sc->sc_dmatag),
(p->map))
;
1023unmap:
1024 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size)(*(sc->sc_dmatag)->_dmamem_unmap)((sc->sc_dmatag), (
p->addr), (p->size))
;
1025free:
1026 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs)(*(sc->sc_dmatag)->_dmamem_free)((sc->sc_dmatag), (p
->segs), (p->nsegs))
;
1027 return (error);
1028}
1029
1030int
1031yds_freemem(struct yds_softc *sc, struct yds_dma *p)
1032{
1033 bus_dmamap_unload(sc->sc_dmatag, p->map)(*(sc->sc_dmatag)->_dmamap_unload)((sc->sc_dmatag), (
p->map))
;
1034 bus_dmamap_destroy(sc->sc_dmatag, p->map)(*(sc->sc_dmatag)->_dmamap_destroy)((sc->sc_dmatag),
(p->map))
;
1035 bus_dmamem_unmap(sc->sc_dmatag, p->addr, p->size)(*(sc->sc_dmatag)->_dmamem_unmap)((sc->sc_dmatag), (
p->addr), (p->size))
;
1036 bus_dmamem_free(sc->sc_dmatag, p->segs, p->nsegs)(*(sc->sc_dmatag)->_dmamem_free)((sc->sc_dmatag), (p
->segs), (p->nsegs))
;
1037 return 0;
1038}
1039
1040int
1041yds_open(void *addr, int flags)
1042{
1043 struct yds_softc *sc = addr;
1044 int mode;
1045
1046 /* Select bank 0. */
1047 YWRITE4(sc, YDS_CONTROL_SELECT, 0)(((sc)->memt)->write_4(((sc)->memh), ((0x0104)), ((0
))))
;
1048
1049 /* Start the DSP operation. */
1050 mode = YREAD4(sc, YDS_MODE)(((sc)->memt)->read_4(((sc)->memh), ((0x0108))));
1051 mode |= YDS_MODE_ACTV0x00000001;
1052 mode &= ~YDS_MODE_ACTV20x00000002;
1053 YWRITE4(sc, YDS_MODE, mode)(((sc)->memt)->write_4(((sc)->memh), ((0x0108)), ((mode
))))
;
1054
1055 return 0;
1056}
1057
1058/*
1059 * Close function is called at splaudio().
1060 */
1061void
1062yds_close(void *addr)
1063{
1064 struct yds_softc *sc = addr;
1065
1066 yds_halt_output(sc);
1067 yds_halt_input(sc);
1068 yds_halt(sc);
1069}
1070
1071int
1072yds_set_params(void *addr, int setmode, int usemode,
1073 struct audio_params *play, struct audio_params *rec)
1074{
1075 struct audio_params *p;
1076 int mode;
1077
1078 for (mode = AUMODE_RECORD0x02; mode != -1;
1079 mode = mode == AUMODE_RECORD0x02 ? AUMODE_PLAY0x01 : -1) {
1080 if ((setmode & mode) == 0)
1081 continue;
1082
1083 p = mode == AUMODE_PLAY0x01 ? play : rec;
1084
1085 if (p->sample_rate < 4000)
1086 p->sample_rate = 4000;
1087 if (p->sample_rate > 48000)
1088 p->sample_rate = 48000;
1089 if (p->precision > 16)
1090 p->precision = 16;
1091 if (p->channels > 2)
1092 p->channels = 2;
1093
1094 switch (p->encoding) {
1095 case AUDIO_ENCODING_SLINEAR_LE6:
1096 if (p->precision != 16)
1097 return EINVAL22;
1098 break;
1099 case AUDIO_ENCODING_ULINEAR_LE8:
1100 case AUDIO_ENCODING_ULINEAR_BE9:
1101 if (p->precision != 8)
1102 return EINVAL22;
1103 break;
1104 default:
1105 return (EINVAL22);
1106 }
1107 p->bps = AUDIO_BPS(p->precision)(p->precision) <= 8 ? 1 : ((p->precision) <= 16 ?
2 : 4)
;
1108 p->msb = 1;
1109 }
1110
1111 return 0;
1112}
1113
1114int
1115yds_round_blocksize(void *addr, int blk)
1116{
1117 /*
1118 * Block size must be bigger than a frame.
1119 * That is 1024bytes at most, i.e. for 48000Hz, 16bit, 2ch.
1120 */
1121 if (blk < 1024)
1122 blk = 1024;
1123
1124 return blk & ~4;
1125}
1126
1127static u_int32_t
1128yds_get_lpfq(u_int sample_rate)
1129{
1130 int i;
1131 static struct lpfqt {
1132 u_int rate;
1133 u_int32_t lpfq;
1134 } lpfqt[] = {
1135 {8000, 0x32020000},
1136 {11025, 0x31770000},
1137 {16000, 0x31390000},
1138 {22050, 0x31c90000},
1139 {32000, 0x33d00000},
1140 {48000, 0x40000000},
1141 {0, 0}
1142 };
1143
1144 if (sample_rate == 44100) /* for P44 slot? */
1145 return 0x370A0000;
1146
1147 for (i = 0; lpfqt[i].rate != 0; i++)
1148 if (sample_rate <= lpfqt[i].rate)
1149 break;
1150
1151 return lpfqt[i].lpfq;
1152}
1153
1154static u_int32_t
1155yds_get_lpfk(u_int sample_rate)
1156{
1157 int i;
1158 static struct lpfkt {
1159 u_int rate;
1160 u_int32_t lpfk;
1161 } lpfkt[] = {
1162 {8000, 0x18b20000},
1163 {11025, 0x20930000},
1164 {16000, 0x2b9a0000},
1165 {22050, 0x35a10000},
1166 {32000, 0x3eaa0000},
1167 {48000, 0x40000000},
1168 {0, 0}
1169 };
1170
1171 if (sample_rate == 44100) /* for P44 slot? */
1172 return 0x46460000;
1173
1174 for (i = 0; lpfkt[i].rate != 0; i++)
1175 if (sample_rate <= lpfkt[i].rate)
1176 break;
1177
1178 return lpfkt[i].lpfk;
1179}
1180
1181int
1182yds_trigger_output(void *addr, void *start, void *end, int blksize,
1183 void (*intr)(void *), void *arg, struct audio_params *param)
1184#define P44 (sc->sc_flags & YDS_CAP_HAS_P440x0010)
1185{
1186 struct yds_softc *sc = addr;
1187 struct yds_dma *p;
1188 struct play_slot_ctrl_bank *psb;
1189 const u_int gain = 0x40000000;
1190 bus_addr_t s;
1191 size_t l;
1192 int i;
1193 int p44, channels;
1194
1195 mtx_enter(&audio_lock);
1196#ifdef DIAGNOSTIC1
1197 if (sc->sc_play.intr)
1198 panic("yds_trigger_output: already running");
1199#endif
1200 sc->sc_play.intr = intr;
1201 sc->sc_play.intr_arg = arg;
1202 sc->sc_play.offset = 0;
1203 sc->sc_play.blksize = blksize;
1204
1205 DPRINTFN(1, ("yds_trigger_output: sc=%p start=%p end=%p "
1206 "blksize=%d intr=%p(%p)\n", addr, start, end, blksize, intr, arg));
1207
1208 p = yds_find_dma(sc, start);
1209 if (!p) {
1210 printf("yds_trigger_output: bad addr %p\n", start);
1211 mtx_leave(&audio_lock);
1212 return (EINVAL22);
1213 }
1214 sc->sc_play.dma = p;
1215
1216#ifdef DIAGNOSTIC1
1217 {
1218 u_int32_t ctrlsize;
1219 if ((ctrlsize = YREAD4(sc, YDS_PLAY_CTRLSIZE)(((sc)->memt)->read_4(((sc)->memh), ((0x0140))))) !=
1220 sizeof(struct play_slot_ctrl_bank) / sizeof(u_int32_t))
1221 panic("%s: invalid play slot ctrldata %d %zd",
1222 sc->sc_dev.dv_xname, ctrlsize,
1223 sizeof(struct play_slot_ctrl_bank));
1224 }
1225#endif
1226
1227#ifdef YDS_USE_P44
1228 /* The document says the P44 SRC supports only stereo, 16bit PCM. */
1229 if (P44)
1230 p44 = ((param->sample_rate == 44100) &&
1231 (param->channels == 2) &&
1232 (param->precision == 16));
1233 else
1234#endif
1235 p44 = 0;
1236 channels = p44 ? 1 : param->channels;
1237
1238 s = DMAADDR(p)((p)->map->dm_segs[0].ds_addr);
1239 l = ((char *)end - (char *)start);
1240 sc->sc_play.length = l;
1241
1242 *sc->ptbl = channels; /* Num of play */
1243
1244 psb = sc->pbankp[0];
1245 memset(psb, 0, sizeof(*psb))__builtin_memset((psb), (0), (sizeof(*psb)));
1246 psb->format = ((channels == 2 ? PSLT_FORMAT_STEREO0x00010000 : 0) |
1247 (param->precision == 8 ? PSLT_FORMAT_8BIT0x80000000 : 0) |
1248 (p44 ? PSLT_FORMAT_SRC4410x10000000 : 0));
1249 psb->pgbase = s;
1250 psb->pgloopend = l;
1251 if (!p44) {
1252 psb->pgdeltaend = (param->sample_rate * 65536 / 48000) << 12;
1253 psb->lpfkend = yds_get_lpfk(param->sample_rate);
1254 psb->eggainend = gain;
1255 psb->lpfq = yds_get_lpfq(param->sample_rate);
1256 psb->pgdelta = psb->pgdeltaend;
1257 psb->lpfk = yds_get_lpfk(param->sample_rate);
1258 psb->eggain = gain;
1259 }
1260
1261 for (i = 0; i < channels; i++) {
1262 /* i == 0: left or mono, i == 1: right */
1263 psb = sc->pbankp[i*2];
1264 if (i)
1265 /* copy from left */
1266 *psb = *(sc->pbankp[0]);
1267 if (channels == 2) {
1268 /* stereo */
1269 if (i == 0) {
1270 psb->lchgain = psb->lchgainend = gain;
1271 } else {
1272 psb->lchgain = psb->lchgainend = 0;
1273 psb->rchgain = psb->rchgainend = gain;
1274 psb->format |= PSLT_FORMAT_RCH0x00000001;
1275 }
1276 } else if (!p44) {
1277 /* mono */
1278 psb->lchgain = psb->rchgain = gain;
1279 psb->lchgainend = psb->rchgainend = gain;
1280 }
1281 /* copy to the other bank */
1282 *(sc->pbankp[i*2+1]) = *psb;
1283 }
1284
1285 YDS_DUMP_PLAY_SLOT(5, sc, 0);
1286 YDS_DUMP_PLAY_SLOT(5, sc, 1);
1287
1288 if (p44)
1289 YWRITE4(sc, YDS_P44_OUT_VOLUME, 0x3fff3fff)(((sc)->memt)->write_4(((sc)->memh), ((0x00B0)), ((0x3fff3fff
))))
;
1290 else
1291 YWRITE4(sc, YDS_DAC_OUT_VOLUME, 0x3fff3fff)(((sc)->memt)->write_4(((sc)->memh), ((0x0084)), ((0x3fff3fff
))))
;
1292
1293 /* Now the play slot for the next frame is set up!! */
1294 /* Sync play slot control data for both directions */
1295 bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->ptbloff), (sizeof(struct play_slot_ctrl_bank
) * channels * 2), (0x04|0x01))
1296 sc->ptbloff,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->ptbloff), (sizeof(struct play_slot_ctrl_bank
) * channels * 2), (0x04|0x01))
1297 sizeof(struct play_slot_ctrl_bank) *(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->ptbloff), (sizeof(struct play_slot_ctrl_bank
) * channels * 2), (0x04|0x01))
1298 channels * N_PLAY_SLOT_CTRL_BANK,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->ptbloff), (sizeof(struct play_slot_ctrl_bank
) * channels * 2), (0x04|0x01))
1299 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->ptbloff), (sizeof(struct play_slot_ctrl_bank
) * channels * 2), (0x04|0x01))
;
1300 /* Sync ring buffer */
1301 bus_dmamap_sync(sc->sc_dmatag, p->map, 0, blksize,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (p
->map), (0), (blksize), (0x04))
1302 BUS_DMASYNC_PREWRITE)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (p
->map), (0), (blksize), (0x04))
;
1303 /* HERE WE GO!! */
1304 YWRITE4(sc, YDS_MODE,(((sc)->memt)->write_4(((sc)->memh), ((0x0108)), (((
((sc)->memt)->read_4(((sc)->memh), ((0x0108)))) | 0x00000001
| 0x00000002))))
1305 YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV | YDS_MODE_ACTV2)(((sc)->memt)->write_4(((sc)->memh), ((0x0108)), (((
((sc)->memt)->read_4(((sc)->memh), ((0x0108)))) | 0x00000001
| 0x00000002))))
;
1306 mtx_leave(&audio_lock);
1307 return 0;
1308}
1309#undef P44
1310
1311int
1312yds_trigger_input(void *addr, void *start, void *end, int blksize,
1313 void (*intr)(void *), void *arg, struct audio_params *param)
1314{
1315 struct yds_softc *sc = addr;
1316 struct yds_dma *p;
1317 u_int srate, format;
1318 struct rec_slot_ctrl_bank *rsb;
1319 bus_addr_t s;
1320 size_t l;
1321
1322 mtx_enter(&audio_lock);
1323#ifdef DIAGNOSTIC1
1324 if (sc->sc_rec.intr)
1325 panic("yds_trigger_input: already running");
1326#endif
1327 sc->sc_rec.intr = intr;
1328 sc->sc_rec.intr_arg = arg;
1329 sc->sc_rec.offset = 0;
1330 sc->sc_rec.blksize = blksize;
1331
1332 DPRINTFN(1, ("yds_trigger_input: "
1333 "sc=%p start=%p end=%p blksize=%d intr=%p(%p)\n",
1334 addr, start, end, blksize, intr, arg));
1335 DPRINTFN(1, (" parameters: rate=%lu, precision=%u, channels=%u\n",
1336 param->sample_rate, param->precision, param->channels));
1337
1338 p = yds_find_dma(sc, start);
1339 if (!p) {
1340 printf("yds_trigger_input: bad addr %p\n", start);
1341 mtx_leave(&audio_lock);
1342 return (EINVAL22);
1343 }
1344 sc->sc_rec.dma = p;
1345
1346 s = DMAADDR(p)((p)->map->dm_segs[0].ds_addr);
1347 l = ((char *)end - (char *)start);
1348 sc->sc_rec.length = l;
1349
1350 rsb = &sc->rbank[0];
1351 memset(rsb, 0, sizeof(*rsb))__builtin_memset((rsb), (0), (sizeof(*rsb)));
1352 rsb->pgbase = s;
1353 rsb->pgloopendadr = l;
1354 /* Seems all 4 banks must be set up... */
1355 sc->rbank[1] = *rsb;
1356 sc->rbank[2] = *rsb;
1357 sc->rbank[3] = *rsb;
1358
1359 YWRITE4(sc, YDS_ADC_IN_VOLUME, 0x3fff3fff)(((sc)->memt)->write_4(((sc)->memh), ((0x00A8)), ((0x3fff3fff
))))
;
1360 YWRITE4(sc, YDS_REC_IN_VOLUME, 0x3fff3fff)(((sc)->memt)->write_4(((sc)->memh), ((0x00AC)), ((0x3fff3fff
))))
;
1361 srate = 48000 * 4096 / param->sample_rate - 1;
1362 format = ((param->precision == 8 ? YDS_FORMAT_8BIT0x01 : 0) |
1363 (param->channels == 2 ? YDS_FORMAT_STEREO0x02 : 0));
1364 DPRINTF(("srate=%d, format=%08x\n", srate, format));
1365#ifdef YDS_USE_REC_SLOT
1366 YWRITE4(sc, YDS_DAC_REC_VOLUME, 0x3fff3fff)(((sc)->memt)->write_4(((sc)->memh), ((0x0098)), ((0x3fff3fff
))))
;
1367 YWRITE4(sc, YDS_P44_REC_VOLUME, 0x3fff3fff)(((sc)->memt)->write_4(((sc)->memh), ((0x00B4)), ((0x3fff3fff
))))
;
1368 YWRITE4(sc, YDS_MAPOF_REC, YDS_RECSLOT_VALID)(((sc)->memt)->write_4(((sc)->memh), ((0x0150)), ((0x00000001
))))
;
1369 YWRITE4(sc, YDS_REC_SAMPLE_RATE, srate)(((sc)->memt)->write_4(((sc)->memh), ((0x00c4)), ((srate
))))
;
1370 YWRITE4(sc, YDS_REC_FORMAT, format)(((sc)->memt)->write_4(((sc)->memh), ((0x00cc)), ((format
))))
;
1371#else
1372 YWRITE4(sc, YDS_MAPOF_REC, YDS_ADCSLOT_VALID)(((sc)->memt)->write_4(((sc)->memh), ((0x0150)), ((0x00000002
))))
;
1373 YWRITE4(sc, YDS_ADC_SAMPLE_RATE, srate)(((sc)->memt)->write_4(((sc)->memh), ((0x00c0)), ((srate
))))
;
1374 YWRITE4(sc, YDS_ADC_FORMAT, format)(((sc)->memt)->write_4(((sc)->memh), ((0x00c8)), ((format
))))
;
1375#endif
1376 /* Now the rec slot for the next frame is set up!! */
1377 /* Sync record slot control data */
1378 bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2* 2), (0x04|0x01))
1379 sc->rbankoff,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2* 2), (0x04|0x01))
1380 sizeof(struct rec_slot_ctrl_bank)*(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2* 2), (0x04|0x01))
1381 N_REC_SLOT_CTRL*(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2* 2), (0x04|0x01))
1382 N_REC_SLOT_CTRL_BANK,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2* 2), (0x04|0x01))
1383 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2* 2), (0x04|0x01))
;
1384 /* Sync ring buffer */
1385 bus_dmamap_sync(sc->sc_dmatag, p->map, 0, blksize,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (p
->map), (0), (blksize), (0x01))
1386 BUS_DMASYNC_PREREAD)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (p
->map), (0), (blksize), (0x01))
;
1387 /* HERE WE GO!! */
1388 YWRITE4(sc, YDS_MODE,(((sc)->memt)->write_4(((sc)->memh), ((0x0108)), (((
((sc)->memt)->read_4(((sc)->memh), ((0x0108)))) | 0x00000001
| 0x00000002))))
1389 YREAD4(sc, YDS_MODE) | YDS_MODE_ACTV | YDS_MODE_ACTV2)(((sc)->memt)->write_4(((sc)->memh), ((0x0108)), (((
((sc)->memt)->read_4(((sc)->memh), ((0x0108)))) | 0x00000001
| 0x00000002))))
;
1390 mtx_leave(&audio_lock);
1391 return 0;
1392}
1393
1394static int
1395yds_halt(struct yds_softc *sc)
1396{
1397 u_int32_t mode;
1398
1399 /* Stop the DSP operation. */
1400 mode = YREAD4(sc, YDS_MODE)(((sc)->memt)->read_4(((sc)->memh), ((0x0108))));
1401 YWRITE4(sc, YDS_MODE, mode & ~(YDS_MODE_ACTV|YDS_MODE_ACTV2))(((sc)->memt)->write_4(((sc)->memh), ((0x0108)), ((mode
& ~(0x00000001|0x00000002)))))
;
1402
1403 /* Paranoia... mute all */
1404 YWRITE4(sc, YDS_P44_OUT_VOLUME, 0)(((sc)->memt)->write_4(((sc)->memh), ((0x00B0)), ((0
))))
;
1405 YWRITE4(sc, YDS_DAC_OUT_VOLUME, 0)(((sc)->memt)->write_4(((sc)->memh), ((0x0084)), ((0
))))
;
1406 YWRITE4(sc, YDS_ADC_IN_VOLUME, 0)(((sc)->memt)->write_4(((sc)->memh), ((0x00A8)), ((0
))))
;
1407 YWRITE4(sc, YDS_REC_IN_VOLUME, 0)(((sc)->memt)->write_4(((sc)->memh), ((0x00AC)), ((0
))))
;
1408 YWRITE4(sc, YDS_DAC_REC_VOLUME, 0)(((sc)->memt)->write_4(((sc)->memh), ((0x0098)), ((0
))))
;
1409 YWRITE4(sc, YDS_P44_REC_VOLUME, 0)(((sc)->memt)->write_4(((sc)->memh), ((0x00B4)), ((0
))))
;
1410
1411 return 0;
1412}
1413
1414int
1415yds_halt_output(void *addr)
1416{
1417 struct yds_softc *sc = addr;
1418
1419 DPRINTF(("yds: yds_halt_output\n"));
1420 mtx_enter(&audio_lock);
1421 if (sc->sc_play.intr) {
1422 sc->sc_play.intr = 0;
1423 /* Sync play slot control data */
1424 bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->pbankoff), (sizeof(struct play_slot_ctrl_bank
)* (*sc->ptbl)*2), (0x08|0x02))
1425 sc->pbankoff,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->pbankoff), (sizeof(struct play_slot_ctrl_bank
)* (*sc->ptbl)*2), (0x08|0x02))
1426 sizeof(struct play_slot_ctrl_bank)*(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->pbankoff), (sizeof(struct play_slot_ctrl_bank
)* (*sc->ptbl)*2), (0x08|0x02))
1427 (*sc->ptbl)*N_PLAY_SLOT_CTRL_BANK,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->pbankoff), (sizeof(struct play_slot_ctrl_bank
)* (*sc->ptbl)*2), (0x08|0x02))
1428 BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->pbankoff), (sizeof(struct play_slot_ctrl_bank
)* (*sc->ptbl)*2), (0x08|0x02))
;
1429 /* Stop the play slot operation */
1430 sc->pbankp[0]->status =
1431 sc->pbankp[1]->status =
1432 sc->pbankp[2]->status =
1433 sc->pbankp[3]->status = 1;
1434 /* Sync ring buffer */
1435 bus_dmamap_sync(sc->sc_dmatag, sc->sc_play.dma->map,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_play.dma->map), (0), (sc->sc_play.length), (0x08
))
1436 0, sc->sc_play.length, BUS_DMASYNC_POSTWRITE)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_play.dma->map), (0), (sc->sc_play.length), (0x08
))
;
1437 }
1438 mtx_leave(&audio_lock);
1439 return 0;
1440}
1441
1442int
1443yds_halt_input(void *addr)
1444{
1445 struct yds_softc *sc = addr;
1446
1447 DPRINTF(("yds: yds_halt_input\n"));
1448 mtx_enter(&audio_lock);
1449 if (sc->sc_rec.intr) {
1450 /* Stop the rec slot operation */
1451 YWRITE4(sc, YDS_MAPOF_REC, 0)(((sc)->memt)->write_4(((sc)->memh), ((0x0150)), ((0
))))
;
1452 sc->sc_rec.intr = 0;
1453 /* Sync rec slot control data */
1454 bus_dmamap_sync(sc->sc_dmatag, sc->sc_ctrldata.map,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2*2), (0x08|0x02))
1455 sc->rbankoff,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2*2), (0x08|0x02))
1456 sizeof(struct rec_slot_ctrl_bank)*(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2*2), (0x08|0x02))
1457 N_REC_SLOT_CTRL*N_REC_SLOT_CTRL_BANK,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2*2), (0x08|0x02))
1458 BUS_DMASYNC_POSTWRITE|BUS_DMASYNC_POSTREAD)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_ctrldata.map), (sc->rbankoff), (sizeof(struct rec_slot_ctrl_bank
)* 2*2), (0x08|0x02))
;
1459 /* Sync ring buffer */
1460 bus_dmamap_sync(sc->sc_dmatag, sc->sc_rec.dma->map,(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_rec.dma->map), (0), (sc->sc_rec.length), (0x02)
)
1461 0, sc->sc_rec.length, BUS_DMASYNC_POSTREAD)(*(sc->sc_dmatag)->_dmamap_sync)((sc->sc_dmatag), (sc
->sc_rec.dma->map), (0), (sc->sc_rec.length), (0x02)
)
;
1462 }
1463 sc->sc_rec.intr = NULL((void *)0);
1464 mtx_leave(&audio_lock);
1465 return 0;
1466}
1467
1468int
1469yds_mixer_set_port(void *addr, mixer_ctrl_t *cp)
1470{
1471 struct yds_softc *sc = addr;
1472
1473 return (sc->sc_codec[0].codec_if->vtbl->mixer_set_port(
1474 sc->sc_codec[0].codec_if, cp));
1475}
1476
1477int
1478yds_mixer_get_port(void *addr, mixer_ctrl_t *cp)
1479{
1480 struct yds_softc *sc = addr;
1481
1482 return (sc->sc_codec[0].codec_if->vtbl->mixer_get_port(
1483 sc->sc_codec[0].codec_if, cp));
1484}
1485
1486int
1487yds_query_devinfo(void *addr, mixer_devinfo_t *dip)
1488{
1489 struct yds_softc *sc = addr;
1490
1491 return (sc->sc_codec[0].codec_if->vtbl->query_devinfo(
1492 sc->sc_codec[0].codec_if, dip));
1493}
1494
1495int
1496yds_get_portnum_by_name(struct yds_softc *sc, char *class, char *device,
1497 char *qualifier)
1498{
1499 return (sc->sc_codec[0].codec_if->vtbl->get_portnum_by_name(
1500 sc->sc_codec[0].codec_if, class, device, qualifier));
1501}
1502
1503void *
1504yds_malloc(void *addr, int direction, size_t size, int pool, int flags)
1505{
1506 struct yds_softc *sc = addr;
1507 struct yds_dma *p;
1508 int error;
1509
1510 p = malloc(sizeof(*p), pool, flags);
1511 if (!p)
1512 return (0);
1513 error = yds_allocmem(sc, size, 16, p);
1514 if (error) {
1515 free(p, pool, sizeof *p);
1516 return (0);
1517 }
1518 p->next = sc->sc_dmas;
1519 sc->sc_dmas = p;
1520 return (KERNADDR(p)((void *)((p)->addr)));
1521}
1522
1523void
1524yds_free(void *addr, void *ptr, int pool)
1525{
1526 struct yds_softc *sc = addr;
1527 struct yds_dma **pp, *p;
1528
1529 for (pp = &sc->sc_dmas; (p = *pp) != NULL((void *)0); pp = &p->next) {
1530 if (KERNADDR(p)((void *)((p)->addr)) == ptr) {
1531 yds_freemem(sc, p);
1532 *pp = p->next;
1533 free(p, pool, sizeof *p);
1534 return;
1535 }
1536 }
1537}
1538
1539static struct yds_dma *
1540yds_find_dma(struct yds_softc *sc, void *addr)
1541{
1542 struct yds_dma *p;
1543
1544 for (p = sc->sc_dmas; p && KERNADDR(p)((void *)((p)->addr)) != addr; p = p->next)
1545 ;
1546
1547 return p;
1548}
1549
1550size_t
1551yds_round_buffersize(void *addr, int direction, size_t size)
1552{
1553 /*
1554 * Buffer size should be at least twice as bigger as a frame.
1555 */
1556 if (size < 1024 * 3)
1557 size = 1024 * 3;
1558 return (size);
1559}
1560
1561int
1562yds_activate(struct device *self, int act)
1563{
1564 struct yds_softc *sc = (struct yds_softc *)self;
1565 int rv = 0;
1566
1567 switch (act) {
1568 case DVACT_QUIESCE2:
1569 if (sc->sc_play.intr || sc->sc_rec.intr)
1570 sc->sc_resume_active = 1;
1571 else
1572 sc->sc_resume_active = 0;
1573 rv = config_activate_children(self, act);
1574 if (sc->sc_resume_active)
1575 yds_close(sc);
1576 break;
1577 case DVACT_RESUME4:
1578 yds_halt(sc);
1579 yds_init(sc, 1);
1580 ac97_resume(&sc->sc_codec[0].host_if, sc->sc_codec[0].codec_if);
1581 if (sc->sc_resume_active)
1582 yds_open(sc, 0);
1583 rv = config_activate_children(self, act);
1584 break;
1585 default:
1586 rv = config_activate_children(self, act);
1587 break;
1588 }
1589 return (rv);
1590}
1591
1592int
1593yds_init(struct yds_softc *sc, int resuming)
1594{
1595 u_int32_t reg;
1596
1597 pci_chipset_tag_t pc = sc->sc_pc;
1598
1599 int to;
1600
1601 DPRINTF(("in yds_init()\n"));
1602
1603 /* Download microcode */
1604 if (!resuming) {
1605 if (yds_download_mcode(sc)) {
1606 printf("%s: download microcode failed\n", sc->sc_dev.dv_xname);
1607 return -1;
1608 }
1609 }
1610 /* Allocate DMA buffers */
1611 if (yds_allocate_slots(sc, resuming)) {
1612 printf("%s: could not allocate slots\n", sc->sc_dev.dv_xname);
1613 return -1;
1614 }
1615
1616 /* Warm reset */
1617 reg = pci_conf_read(pc, sc->sc_pcitag, YDS_PCI_DSCTRL0x48);
1618 pci_conf_write(pc, sc->sc_pcitag, YDS_PCI_DSCTRL0x48, reg | YDS_DSCTRL_WRST0x00000004);
1619 delay(50000)(*delay_func)(50000);
1620
1621 /*
1622 * Detect primary/secondary AC97
1623 * YMF754 Hardware Specification Rev 1.01 page 24
1624 */
1625 reg = pci_conf_read(pc, sc->sc_pcitag, YDS_PCI_DSCTRL0x48);
1626 pci_conf_write(pc, sc->sc_pcitag, YDS_PCI_DSCTRL0x48,
1627 reg & ~YDS_DSCTRL_CRST0x00000001);
1628 delay(400000)(*delay_func)(400000); /* Needed for 740C. */
1629
1630 /* Primary */
1631 for (to = 0; to < AC97_TIMEOUT1000; to++) {
1632 if ((YREAD2(sc, AC97_STAT_ADDR1)(((sc)->memt)->read_2(((sc)->memh), ((0x0066)))) & AC97_BUSY0x8000) == 0)
1633 break;
1634 delay(1)(*delay_func)(1);
1635 }
1636 if (to == AC97_TIMEOUT1000) {
1637 printf("%s: no AC97 available\n", sc->sc_dev.dv_xname);
1638 return -1;
1639 }
1640
1641 /* Secondary */
1642 /* Secondary AC97 is used for 4ch audio. Currently unused. */
1643 ac97_id2 = -1;
1644 if ((YREAD2(sc, YDS_ACTIVITY)(((sc)->memt)->read_2(((sc)->memh), ((0x0006)))) & YDS_ACTIVITY_DOCKA0x0010) == 0)
1645 goto detected;
1646#if 0 /* reset secondary... */
1647 YWRITE2(sc, YDS_GPIO_OCTRL,(((sc)->memt)->write_2(((sc)->memh), ((0x0056)), (((
((sc)->memt)->read_2(((sc)->memh), ((0x0056)))) &
~0x0004))))
1648 YREAD2(sc, YDS_GPIO_OCTRL) & ~YDS_GPIO_GPO2)(((sc)->memt)->write_2(((sc)->memh), ((0x0056)), (((
((sc)->memt)->read_2(((sc)->memh), ((0x0056)))) &
~0x0004))))
;
1649 YWRITE2(sc, YDS_GPIO_FUNCE,(((sc)->memt)->write_2(((sc)->memh), ((0x0058)), (((
(((sc)->memt)->read_2(((sc)->memh), ((0x0058))))&
(~0x0004))|0x0040))))
1650 (YREAD2(sc, YDS_GPIO_FUNCE)&(~YDS_GPIO_GPC2))|YDS_GPIO_GPE2)(((sc)->memt)->write_2(((sc)->memh), ((0x0058)), (((
(((sc)->memt)->read_2(((sc)->memh), ((0x0058))))&
(~0x0004))|0x0040))))
;
1651#endif
1652 for (to = 0; to < AC97_TIMEOUT1000; to++) {
1653 if ((YREAD2(sc, AC97_STAT_ADDR2)(((sc)->memt)->read_2(((sc)->memh), ((0x006a)))) & AC97_BUSY0x8000) == 0)
1654 break;
1655 delay(1)(*delay_func)(1);
1656 }
1657 if (to < AC97_TIMEOUT1000) {
1658 /* detect id */
1659 for (ac97_id2 = 1; ac97_id2 < 4; ac97_id2++) {
1660 YWRITE2(sc, AC97_CMD_ADDR,(((sc)->memt)->write_2(((sc)->memh), ((0x0062)), ((0x8000
| ((ac97_id2) << 8) | 0x28))))
1661 AC97_CMD_READ | AC97_ID(ac97_id2) | 0x28)(((sc)->memt)->write_2(((sc)->memh), ((0x0062)), ((0x8000
| ((ac97_id2) << 8) | 0x28))))
;
1662
1663 for (to = 0; to < AC97_TIMEOUT1000; to++) {
1664 if ((YREAD2(sc, AC97_STAT_ADDR2)(((sc)->memt)->read_2(((sc)->memh), ((0x006a)))) & AC97_BUSY0x8000)
1665 == 0)
1666 goto detected;
1667 delay(1)(*delay_func)(1);
1668 }
1669 }
1670 if (ac97_id2 == 4)
1671 ac97_id2 = -1;
1672detected:
1673 ;
1674 }
1675
1676 pci_conf_write(pc, sc->sc_pcitag, YDS_PCI_DSCTRL0x48,
1677 reg | YDS_DSCTRL_CRST0x00000001);
1678 delay (20)(*delay_func)(20);
1679 pci_conf_write(pc, sc->sc_pcitag, YDS_PCI_DSCTRL0x48,
1680 reg & ~YDS_DSCTRL_CRST0x00000001);
1681 delay (400000)(*delay_func)(400000);
1682 for (to = 0; to < AC97_TIMEOUT1000; to++) {
1683 if ((YREAD2(sc, AC97_STAT_ADDR1)(((sc)->memt)->read_2(((sc)->memh), ((0x0066)))) & AC97_BUSY0x8000) == 0)
1684 break;
1685 delay(1)(*delay_func)(1);
1686 }
1687
1688 DPRINTF(("out of yds_init()\n"));
1689
1690 return 0;
1691}