xref: /illumos-gate/usr/src/uts/sun/io/audio/drv/audiocs/audio_4231.c (revision 68c47f65208790c466e5e484f2293d3baed71c6a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 
27 /*
28  * audiocs Audio Driver
29  *
30  * This Audio Driver controls the Crystal CS4231 Codec used on many SPARC
31  * platforms. It does not support the CS4231 on Power PCs or x86 PCs. It
32  * does support two different DMA engines, the APC and EB2. The code for
33  * those DMA engines is split out and a well defined, but private, interface
34  * is used to control those DMA engines.
35  *
36  * For some reason setting the CS4231's registers doesn't always
37  * succeed.  Therefore every time we set a register we always read it
38  * back to make sure it was set. If not we wait a little while and
39  * then try again. This is all taken care of in the routines
40  * audiocs_put_index() and audiocs_sel_index() and the macros ORIDX()
41  * and ANDIDX(). We don't worry about the status register because it
42  * is cleared by writing anything to it.  So it doesn't matter what
43  * the value written is.
44  *
45  * This driver supports suspending and resuming. A suspend just stops playing
46  * and recording. The play DMA buffers end up getting thrown away, but when
47  * you shut down the machine there is a break in the audio anyway, so they
48  * won't be missed and it isn't worth the effort to save them. When we resume
49  * we always start playing and recording. If they aren't needed they get
50  * shut off by the mixer.
51  *
52  * Power management is supported by this driver.
53  *
54  *	NOTE: This module depends on drv/audio being loaded first.
55  */
56 
57 #include <sys/modctl.h>
58 #include <sys/kmem.h>
59 #include <sys/stropts.h>
60 #include <sys/ddi.h>
61 #include <sys/sunddi.h>
62 #include <sys/note.h>
63 #include <sys/audio/audio_driver.h>
64 #include "audio_4231.h"
65 
66 /*
67  * Module linkage routines for the kernel
68  */
69 static int audiocs_ddi_attach(dev_info_t *, ddi_attach_cmd_t);
70 static int audiocs_ddi_detach(dev_info_t *, ddi_detach_cmd_t);
71 static int audiocs_ddi_power(dev_info_t *, int, int);
72 
73 /*
74  * Entry point routine prototypes
75  */
76 static int audiocs_open(void *, int, unsigned *, caddr_t *);
77 static void audiocs_close(void *);
78 static int audiocs_start(void *);
79 static void audiocs_stop(void *);
80 static int audiocs_format(void *);
81 static int audiocs_channels(void *);
82 static int audiocs_rate(void *);
83 static uint64_t audiocs_count(void *);
84 static void audiocs_sync(void *, unsigned);
85 
86 /*
87  * Control callbacks.
88  */
89 static int audiocs_get_value(void *, uint64_t *);
90 static int audiocs_set_ogain(void *, uint64_t);
91 static int audiocs_set_igain(void *, uint64_t);
92 static int audiocs_set_mgain(void *, uint64_t);
93 static int audiocs_set_inputs(void *, uint64_t);
94 static int audiocs_set_outputs(void *, uint64_t);
95 static int audiocs_set_micboost(void *, uint64_t);
96 
97 /* Local Routines */
98 static int audiocs_resume(dev_info_t *);
99 static int audiocs_attach(dev_info_t *);
100 static int audiocs_detach(dev_info_t *);
101 static int audiocs_suspend(dev_info_t *);
102 
103 static void audiocs_destroy(CS_state_t *);
104 static int audiocs_init_state(CS_state_t *);
105 static int audiocs_chip_init(CS_state_t *);
106 static int audiocs_alloc_engine(CS_state_t *, int);
107 static void audiocs_free_engine(CS_engine_t *);
108 static void audiocs_get_ports(CS_state_t *);
109 static void audiocs_configure_input(CS_state_t *);
110 static void audiocs_configure_output(CS_state_t *);
111 static CS_ctrl_t *audiocs_alloc_ctrl(CS_state_t *, uint32_t, uint64_t);
112 static void audiocs_free_ctrl(CS_ctrl_t *);
113 static int audiocs_add_controls(CS_state_t *);
114 static void audiocs_del_controls(CS_state_t *);
115 static void audiocs_power_up(CS_state_t *);
116 static void audiocs_power_down(CS_state_t *);
117 static int audiocs_poll_ready(CS_state_t *);
118 #ifdef	DEBUG
119 static void audiocs_put_index(CS_state_t *,  uint8_t, uint8_t, int);
120 static void audiocs_sel_index(CS_state_t *, uint8_t, int);
121 #define	SELIDX(s, idx)		audiocs_sel_index(s, idx, __LINE__)
122 #define	PUTIDX(s, val, mask)	audiocs_put_index(s, val, mask, __LINE__)
123 #else
124 static void audiocs_put_index(CS_state_t *,  uint8_t, uint8_t);
125 static void audiocs_sel_index(CS_state_t *, uint8_t);
126 #define	SELIDX(s, idx)		audiocs_sel_index(s, idx)
127 #define	PUTIDX(s, val, mask)	audiocs_put_index(s, val, mask)
128 #endif
129 #define	GETIDX(s)		ddi_get8((handle), &CS4231_IDR)
130 
131 #define	ORIDX(s, val, mask)						\
132 	PUTIDX(s,							\
133 	    (ddi_get8((handle), &CS4231_IDR) | (uint8_t)(val)),		\
134 	    (uint8_t)(mask))
135 
136 #define	ANDIDX(s, val, mask)						\
137 	PUTIDX(s, (ddi_get8((handle), &CS4231_IDR) & (uint8_t)(val)),	\
138 	    (uint8_t)(mask))
139 
140 static audio_engine_ops_t audiocs_engine_ops = {
141 	AUDIO_ENGINE_VERSION,
142 	audiocs_open,
143 	audiocs_close,
144 	audiocs_start,
145 	audiocs_stop,
146 	audiocs_count,
147 	audiocs_format,
148 	audiocs_channels,
149 	audiocs_rate,
150 	audiocs_sync,
151 	NULL,
152 	NULL,
153 	NULL,
154 };
155 
156 #define	OUTPUT_SPEAKER		0
157 #define	OUTPUT_HEADPHONES	1
158 #define	OUTPUT_LINEOUT		2
159 
160 static const char *audiocs_outputs[] = {
161 	AUDIO_PORT_SPEAKER,
162 	AUDIO_PORT_HEADPHONES,
163 	AUDIO_PORT_LINEOUT,
164 	NULL
165 };
166 
167 #define	INPUT_MIC		0
168 #define	INPUT_LINEIN		1
169 #define	INPUT_STEREOMIX		2
170 #define	INPUT_CD		3
171 
172 static const char *audiocs_inputs[] = {
173 	AUDIO_PORT_MIC,
174 	AUDIO_PORT_LINEIN,
175 	AUDIO_PORT_STEREOMIX,
176 	AUDIO_PORT_CD,
177 	NULL
178 };
179 
180 /*
181  * Global variables, but viewable only by this file.
182  */
183 
184 /* play gain array, converts linear gain to 64 steps of log10 gain */
185 static uint8_t cs4231_atten[] = {
186 	0x3f,	0x3e,	0x3d,	0x3c,	0x3b,	/* [000] -> [004] */
187 	0x3a,	0x39,	0x38,	0x37,	0x36,	/* [005] -> [009] */
188 	0x35,	0x34,	0x33,	0x32,	0x31,	/* [010] -> [014] */
189 	0x30,	0x2f,	0x2e,	0x2d,	0x2c,	/* [015] -> [019] */
190 	0x2b,	0x2a,	0x29,	0x29,	0x28,	/* [020] -> [024] */
191 	0x28,	0x27,	0x27,	0x26,	0x26,	/* [025] -> [029] */
192 	0x25,	0x25,	0x24,	0x24,	0x23,	/* [030] -> [034] */
193 	0x23,	0x22,	0x22,	0x21,	0x21,	/* [035] -> [039] */
194 	0x20,	0x20,	0x1f,	0x1f,	0x1f,	/* [040] -> [044] */
195 	0x1e,	0x1e,	0x1e,	0x1d,	0x1d,	/* [045] -> [049] */
196 	0x1d,	0x1c,	0x1c,	0x1c,	0x1b,	/* [050] -> [054] */
197 	0x1b,	0x1b,	0x1a,	0x1a,	0x1a,	/* [055] -> [059] */
198 	0x1a,	0x19,	0x19,	0x19,	0x19,	/* [060] -> [064] */
199 	0x18,	0x18,	0x18,	0x18,	0x17,	/* [065] -> [069] */
200 	0x17,	0x17,	0x17,	0x16,	0x16,	/* [070] -> [074] */
201 	0x16,	0x16,	0x16,	0x15,	0x15,	/* [075] -> [079] */
202 	0x15,	0x15,	0x15,	0x14,	0x14,	/* [080] -> [084] */
203 	0x14,	0x14,	0x14,	0x13,	0x13,	/* [085] -> [089] */
204 	0x13,	0x13,	0x13,	0x12,	0x12,	/* [090] -> [094] */
205 	0x12,	0x12,	0x12,	0x12,	0x11,	/* [095] -> [099] */
206 	0x11,	0x11,	0x11,	0x11,	0x11,	/* [100] -> [104] */
207 	0x10,	0x10,	0x10,	0x10,	0x10,	/* [105] -> [109] */
208 	0x10,	0x0f,	0x0f,	0x0f,	0x0f,	/* [110] -> [114] */
209 	0x0f,	0x0f,	0x0e,	0x0e,	0x0e,	/* [114] -> [119] */
210 	0x0e,	0x0e,	0x0e,	0x0e,	0x0d,	/* [120] -> [124] */
211 	0x0d,	0x0d,	0x0d,	0x0d,	0x0d,	/* [125] -> [129] */
212 	0x0d,	0x0c,	0x0c,	0x0c,	0x0c,	/* [130] -> [134] */
213 	0x0c,	0x0c,	0x0c,	0x0b,	0x0b,	/* [135] -> [139] */
214 	0x0b,	0x0b,	0x0b,	0x0b,	0x0b,	/* [140] -> [144] */
215 	0x0b,	0x0a,	0x0a,	0x0a,	0x0a,	/* [145] -> [149] */
216 	0x0a,	0x0a,	0x0a,	0x0a,	0x09,	/* [150] -> [154] */
217 	0x09,	0x09,	0x09,	0x09,	0x09,	/* [155] -> [159] */
218 	0x09,	0x09,	0x08,	0x08,	0x08,	/* [160] -> [164] */
219 	0x08,	0x08,	0x08,	0x08,	0x08,	/* [165] -> [169] */
220 	0x08,	0x07,	0x07,	0x07,	0x07,	/* [170] -> [174] */
221 	0x07,	0x07,	0x07,	0x07,	0x07,	/* [175] -> [179] */
222 	0x06,	0x06,	0x06,	0x06,	0x06,	/* [180] -> [184] */
223 	0x06,	0x06,	0x06,	0x06,	0x05,	/* [185] -> [189] */
224 	0x05,	0x05,	0x05,	0x05,	0x05,	/* [190] -> [194] */
225 	0x05,	0x05,	0x05,	0x05,	0x04,	/* [195] -> [199] */
226 	0x04,	0x04,	0x04,	0x04,	0x04,	/* [200] -> [204] */
227 	0x04,	0x04,	0x04,	0x04,	0x03,	/* [205] -> [209] */
228 	0x03,	0x03,	0x03,	0x03,	0x03,	/* [210] -> [214] */
229 	0x03,	0x03,	0x03,	0x03,	0x03,	/* [215] -> [219] */
230 	0x02,	0x02,	0x02,	0x02,	0x02,	/* [220] -> [224] */
231 	0x02,	0x02,	0x02,	0x02,	0x02,	/* [225] -> [229] */
232 	0x02,	0x01,	0x01,	0x01,	0x01,	/* [230] -> [234] */
233 	0x01,	0x01,	0x01,	0x01,	0x01,	/* [235] -> [239] */
234 	0x01,	0x01,	0x01,	0x00,	0x00,	/* [240] -> [244] */
235 	0x00,	0x00,	0x00,	0x00,	0x00,	/* [245] -> [249] */
236 	0x00,	0x00,	0x00,	0x00,	0x00,	/* [250] -> [254] */
237 	0x00					/* [255] */
238 };
239 
240 /*
241  * STREAMS Structures
242  */
243 
244 /*
245  * DDI Structures
246  */
247 
248 /* Device operations structure */
249 static struct dev_ops audiocs_dev_ops = {
250 	DEVO_REV,			/* devo_rev */
251 	0,				/* devo_refcnt */
252 	NULL,				/* devo_getinfo */
253 	nulldev,			/* devo_identify - obsolete */
254 	nulldev,			/* devo_probe - not needed */
255 	audiocs_ddi_attach,		/* devo_attach */
256 	audiocs_ddi_detach,		/* devo_detach */
257 	nodev,				/* devo_reset */
258 	NULL,				/* devi_cb_ops */
259 	NULL,				/* devo_bus_ops */
260 	audiocs_ddi_power,		/* devo_power */
261 	ddi_quiesce_not_supported,	/* devo_quiesce */
262 };
263 
264 /* Linkage structure for loadable drivers */
265 static struct modldrv audiocs_modldrv = {
266 	&mod_driverops,		/* drv_modops */
267 	CS4231_MOD_NAME,	/* drv_linkinfo */
268 	&audiocs_dev_ops	/* drv_dev_ops */
269 };
270 
271 /* Module linkage structure */
272 static struct modlinkage audiocs_modlinkage = {
273 	MODREV_1,			/* ml_rev */
274 	(void *)&audiocs_modldrv,	/* ml_linkage */
275 	NULL				/* NULL terminates the list */
276 };
277 
278 
279 /* *******  Loadable Module Configuration Entry Points  ********************* */
280 
281 /*
282  * _init()
283  *
284  * Description:
285  *	Implements _init(9E).
286  *
287  * Returns:
288  *	mod_install() status, see mod_install(9f)
289  */
290 int
_init(void)291 _init(void)
292 {
293 	int	rv;
294 
295 	audio_init_ops(&audiocs_dev_ops, CS4231_NAME);
296 
297 	if ((rv = mod_install(&audiocs_modlinkage)) != 0) {
298 		audio_fini_ops(&audiocs_dev_ops);
299 	}
300 
301 	return (rv);
302 }
303 
304 /*
305  * _fini()
306  *
307  * Description:
308  *	Implements _fini(9E).
309  *
310  * Returns:
311  *	mod_remove() status, see mod_remove(9f)
312  */
313 int
_fini(void)314 _fini(void)
315 {
316 	int	rv;
317 
318 	if ((rv = mod_remove(&audiocs_modlinkage)) == 0) {
319 		audio_fini_ops(&audiocs_dev_ops);
320 	}
321 
322 	return (rv);
323 }
324 
325 /*
326  * _info()
327  *
328  * Description:
329  *	Implements _info(9E).
330  *
331  * Arguments:
332  *	modinfo *modinfop	Pointer to the opaque modinfo structure
333  *
334  * Returns:
335  *	mod_info() status, see mod_info(9f)
336  */
337 int
_info(struct modinfo * modinfop)338 _info(struct modinfo *modinfop)
339 {
340 	return (mod_info(&audiocs_modlinkage, modinfop));
341 }
342 
343 
344 /* *******  Driver Entry Points  ******************************************** */
345 
346 /*
347  * audiocs_ddi_attach()
348  *
349  * Description:
350  *	Implement attach(9e).
351  *
352  * Arguments:
353  *	dev_info_t	*dip	Pointer to the device's dev_info struct
354  *	ddi_attach_cmd_t cmd	Attach command
355  *
356  * Returns:
357  *	DDI_SUCCESS		The driver was initialized properly
358  *	DDI_FAILURE		The driver couldn't be initialized properly
359  */
360 static int
audiocs_ddi_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)361 audiocs_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
362 {
363 	switch (cmd) {
364 	case DDI_ATTACH:
365 		return (audiocs_attach(dip));
366 
367 	case DDI_RESUME:
368 		return (audiocs_resume(dip));
369 
370 	default:
371 		return (DDI_FAILURE);
372 	}
373 }
374 
375 /*
376  * audiocs_ddi_detach()
377  *
378  * Description:
379  *	Implement detach(9e).
380  *
381  * Arguments:
382  *	dev_info_t	*dip	Pointer to the device's dev_info struct
383  *	ddi_detach_cmd_t cmd	Detach command
384  *
385  * Returns:
386  *	DDI_SUCCESS		Success.
387  *	DDI_FAILURE		Failure.
388  */
389 static int
audiocs_ddi_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)390 audiocs_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
391 {
392 	switch (cmd) {
393 	case DDI_DETACH:
394 		return (audiocs_detach(dip));
395 
396 	case DDI_SUSPEND:
397 		return (audiocs_suspend(dip));
398 
399 	default:
400 		return (DDI_FAILURE);
401 	}
402 }
403 
404 /*
405  * audiocs_ddi_power()
406  *
407  * Description:
408  *	Implements power(9E).
409  *
410  * Arguments:
411  *	def_info_t	*dip		Ptr to the device's dev_info structure
412  *	int		component	Which component to power up/down
413  *	int		level		The power level for the component
414  *
415  * Returns:
416  *	DDI_SUCCESS		Power level changed, we always succeed
417  */
418 static int
audiocs_ddi_power(dev_info_t * dip,int component,int level)419 audiocs_ddi_power(dev_info_t *dip, int component, int level)
420 {
421 	CS_state_t		*state;
422 
423 	if (component != CS4231_COMPONENT)
424 		return (DDI_FAILURE);
425 
426 	/* get the state structure */
427 	state = ddi_get_driver_private(dip);
428 
429 	ASSERT(!mutex_owned(&state->cs_lock));
430 
431 	/* make sure we have some work to do */
432 	mutex_enter(&state->cs_lock);
433 
434 	/*
435 	 * We don't do anything if we're suspended.  Suspend/resume diddles
436 	 * with power anyway.
437 	 */
438 	if (!state->cs_suspended) {
439 
440 		/* check the level change to see what we need to do */
441 		if (level == CS4231_PWR_OFF && state->cs_powered) {
442 
443 			/* power down and save the state */
444 			audiocs_power_down(state);
445 			state->cs_powered = B_FALSE;
446 
447 		} else if (level == CS4231_PWR_ON && !state->cs_powered) {
448 
449 			/* power up */
450 			audiocs_power_up(state);
451 			state->cs_powered = B_TRUE;
452 		}
453 	}
454 
455 	mutex_exit(&state->cs_lock);
456 
457 	ASSERT(!mutex_owned(&state->cs_lock));
458 
459 	return (DDI_SUCCESS);
460 }
461 
462 /* ******* Local Routines *************************************************** */
463 
464 static void
audiocs_destroy(CS_state_t * state)465 audiocs_destroy(CS_state_t *state)
466 {
467 	if (state == NULL)
468 		return;
469 
470 	for (int i = CS4231_PLAY; i <= CS4231_REC; i++) {
471 		audiocs_free_engine(state->cs_engines[i]);
472 	}
473 	audiocs_del_controls(state);
474 
475 	if (state->cs_adev) {
476 		audio_dev_free(state->cs_adev);
477 	}
478 
479 	/* unmap the registers */
480 	CS4231_DMA_UNMAP_REGS(state);
481 
482 	/* destroy the state mutex */
483 	mutex_destroy(&state->cs_lock);
484 	kmem_free(state, sizeof (*state));
485 }
486 
487 /*
488  * audiocs_attach()
489  *
490  * Description:
491  *	Attach an instance of the CS4231 driver. This routine does the device
492  *	dependent attach tasks.  When it is complete it calls
493  *	audio_dev_register() to register with the framework.
494  *
495  * Arguments:
496  *	dev_info_t	*dip	Pointer to the device's dev_info struct
497  *
498  * Returns:
499  *	DDI_SUCCESS		The driver was initialized properly
500  *	DDI_FAILURE		The driver couldn't be initialized properly
501  */
502 static int
audiocs_attach(dev_info_t * dip)503 audiocs_attach(dev_info_t *dip)
504 {
505 	CS_state_t		*state;
506 	audio_dev_t		*adev;
507 
508 	/* allocate the state structure */
509 	state = kmem_zalloc(sizeof (*state), KM_SLEEP);
510 	state->cs_dip = dip;
511 	ddi_set_driver_private(dip, state);
512 
513 	/* now fill it in, initialize the state mutexs first */
514 	mutex_init(&state->cs_lock, NULL, MUTEX_DRIVER, NULL);
515 
516 	/*
517 	 * audio state initialization... should always succeed,
518 	 * framework will message failure.
519 	 */
520 	if ((state->cs_adev = audio_dev_alloc(dip, 0)) == NULL) {
521 		goto error;
522 	}
523 	adev = state->cs_adev;
524 	audio_dev_set_description(adev, CS_DEV_CONFIG_ONBRD1);
525 	audio_dev_add_info(adev, "Legacy codec: Crystal Semiconductor CS4231");
526 
527 	/* initialize the audio state structures */
528 	if ((audiocs_init_state(state)) == DDI_FAILURE) {
529 		audio_dev_warn(adev, "init_state() failed");
530 		goto error;
531 	}
532 
533 	mutex_enter(&state->cs_lock);
534 
535 	/* initialize the audio chip */
536 	if ((audiocs_chip_init(state)) == DDI_FAILURE) {
537 		mutex_exit(&state->cs_lock);
538 		audio_dev_warn(adev, "chip_init() failed");
539 		goto error;
540 	}
541 	/* chip init will have powered us up */
542 	state->cs_powered = B_TRUE;
543 
544 	mutex_exit(&state->cs_lock);
545 
546 	/* finally register with framework to kick everything off */
547 	if (audio_dev_register(state->cs_adev) != DDI_SUCCESS) {
548 		audio_dev_warn(state->cs_adev, "unable to register audio dev");
549 	}
550 
551 	/* everything worked out, so report the device */
552 	ddi_report_dev(dip);
553 
554 	return (DDI_SUCCESS);
555 
556 error:
557 	audiocs_destroy(state);
558 	return (DDI_FAILURE);
559 }
560 
561 /*
562  * audiocs_resume()
563  *
564  * Description:
565  *	Resume a suspended device instance.
566  *
567  * Arguments:
568  *	dev_info_t	*dip	Pointer to the device's dev_info struct
569  *
570  * Returns:
571  *	DDI_SUCCESS		The driver was initialized properly
572  *	DDI_FAILURE		The driver couldn't be initialized properly
573  */
574 static int
audiocs_resume(dev_info_t * dip)575 audiocs_resume(dev_info_t *dip)
576 {
577 	CS_state_t		*state;
578 	audio_dev_t		*adev;
579 
580 	/* we've already allocated the state structure so get ptr */
581 	state = ddi_get_driver_private(dip);
582 	adev = state->cs_adev;
583 
584 	ASSERT(dip == state->cs_dip);
585 	ASSERT(!mutex_owned(&state->cs_lock));
586 
587 	/* mark the Codec busy -- this should keep power(9e) away */
588 	(void) pm_busy_component(state->cs_dip, CS4231_COMPONENT);
589 
590 	/* power it up */
591 	audiocs_power_up(state);
592 	state->cs_powered = B_TRUE;
593 
594 	mutex_enter(&state->cs_lock);
595 
596 	/* initialize the audio chip */
597 	if ((audiocs_chip_init(state)) == DDI_FAILURE) {
598 		mutex_exit(&state->cs_lock);
599 		audio_dev_warn(adev, "chip_init() failed");
600 		(void) pm_idle_component(state->cs_dip, CS4231_COMPONENT);
601 		return (DDI_FAILURE);
602 	}
603 
604 	state->cs_suspended = B_FALSE;
605 
606 	mutex_exit(&state->cs_lock);
607 
608 	/*
609 	 * We have already powered up the chip, but this alerts the
610 	 * framework to the fact.
611 	 */
612 	(void) pm_raise_power(dip, CS4231_COMPONENT, CS4231_PWR_ON);
613 	(void) pm_idle_component(state->cs_dip, CS4231_COMPONENT);
614 
615 	audio_dev_resume(state->cs_adev);
616 
617 	return (DDI_SUCCESS);
618 }
619 
620 /*
621  * audiocs_detach()
622  *
623  * Description:
624  *	Detach an instance of the CS4231 driver.
625  *
626  * Arguments:
627  *	dev_info_t	*dip	Pointer to the device's dev_info struct
628  *
629  * Returns:
630  *	DDI_SUCCESS		The driver was detached
631  *	DDI_FAILURE		The driver couldn't be detached (busy)
632  */
633 static int
audiocs_detach(dev_info_t * dip)634 audiocs_detach(dev_info_t *dip)
635 {
636 	CS_state_t		*state;
637 	audio_dev_t		*adev;
638 	ddi_acc_handle_t	handle;
639 
640 	/* get the state structure */
641 	state = ddi_get_driver_private(dip);
642 	handle = CODEC_HANDLE;
643 	adev = state->cs_adev;
644 
645 	/* don't detach if still in use */
646 	if (audio_dev_unregister(adev) != DDI_SUCCESS) {
647 		return (DDI_FAILURE);
648 	}
649 
650 	if (state->cs_powered) {
651 		/*
652 		 * Make sure the Codec and DMA engine are off.
653 		 */
654 		SELIDX(state, INTC_REG);
655 		ANDIDX(state, ~(INTC_PEN|INTC_CEN), INTC_VALID_MASK);
656 
657 		/* make sure the DMA engine isn't going to do anything */
658 		CS4231_DMA_RESET(state);
659 
660 		/*
661 		 * power down the device, no reason to waste power without
662 		 * a driver
663 		 */
664 		(void) pm_lower_power(dip, CS4231_COMPONENT, CS4231_PWR_OFF);
665 	}
666 
667 	audiocs_destroy(state);
668 
669 	return (DDI_SUCCESS);
670 }
671 
672 /*
673  * audiocs_suspend()
674  *
675  * Description:
676  *	Suspend an instance of the CS4231 driver.
677  *
678  * Arguments:
679  *	dev_info_t	*dip	Pointer to the device's dev_info struct
680  *
681  * Returns:
682  *	DDI_SUCCESS		The driver was detached
683  *	DDI_FAILURE		The driver couldn't be detached
684  */
685 static int
audiocs_suspend(dev_info_t * dip)686 audiocs_suspend(dev_info_t *dip)
687 {
688 	CS_state_t		*state;
689 
690 	/* get the state structure */
691 	state = ddi_get_driver_private(dip);
692 
693 	mutex_enter(&state->cs_lock);
694 
695 	ASSERT(!state->cs_suspended);
696 
697 	audio_dev_suspend(state->cs_adev);
698 
699 	if (state->cs_powered) {
700 		/* now we can power down the Codec */
701 		audiocs_power_down(state);
702 		state->cs_powered = B_FALSE;
703 	}
704 	state->cs_suspended = B_TRUE;	/* stop new ops */
705 	mutex_exit(&state->cs_lock);
706 
707 	return (DDI_SUCCESS);
708 }
709 
710 #define	PLAYCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_PLAY)
711 #define	RECCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_REC)
712 #define	MONCTL	(AUDIO_CTRL_FLAG_RW | AUDIO_CTRL_FLAG_MONITOR)
713 #define	PCMVOL	(PLAYCTL | AUDIO_CTRL_FLAG_PCMVOL)
714 #define	MAINVOL	(PLAYCTL | AUDIO_CTRL_FLAG_MAINVOL)
715 #define	RECVOL	(RECCTL | AUDIO_CTRL_FLAG_RECVOL)
716 #define	MONVOL	(MONCTL | AUDIO_CTRL_FLAG_MONVOL)
717 
718 /*
719  * audiocs_alloc_ctrl
720  *
721  * Description:
722  *	Allocates a control structure for the audio mixer.
723  *
724  * Arguments:
725  *	CS_state_t	*state		Device soft state.
726  *	uint32_t	num		Control number to allocate.
727  *	uint64_t	val		Initial value.
728  *
729  * Returns:
730  *	Pointer to newly allocated CS_ctrl_t structure.
731  */
732 static CS_ctrl_t *
audiocs_alloc_ctrl(CS_state_t * state,uint32_t num,uint64_t val)733 audiocs_alloc_ctrl(CS_state_t *state, uint32_t num, uint64_t val)
734 {
735 	audio_ctrl_desc_t	desc;
736 	audio_ctrl_wr_t		fn;
737 	CS_ctrl_t		*cc;
738 
739 	cc = kmem_zalloc(sizeof (*cc), KM_SLEEP);
740 	cc->cc_state = state;
741 	cc->cc_num = num;
742 
743 	bzero(&desc, sizeof (desc));
744 
745 	switch (num) {
746 	case CTL_VOLUME:
747 		desc.acd_name = AUDIO_CTRL_ID_VOLUME;
748 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
749 		desc.acd_minvalue = 0;
750 		desc.acd_maxvalue = 100;
751 		desc.acd_flags = PCMVOL;
752 		fn = audiocs_set_ogain;
753 		break;
754 
755 	case CTL_IGAIN:
756 		desc.acd_name = AUDIO_CTRL_ID_RECGAIN;
757 		desc.acd_type = AUDIO_CTRL_TYPE_STEREO;
758 		desc.acd_minvalue = 0;
759 		desc.acd_maxvalue = 100;
760 		desc.acd_flags = RECVOL;
761 		fn = audiocs_set_igain;
762 		break;
763 
764 	case CTL_MGAIN:
765 		desc.acd_name = AUDIO_CTRL_ID_MONGAIN;
766 		desc.acd_type = AUDIO_CTRL_TYPE_MONO;
767 		desc.acd_minvalue = 0;
768 		desc.acd_maxvalue = 100;
769 		desc.acd_flags = MONVOL;
770 		fn = audiocs_set_mgain;
771 		break;
772 
773 	case CTL_INPUTS:
774 		desc.acd_name = AUDIO_CTRL_ID_RECSRC;
775 		desc.acd_type = AUDIO_CTRL_TYPE_ENUM;
776 		desc.acd_minvalue = state->cs_imask;
777 		desc.acd_maxvalue = state->cs_imask;
778 		desc.acd_flags = RECCTL;
779 		for (int i = 0; audiocs_inputs[i]; i++) {
780 			desc.acd_enum[i] = audiocs_inputs[i];
781 		}
782 		fn = audiocs_set_inputs;
783 
784 		break;
785 
786 	case CTL_OUTPUTS:
787 		desc.acd_name = AUDIO_CTRL_ID_OUTPUTS;
788 		desc.acd_type = AUDIO_CTRL_TYPE_ENUM;
789 		desc.acd_minvalue = state->cs_omod;
790 		desc.acd_maxvalue = state->cs_omask;
791 		desc.acd_flags = PLAYCTL | AUDIO_CTRL_FLAG_MULTI;
792 		for (int i = 0; audiocs_outputs[i]; i++) {
793 			desc.acd_enum[i] = audiocs_outputs[i];
794 		}
795 		fn = audiocs_set_outputs;
796 		break;
797 
798 	case CTL_MICBOOST:
799 		desc.acd_name = AUDIO_CTRL_ID_MICBOOST;
800 		desc.acd_type = AUDIO_CTRL_TYPE_BOOLEAN;
801 		desc.acd_minvalue = 0;
802 		desc.acd_maxvalue = 1;
803 		desc.acd_flags = RECCTL;
804 		fn = audiocs_set_micboost;
805 		break;
806 	}
807 
808 	cc->cc_val = val;
809 	cc->cc_ctrl = audio_dev_add_control(state->cs_adev, &desc,
810 	    audiocs_get_value, fn, cc);
811 
812 	return (cc);
813 }
814 
815 /*
816  * audiocs_free_ctrl
817  *
818  * Description:
819  *	Frees a control and all resources associated with it.
820  *
821  * Arguments:
822  *	CS_ctrl_t	*cc	Pointer to control structure.
823  */
824 static void
audiocs_free_ctrl(CS_ctrl_t * cc)825 audiocs_free_ctrl(CS_ctrl_t *cc)
826 {
827 	if (cc == NULL)
828 		return;
829 	if (cc->cc_ctrl)
830 		audio_dev_del_control(cc->cc_ctrl);
831 	kmem_free(cc, sizeof (*cc));
832 }
833 
834 /*
835  * audiocs_add_controls
836  *
837  * Description:
838  *	Allocates and registers all controls for this device.
839  *
840  * Arguments:
841  *	CS_state_t	*state		Device soft state.
842  *
843  * Returns:
844  *	DDI_SUCCESS	All controls added and registered
845  *	DDI_FAILURE	At least one control was not added or registered.
846  */
847 static int
audiocs_add_controls(CS_state_t * state)848 audiocs_add_controls(CS_state_t *state)
849 {
850 #define	ADD_CTRL(CTL, ID, VAL)						\
851 	state->cs_##CTL = audiocs_alloc_ctrl(state, ID, VAL);		\
852 	if (state->cs_##CTL == NULL) {					\
853 		audio_dev_warn(state->cs_adev,				\
854 		    "unable to allocate %s control", #ID);		\
855 		return (DDI_FAILURE);					\
856 	}
857 
858 	ADD_CTRL(ogain, CTL_VOLUME, 0x4b4b);
859 	ADD_CTRL(igain, CTL_IGAIN, 0x3232);
860 	ADD_CTRL(mgain, CTL_MGAIN, 0);
861 	ADD_CTRL(micboost, CTL_MICBOOST, 0);
862 	ADD_CTRL(outputs, CTL_OUTPUTS, (state->cs_omask & ~state->cs_omod) |
863 	    (1U << OUTPUT_SPEAKER));
864 	ADD_CTRL(inputs, CTL_INPUTS, (1U << INPUT_MIC));
865 
866 	return (DDI_SUCCESS);
867 }
868 
869 /*
870  * audiocs_del_controls
871  *
872  * Description:
873  *	Unregisters and frees all controls for this device.
874  *
875  * Arguments:
876  *	CS_state_t	*state		Device soft state.
877  */
878 void
audiocs_del_controls(CS_state_t * state)879 audiocs_del_controls(CS_state_t *state)
880 {
881 	audiocs_free_ctrl(state->cs_ogain);
882 	audiocs_free_ctrl(state->cs_igain);
883 	audiocs_free_ctrl(state->cs_mgain);
884 	audiocs_free_ctrl(state->cs_micboost);
885 	audiocs_free_ctrl(state->cs_inputs);
886 	audiocs_free_ctrl(state->cs_outputs);
887 }
888 
889 
890 /*
891  * audiocs_chip_init()
892  *
893  * Description:
894  *	Power up the audio core, initialize the audio Codec, prepare the chip
895  *	for use.
896  *
897  * Arguments:
898  *	CS_state_t	*state		The device's state structure
899  *
900  * Returns:
901  *	DDI_SUCCESS			Chip initialized and ready to use
902  *	DDI_FAILURE			Chip not initialized and not ready
903  */
904 static int
audiocs_chip_init(CS_state_t * state)905 audiocs_chip_init(CS_state_t *state)
906 {
907 	ddi_acc_handle_t	handle = CODEC_HANDLE;
908 
909 	/* make sure we are powered up */
910 	CS4231_DMA_POWER(state, CS4231_PWR_ON);
911 
912 	CS4231_DMA_RESET(state);
913 
914 	/* wait for the Codec before we continue */
915 	if (audiocs_poll_ready(state) == DDI_FAILURE) {
916 		return (DDI_FAILURE);
917 	}
918 
919 	/* activate registers 16 -> 31 */
920 	SELIDX(state, MID_REG);
921 	ddi_put8(handle, &CS4231_IDR, MID_MODE2);
922 
923 	/* now figure out what version we have */
924 	SELIDX(state, VID_REG);
925 	if (ddi_get8(handle, &CS4231_IDR) & VID_A) {
926 		state->cs_revA = B_TRUE;
927 	} else {
928 		state->cs_revA = B_FALSE;
929 	}
930 
931 	/* get rid of annoying popping by muting the output channels */
932 	SELIDX(state, LDACO_REG);
933 	PUTIDX(state, LDACO_LDM | LDACO_MID_GAIN, LDAC0_VALID_MASK);
934 	SELIDX(state, RDACO_REG);
935 	PUTIDX(state, RDACO_RDM | RDACO_MID_GAIN, RDAC0_VALID_MASK);
936 
937 	/* initialize aux input channels to known gain values & muted */
938 	SELIDX(state, LAUX1_REG);
939 	PUTIDX(state, LAUX1_LX1M | LAUX1_UNITY_GAIN, LAUX1_VALID_MASK);
940 	SELIDX(state, RAUX1_REG);
941 	PUTIDX(state, RAUX1_RX1M | RAUX1_UNITY_GAIN, RAUX1_VALID_MASK);
942 	SELIDX(state, LAUX2_REG);
943 	PUTIDX(state, LAUX2_LX2M | LAUX2_UNITY_GAIN, LAUX2_VALID_MASK);
944 	SELIDX(state, RAUX2_REG);
945 	PUTIDX(state, RAUX2_RX2M | RAUX2_UNITY_GAIN, RAUX2_VALID_MASK);
946 
947 	/* initialize aux input channels to known gain values & muted */
948 	SELIDX(state, LLIC_REG);
949 	PUTIDX(state, LLIC_LLM | LLIC_UNITY_GAIN, LLIC_VALID_MASK);
950 	SELIDX(state, RLIC_REG);
951 	PUTIDX(state, RLIC_RLM | RLIC_UNITY_GAIN, RLIC_VALID_MASK);
952 
953 	/* program the sample rate, play and capture must be the same */
954 	SELIDX(state, FSDF_REG | IAR_MCE);
955 	PUTIDX(state, FS_48000 | PDF_LINEAR16NE | PDF_STEREO, FSDF_VALID_MASK);
956 	if (audiocs_poll_ready(state) == DDI_FAILURE) {
957 		return (DDI_FAILURE);
958 	}
959 
960 	SELIDX(state, CDF_REG | IAR_MCE);
961 	PUTIDX(state, CDF_LINEAR16NE | CDF_STEREO, CDF_VALID_MASK);
962 	if (audiocs_poll_ready(state) == DDI_FAILURE) {
963 		return (DDI_FAILURE);
964 	}
965 
966 	/*
967 	 * Set up the Codec for playback and capture disabled, dual DMA, and
968 	 * playback and capture DMA.
969 	 */
970 	SELIDX(state, (INTC_REG | IAR_MCE));
971 	PUTIDX(state, INTC_DDC | INTC_PDMA | INTC_CDMA, INTC_VALID_MASK);
972 	if (audiocs_poll_ready(state) == DDI_FAILURE) {
973 		return (DDI_FAILURE);
974 	}
975 
976 	/*
977 	 * Turn on the output level bit to be 2.8 Vpp. Also, don't go to 0 on
978 	 * underflow.
979 	 */
980 	SELIDX(state, AFE1_REG);
981 	PUTIDX(state, AFE1_OLB, AFE1_VALID_MASK);
982 
983 	/* turn on the high pass filter if Rev A */
984 	SELIDX(state, AFE2_REG);
985 	if (state->cs_revA) {
986 		PUTIDX(state, AFE2_HPF, AFE2_VALID_MASK);
987 	} else {
988 		PUTIDX(state, 0, AFE2_VALID_MASK);
989 	}
990 
991 
992 	/* clear the play and capture interrupt flags */
993 	SELIDX(state, AFS_REG);
994 	ddi_put8(handle, &CS4231_STATUS, (AFS_RESET_STATUS));
995 
996 	/* the play and record gains will be set by the audio mixer */
997 
998 	/* unmute the output */
999 	SELIDX(state, LDACO_REG);
1000 	ANDIDX(state, ~LDACO_LDM, LDAC0_VALID_MASK);
1001 	SELIDX(state, RDACO_REG);
1002 	ANDIDX(state, ~RDACO_RDM, RDAC0_VALID_MASK);
1003 
1004 	/* unmute the mono speaker and mute mono in */
1005 	SELIDX(state, MIOC_REG);
1006 	PUTIDX(state, MIOC_MIM, MIOC_VALID_MASK);
1007 
1008 	audiocs_configure_output(state);
1009 	audiocs_configure_input(state);
1010 
1011 	return (DDI_SUCCESS);
1012 }
1013 
1014 /*
1015  * audiocs_init_state()
1016  *
1017  * Description:
1018  *	This routine initializes the audio driver's state structure and
1019  *	maps in the registers. This also includes reading the properties.
1020  *
1021  *	CAUTION: This routine maps the registers and initializes a mutex.
1022  *		 Failure cleanup is handled by cs4231_attach(). It is not
1023  *		 handled locally by this routine.
1024  *
1025  * Arguments:
1026  *	CS_state_t	*state		The device's state structure
1027  *
1028  * Returns:
1029  *	DDI_SUCCESS			State structure initialized
1030  *	DDI_FAILURE			State structure not initialized
1031  */
1032 static int
audiocs_init_state(CS_state_t * state)1033 audiocs_init_state(CS_state_t *state)
1034 {
1035 	audio_dev_t	*adev = state->cs_adev;
1036 	dev_info_t	*dip = state->cs_dip;
1037 	char		*prop_str;
1038 	char		*pm_comp[] = {
1039 				"NAME=audiocs audio device",
1040 				"0=off",
1041 				"1=on" };
1042 
1043 	/* set up the pm-components */
1044 	if (ddi_prop_update_string_array(DDI_DEV_T_NONE, dip,
1045 	    "pm-components", pm_comp, 3) != DDI_PROP_SUCCESS) {
1046 		audio_dev_warn(adev, "couldn't create pm-components property");
1047 		return (DDI_FAILURE);
1048 	}
1049 
1050 	/* figure out which DMA engine hardware we have */
1051 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1052 	    "dma-model", &prop_str) == DDI_PROP_SUCCESS) {
1053 		if (strcmp(prop_str, "eb2dma") == 0) {
1054 			state->cs_dma_engine = EB2_DMA;
1055 			state->cs_dma_ops = &cs4231_eb2dma_ops;
1056 		} else {
1057 			state->cs_dma_engine = APC_DMA;
1058 			state->cs_dma_ops = &cs4231_apcdma_ops;
1059 		}
1060 		ddi_prop_free(prop_str);
1061 	} else {
1062 		state->cs_dma_engine = APC_DMA;
1063 		state->cs_dma_ops = &cs4231_apcdma_ops;
1064 	}
1065 
1066 	/* cs_regs, cs_eb2_regs and cs_handles filled in later */
1067 
1068 	/* most of what's left is filled in when the registers are mapped */
1069 
1070 	audiocs_get_ports(state);
1071 
1072 	/* Allocate engines, must be done before register mapping called  */
1073 	if ((audiocs_alloc_engine(state, CS4231_PLAY) != DDI_SUCCESS) ||
1074 	    (audiocs_alloc_engine(state, CS4231_REC) != DDI_SUCCESS)) {
1075 		return (DDI_FAILURE);
1076 	}
1077 
1078 	/* Map in the registers */
1079 	if (CS4231_DMA_MAP_REGS(state) == DDI_FAILURE) {
1080 		return (DDI_FAILURE);
1081 	}
1082 
1083 
1084 	/* Allocate and add controls, must be done *after* registers mapped */
1085 	if (audiocs_add_controls(state) != DDI_SUCCESS) {
1086 		return (DDI_FAILURE);
1087 	}
1088 
1089 	state->cs_suspended = B_FALSE;
1090 	state->cs_powered = B_FALSE;
1091 
1092 	return (DDI_SUCCESS);
1093 }
1094 
1095 /*
1096  * audiocs_get_ports()
1097  *
1098  * Description:
1099  *	Get which audiocs h/w version we have and use this to
1100  *	determine the input and output ports as well whether or not
1101  *	the hardware has internal loopbacks or not. We also have three
1102  *	different ways for the properties to be specified, which we
1103  *	also need to worry about.
1104  *
1105  * Vers	Platform(s)	DMA eng.	audio-module**	loopback
1106  * a    SS-4+/SS-5+	apcdma		no		no
1107  * b	Ultra-1&2	apcdma		no		yes
1108  * c	positron	apcdma		no		yes
1109  * d	PPC - retired
1110  * e	x86 - retired
1111  * f	tazmo		eb2dma		Perigee		no
1112  * g	tazmo		eb2dma		Quark		yes
1113  * h	darwin+		eb2dma		no		N/A
1114  *
1115  * Vers	model~		aux1*		aux2*
1116  * a	N/A		N/A		N/A
1117  * b	N/A		N/A		N/A
1118  * c	N/A		N/A		N/A
1119  * d	retired
1120  * e	retired
1121  * f	SUNW,CS4231f	N/A		N/A
1122  * g	SUNW,CS4231g	N/A		N/A
1123  * h	SUNW,CS4231h	cdrom		none
1124  *
1125  * *   = Replaces internal-loopback for latest property type, can be
1126  *	 set to "cdrom", "loopback", or "none".
1127  *
1128  * **  = For plugin audio modules only. Starting with darwin, this
1129  *	 property is replaces by the model property.
1130  *
1131  * ~   = Replaces audio-module.
1132  *
1133  * +   = Has the capability of having a cable run from the internal
1134  *	 CD-ROM to the audio device.
1135  *
1136  * N/A = Not applicable, the property wasn't created for early
1137  *	 platforms, or the property has been retired.
1138  *
1139  * NOTE: Older tazmo and quark machines don't have the model property.
1140  *
1141  * Arguments:
1142  *	CS_state_t	*state		The device's state structure
1143  */
1144 static void
audiocs_get_ports(CS_state_t * state)1145 audiocs_get_ports(CS_state_t *state)
1146 {
1147 	dev_info_t	*dip = state->cs_dip;
1148 	audio_dev_t	*adev = state->cs_adev;
1149 	char		*prop_str;
1150 
1151 	/* First we set the common ports, etc. */
1152 	state->cs_omask = state->cs_omod =
1153 	    (1U << OUTPUT_SPEAKER) |
1154 	    (1U << OUTPUT_HEADPHONES) |
1155 	    (1U << OUTPUT_LINEOUT);
1156 	state->cs_imask =
1157 	    (1U << INPUT_MIC) |
1158 	    (1U << INPUT_LINEIN) |
1159 	    (1U << INPUT_STEREOMIX);
1160 
1161 	/* now we try the new "model" property */
1162 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1163 	    "model", &prop_str) == DDI_PROP_SUCCESS) {
1164 		if (strcmp(prop_str, "SUNW,CS4231h") == 0) {
1165 			/* darwin */
1166 			audio_dev_set_version(adev, CS_DEV_VERSION_H);
1167 			state->cs_imask |= (1U << INPUT_CD);
1168 			state->cs_omod = (1U << OUTPUT_SPEAKER);
1169 		} else if (strcmp(prop_str, "SUNW,CS4231g") == 0) {
1170 			/* quark audio module */
1171 			audio_dev_set_version(adev, CS_DEV_VERSION_G);
1172 			/*
1173 			 * NB: This could do SUNVTS LOOPBACK, but we
1174 			 * don't support it for now... owing to no
1175 			 * support in framework.
1176 			 */
1177 		} else if (strcmp(prop_str, "SUNW,CS4231f") == 0) {
1178 			/* tazmo */
1179 			audio_dev_set_version(adev, CS_DEV_VERSION_F);
1180 		} else {
1181 			audio_dev_set_version(adev, prop_str);
1182 			audio_dev_warn(adev,
1183 			    "unknown audio model: %s, some parts of "
1184 			    "audio may not work correctly", prop_str);
1185 		}
1186 		ddi_prop_free(prop_str);	/* done with the property */
1187 	} else {	/* now try the older "audio-module" property */
1188 		if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip,
1189 		    DDI_PROP_DONTPASS, "audio-module", &prop_str) ==
1190 		    DDI_PROP_SUCCESS) {
1191 			switch (*prop_str) {
1192 			case 'Q':	/* quark audio module */
1193 				audio_dev_set_version(adev, CS_DEV_VERSION_G);
1194 				/* See quark comment above about SunVTS */
1195 				break;
1196 			case 'P':	/* tazmo */
1197 				audio_dev_set_version(adev, CS_DEV_VERSION_F);
1198 				break;
1199 			default:
1200 				audio_dev_set_version(adev, prop_str);
1201 				audio_dev_warn(adev,
1202 				    "unknown audio module: %s, some "
1203 				    "parts of audio may not work correctly",
1204 				    prop_str);
1205 				break;
1206 			}
1207 			ddi_prop_free(prop_str);	/* done with the prop */
1208 		} else {	/* now try heuristics, ;-( */
1209 			if (ddi_prop_get_int(DDI_DEV_T_ANY, dip,
1210 			    DDI_PROP_DONTPASS, "internal-loopback", B_FALSE)) {
1211 				if (state->cs_dma_engine == EB2_DMA) {
1212 					audio_dev_set_version(adev,
1213 					    CS_DEV_VERSION_C);
1214 				} else {
1215 					audio_dev_set_version(adev,
1216 					    CS_DEV_VERSION_B);
1217 				}
1218 				/*
1219 				 * Again, we don't support SunVTS for these
1220 				 * boards, although we potentially could.
1221 				 */
1222 			} else {
1223 				audio_dev_set_version(adev, CS_DEV_VERSION_A);
1224 				state->cs_imask |= (1U << INPUT_CD);
1225 			}
1226 		}
1227 	}
1228 }
1229 
1230 /*
1231  * audiocs_power_up()
1232  *
1233  * Description:
1234  *	Power up the Codec and restore the codec's registers.
1235  *
1236  *	NOTE: We don't worry about locking since the only routines
1237  *		that may call us are attach() and power() Both of
1238  *		which should be the only threads in the driver.
1239  *
1240  * Arguments:
1241  *	CS_state_t	*state		The device's state structure
1242  */
1243 static void
audiocs_power_up(CS_state_t * state)1244 audiocs_power_up(CS_state_t *state)
1245 {
1246 	ddi_acc_handle_t	handle = CODEC_HANDLE;
1247 	int			i;
1248 
1249 	/* turn on the Codec */
1250 	CS4231_DMA_POWER(state, CS4231_PWR_ON);
1251 
1252 	/* reset the DMA engine(s) */
1253 	CS4231_DMA_RESET(state);
1254 
1255 	(void) audiocs_poll_ready(state);
1256 
1257 	/*
1258 	 * Reload the Codec's registers, the DMA engines will be
1259 	 * taken care of when play and record start up again. But
1260 	 * first enable registers 16 -> 31.
1261 	 */
1262 	SELIDX(state, MID_REG);
1263 	PUTIDX(state, state->cs_save[MID_REG], MID_VALID_MASK);
1264 
1265 	for (i = 0; i < CS4231_REGS; i++) {
1266 		/* restore Codec registers */
1267 		SELIDX(state, (i | IAR_MCE));
1268 		ddi_put8(handle, &CS4231_IDR, state->cs_save[i]);
1269 		(void) audiocs_poll_ready(state);
1270 	}
1271 	/* clear MCE bit */
1272 	SELIDX(state, 0);
1273 }
1274 
1275 /*
1276  * audiocs_power_down()
1277  *
1278  * Description:
1279  *	Power down the Codec and save the codec's registers.
1280  *
1281  *	NOTE: See the note in cs4231_power_up() about locking.
1282  *
1283  * Arguments:
1284  *	CS_state_t	*state		The device's state structure
1285  */
1286 static void
audiocs_power_down(CS_state_t * state)1287 audiocs_power_down(CS_state_t *state)
1288 {
1289 	ddi_acc_handle_t	handle;
1290 	int			i;
1291 
1292 	handle = state->cs_handles.cs_codec_hndl;
1293 
1294 	/*
1295 	 * We are powering down, so we don't need to do a thing with
1296 	 * the DMA engines. However, we do need to save the Codec
1297 	 * registers.
1298 	 */
1299 
1300 	for (i = 0; i < CS4231_REGS; i++) {
1301 		/* save Codec regs */
1302 		SELIDX(state, i);
1303 		state->cs_save[i] = ddi_get8(handle, &CS4231_IDR);
1304 	}
1305 
1306 	/* turn off the Codec */
1307 	CS4231_DMA_POWER(state, CS4231_PWR_OFF);
1308 
1309 }	/* cs4231_power_down() */
1310 
1311 /*
1312  * audiocs_configure_input()
1313  *
1314  * Description:
1315  *	Configure input properties of the mixer (e.g. igain, ports).
1316  *
1317  * Arguments:
1318  *	CS_state_t	*state		The device's state structure
1319  */
1320 static void
audiocs_configure_input(CS_state_t * state)1321 audiocs_configure_input(CS_state_t *state)
1322 {
1323 	uint8_t		l, r;
1324 	uint64_t	inputs;
1325 	uint64_t	micboost;
1326 
1327 	ASSERT(mutex_owned(&state->cs_lock));
1328 
1329 	inputs = state->cs_inputs->cc_val;
1330 	micboost = state->cs_micboost->cc_val;
1331 	r = (state->cs_igain->cc_val & 0xff);
1332 	l = ((state->cs_igain->cc_val & 0xff00) >> 8);
1333 
1334 	/* rescale these for our atten array */
1335 	l = (((uint32_t)l * 255) / 100) & 0xff;
1336 	r = (((uint32_t)r * 255) / 100) & 0xff;
1337 
1338 	/* we downshift by 4 bits -- igain only has 16 possible values */
1339 	/* NB: that we do not scale here!  The SADA driver didn't do so. */
1340 	l = l >> 4;
1341 	r = r >> 4;
1342 
1343 	if (inputs & (1U << INPUT_MIC)) {
1344 		l |= LADCI_LMIC;
1345 		r |= RADCI_RMIC;
1346 	}
1347 	if (inputs & (1U << INPUT_LINEIN)) {
1348 		l |= LADCI_LLINE;
1349 		r |= RADCI_RLINE;
1350 	}
1351 	if (inputs & (1U << INPUT_CD)) {
1352 		/* note that SunVTS also uses this */
1353 		l |= LADCI_LAUX1;
1354 		r |= RADCI_RAUX1;
1355 	}
1356 	if (inputs & (1U << INPUT_STEREOMIX)) {
1357 		l |= LADCI_LLOOP;
1358 		r |= RADCI_RLOOP;
1359 	}
1360 	if (micboost) {
1361 		l |= LADCI_LMGE;
1362 		r |= RADCI_RMGE;
1363 	}
1364 
1365 	SELIDX(state, LADCI_REG);
1366 	PUTIDX(state, l, LADCI_VALID_MASK);
1367 
1368 	SELIDX(state, RADCI_REG);
1369 	PUTIDX(state, r, RADCI_VALID_MASK);
1370 }
1371 
1372 /*
1373  * audiocs_configure_output()
1374  *
1375  * Description:
1376  *	Configure output properties of the mixer (e.g. ogain, mgain).
1377  *
1378  * Arguments:
1379  *	CS_state_t	*state		The device's state structure
1380  */
1381 static void
audiocs_configure_output(CS_state_t * state)1382 audiocs_configure_output(CS_state_t *state)
1383 {
1384 	uint64_t		outputs;
1385 	uint8_t			l, r;
1386 	uint8_t			rmute, lmute;
1387 	uint8_t			mgain;
1388 	ddi_acc_handle_t	handle = CODEC_HANDLE;
1389 
1390 	rmute = lmute = 0;
1391 
1392 	ASSERT(mutex_owned(&state->cs_lock));
1393 
1394 	outputs = state->cs_outputs->cc_val;
1395 
1396 	/* port selection */
1397 	SELIDX(state, MIOC_REG);
1398 	if (outputs & (1U << OUTPUT_SPEAKER)) {
1399 		ANDIDX(state, ~MIOC_MONO_SPKR_MUTE, MIOC_VALID_MASK);
1400 	} else {
1401 		ORIDX(state, MIOC_MONO_SPKR_MUTE, MIOC_VALID_MASK);
1402 	}
1403 	SELIDX(state, PC_REG);
1404 	if (outputs & (1U << OUTPUT_HEADPHONES)) {
1405 		ANDIDX(state, ~PC_HEADPHONE_MUTE, PC_VALID_MASK);
1406 	} else {
1407 		ORIDX(state, PC_HEADPHONE_MUTE, PC_VALID_MASK);
1408 	}
1409 	SELIDX(state, PC_REG);
1410 	if (outputs & (1U << OUTPUT_LINEOUT)) {
1411 		ANDIDX(state, ~PC_LINE_OUT_MUTE, PC_VALID_MASK);
1412 	} else {
1413 		ORIDX(state, PC_LINE_OUT_MUTE, PC_VALID_MASK);
1414 	}
1415 
1416 	/* monitor gain */
1417 	mgain = cs4231_atten[((state->cs_mgain->cc_val * 255) / 100) & 0xff];
1418 	SELIDX(state, LC_REG);
1419 	if (mgain == 0) {
1420 		/* disable loopbacks when gain == 0 */
1421 		PUTIDX(state, LC_OFF, LC_VALID_MASK);
1422 	} else {
1423 		/* we use cs4231_atten[] to linearize attenuation */
1424 		PUTIDX(state, (mgain << 2) | LC_LBE, LC_VALID_MASK);
1425 	}
1426 
1427 	/* output gain */
1428 	l = ((state->cs_ogain->cc_val >> 8) & 0xff);
1429 	r = (state->cs_ogain->cc_val & 0xff);
1430 	if (l == 0) {
1431 		lmute = LDACO_LDM;
1432 	}
1433 	if (r == 0) {
1434 		rmute = RDACO_RDM;
1435 	}
1436 
1437 	/* rescale these for our atten array */
1438 	l = cs4231_atten[(((uint32_t)l * 255) / 100) & 0xff] | lmute;
1439 	r = cs4231_atten[(((uint32_t)r * 255) / 100) & 0xff] | rmute;
1440 
1441 	SELIDX(state, LDACO_REG);
1442 	PUTIDX(state, l, LDAC0_VALID_MASK);
1443 	SELIDX(state, RDACO_REG);
1444 	PUTIDX(state, r, RDAC0_VALID_MASK);
1445 }
1446 
1447 /*
1448  * audiocs_get_value()
1449  *
1450  * Description:
1451  *	Get a control value
1452  *
1453  * Arguments:
1454  *	void		*arg		The device's state structure
1455  *	uint64_t	*valp		Pointer to store value.
1456  *
1457  * Returns:
1458  *	0		The Codec parameter has been retrieved.
1459  */
1460 static int
audiocs_get_value(void * arg,uint64_t * valp)1461 audiocs_get_value(void *arg, uint64_t *valp)
1462 {
1463 	CS_ctrl_t		*cc = arg;
1464 	CS_state_t		*state = cc->cc_state;
1465 
1466 	mutex_enter(&state->cs_lock);
1467 	*valp = cc->cc_val;
1468 	mutex_exit(&state->cs_lock);
1469 	return (0);
1470 }
1471 
1472 
1473 /*
1474  * audiocs_set_ogain()
1475  *
1476  * Description:
1477  *	Set the play gain.
1478  *
1479  * Arguments:
1480  *	void		*arg		The device's state structure
1481  *	uint64_t	val		The gain to set (both left and right)
1482  *
1483  * Returns:
1484  *	0		The Codec parameter has been set
1485  */
1486 static int
audiocs_set_ogain(void * arg,uint64_t val)1487 audiocs_set_ogain(void *arg, uint64_t val)
1488 {
1489 	CS_ctrl_t		*cc = arg;
1490 	CS_state_t		*state = cc->cc_state;
1491 
1492 	if ((val & ~0xffff) ||
1493 	    ((val & 0xff) > 100) ||
1494 	    (((val & 0xff00) >> 8) > 100))
1495 		return (EINVAL);
1496 
1497 	mutex_enter(&state->cs_lock);
1498 	cc->cc_val = val;
1499 	audiocs_configure_output(state);
1500 	mutex_exit(&state->cs_lock);
1501 	return (0);
1502 }
1503 
1504 /*
1505  * audiocs_set_micboost()
1506  *
1507  * Description:
1508  *	Set the 20 dB microphone boost.
1509  *
1510  * Arguments:
1511  *	void		*arg		The device's state structure
1512  *	uint64_t	val		The 1 to enable, 0 to disable.
1513  *
1514  * Returns:
1515  *	0		The Codec parameter has been set
1516  */
1517 static int
audiocs_set_micboost(void * arg,uint64_t val)1518 audiocs_set_micboost(void *arg, uint64_t val)
1519 {
1520 	CS_ctrl_t	*cc = arg;
1521 	CS_state_t	*state = cc->cc_state;
1522 
1523 	mutex_enter(&state->cs_lock);
1524 	cc->cc_val = val ? B_TRUE : B_FALSE;
1525 	audiocs_configure_input(state);
1526 	mutex_exit(&state->cs_lock);
1527 	return (0);
1528 }
1529 
1530 /*
1531  * audiocs_set_igain()
1532  *
1533  * Description:
1534  *	Set the record gain.
1535  *
1536  * Arguments:
1537  *	void		*arg		The device's state structure
1538  *	uint64_t	val		The gain to set (both left and right)
1539  *
1540  * Returns:
1541  *	0		The Codec parameter has been set
1542  */
1543 static int
audiocs_set_igain(void * arg,uint64_t val)1544 audiocs_set_igain(void *arg, uint64_t val)
1545 {
1546 	CS_ctrl_t	*cc = arg;
1547 	CS_state_t	*state = cc->cc_state;
1548 
1549 	if ((val & ~0xffff) ||
1550 	    ((val & 0xff) > 100) ||
1551 	    (((val & 0xff00) >> 8) > 100))
1552 		return (EINVAL);
1553 
1554 	mutex_enter(&state->cs_lock);
1555 	cc->cc_val = val;
1556 	audiocs_configure_input(state);
1557 	mutex_exit(&state->cs_lock);
1558 
1559 	return (0);
1560 }
1561 
1562 /*
1563  * audiocs_set_inputs()
1564  *
1565  * Description:
1566  *	Set the input ports.
1567  *
1568  * Arguments:
1569  *	void		*arg		The device's state structure
1570  *	uint64_t	val		The mask of output ports.
1571  *
1572  * Returns:
1573  *	0		The Codec parameter has been set
1574  */
1575 static int
audiocs_set_inputs(void * arg,uint64_t val)1576 audiocs_set_inputs(void *arg, uint64_t val)
1577 {
1578 	CS_ctrl_t	*cc = arg;
1579 	CS_state_t	*state = cc->cc_state;
1580 
1581 	if (val & ~(state->cs_imask))
1582 		return (EINVAL);
1583 
1584 	mutex_enter(&state->cs_lock);
1585 	cc->cc_val = val;
1586 	audiocs_configure_input(state);
1587 	mutex_exit(&state->cs_lock);
1588 
1589 	return (0);
1590 }
1591 
1592 /*
1593  * audiocs_set_outputs()
1594  *
1595  * Description:
1596  *	Set the output ports.
1597  *
1598  * Arguments:
1599  *	void		*arg		The device's state structure
1600  *	uint64_t	val		The mask of input ports.
1601  *
1602  * Returns:
1603  *	0		The Codec parameter has been set
1604  */
1605 static int
audiocs_set_outputs(void * arg,uint64_t val)1606 audiocs_set_outputs(void *arg, uint64_t val)
1607 {
1608 	CS_ctrl_t	*cc = arg;
1609 	CS_state_t	*state = cc->cc_state;
1610 
1611 	if ((val & ~(state->cs_omod)) !=
1612 	    (state->cs_omask & ~state->cs_omod))
1613 		return (EINVAL);
1614 
1615 	mutex_enter(&state->cs_lock);
1616 	cc->cc_val = val;
1617 	audiocs_configure_output(state);
1618 	mutex_exit(&state->cs_lock);
1619 
1620 	return (0);
1621 }
1622 
1623 /*
1624  * audiocs_set_mgain()
1625  *
1626  * Description:
1627  *	Set the monitor gain.
1628  *
1629  * Arguments:
1630  *	void		*arg		The device's state structure
1631  *	uint64_t	val		The gain to set (monoaural).)
1632  *
1633  * Returns:
1634  *	0		The Codec parameter has been set
1635  */
1636 static int
audiocs_set_mgain(void * arg,uint64_t gain)1637 audiocs_set_mgain(void *arg, uint64_t gain)
1638 {
1639 	CS_ctrl_t	*cc = arg;
1640 	CS_state_t	*state = cc->cc_state;
1641 
1642 	if (gain > 100)
1643 		return (EINVAL);
1644 
1645 	mutex_enter(&state->cs_lock);
1646 	cc->cc_val = gain;
1647 	audiocs_configure_output(state);
1648 	mutex_exit(&state->cs_lock);
1649 
1650 	return (0);
1651 }
1652 
1653 /*
1654  * audiocs_open()
1655  *
1656  * Description:
1657  *	Opens a DMA engine for use.
1658  *
1659  * Arguments:
1660  *	void		*arg		The DMA engine to set up
1661  *	int		flag		Open flags
1662  *	unsigned	*nframesp	Receives number of frames
1663  *	caddr_t		*bufp		Receives kernel data buffer
1664  *
1665  * Returns:
1666  *	0	on success
1667  *	errno	on failure
1668  */
1669 static int
audiocs_open(void * arg,int flag,unsigned * nframesp,caddr_t * bufp)1670 audiocs_open(void *arg, int flag, unsigned *nframesp, caddr_t *bufp)
1671 {
1672 	CS_engine_t	*eng = arg;
1673 	CS_state_t	*state = eng->ce_state;
1674 	dev_info_t	*dip = state->cs_dip;
1675 
1676 	_NOTE(ARGUNUSED(flag));
1677 
1678 	(void) pm_busy_component(dip, CS4231_COMPONENT);
1679 	if (pm_raise_power(dip, CS4231_COMPONENT, CS4231_PWR_ON) ==
1680 	    DDI_FAILURE) {
1681 
1682 		/* match the busy call above */
1683 		(void) pm_idle_component(dip, CS4231_COMPONENT);
1684 
1685 		audio_dev_warn(state->cs_adev, "power up failed");
1686 	}
1687 
1688 	eng->ce_count = 0;
1689 	*nframesp = CS4231_NFRAMES;
1690 	*bufp = eng->ce_kaddr;
1691 
1692 	return (0);
1693 }
1694 
1695 /*
1696  * audiocs_close()
1697  *
1698  * Description:
1699  *	Closes an audio DMA engine that was previously opened.  Since
1700  *	nobody is using it, we take this opportunity to possibly power
1701  *	down the entire device.
1702  *
1703  * Arguments:
1704  *	void	*arg		The DMA engine to shut down
1705  */
1706 static void
audiocs_close(void * arg)1707 audiocs_close(void *arg)
1708 {
1709 	CS_engine_t	*eng = arg;
1710 	CS_state_t	*state = eng->ce_state;
1711 
1712 	(void) pm_idle_component(state->cs_dip, CS4231_COMPONENT);
1713 }
1714 
1715 /*
1716  * audiocs_stop()
1717  *
1718  * Description:
1719  *	This is called by the framework to stop an engine that is
1720  *	transferring data.
1721  *
1722  * Arguments:
1723  *	void	*arg		The DMA engine to stop
1724  */
1725 static void
audiocs_stop(void * arg)1726 audiocs_stop(void *arg)
1727 {
1728 	CS_engine_t		*eng = arg;
1729 	CS_state_t		*state = eng->ce_state;
1730 	ddi_acc_handle_t	handle = CODEC_HANDLE;
1731 
1732 	mutex_enter(&state->cs_lock);
1733 	/*
1734 	 * Stop the DMA engine.
1735 	 */
1736 	CS4231_DMA_STOP(state, eng);
1737 
1738 	/*
1739 	 * Stop the codec.
1740 	 */
1741 	SELIDX(state, INTC_REG);
1742 	ANDIDX(state, ~(eng->ce_codec_en), INTC_VALID_MASK);
1743 	mutex_exit(&state->cs_lock);
1744 }
1745 
1746 /*
1747  * audiocs_start()
1748  *
1749  * Description:
1750  *	This is called by the framework to start an engine transferring data.
1751  *
1752  * Arguments:
1753  *	void	*arg		The DMA engine to start
1754  *
1755  * Returns:
1756  *	0 	on success, an errno otherwise
1757  */
1758 static int
audiocs_start(void * arg)1759 audiocs_start(void *arg)
1760 {
1761 	CS_engine_t		*eng = arg;
1762 	CS_state_t		*state = eng->ce_state;
1763 	ddi_acc_handle_t	handle = CODEC_HANDLE;
1764 	uint8_t			mask;
1765 	uint8_t			value;
1766 	uint8_t			reg;
1767 	int			rv;
1768 
1769 	mutex_enter(&state->cs_lock);
1770 
1771 	if (eng->ce_num == CS4231_PLAY) {
1772 		/* sample rate only set on play side */
1773 		value = FS_48000 | PDF_STEREO | PDF_LINEAR16NE;
1774 		reg = FSDF_REG;
1775 		mask = FSDF_VALID_MASK;
1776 	} else {
1777 		value = CDF_STEREO | CDF_LINEAR16NE;
1778 		reg = CDF_REG;
1779 		mask = CDF_VALID_MASK;
1780 	}
1781 	eng->ce_curoff = 0;
1782 	eng->ce_curidx = 0;
1783 
1784 	SELIDX(state, reg | IAR_MCE);
1785 	PUTIDX(state, value, mask);
1786 
1787 	if (audiocs_poll_ready(state) != DDI_SUCCESS) {
1788 		rv = EIO;
1789 	} else if (CS4231_DMA_START(state, eng) != DDI_SUCCESS) {
1790 		rv = EIO;
1791 	} else {
1792 		/*
1793 		 * Start the codec.
1794 		 */
1795 		SELIDX(state, INTC_REG);
1796 		ORIDX(state, eng->ce_codec_en, INTC_VALID_MASK);
1797 		rv = 0;
1798 	}
1799 
1800 	mutex_exit(&state->cs_lock);
1801 	return (rv);
1802 }
1803 
1804 /*
1805  * audiocs_format()
1806  *
1807  * Description:
1808  *	Called by the framework to query the format of the device.
1809  *
1810  * Arguments:
1811  *	void	*arg		The DMA engine to query
1812  *
1813  * Returns:
1814  *	AUDIO_FORMAT_S16_NE
1815  */
1816 static int
audiocs_format(void * arg)1817 audiocs_format(void *arg)
1818 {
1819 	_NOTE(ARGUNUSED(arg));
1820 
1821 	return (AUDIO_FORMAT_S16_NE);
1822 }
1823 
1824 /*
1825  * audiocs_channels()
1826  *
1827  * Description:
1828  *	Called by the framework to query the channels of the device.
1829  *
1830  * Arguments:
1831  *	void	*arg		The DMA engine to query
1832  *
1833  * Returns:
1834  *	2 (stereo)
1835  */
1836 static int
audiocs_channels(void * arg)1837 audiocs_channels(void *arg)
1838 {
1839 	_NOTE(ARGUNUSED(arg));
1840 
1841 	return (2);
1842 }
1843 
1844 /*
1845  * audiocs_rates()
1846  *
1847  * Description:
1848  *	Called by the framework to query the sample rate of the device.
1849  *
1850  * Arguments:
1851  *	void	*arg		The DMA engine to query
1852  *
1853  * Returns:
1854  *	48000
1855  */
1856 static int
audiocs_rate(void * arg)1857 audiocs_rate(void *arg)
1858 {
1859 	_NOTE(ARGUNUSED(arg));
1860 
1861 	return (48000);
1862 }
1863 
1864 /*
1865  * audiocs_count()
1866  *
1867  * Description:
1868  *	This is called by the framework to get the engine's frame counter
1869  *
1870  * Arguments:
1871  *	void	*arg		The DMA engine to query
1872  *
1873  * Returns:
1874  *	frame count for current engine
1875  */
1876 static uint64_t
audiocs_count(void * arg)1877 audiocs_count(void *arg)
1878 {
1879 	CS_engine_t		*eng = arg;
1880 	CS_state_t		*state = eng->ce_state;
1881 	uint64_t		val;
1882 	uint32_t		off;
1883 
1884 	mutex_enter(&state->cs_lock);
1885 
1886 	off = CS4231_DMA_ADDR(state, eng);
1887 	ASSERT(off >= eng->ce_paddr);
1888 	off -= eng->ce_paddr;
1889 
1890 	/*
1891 	 * Every now and then, we get a value that is just a wee bit
1892 	 * too large.  This seems to be a small value related to
1893 	 * prefetch.  Rather than believe it, we just assume the last
1894 	 * offset in the buffer.  This should allow us to handle
1895 	 * wraps, but without inserting bogus sample counts.
1896 	 */
1897 	if (off >= CS4231_BUFSZ) {
1898 		off = CS4231_BUFSZ - 4;
1899 	}
1900 
1901 	off /= 4;
1902 
1903 	val = (off >= eng->ce_curoff) ?
1904 	    off - eng->ce_curoff :
1905 	    off + CS4231_NFRAMES - eng->ce_curoff;
1906 
1907 	eng->ce_count += val;
1908 	eng->ce_curoff = off;
1909 	val = eng->ce_count;
1910 
1911 	/* while here, possibly reload the next address */
1912 	CS4231_DMA_RELOAD(state, eng);
1913 	mutex_exit(&state->cs_lock);
1914 
1915 	return (val);
1916 }
1917 
1918 /*
1919  * audiocs_sync()
1920  *
1921  * Description:
1922  *	This is called by the framework to synchronize DMA caches.
1923  *
1924  * Arguments:
1925  *	void	*arg		The DMA engine to sync
1926  */
1927 static void
audiocs_sync(void * arg,unsigned nframes)1928 audiocs_sync(void *arg, unsigned nframes)
1929 {
1930 	CS_engine_t *eng = arg;
1931 	_NOTE(ARGUNUSED(nframes));
1932 
1933 	(void) ddi_dma_sync(eng->ce_dmah, 0, 0, eng->ce_syncdir);
1934 }
1935 
1936 /*
1937  * audiocs_alloc_engine()
1938  *
1939  * Description:
1940  *	Allocates the DMA handles and the memory for the DMA engine.
1941  *
1942  * Arguments:
1943  *	CS_state_t	*dip	Pointer to the device's soft state
1944  *	int		num	Engine number, CS4231_PLAY or CS4231_REC.
1945  *
1946  * Returns:
1947  *	DDI_SUCCESS		Engine initialized.
1948  *	DDI_FAILURE		Engine not initialized.
1949  */
1950 int
audiocs_alloc_engine(CS_state_t * state,int num)1951 audiocs_alloc_engine(CS_state_t *state, int num)
1952 {
1953 	unsigned		caps;
1954 	int			dir;
1955 	int			rc;
1956 	audio_dev_t		*adev;
1957 	dev_info_t		*dip;
1958 	CS_engine_t		*eng;
1959 	uint_t			ccnt;
1960 	ddi_dma_cookie_t	dmac;
1961 	size_t			bufsz;
1962 
1963 	static ddi_device_acc_attr_t buf_attr = {
1964 		DDI_DEVICE_ATTR_V0,
1965 		DDI_NEVERSWAP_ACC,
1966 		DDI_STRICTORDER_ACC
1967 	};
1968 
1969 	adev = state->cs_adev;
1970 	dip = state->cs_dip;
1971 
1972 	eng = kmem_zalloc(sizeof (*eng), KM_SLEEP);
1973 	eng->ce_state = state;
1974 	eng->ce_started = B_FALSE;
1975 	eng->ce_num = num;
1976 
1977 	switch (num) {
1978 	case CS4231_REC:
1979 		dir = DDI_DMA_READ;
1980 		caps = ENGINE_INPUT_CAP;
1981 		eng->ce_syncdir = DDI_DMA_SYNC_FORKERNEL;
1982 		eng->ce_codec_en = INTC_CEN;
1983 		break;
1984 	case CS4231_PLAY:
1985 		dir = DDI_DMA_WRITE;
1986 		caps = ENGINE_OUTPUT_CAP;
1987 		eng->ce_syncdir = DDI_DMA_SYNC_FORDEV;
1988 		eng->ce_codec_en = INTC_PEN;
1989 		break;
1990 	default:
1991 		kmem_free(eng, sizeof (*eng));
1992 		audio_dev_warn(adev, "bad engine number (%d)!", num);
1993 		return (DDI_FAILURE);
1994 	}
1995 	state->cs_engines[num] = eng;
1996 
1997 	/* allocate dma handle */
1998 	rc = ddi_dma_alloc_handle(dip, CS4231_DMA_ATTR(state), DDI_DMA_SLEEP,
1999 	    NULL, &eng->ce_dmah);
2000 	if (rc != DDI_SUCCESS) {
2001 		audio_dev_warn(adev, "ddi_dma_alloc_handle failed: %d", rc);
2002 		return (DDI_FAILURE);
2003 	}
2004 	/* allocate DMA buffer */
2005 	rc = ddi_dma_mem_alloc(eng->ce_dmah, CS4231_BUFSZ, &buf_attr,
2006 	    DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL, &eng->ce_kaddr,
2007 	    &bufsz, &eng->ce_acch);
2008 	if (rc == DDI_FAILURE) {
2009 		audio_dev_warn(adev, "dma_mem_alloc failed");
2010 		return (DDI_FAILURE);
2011 	}
2012 
2013 	/* bind DMA buffer */
2014 	rc = ddi_dma_addr_bind_handle(eng->ce_dmah, NULL,
2015 	    eng->ce_kaddr, CS4231_BUFSZ, dir | DDI_DMA_CONSISTENT,
2016 	    DDI_DMA_SLEEP, NULL, &dmac, &ccnt);
2017 	if ((rc != DDI_DMA_MAPPED) || (ccnt != 1)) {
2018 		audio_dev_warn(adev,
2019 		    "ddi_dma_addr_bind_handle failed: %d", rc);
2020 		return (DDI_FAILURE);
2021 	}
2022 
2023 	eng->ce_paddr = dmac.dmac_address;
2024 
2025 	eng->ce_engine = audio_engine_alloc(&audiocs_engine_ops, caps);
2026 	if (eng->ce_engine == NULL) {
2027 		audio_dev_warn(adev, "audio_engine_alloc failed");
2028 		return (DDI_FAILURE);
2029 	}
2030 
2031 	audio_engine_set_private(eng->ce_engine, eng);
2032 	audio_dev_add_engine(adev, eng->ce_engine);
2033 	return (DDI_SUCCESS);
2034 }
2035 
2036 /*
2037  * audiocs_free_engine()
2038  *
2039  * Description:
2040  *	This routine fress the engine and all associated resources.
2041  *
2042  * Arguments:
2043  *	CS_engine_t	*eng	Engine to free.
2044  */
2045 void
audiocs_free_engine(CS_engine_t * eng)2046 audiocs_free_engine(CS_engine_t *eng)
2047 {
2048 	CS_state_t	*state = eng->ce_state;
2049 	audio_dev_t	*adev = state->cs_adev;
2050 
2051 	if (eng == NULL)
2052 		return;
2053 	if (eng->ce_engine) {
2054 		audio_dev_remove_engine(adev, eng->ce_engine);
2055 		audio_engine_free(eng->ce_engine);
2056 	}
2057 	if (eng->ce_paddr) {
2058 		(void) ddi_dma_unbind_handle(eng->ce_dmah);
2059 	}
2060 	if (eng->ce_acch) {
2061 		ddi_dma_mem_free(&eng->ce_acch);
2062 	}
2063 	if (eng->ce_dmah) {
2064 		ddi_dma_free_handle(&eng->ce_dmah);
2065 	}
2066 	kmem_free(eng, sizeof (*eng));
2067 }
2068 
2069 /*
2070  * audiocs_poll_ready()
2071  *
2072  * Description:
2073  *	This routine waits for the Codec to complete its initialization
2074  *	sequence and is done with its autocalibration.
2075  *
2076  *	Early versions of the Codec have a bug that can take as long as
2077  *	15 seconds to complete its initialization. For these cases we
2078  *	use a timeout mechanism so we don't keep the machine locked up.
2079  *
2080  * Arguments:
2081  *	CS_state_t	*state	The device's state structure
2082  *
2083  * Returns:
2084  *	DDI_SUCCESS		The Codec is ready to continue
2085  *	DDI_FAILURE		The Codec isn't ready to continue
2086  */
2087 int
audiocs_poll_ready(CS_state_t * state)2088 audiocs_poll_ready(CS_state_t *state)
2089 {
2090 	ddi_acc_handle_t	handle = CODEC_HANDLE;
2091 	int			x = 0;
2092 	uint8_t			iar;
2093 	uint8_t			idr;
2094 
2095 	ASSERT(state->cs_regs != NULL);
2096 	ASSERT(handle != NULL);
2097 
2098 	/* wait for the chip to initialize itself */
2099 	iar = ddi_get8(handle, &CS4231_IAR);
2100 
2101 	while ((iar & IAR_INIT) && x++ < CS4231_TIMEOUT) {
2102 		drv_usecwait(50);
2103 		iar = ddi_get8(handle, &CS4231_IAR);
2104 	}
2105 
2106 	if (x >= CS4231_TIMEOUT) {
2107 		return (DDI_FAILURE);
2108 	}
2109 
2110 	x = 0;
2111 
2112 	/*
2113 	 * Now wait for the chip to complete its autocalibration.
2114 	 * Set the test register.
2115 	 */
2116 	SELIDX(state, ESI_REG);
2117 
2118 	idr = ddi_get8(handle, &CS4231_IDR);
2119 
2120 	while ((idr & ESI_ACI) && x++ < CS4231_TIMEOUT) {
2121 		drv_usecwait(50);
2122 		idr = ddi_get8(handle, &CS4231_IDR);
2123 	}
2124 
2125 	if (x >= CS4231_TIMEOUT) {
2126 		return (DDI_FAILURE);
2127 	}
2128 
2129 
2130 	return (DDI_SUCCESS);
2131 
2132 }
2133 
2134 /*
2135  * audiocs_sel_index()
2136  *
2137  * Description:
2138  *	Select a cs4231 register. The cs4231 has a hardware bug where a
2139  *	register is not always selected the first time. We try and try
2140  *	again until the proper register is selected or we time out and
2141  *	print an error message.
2142  *
2143  * Arguments:
2144  *	audiohdl_t	ahandle		Handle to this device
2145  *	ddi_acc_handle_t handle		A handle to the device's registers
2146  *	uint8_t		addr		The register address to program
2147  *	int		reg		The register to select
2148  */
2149 void
2150 #ifdef	DEBUG
audiocs_sel_index(CS_state_t * state,uint8_t reg,int n)2151 audiocs_sel_index(CS_state_t *state, uint8_t reg, int n)
2152 #else
2153 audiocs_sel_index(CS_state_t *state, uint8_t reg)
2154 #endif
2155 {
2156 	int			x;
2157 	uint8_t			T;
2158 	ddi_acc_handle_t	handle = CODEC_HANDLE;
2159 	uint8_t			*addr = &CS4231_IAR;
2160 
2161 	for (x = 0; x < CS4231_RETRIES; x++) {
2162 		ddi_put8(handle, addr, reg);
2163 		T = ddi_get8(handle, addr);
2164 		if (T == reg) {
2165 			break;
2166 		}
2167 		drv_usecwait(1000);
2168 	}
2169 
2170 	if (x == CS4231_RETRIES) {
2171 		audio_dev_warn(state->cs_adev,
2172 #ifdef	DEBUG
2173 		    "line %d: Couldn't select index (0x%02x 0x%02x)", n,
2174 #else
2175 		    "Couldn't select index (0x%02x 0x%02x)",
2176 #endif
2177 		    T, reg);
2178 		audio_dev_warn(state->cs_adev,
2179 		    "audio may not work correctly until it is stopped and "
2180 		    "restarted");
2181 	}
2182 }
2183 
2184 /*
2185  * audiocs_put_index()
2186  *
2187  * Description:
2188  *	Program a cs4231 register. The cs4231 has a hardware bug where a
2189  *	register is not programmed properly the first time. We program a value,
2190  *	then immediately read back the value and reprogram if nescessary.
2191  *	We do this until the register is properly programmed or we time out and
2192  *	print an error message.
2193  *
2194  * Arguments:
2195  *	CS_state_t	state		Handle to this device
2196  *	uint8_t		mask		Mask to not set reserved register bits
2197  *	int		val		The value to program
2198  */
2199 void
2200 #ifdef DEBUG
audiocs_put_index(CS_state_t * state,uint8_t val,uint8_t mask,int n)2201 audiocs_put_index(CS_state_t *state, uint8_t val, uint8_t mask, int n)
2202 #else
2203 audiocs_put_index(CS_state_t *state, uint8_t val, uint8_t mask)
2204 #endif
2205 {
2206 	int			x;
2207 	uint8_t			T;
2208 	ddi_acc_handle_t	handle = CODEC_HANDLE;
2209 	uint8_t			*addr = &CS4231_IDR;
2210 
2211 	val &= mask;
2212 
2213 	for (x = 0; x < CS4231_RETRIES; x++) {
2214 		ddi_put8(handle, addr, val);
2215 		T = ddi_get8(handle, addr);
2216 		if (T == val) {
2217 			break;
2218 		}
2219 		drv_usecwait(1000);
2220 	}
2221 
2222 	if (x == CS4231_RETRIES) {
2223 #ifdef DEBUG
2224 		audio_dev_warn(state->cs_adev,
2225 		    "line %d: Couldn't set value (0x%02x 0x%02x)", n, T, val);
2226 #else
2227 		audio_dev_warn(state->cs_adev,
2228 		    "Couldn't set value (0x%02x 0x%02x)", T, val);
2229 #endif
2230 		audio_dev_warn(state->cs_adev,
2231 		    "audio may not work correctly until it is stopped and "
2232 		    "restarted");
2233 	}
2234 }
2235