Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/audio/drv/audioixp/audioixp.c
+++ new/usr/src/uts/common/io/audio/drv/audioixp/audioixp.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /*
27 27 * audioixp Audio Driver
28 28 *
29 29 * This driver supports audio hardware integrated in ATI IXP400 chipset.
30 30 *
31 31 * The IXP400 audio core is an AC'97 controller, which has independent
32 32 * channels for PCM in, PCM out. The AC'97 controller is a PCI bus master
33 33 * with scatter/gather support. Each channel has a DMA engine. Currently,
34 34 * we use only the PCM in and PCM out channels. Each DMA engine uses one
35 35 * buffer descriptor list. Each entry contains a pointer to a data buffer,
36 36 * status, length of the buffer being pointed to and the pointer to the next
37 37 * entry. Length of the buffer is in number of bytes. Interrupt will be
38 38 * triggered each time a entry is processed by hardware.
39 39 *
40 40 * System power management is not yet supported by the driver.
41 41 *
42 42 * NOTE:
43 43 * This driver depends on the misc/ac97 and drv/audio modules being
44 44 * loaded first.
45 45 */
46 46 #include <sys/types.h>
47 47 #include <sys/modctl.h>
48 48 #include <sys/kmem.h>
49 49 #include <sys/conf.h>
50 50 #include <sys/ddi.h>
51 51 #include <sys/sunddi.h>
52 52 #include <sys/pci.h>
53 53 #include <sys/note.h>
54 54 #include <sys/audio/audio_driver.h>
55 55 #include <sys/audio/ac97.h>
56 56 #include "audioixp.h"
57 57
58 58 /*
59 59 * Module linkage routines for the kernel
60 60 */
61 61 static int audioixp_ddi_attach(dev_info_t *, ddi_attach_cmd_t);
62 62 static int audioixp_ddi_detach(dev_info_t *, ddi_detach_cmd_t);
63 63 static int audioixp_quiesce(dev_info_t *);
64 64 static int audioixp_resume(dev_info_t *);
65 65 static int audioixp_suspend(dev_info_t *);
66 66
67 67 /*
68 68 * Entry point routine prototypes
69 69 */
70 70 static int audioixp_open(void *, int, unsigned *, caddr_t *);
71 71 static void audioixp_close(void *);
72 72 static int audioixp_start(void *);
73 73 static void audioixp_stop(void *);
74 74 static int audioixp_format(void *);
75 75 static int audioixp_channels(void *);
76 76 static int audioixp_rate(void *);
77 77 static uint64_t audioixp_count(void *);
78 78 static void audioixp_sync(void *, unsigned);
79 79
80 80 static audio_engine_ops_t audioixp_engine_ops = {
81 81 AUDIO_ENGINE_VERSION,
82 82 audioixp_open,
83 83 audioixp_close,
84 84 audioixp_start,
85 85 audioixp_stop,
86 86 audioixp_count,
87 87 audioixp_format,
88 88 audioixp_channels,
89 89 audioixp_rate,
90 90 audioixp_sync,
91 91 NULL,
92 92 NULL,
93 93 NULL
94 94 };
95 95
96 96 /*
97 97 * We drive audioixp in stereo only, so we don't want to display controls
98 98 * that are used for multichannel codecs. Note that this multichannel
99 99 * configuration limitation is a problem for audioixp devices.
100 100 */
101 101 const char *audioixp_remove_ac97[] = {
102 102 AUDIO_CTRL_ID_CENTER,
103 103 AUDIO_CTRL_ID_LFE,
104 104 AUDIO_CTRL_ID_SURROUND,
105 105 AUDIO_CTRL_ID_JACK1,
106 106 AUDIO_CTRL_ID_JACK2,
107 107 };
108 108
109 109 /*
110 110 * Local Routine Prototypes
111 111 */
112 112 static int audioixp_attach(dev_info_t *);
113 113 static int audioixp_detach(dev_info_t *);
114 114 static int audioixp_alloc_port(audioixp_state_t *, int);
115 115 static void audioixp_update_port(audioixp_port_t *);
116 116
117 117 static int audioixp_codec_sync(audioixp_state_t *);
118 118 static void audioixp_wr97(void *, uint8_t, uint16_t);
119 119 static uint16_t audioixp_rd97(void *, uint8_t);
120 120 static int audioixp_reset_ac97(audioixp_state_t *);
121 121 static int audioixp_map_regs(audioixp_state_t *);
122 122 static void audioixp_unmap_regs(audioixp_state_t *);
123 123 static int audioixp_chip_init(audioixp_state_t *);
124 124 static void audioixp_destroy(audioixp_state_t *);
125 125
126 126 /*
127 127 * Global variables, but used only by this file.
128 128 */
129 129
130 130 /*
131 131 * DDI Structures
132 132 */
133 133
134 134 /* Device operations structure */
135 135 static struct dev_ops audioixp_dev_ops = {
136 136 DEVO_REV, /* devo_rev */
137 137 0, /* devo_refcnt */
138 138 NULL, /* devo_getinfo */
139 139 nulldev, /* devo_identify - obsolete */
140 140 nulldev, /* devo_probe */
141 141 audioixp_ddi_attach, /* devo_attach */
142 142 audioixp_ddi_detach, /* devo_detach */
143 143 nodev, /* devo_reset */
144 144 NULL, /* devi_cb_ops */
145 145 NULL, /* devo_bus_ops */
146 146 NULL, /* devo_power */
147 147 audioixp_quiesce, /* devo_quiesce */
148 148 };
↓ open down ↓ |
148 lines elided |
↑ open up ↑ |
149 149
150 150 /* Linkage structure for loadable drivers */
151 151 static struct modldrv audioixp_modldrv = {
152 152 &mod_driverops, /* drv_modops */
153 153 IXP_MOD_NAME, /* drv_linkinfo */
154 154 &audioixp_dev_ops, /* drv_dev_ops */
155 155 };
156 156
157 157 /* Module linkage structure */
158 158 static struct modlinkage audioixp_modlinkage = {
159 - MODREV_1, /* ml_rev */
160 - (void *)&audioixp_modldrv, /* ml_linkage */
161 - NULL /* NULL terminates the list */
159 + MODREV_1, /* ml_rev */
160 + { (void *)&audioixp_modldrv, NULL } /* ml_linkage */
162 161 };
163 162
164 163 /*
165 164 * device access attributes for register mapping
166 165 */
167 166 static struct ddi_device_acc_attr dev_attr = {
168 167 DDI_DEVICE_ATTR_V0,
169 168 DDI_STRUCTURE_LE_ACC,
170 169 DDI_STRICTORDER_ACC
171 170 };
172 171 static struct ddi_device_acc_attr buf_attr = {
173 172 DDI_DEVICE_ATTR_V0,
174 173 DDI_NEVERSWAP_ACC,
175 174 DDI_STRICTORDER_ACC
176 175 };
177 176
178 177 /*
179 178 * DMA attributes of buffer descriptor list
180 179 */
181 180 static ddi_dma_attr_t bdlist_dma_attr = {
182 181 DMA_ATTR_V0, /* version */
183 182 0, /* addr_lo */
184 183 0xffffffff, /* addr_hi */
185 184 0x0000ffff, /* count_max */
186 185 8, /* align, BDL must be aligned on a 8-byte boundary */
187 186 0x3c, /* burstsize */
188 187 8, /* minxfer, set to the size of a BDlist entry */
189 188 0x0000ffff, /* maxxfer */
190 189 0x00000fff, /* seg, set to the RAM pagesize of intel platform */
191 190 1, /* sgllen, there's no scatter-gather list */
192 191 8, /* granular, set to the value of minxfer */
193 192 0 /* flags, use virtual address */
194 193 };
195 194
196 195 /*
197 196 * DMA attributes of buffers to be used to receive/send audio data
198 197 */
199 198 static ddi_dma_attr_t sample_buf_dma_attr = {
200 199 DMA_ATTR_V0,
201 200 0, /* addr_lo */
202 201 0xffffffff, /* addr_hi */
203 202 0x0001fffe, /* count_max */
204 203 4, /* align, data buffer is aligned on a 2-byte boundary */
205 204 0x3c, /* burstsize */
206 205 4, /* minxfer, set to the size of a sample data */
207 206 0x0001ffff, /* maxxfer */
208 207 0x0001ffff, /* seg */
209 208 1, /* sgllen, no scatter-gather */
210 209 4, /* granular, set to the value of minxfer */
211 210 0, /* flags, use virtual address */
212 211 };
213 212
214 213 /*
215 214 * _init()
216 215 *
217 216 * Description:
218 217 * Driver initialization, called when driver is first loaded.
219 218 * This is how access is initially given to all the static structures.
220 219 *
221 220 * Arguments:
222 221 * None
223 222 *
224 223 * Returns:
225 224 * ddi_soft_state_init() status, see ddi_soft_state_init(9f), or
226 225 * mod_install() status, see mod_install(9f)
227 226 */
228 227 int
229 228 _init(void)
230 229 {
231 230 int error;
232 231
233 232 audio_init_ops(&audioixp_dev_ops, IXP_NAME);
234 233
235 234 if ((error = mod_install(&audioixp_modlinkage)) != 0) {
236 235 audio_fini_ops(&audioixp_dev_ops);
237 236 }
238 237
239 238 return (error);
240 239 }
241 240
242 241 /*
243 242 * _fini()
244 243 *
245 244 * Description:
246 245 * Module de-initialization, called when the driver is to be unloaded.
247 246 *
248 247 * Arguments:
249 248 * None
250 249 *
251 250 * Returns:
252 251 * mod_remove() status, see mod_remove(9f)
253 252 */
254 253 int
255 254 _fini(void)
256 255 {
257 256 int error;
258 257
259 258 if ((error = mod_remove(&audioixp_modlinkage)) != 0) {
260 259 return (error);
261 260 }
262 261
263 262 audio_fini_ops(&audioixp_dev_ops);
264 263
265 264 return (0);
266 265 }
267 266
268 267 /*
269 268 * _info()
270 269 *
271 270 * Description:
272 271 * Module information, returns information about the driver.
273 272 *
274 273 * Arguments:
275 274 * modinfo *modinfop Pointer to the opaque modinfo structure
276 275 *
277 276 * Returns:
278 277 * mod_info() status, see mod_info(9f)
279 278 */
280 279 int
281 280 _info(struct modinfo *modinfop)
282 281 {
283 282 return (mod_info(&audioixp_modlinkage, modinfop));
284 283 }
285 284
286 285
287 286 /* ******************* Driver Entry Points ********************************* */
288 287
289 288 /*
290 289 * audioixp_ddi_attach()
291 290 *
292 291 * Description:
293 292 * Attach an instance of the audioixp driver.
294 293 *
295 294 * Arguments:
296 295 * dev_info_t *dip Pointer to the device's dev_info struct
297 296 * ddi_attach_cmd_t cmd Attach command
298 297 *
299 298 * Returns:
300 299 * DDI_SUCCESS The driver was initialized properly
301 300 * DDI_FAILURE The driver couldn't be initialized properly
302 301 */
303 302 static int
304 303 audioixp_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
305 304 {
306 305 switch (cmd) {
307 306 case DDI_ATTACH:
308 307 return (audioixp_attach(dip));
309 308
310 309 /*
311 310 * now, no suspend/resume supported. we'll do it in the future.
312 311 */
313 312 case DDI_RESUME:
314 313 return (audioixp_resume(dip));
315 314 default:
316 315 return (DDI_FAILURE);
317 316 }
318 317 }
319 318
320 319 /*
321 320 * audioixp_ddi_detach()
322 321 *
323 322 * Description:
324 323 * Detach an instance of the audioixp driver.
325 324 *
326 325 * Arguments:
327 326 * dev_info_t *dip Pointer to the device's dev_info struct
328 327 * ddi_detach_cmd_t cmd Detach command
329 328 *
330 329 * Returns:
331 330 * DDI_SUCCESS The driver was detached
332 331 * DDI_FAILURE The driver couldn't be detached
333 332 */
334 333 static int
335 334 audioixp_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
336 335 {
337 336 switch (cmd) {
338 337 case DDI_DETACH:
339 338 return (audioixp_detach(dip));
340 339
341 340 /*
342 341 * now, no suspend/resume supported. we'll do it in the future.
343 342 */
344 343 case DDI_SUSPEND:
345 344 return (audioixp_suspend(dip));
346 345
347 346 default:
348 347 return (DDI_FAILURE);
349 348 }
350 349 }
351 350
352 351 /*
353 352 * quiesce(9E) entry point.
354 353 *
355 354 * This function is called when the system is single-threaded at high
356 355 * PIL with preemption disabled. Therefore, this function must not be blocked.
357 356 *
358 357 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
359 358 * DDI_FAILURE indicates an error condition and should almost never happen.
360 359 */
361 360 static int
362 361 audioixp_quiesce(dev_info_t *dip)
363 362 {
364 363 audioixp_state_t *statep;
365 364
366 365 statep = ddi_get_driver_private(dip);
367 366 ASSERT(statep != NULL);
368 367
369 368 /* stop DMA engines */
370 369 CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT);
371 370 CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT_DMA);
372 371 CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN);
373 372 CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN_DMA);
374 373
375 374 return (DDI_SUCCESS);
376 375 }
377 376
378 377 static int
379 378 audioixp_suspend(dev_info_t *dip)
380 379 {
381 380 audioixp_state_t *statep;
382 381
383 382 statep = ddi_get_driver_private(dip);
384 383 ASSERT(statep != NULL);
385 384
386 385 audio_dev_suspend(statep->adev);
387 386
388 387 return (DDI_SUCCESS);
389 388 }
390 389
391 390 static int
392 391 audioixp_resume(dev_info_t *dip)
393 392 {
394 393 audioixp_state_t *statep;
395 394
396 395 statep = ddi_get_driver_private(dip);
397 396 ASSERT(statep != NULL);
398 397
399 398 if (audioixp_chip_init(statep) != DDI_SUCCESS) {
400 399 audio_dev_warn(statep->adev, "DDI_RESUME failed to init chip");
401 400 return (DDI_SUCCESS);
402 401 }
403 402
404 403 ac97_reset(statep->ac97);
405 404 audio_dev_resume(statep->adev);
406 405
407 406 return (DDI_SUCCESS);
408 407 }
409 408
410 409 /*
411 410 * audioixp_open()
412 411 *
413 412 * Description:
414 413 * Opens a DMA engine for use.
415 414 *
416 415 * Arguments:
417 416 * void *arg The DMA engine to set up
418 417 * int flag Open flags
419 418 * unsigned *nframesp Receives number of frames
420 419 * caddr_t *bufp Receives kernel data buffer
421 420 *
422 421 * Returns:
423 422 * 0 on success
424 423 * errno on failure
425 424 */
426 425 static int
427 426 audioixp_open(void *arg, int flag, unsigned *nframesp, caddr_t *bufp)
428 427 {
429 428 audioixp_port_t *port = arg;
430 429
431 430 _NOTE(ARGUNUSED(flag));
432 431
433 432 port->started = B_FALSE;
434 433 port->count = 0;
435 434 port->offset = 0;
436 435 *nframesp = port->nframes;
437 436 *bufp = port->samp_kaddr;
438 437
439 438 return (0);
440 439 }
441 440
442 441 /*
443 442 * audioixp_close()
444 443 *
445 444 * Description:
446 445 * Closes an audio DMA engine that was previously opened. Since
447 446 * nobody is using it, we take this opportunity to possibly power
448 447 * down the entire device.
449 448 *
450 449 * Arguments:
451 450 * void *arg The DMA engine to shut down
452 451 */
453 452 static void
454 453 audioixp_close(void *arg)
455 454 {
456 455 _NOTE(ARGUNUSED(arg));
457 456 }
458 457
459 458 /*
460 459 * audioixp_stop()
461 460 *
462 461 * Description:
463 462 * This is called by the framework to stop a port that is
464 463 * transferring data.
465 464 *
466 465 * Arguments:
467 466 * void *arg The DMA engine to stop
468 467 */
469 468 static void
470 469 audioixp_stop(void *arg)
471 470 {
472 471 audioixp_port_t *port = arg;
473 472 audioixp_state_t *statep = port->statep;
474 473
475 474 mutex_enter(&statep->inst_lock);
476 475 if (port->num == IXP_REC) {
477 476 CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN);
478 477 CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN_DMA);
479 478 } else {
480 479 CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT);
481 480 CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT_DMA);
482 481 }
483 482 mutex_exit(&statep->inst_lock);
484 483 }
485 484
486 485 /*
487 486 * audioixp_start()
488 487 *
489 488 * Description:
490 489 * This is called by the framework to start a port transferring data.
491 490 *
492 491 * Arguments:
493 492 * void *arg The DMA engine to start
494 493 *
495 494 * Returns:
496 495 * 0 on success (never fails, errno if it did)
497 496 */
498 497 static int
499 498 audioixp_start(void *arg)
500 499 {
501 500 audioixp_port_t *port = arg;
502 501 audioixp_state_t *statep = port->statep;
503 502
504 503 mutex_enter(&statep->inst_lock);
505 504
506 505 port->offset = 0;
507 506
508 507 if (port->num == IXP_REC) {
509 508 PUT32(IXP_AUDIO_FIFO_FLUSH, IXP_AUDIO_FIFO_FLUSH_IN);
510 509 SET32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_INTER_IN);
511 510
512 511 SET32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN_DMA);
513 512 PUT32(IXP_AUDIO_IN_DMA_LINK_P,
514 513 port->bdl_paddr | IXP_AUDIO_IN_DMA_LINK_P_EN);
515 514
516 515 SET32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN);
517 516 } else {
518 517 uint32_t slot = GET32(IXP_AUDIO_OUT_DMA_SLOT_EN_THRESHOLD);
519 518 PUT32(IXP_AUDIO_FIFO_FLUSH, IXP_AUDIO_FIFO_FLUSH_OUT);
520 519 /* clear all slots */
521 520 slot &= ~ (IXP_AUDIO_OUT_DMA_SLOT_3 |
522 521 IXP_AUDIO_OUT_DMA_SLOT_4 |
523 522 IXP_AUDIO_OUT_DMA_SLOT_5 |
524 523 IXP_AUDIO_OUT_DMA_SLOT_6 |
525 524 IXP_AUDIO_OUT_DMA_SLOT_7 |
526 525 IXP_AUDIO_OUT_DMA_SLOT_8 |
527 526 IXP_AUDIO_OUT_DMA_SLOT_9 |
528 527 IXP_AUDIO_OUT_DMA_SLOT_10 |
529 528 IXP_AUDIO_OUT_DMA_SLOT_11 |
530 529 IXP_AUDIO_OUT_DMA_SLOT_12);
531 530 /* enable AC'97 output slots (depending on output channels) */
532 531 slot |= IXP_AUDIO_OUT_DMA_SLOT_3 |
533 532 IXP_AUDIO_OUT_DMA_SLOT_4;
534 533 if (port->nchan >= 4) {
535 534 slot |= IXP_AUDIO_OUT_DMA_SLOT_6 |
536 535 IXP_AUDIO_OUT_DMA_SLOT_9;
537 536 }
538 537 if (port->nchan >= 6) {
539 538 slot |= IXP_AUDIO_OUT_DMA_SLOT_7 |
540 539 IXP_AUDIO_OUT_DMA_SLOT_8;
541 540 }
542 541
543 542 PUT32(IXP_AUDIO_OUT_DMA_SLOT_EN_THRESHOLD, slot);
544 543
545 544 SET32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_INTER_OUT);
546 545
547 546 SET32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT_DMA);
548 547 PUT32(IXP_AUDIO_OUT_DMA_LINK_P,
549 548 port->bdl_paddr | IXP_AUDIO_OUT_DMA_LINK_P_EN);
550 549
551 550 SET32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT);
552 551 }
553 552 mutex_exit(&statep->inst_lock);
554 553 return (0);
555 554 }
556 555
557 556 /*
558 557 * audioixp_format()
559 558 *
560 559 * Description:
561 560 * This is called by the framework to query the format for the device.
562 561 *
563 562 * Arguments:
564 563 * void *arg The DMA engine to query
565 564 *
566 565 * Returns:
567 566 * AUDIO_FORMAT_S16_LE
568 567 */
569 568 static int
570 569 audioixp_format(void *arg)
571 570 {
572 571 _NOTE(ARGUNUSED(arg));
573 572
574 573 return (AUDIO_FORMAT_S16_LE);
575 574 }
576 575
577 576 /*
578 577 * audioixp_channels()
579 578 *
580 579 * Description:
581 580 * This is called by the framework to query the channels for the device.
582 581 *
583 582 * Arguments:
584 583 * void *arg The DMA engine to query
585 584 *
586 585 * Returns:
587 586 * Number of channels for the device.
588 587 */
589 588 static int
590 589 audioixp_channels(void *arg)
591 590 {
592 591 audioixp_port_t *port = arg;
593 592
594 593 return (port->nchan);
595 594 }
596 595
597 596 /*
598 597 * audioixp_rate()
599 598 *
600 599 * Description:
601 600 * This is called by the framework to query the rate of the device.
602 601 *
603 602 * Arguments:
604 603 * void *arg The DMA engine to query
605 604 *
606 605 * Returns:
607 606 * 48000
608 607 */
609 608 static int
610 609 audioixp_rate(void *arg)
611 610 {
612 611 _NOTE(ARGUNUSED(arg));
613 612
614 613 return (48000);
615 614 }
616 615
617 616 /*
618 617 * audioixp_count()
619 618 *
620 619 * Description:
621 620 * This is called by the framework to get the engine's frame counter
622 621 *
623 622 * Arguments:
624 623 * void *arg The DMA engine to query
625 624 *
626 625 * Returns:
627 626 * frame count for current engine
628 627 */
629 628 static uint64_t
630 629 audioixp_count(void *arg)
631 630 {
632 631 audioixp_port_t *port = arg;
633 632 audioixp_state_t *statep = port->statep;
634 633 uint64_t val;
635 634
636 635 mutex_enter(&statep->inst_lock);
637 636 audioixp_update_port(port);
638 637 val = port->count;
639 638 mutex_exit(&statep->inst_lock);
640 639
641 640 return (val);
642 641 }
643 642
644 643 /*
645 644 * audioixp_sync()
646 645 *
647 646 * Description:
648 647 * This is called by the framework to synchronize DMA caches.
649 648 *
650 649 * Arguments:
651 650 * void *arg The DMA engine to sync
652 651 */
653 652 static void
654 653 audioixp_sync(void *arg, unsigned nframes)
655 654 {
656 655 audioixp_port_t *port = arg;
657 656 _NOTE(ARGUNUSED(nframes));
658 657
659 658 (void) ddi_dma_sync(port->samp_dmah, 0, 0, port->sync_dir);
660 659 }
661 660
662 661 /* *********************** Local Routines *************************** */
663 662
664 663 /*
665 664 * audioixp_alloc_port()
666 665 *
667 666 * Description:
668 667 * This routine allocates the DMA handles and the memory for the
669 668 * DMA engines to use. It also configures the BDL lists properly
670 669 * for use.
671 670 *
672 671 * Arguments:
673 672 * dev_info_t *dip Pointer to the device's devinfo
674 673 *
675 674 * Returns:
676 675 * DDI_SUCCESS Registers successfully mapped
677 676 * DDI_FAILURE Registers not successfully mapped
678 677 */
679 678 static int
680 679 audioixp_alloc_port(audioixp_state_t *statep, int num)
681 680 {
682 681 ddi_dma_cookie_t cookie;
683 682 uint_t count;
684 683 int dir;
685 684 unsigned caps;
686 685 audio_dev_t *adev;
687 686 audioixp_port_t *port;
688 687 uint32_t paddr;
689 688 int rc;
690 689 dev_info_t *dip;
691 690 audioixp_bd_entry_t *bdentry;
692 691
693 692 adev = statep->adev;
694 693 dip = statep->dip;
695 694
696 695 port = kmem_zalloc(sizeof (*port), KM_SLEEP);
697 696 port->statep = statep;
698 697 port->started = B_FALSE;
699 698 port->num = num;
700 699
701 700 switch (num) {
702 701 case IXP_REC:
703 702 statep->rec_port = port;
704 703 dir = DDI_DMA_READ;
705 704 caps = ENGINE_INPUT_CAP;
706 705 port->sync_dir = DDI_DMA_SYNC_FORKERNEL;
707 706 port->nchan = 2;
708 707 break;
709 708 case IXP_PLAY:
710 709 statep->play_port = port;
711 710 dir = DDI_DMA_WRITE;
712 711 caps = ENGINE_OUTPUT_CAP;
713 712 port->sync_dir = DDI_DMA_SYNC_FORDEV;
714 713 /*
715 714 * We allow for end users to configure more channels
716 715 * than just two, but we default to just two. The
717 716 * default stereo configuration works well. On the
718 717 * configurations we have tested, we've found that
719 718 * more than two channels (or rather 6 channels) can
720 719 * cause inexplicable noise. The noise is more
721 720 * noticeable when the system is running under load.
722 721 * (Holding the space bar in "top" while playing an
723 722 * MP3 is an easy way to recreate it.) End users who
724 723 * want to experiment, or have configurations that
725 724 * don't suffer from this, may increase the channels
726 725 * by setting this max-channels property. We leave it
727 726 * undocumented for now.
728 727 */
729 728 port->nchan = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
730 729 "max-channels", 2);
731 730 port->nchan = min(ac97_num_channels(statep->ac97),
732 731 port->nchan);
733 732 port->nchan &= ~1; /* make sure its an even number */
734 733 port->nchan = max(port->nchan, 2);
735 734 break;
736 735 default:
737 736 audio_dev_warn(adev, "bad port number (%d)!", num);
738 737 return (DDI_FAILURE);
739 738 }
740 739
741 740 port->nframes = 4096;
742 741 port->fragfr = port->nframes / IXP_BD_NUMS;
743 742 port->fragsz = port->fragfr * port->nchan * 2;
744 743 port->samp_size = port->nframes * port->nchan * 2;
745 744
746 745 /* allocate dma handle */
747 746 rc = ddi_dma_alloc_handle(dip, &sample_buf_dma_attr, DDI_DMA_SLEEP,
748 747 NULL, &port->samp_dmah);
749 748 if (rc != DDI_SUCCESS) {
750 749 audio_dev_warn(adev, "ddi_dma_alloc_handle failed: %d", rc);
751 750 return (DDI_FAILURE);
752 751 }
753 752 /* allocate DMA buffer */
754 753 rc = ddi_dma_mem_alloc(port->samp_dmah, port->samp_size, &buf_attr,
755 754 DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &port->samp_kaddr,
756 755 &port->samp_size, &port->samp_acch);
757 756 if (rc == DDI_FAILURE) {
758 757 audio_dev_warn(adev, "dma_mem_alloc failed");
759 758 return (DDI_FAILURE);
760 759 }
761 760
762 761 /* bind DMA buffer */
763 762 rc = ddi_dma_addr_bind_handle(port->samp_dmah, NULL,
764 763 port->samp_kaddr, port->samp_size, dir|DDI_DMA_CONSISTENT,
765 764 DDI_DMA_SLEEP, NULL, &cookie, &count);
766 765 if ((rc != DDI_DMA_MAPPED) || (count != 1)) {
767 766 audio_dev_warn(adev,
768 767 "ddi_dma_addr_bind_handle failed: %d", rc);
769 768 return (DDI_FAILURE);
770 769 }
771 770 port->samp_paddr = cookie.dmac_address;
772 771
773 772 /*
774 773 * now, from here we allocate DMA memory for buffer descriptor list.
775 774 * we allocate adjacent DMA memory for all DMA engines.
776 775 */
777 776 rc = ddi_dma_alloc_handle(dip, &bdlist_dma_attr, DDI_DMA_SLEEP,
778 777 NULL, &port->bdl_dmah);
779 778 if (rc != DDI_SUCCESS) {
780 779 audio_dev_warn(adev, "ddi_dma_alloc_handle(bdlist) failed");
781 780 return (DDI_FAILURE);
782 781 }
783 782
784 783 /*
785 784 * we allocate all buffer descriptors lists in continuous dma memory.
786 785 */
787 786 port->bdl_size = sizeof (audioixp_bd_entry_t) * IXP_BD_NUMS;
788 787 rc = ddi_dma_mem_alloc(port->bdl_dmah, port->bdl_size,
789 788 &dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
790 789 &port->bdl_kaddr, &port->bdl_size, &port->bdl_acch);
791 790 if (rc != DDI_SUCCESS) {
792 791 audio_dev_warn(adev, "ddi_dma_mem_alloc(bdlist) failed");
793 792 return (DDI_FAILURE);
794 793 }
795 794
796 795 rc = ddi_dma_addr_bind_handle(port->bdl_dmah, NULL, port->bdl_kaddr,
797 796 port->bdl_size, DDI_DMA_WRITE|DDI_DMA_CONSISTENT, DDI_DMA_SLEEP,
798 797 NULL, &cookie, &count);
799 798 if ((rc != DDI_DMA_MAPPED) || (count != 1)) {
800 799 audio_dev_warn(adev, "addr_bind_handle failed");
801 800 return (DDI_FAILURE);
802 801 }
803 802 port->bdl_paddr = cookie.dmac_address;
804 803
805 804 /*
806 805 * Wire up the BD list.
807 806 */
808 807 paddr = port->samp_paddr;
809 808 bdentry = (void *)port->bdl_kaddr;
810 809
811 810 for (int i = 0; i < IXP_BD_NUMS; i++) {
812 811
813 812 /* set base address of buffer */
814 813 ddi_put32(port->bdl_acch, &bdentry->buf_base, paddr);
815 814 ddi_put16(port->bdl_acch, &bdentry->status, 0);
816 815 ddi_put16(port->bdl_acch, &bdentry->buf_len, port->fragsz / 4);
817 816 ddi_put32(port->bdl_acch, &bdentry->next, port->bdl_paddr +
818 817 (((i + 1) % IXP_BD_NUMS) * sizeof (audioixp_bd_entry_t)));
819 818 paddr += port->fragsz;
820 819 bdentry++;
821 820 }
822 821 (void) ddi_dma_sync(port->bdl_dmah, 0, 0, DDI_DMA_SYNC_FORDEV);
823 822
824 823 port->engine = audio_engine_alloc(&audioixp_engine_ops, caps);
825 824 if (port->engine == NULL) {
826 825 audio_dev_warn(adev, "audio_engine_alloc failed");
827 826 return (DDI_FAILURE);
828 827 }
829 828
830 829 audio_engine_set_private(port->engine, port);
831 830 audio_dev_add_engine(adev, port->engine);
832 831
833 832 return (DDI_SUCCESS);
834 833 }
835 834
836 835 /*
837 836 * audioixp_free_port()
838 837 *
839 838 * Description:
840 839 * This routine unbinds the DMA cookies, frees the DMA buffers,
841 840 * deallocates the DMA handles.
842 841 *
843 842 * Arguments:
844 843 * audioixp_port_t *port The port structure for a DMA engine.
845 844 */
846 845 static void
847 846 audioixp_free_port(audioixp_port_t *port)
848 847 {
849 848 if (port == NULL)
850 849 return;
851 850
852 851 if (port->engine) {
853 852 audio_dev_remove_engine(port->statep->adev, port->engine);
854 853 audio_engine_free(port->engine);
855 854 }
856 855 if (port->bdl_paddr) {
857 856 (void) ddi_dma_unbind_handle(port->bdl_dmah);
858 857 }
859 858 if (port->bdl_acch) {
860 859 ddi_dma_mem_free(&port->bdl_acch);
861 860 }
862 861 if (port->bdl_dmah) {
863 862 ddi_dma_free_handle(&port->bdl_dmah);
864 863 }
865 864 if (port->samp_paddr) {
866 865 (void) ddi_dma_unbind_handle(port->samp_dmah);
867 866 }
868 867 if (port->samp_acch) {
869 868 ddi_dma_mem_free(&port->samp_acch);
870 869 }
871 870 if (port->samp_dmah) {
872 871 ddi_dma_free_handle(&port->samp_dmah);
873 872 }
874 873 kmem_free(port, sizeof (*port));
875 874 }
876 875
877 876 /*
878 877 * audioixp_update_port()
879 878 *
880 879 * Description:
881 880 * This routine updates the ports frame counter from hardware, and
882 881 * gracefully handles wraps.
883 882 *
884 883 * Arguments:
885 884 * audioixp_port_t *port The port to update.
886 885 */
887 886 static void
888 887 audioixp_update_port(audioixp_port_t *port)
889 888 {
890 889 audioixp_state_t *statep = port->statep;
891 890 unsigned regoff;
892 891 unsigned n;
893 892 int loop;
894 893 uint32_t offset;
895 894 uint32_t paddr;
896 895
897 896 if (port->num == IXP_REC) {
898 897 regoff = IXP_AUDIO_IN_DMA_DT_CUR;
899 898 } else {
900 899 regoff = IXP_AUDIO_OUT_DMA_DT_CUR;
901 900 }
902 901
903 902 /*
904 903 * Apparently it may take several tries to get an update on the
905 904 * position. Is this a hardware bug?
906 905 */
907 906 for (loop = 100; loop; loop--) {
908 907 paddr = GET32(regoff);
909 908
910 909 /* make sure address is reasonable */
911 910 if ((paddr < port->samp_paddr) ||
912 911 (paddr >= (port->samp_paddr + port->samp_size))) {
913 912 continue;
914 913 }
915 914
916 915 offset = paddr - port->samp_paddr;
917 916
918 917 if (offset >= port->offset) {
919 918 n = offset - port->offset;
920 919 } else {
921 920 n = offset + (port->samp_size - port->offset);
922 921 }
923 922 port->offset = offset;
924 923 port->count += (n / (port->nchan * sizeof (uint16_t)));
925 924 return;
926 925 }
927 926
928 927 audio_dev_warn(statep->adev, "Unable to update count (h/w bug?)");
929 928 }
930 929
931 930
932 931 /*
933 932 * audioixp_map_regs()
934 933 *
935 934 * Description:
936 935 * The registers are mapped in.
937 936 *
938 937 * Arguments:
939 938 * audioixp_state_t *state The device's state structure
940 939 *
941 940 * Returns:
942 941 * DDI_SUCCESS Registers successfully mapped
943 942 * DDI_FAILURE Registers not successfully mapped
944 943 */
945 944 static int
946 945 audioixp_map_regs(audioixp_state_t *statep)
947 946 {
948 947 dev_info_t *dip = statep->dip;
949 948
950 949 /* map PCI config space */
951 950 if (pci_config_setup(statep->dip, &statep->pcih) == DDI_FAILURE) {
952 951 audio_dev_warn(statep->adev, "unable to map PCI config space");
953 952 return (DDI_FAILURE);
954 953 }
955 954
956 955 /* map audio mixer register */
957 956 if ((ddi_regs_map_setup(dip, IXP_IO_AM_REGS, &statep->regsp, 0, 0,
958 957 &dev_attr, &statep->regsh)) != DDI_SUCCESS) {
959 958 audio_dev_warn(statep->adev, "unable to map audio registers");
960 959 return (DDI_FAILURE);
961 960 }
962 961 return (DDI_SUCCESS);
963 962 }
964 963
965 964 /*
966 965 * audioixp_unmap_regs()
967 966 *
968 967 * Description:
969 968 * This routine unmaps control registers.
970 969 *
971 970 * Arguments:
972 971 * audioixp_state_t *state The device's state structure
973 972 */
974 973 static void
975 974 audioixp_unmap_regs(audioixp_state_t *statep)
976 975 {
977 976 if (statep->regsh) {
978 977 ddi_regs_map_free(&statep->regsh);
979 978 }
980 979
981 980 if (statep->pcih) {
982 981 pci_config_teardown(&statep->pcih);
983 982 }
984 983 }
985 984
986 985 /*
987 986 * audioixp_codec_ready()
988 987 *
989 988 * Description:
990 989 * This routine checks the state of codecs. It checks the flag to confirm
991 990 * that primary codec is ready.
992 991 *
993 992 * Arguments:
994 993 * audioixp_state_t *state The device's state structure
995 994 *
996 995 * Returns:
997 996 * DDI_SUCCESS codec is ready
998 997 * DDI_FAILURE codec is not ready
999 998 */
1000 999 static int
1001 1000 audioixp_codec_ready(audioixp_state_t *statep)
1002 1001 {
1003 1002 uint32_t sr;
1004 1003
1005 1004 PUT32(IXP_AUDIO_INT, 0xffffffff);
1006 1005 drv_usecwait(1000);
1007 1006
1008 1007 sr = GET32(IXP_AUDIO_INT);
1009 1008 if (sr & IXP_AUDIO_INT_CODEC0_NOT_READY) {
1010 1009 PUT32(IXP_AUDIO_INT, IXP_AUDIO_INT_CODEC0_NOT_READY);
1011 1010 audio_dev_warn(statep->adev, "primary codec not ready");
1012 1011
1013 1012 return (DDI_FAILURE);
1014 1013 }
1015 1014 return (DDI_SUCCESS);
1016 1015 }
1017 1016
1018 1017 /*
1019 1018 * audioixp_codec_sync()
1020 1019 *
1021 1020 * Description:
1022 1021 * Serialize access to the AC97 audio mixer registers.
1023 1022 *
1024 1023 * Arguments:
1025 1024 * audioixp_state_t *state The device's state structure
1026 1025 *
1027 1026 * Returns:
1028 1027 * DDI_SUCCESS Ready for an I/O access to the codec
1029 1028 * DDI_FAILURE An I/O access is currently in progress, can't
1030 1029 * perform another I/O access.
1031 1030 */
1032 1031 static int
1033 1032 audioixp_codec_sync(audioixp_state_t *statep)
1034 1033 {
1035 1034 int i;
1036 1035 uint32_t cmd;
1037 1036
1038 1037 for (i = 0; i < 300; i++) {
1039 1038 cmd = GET32(IXP_AUDIO_OUT_PHY_ADDR_DATA);
1040 1039 if (!(cmd & IXP_AUDIO_OUT_PHY_EN)) {
1041 1040 return (DDI_SUCCESS);
1042 1041 }
1043 1042 drv_usecwait(10);
1044 1043 }
1045 1044
1046 1045 audio_dev_warn(statep->adev, "unable to synchronize codec");
1047 1046 return (DDI_FAILURE);
1048 1047 }
1049 1048
1050 1049 /*
1051 1050 * audioixp_rd97()
1052 1051 *
1053 1052 * Description:
1054 1053 * Get the specific AC97 Codec register.
1055 1054 *
1056 1055 * Arguments:
1057 1056 * void *arg The device's state structure
1058 1057 * uint8_t reg AC97 register number
1059 1058 *
1060 1059 * Returns:
1061 1060 * Register value.
1062 1061 */
1063 1062 static uint16_t
1064 1063 audioixp_rd97(void *arg, uint8_t reg)
1065 1064 {
1066 1065 audioixp_state_t *statep = arg;
1067 1066 uint32_t value;
1068 1067 uint32_t result;
1069 1068
1070 1069 if (audioixp_codec_sync(statep) != DDI_SUCCESS)
1071 1070 return (0xffff);
1072 1071
1073 1072 value = IXP_AUDIO_OUT_PHY_PRIMARY_CODEC |
1074 1073 IXP_AUDIO_OUT_PHY_READ |
1075 1074 IXP_AUDIO_OUT_PHY_EN |
1076 1075 ((unsigned)reg << IXP_AUDIO_OUT_PHY_ADDR_SHIFT);
1077 1076 PUT32(IXP_AUDIO_OUT_PHY_ADDR_DATA, value);
1078 1077
1079 1078 if (audioixp_codec_sync(statep) != DDI_SUCCESS)
1080 1079 return (0xffff);
1081 1080
1082 1081 for (int i = 0; i < 300; i++) {
1083 1082 result = GET32(IXP_AUDIO_IN_PHY_ADDR_DATA);
1084 1083 if (result & IXP_AUDIO_IN_PHY_READY) {
1085 1084 return (result >> IXP_AUDIO_IN_PHY_DATA_SHIFT);
1086 1085 }
1087 1086 drv_usecwait(10);
1088 1087 }
1089 1088
1090 1089 done:
1091 1090 audio_dev_warn(statep->adev, "time out reading codec reg %d", reg);
1092 1091 return (0xffff);
1093 1092 }
1094 1093
1095 1094 /*
1096 1095 * audioixp_wr97()
1097 1096 *
1098 1097 * Description:
1099 1098 * Set the specific AC97 Codec register.
1100 1099 *
1101 1100 * Arguments:
1102 1101 * void *arg The device's state structure
1103 1102 * uint8_t reg AC97 register number
1104 1103 * uint16_t data The data want to be set
1105 1104 */
1106 1105 static void
1107 1106 audioixp_wr97(void *arg, uint8_t reg, uint16_t data)
1108 1107 {
1109 1108 audioixp_state_t *statep = arg;
1110 1109 uint32_t value;
1111 1110
1112 1111 if (audioixp_codec_sync(statep) != DDI_SUCCESS) {
1113 1112 return;
1114 1113 }
1115 1114
1116 1115 value = IXP_AUDIO_OUT_PHY_PRIMARY_CODEC |
1117 1116 IXP_AUDIO_OUT_PHY_WRITE |
1118 1117 IXP_AUDIO_OUT_PHY_EN |
1119 1118 ((unsigned)reg << IXP_AUDIO_OUT_PHY_ADDR_SHIFT) |
1120 1119 ((unsigned)data << IXP_AUDIO_OUT_PHY_DATA_SHIFT);
1121 1120 PUT32(IXP_AUDIO_OUT_PHY_ADDR_DATA, value);
1122 1121
1123 1122 (void) audioixp_rd97(statep, reg);
1124 1123 }
1125 1124
1126 1125 /*
1127 1126 * audioixp_reset_ac97()
1128 1127 *
1129 1128 * Description:
1130 1129 * Reset AC97 Codec register.
1131 1130 *
1132 1131 * Arguments:
1133 1132 * audioixp_state_t *state The device's state structure
1134 1133 *
1135 1134 * Returns:
1136 1135 * DDI_SUCCESS Reset the codec successfully
1137 1136 * DDI_FAILURE Failed to reset the codec
1138 1137 */
1139 1138 static int
1140 1139 audioixp_reset_ac97(audioixp_state_t *statep)
1141 1140 {
1142 1141 uint32_t cmd;
1143 1142 int i;
1144 1143
1145 1144 CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_POWER_DOWN);
1146 1145 drv_usecwait(10);
1147 1146
1148 1147 /* register reset */
1149 1148 SET32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_AC_SOFT_RESET);
1150 1149 /* force a read to flush caches */
1151 1150 (void) GET32(IXP_AUDIO_CMD);
1152 1151
1153 1152 drv_usecwait(10);
1154 1153 CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_AC_SOFT_RESET);
1155 1154
1156 1155 /* cold reset */
1157 1156 for (i = 0; i < 300; i++) {
1158 1157 cmd = GET32(IXP_AUDIO_CMD);
1159 1158 if (cmd & IXP_AUDIO_CMD_AC_ACTIVE) {
1160 1159 cmd |= IXP_AUDIO_CMD_AC_RESET | IXP_AUDIO_CMD_AC_SYNC;
1161 1160 PUT32(IXP_AUDIO_CMD, cmd);
1162 1161 return (DDI_SUCCESS);
1163 1162 }
1164 1163 cmd &= ~IXP_AUDIO_CMD_AC_RESET;
1165 1164 cmd |= IXP_AUDIO_CMD_AC_SYNC;
1166 1165 PUT32(IXP_AUDIO_CMD, cmd);
1167 1166 (void) GET32(IXP_AUDIO_CMD);
1168 1167 drv_usecwait(10);
1169 1168 cmd |= IXP_AUDIO_CMD_AC_RESET;
1170 1169 PUT32(IXP_AUDIO_CMD, cmd);
1171 1170 drv_usecwait(10);
1172 1171 }
1173 1172
1174 1173 audio_dev_warn(statep->adev, "AC'97 reset timed out");
1175 1174 return (DDI_FAILURE);
1176 1175 }
1177 1176
1178 1177 /*
1179 1178 * audioixp_chip_init()
1180 1179 *
1181 1180 * Description:
1182 1181 * This routine initializes ATI IXP audio controller and the AC97
1183 1182 * codec.
1184 1183 *
1185 1184 * Arguments:
1186 1185 * audioixp_state_t *state The device's state structure
1187 1186 *
1188 1187 * Returns:
1189 1188 * DDI_SUCCESS The hardware was initialized properly
1190 1189 * DDI_FAILURE The hardware couldn't be initialized properly
1191 1190 */
1192 1191 static int
1193 1192 audioixp_chip_init(audioixp_state_t *statep)
1194 1193 {
1195 1194 /*
1196 1195 * put the audio controller into quiet state, everything off
1197 1196 */
1198 1197 CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT_DMA);
1199 1198 CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN_DMA);
1200 1199
1201 1200 /* AC97 reset */
1202 1201 if (audioixp_reset_ac97(statep) != DDI_SUCCESS) {
1203 1202 audio_dev_warn(statep->adev, "AC97 codec reset failed");
1204 1203 return (DDI_FAILURE);
1205 1204 }
1206 1205
1207 1206 if (audioixp_codec_ready(statep) != DDI_SUCCESS) {
1208 1207 audio_dev_warn(statep->adev, "AC97 codec not ready");
1209 1208 return (DDI_FAILURE);
1210 1209 }
1211 1210
1212 1211 return (DDI_SUCCESS);
1213 1212
1214 1213 } /* audioixp_chip_init() */
1215 1214
1216 1215 /*
1217 1216 * audioixp_attach()
1218 1217 *
1219 1218 * Description:
1220 1219 * Attach an instance of the audioixp driver. This routine does
1221 1220 * the device dependent attach tasks.
1222 1221 *
1223 1222 * Arguments:
1224 1223 * dev_info_t *dip Pointer to the device's dev_info struct
1225 1224 * ddi_attach_cmd_t cmd Attach command
1226 1225 *
1227 1226 * Returns:
1228 1227 * DDI_SUCCESS The driver was initialized properly
1229 1228 * DDI_FAILURE The driver couldn't be initialized properly
1230 1229 */
1231 1230 static int
1232 1231 audioixp_attach(dev_info_t *dip)
1233 1232 {
1234 1233 uint16_t cmdeg;
1235 1234 audioixp_state_t *statep;
1236 1235 audio_dev_t *adev;
1237 1236 uint32_t devid;
1238 1237 const char *name;
1239 1238 const char *rev;
1240 1239
1241 1240 /* allocate the soft state structure */
1242 1241 statep = kmem_zalloc(sizeof (*statep), KM_SLEEP);
1243 1242 statep->dip = dip;
1244 1243 ddi_set_driver_private(dip, statep);
1245 1244 mutex_init(&statep->inst_lock, NULL, MUTEX_DRIVER, NULL);
1246 1245
1247 1246 /* allocate framework audio device */
1248 1247 if ((adev = audio_dev_alloc(dip, 0)) == NULL) {
1249 1248 cmn_err(CE_WARN, "!%s%d: unable to allocate audio dev",
1250 1249 ddi_driver_name(dip), ddi_get_instance(dip));
1251 1250 goto error;
1252 1251 }
1253 1252 statep->adev = adev;
1254 1253
1255 1254 /* map in the registers */
1256 1255 if (audioixp_map_regs(statep) != DDI_SUCCESS) {
1257 1256 audio_dev_warn(adev, "couldn't map registers");
1258 1257 goto error;
1259 1258 }
1260 1259
1261 1260 /* set device information -- this could be smarter */
1262 1261 devid = ((pci_config_get16(statep->pcih, PCI_CONF_VENID)) << 16) |
1263 1262 pci_config_get16(statep->pcih, PCI_CONF_DEVID);
1264 1263
1265 1264 name = "ATI AC'97";
1266 1265 switch (devid) {
1267 1266 case IXP_PCI_ID_200:
1268 1267 rev = "IXP150";
1269 1268 break;
1270 1269 case IXP_PCI_ID_300:
1271 1270 rev = "SB300";
1272 1271 break;
1273 1272 case IXP_PCI_ID_400:
1274 1273 if (pci_config_get8(statep->pcih, PCI_CONF_REVID) & 0x80) {
1275 1274 rev = "SB450";
1276 1275 } else {
1277 1276 rev = "SB400";
1278 1277 }
1279 1278 break;
1280 1279 case IXP_PCI_ID_SB600:
1281 1280 rev = "SB600";
1282 1281 break;
1283 1282 default:
1284 1283 rev = "Unknown";
1285 1284 break;
1286 1285 }
1287 1286 audio_dev_set_description(adev, name);
1288 1287 audio_dev_set_version(adev, rev);
1289 1288
1290 1289 /* set PCI command register */
1291 1290 cmdeg = pci_config_get16(statep->pcih, PCI_CONF_COMM);
1292 1291 pci_config_put16(statep->pcih, PCI_CONF_COMM,
1293 1292 cmdeg | PCI_COMM_IO | PCI_COMM_MAE);
1294 1293
1295 1294 statep->ac97 = ac97_alloc(dip, audioixp_rd97, audioixp_wr97, statep);
1296 1295 if (statep->ac97 == NULL) {
1297 1296 audio_dev_warn(adev, "failed to allocate ac97 handle");
1298 1297 goto error;
1299 1298 }
1300 1299
1301 1300 /* allocate port structures */
1302 1301 if ((audioixp_alloc_port(statep, IXP_PLAY) != DDI_SUCCESS) ||
1303 1302 (audioixp_alloc_port(statep, IXP_REC) != DDI_SUCCESS)) {
1304 1303 goto error;
1305 1304 }
1306 1305
1307 1306 /*
1308 1307 * If we have locked in a stereo configuration, then don't expose
1309 1308 * multichannel-specific AC'97 codec controls.
1310 1309 */
1311 1310 if (statep->play_port->nchan == 2) {
1312 1311 int i;
1313 1312 ac97_ctrl_t *ctrl;
1314 1313 const char *name;
1315 1314
1316 1315 for (i = 0; (name = audioixp_remove_ac97[i]) != NULL; i++) {
1317 1316 ctrl = ac97_control_find(statep->ac97, name);
1318 1317 if (ctrl != NULL) {
1319 1318 ac97_control_unregister(ctrl);
1320 1319 }
1321 1320 }
1322 1321 }
1323 1322
1324 1323 if (audioixp_chip_init(statep) != DDI_SUCCESS) {
1325 1324 audio_dev_warn(statep->adev, "failed to init chip");
1326 1325 goto error;
1327 1326 }
1328 1327
1329 1328 /* initialize the AC'97 part */
1330 1329 if (ac97_init(statep->ac97, adev) != DDI_SUCCESS) {
1331 1330 audio_dev_warn(adev, "ac'97 initialization failed");
1332 1331 goto error;
1333 1332 }
1334 1333
1335 1334 if (audio_dev_register(adev) != DDI_SUCCESS) {
1336 1335 audio_dev_warn(adev, "unable to register with framework");
1337 1336 goto error;
1338 1337 }
1339 1338
1340 1339 ddi_report_dev(dip);
1341 1340
1342 1341 return (DDI_SUCCESS);
1343 1342
1344 1343 error:
1345 1344 audioixp_destroy(statep);
1346 1345 return (DDI_FAILURE);
1347 1346 }
1348 1347
1349 1348 /*
1350 1349 * audioixp_detach()
1351 1350 *
1352 1351 * Description:
1353 1352 * Detach an instance of the audioixp driver.
1354 1353 *
1355 1354 * Arguments:
1356 1355 * dev_info_t *dip Pointer to the device's dev_info struct
1357 1356 *
1358 1357 * Returns:
1359 1358 * DDI_SUCCESS The driver was detached
1360 1359 * DDI_FAILURE The driver couldn't be detached
1361 1360 */
1362 1361 static int
1363 1362 audioixp_detach(dev_info_t *dip)
1364 1363 {
1365 1364 audioixp_state_t *statep;
1366 1365
1367 1366 statep = ddi_get_driver_private(dip);
1368 1367
1369 1368 if (audio_dev_unregister(statep->adev) != DDI_SUCCESS) {
1370 1369 return (DDI_FAILURE);
1371 1370 }
1372 1371
1373 1372 audioixp_destroy(statep);
1374 1373 return (DDI_SUCCESS);
1375 1374 }
1376 1375
1377 1376 /*
1378 1377 * audioixp_destroy()
1379 1378 *
1380 1379 * Description:
1381 1380 * This routine releases all resources held by the device instance,
1382 1381 * as part of either detach or a failure in attach.
1383 1382 *
1384 1383 * Arguments:
1385 1384 * audioixp_state_t *state The device soft state.
1386 1385 */
1387 1386 static void
1388 1387 audioixp_destroy(audioixp_state_t *statep)
1389 1388 {
1390 1389 /*
1391 1390 * put the audio controller into quiet state, everything off
1392 1391 */
1393 1392 CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_OUT_DMA);
1394 1393 CLR32(IXP_AUDIO_CMD, IXP_AUDIO_CMD_EN_IN_DMA);
1395 1394
1396 1395 audioixp_free_port(statep->play_port);
1397 1396 audioixp_free_port(statep->rec_port);
1398 1397
1399 1398 audioixp_unmap_regs(statep);
1400 1399
1401 1400 if (statep->ac97) {
1402 1401 ac97_free(statep->ac97);
1403 1402 }
1404 1403
1405 1404 if (statep->adev) {
1406 1405 audio_dev_free(statep->adev);
1407 1406 }
1408 1407
1409 1408 mutex_destroy(&statep->inst_lock);
1410 1409 kmem_free(statep, sizeof (*statep));
1411 1410 }
↓ open down ↓ |
1240 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX