usr/src/uts/common/io/audio/drv/audiocmi/audiocmi.c
changeset 11936 54dc8a89ba0d
parent 11386 818b0d2a69dd
child 12165 e481916a5729
equal deleted inserted replaced
11935:538c866aaac6 11936:54dc8a89ba0d
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
    17  * information: Portions Copyright [yyyy] [name of copyright owner]
    18  *
    18  *
    19  * CDDL HEADER END
    19  * CDDL HEADER END
    20  */
    20  */
    21 /*
    21 /*
    22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
    22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
    23  * Use is subject to license terms.
    23  * Use is subject to license terms.
    24  */
    24  */
    25 /*
    25 /*
    26  * Purpose: Driver for CMEDIA CM8738 PCI audio controller.
    26  * Purpose: Driver for CMEDIA CM8738 PCI audio controller.
    27  */
    27  */
    87 	0x1,			/* dma_attr_sgllen */
    87 	0x1,			/* dma_attr_sgllen */
    88 	0x1,			/* dma_attr_granular */
    88 	0x1,			/* dma_attr_granular */
    89 	0			/* dma_attr_flags */
    89 	0			/* dma_attr_flags */
    90 };
    90 };
    91 
    91 
    92 static uint_t
    92 
    93 cmpci_intr(caddr_t arg1, caddr_t arg2)
    93 static int
    94 {
    94 cmpci_open(void *arg, int flag, uint_t *nframesp, caddr_t *bufp)
    95 	cmpci_dev_t	*dev = (void *)arg1;
    95 {
    96 
    96 	cmpci_port_t *port = arg;
    97 	uint32_t	intstat, intctrl, intclear;
    97 	cmpci_dev_t *dev = port->dev;
    98 	void		(*cb0)(audio_engine_t *) = NULL;
    98 
    99 	void		(*cb1)(audio_engine_t *) = NULL;
    99 	_NOTE(ARGUNUSED(flag));
   100 	uint_t		rv;
       
   101 
       
   102 	_NOTE(ARGUNUSED(arg2));
       
   103 
       
   104 	rv = DDI_INTR_UNCLAIMED;
       
   105 
   100 
   106 	mutex_enter(&dev->mutex);
   101 	mutex_enter(&dev->mutex);
   107 	if (dev->suspended) {
   102 
   108 		mutex_exit(&dev->mutex);
   103 	*nframesp = port->nframes;
   109 		return (rv);
   104 	*bufp = port->kaddr;
   110 	}
   105 
   111 
   106 	port->count = 0;
   112 	intclear = 0;
       
   113 	intstat = GET32(dev, REG_INTSTAT);
       
   114 	intctrl = GET32(dev, REG_INTCTRL);
       
   115 	if ((intstat & INTSTAT_CH0_INT) && (intctrl & INTCTRL_CH0_EN)) {
       
   116 		intclear |= INTCTRL_CH0_EN;
       
   117 		cb0 = dev->port[0].callb;
       
   118 	}
       
   119 	if ((intstat & INTSTAT_CH1_INT) && (intctrl & INTCTRL_CH1_EN)) {
       
   120 		intclear |= INTCTRL_CH1_EN;
       
   121 		cb1 = dev->port[1].callb;
       
   122 	}
       
   123 
       
   124 	/* toggle the bits that we are going to handle */
       
   125 	if (intclear) {
       
   126 		CLR32(dev, REG_INTCTRL, intclear);
       
   127 		SET32(dev, REG_INTCTRL, intclear);
       
   128 		rv = DDI_INTR_CLAIMED;
       
   129 
       
   130 		KSINTR(dev)->intrs[KSTAT_INTR_HARD]++;
       
   131 	}
       
   132 
       
   133 	mutex_exit(&dev->mutex);
   107 	mutex_exit(&dev->mutex);
   134 
   108 
   135 	if (cb0) {
   109 	return (0);
   136 		(*cb0)(dev->port[0].engine);
       
   137 	}
       
   138 	if (cb1) {
       
   139 		(*cb1)(dev->port[1].engine);
       
   140 	}
       
   141 
       
   142 	return (rv);
       
   143 }
   110 }
   144 
   111 
   145 static void
   112 static void
   146 cmpci_reset_port(cmpci_port_t *port)
   113 cmpci_close(void *arg)
   147 {
   114 {
   148 	cmpci_dev_t *dev = port->dev;
   115 	_NOTE(ARGUNUSED(arg));
   149 
   116 }
   150 	if (dev->suspended)
   117 
   151 		return;
   118 static int
       
   119 cmpci_start(void *arg)
       
   120 {
       
   121 	cmpci_port_t	*port = arg;
       
   122 	cmpci_dev_t	*dev = port->dev;
       
   123 
       
   124 	mutex_enter(&dev->mutex);
   152 
   125 
   153 	port->offset = 0;
   126 	port->offset = 0;
   154 
   127 
   155 	/* reset channel */
   128 	/* reset channel */
   156 	SET32(dev, REG_FUNCTRL0, port->fc0_rst_bit);
   129 	SET32(dev, REG_FUNCTRL0, port->fc0_rst_bit);
   220 		}
   193 		}
   221 	}
   194 	}
   222 
   195 
   223 	PUT32(dev, port->reg_paddr, port->paddr);
   196 	PUT32(dev, port->reg_paddr, port->paddr);
   224 	PUT16(dev, port->reg_bufsz, (port->bufsz / 4) - 1);
   197 	PUT16(dev, port->reg_bufsz, (port->bufsz / 4) - 1);
   225 	PUT16(dev, port->reg_fragsz, (port->fragfr *  port->nchan / 2) - 1);
   198 	PUT16(dev, port->reg_fragsz, (port->bufsz  / 4) - 1);
   226 
   199 
   227 	/* Analog output */
   200 	/* Analog output */
   228 	if (port->capture) {
   201 	if (port->capture) {
   229 		/* Analog capture */
   202 		/* Analog capture */
   230 		SET32(dev, REG_FUNCTRL0, port->fc0_rec_bit);
   203 		SET32(dev, REG_FUNCTRL0, port->fc0_rec_bit);
   231 	} else {
   204 	} else {
   232 		CLR32(dev, REG_FUNCTRL0, port->fc0_rec_bit);
   205 		CLR32(dev, REG_FUNCTRL0, port->fc0_rec_bit);
   233 	}
   206 	}
       
   207 
       
   208 	SET32(dev, REG_FUNCTRL0, port->fc0_en_bit);
       
   209 	mutex_exit(&dev->mutex);
       
   210 
       
   211 	return (0);
   234 }
   212 }
   235 
   213 
   236 static void
   214 static void
   237 cmpci_start_port(cmpci_port_t *port)
   215 cmpci_stop(void *arg)
   238 {
   216 {
       
   217 	cmpci_port_t	*port = arg;
   239 	cmpci_dev_t	*dev = port->dev;
   218 	cmpci_dev_t	*dev = port->dev;
   240 
   219 
   241 	if (dev->suspended)
   220 	mutex_enter(&dev->mutex);
   242 		return;
   221 	CLR32(dev, REG_FUNCTRL0, port->fc0_en_bit);
   243 
   222 	mutex_exit(&dev->mutex);
   244 	SET32(dev, REG_FUNCTRL0, port->fc0_en_bit);
   223 }
   245 	SET32(dev, REG_INTCTRL, port->int_en_bit);
   224 
   246 }
   225 static uint64_t
   247 
   226 cmpci_count(void *arg)
   248 static void
   227 {
   249 cmpci_stop_port(cmpci_port_t *port)
   228 	cmpci_port_t	*port = arg;
   250 {
       
   251 	cmpci_dev_t	*dev = port->dev;
   229 	cmpci_dev_t	*dev = port->dev;
   252 
   230 	uint64_t	count;
   253 	if (dev->suspended)
   231 	uint32_t	offset;
   254 		return;
       
   255 
       
   256 	CLR32(dev, REG_FUNCTRL0, port->fc0_en_bit);
       
   257 	CLR32(dev, REG_INTCTRL, port->int_en_bit);
       
   258 }
       
   259 
       
   260 static int
       
   261 cmpci_open(void *arg, int flag, uint_t *fragfrp, uint_t *nfp, caddr_t *bufp)
       
   262 {
       
   263 	cmpci_port_t *port = arg;
       
   264 	cmpci_dev_t *dev = port->dev;
       
   265 
       
   266 	_NOTE(ARGUNUSED(flag));
       
   267 
   232 
   268 	mutex_enter(&dev->mutex);
   233 	mutex_enter(&dev->mutex);
   269 
       
   270 	*fragfrp = port->fragfr;
       
   271 	*nfp = port->nfrags;
       
   272 	*bufp = port->kaddr;
       
   273 
       
   274 	port->count = 0;
       
   275 	port->open = B_TRUE;
       
   276 
       
   277 	cmpci_reset_port(port);
       
   278 	cmpci_start_port(port);
       
   279 
       
   280 	mutex_exit(&dev->mutex);
       
   281 	return (0);
       
   282 }
       
   283 
       
   284 static void
       
   285 cmpci_close(void *arg)
       
   286 {
       
   287 	cmpci_port_t *port = arg;
       
   288 	cmpci_dev_t *dev = port->dev;
       
   289 
       
   290 	mutex_enter(&dev->mutex);
       
   291 	port->open = B_FALSE;
       
   292 	cmpci_stop_port(port);
       
   293 	mutex_exit(&dev->mutex);
       
   294 }
       
   295 
       
   296 static void
       
   297 cmpci_update_port(cmpci_port_t *port)
       
   298 {
       
   299 	cmpci_dev_t	*dev = port->dev;
       
   300 	uint32_t	count;
       
   301 	uint32_t	offset;
       
   302 
       
   303 	if ((dev->suspended) || (!port->open))
       
   304 		return;
       
   305 
   234 
   306 	/* this gives us the offset in dwords */
   235 	/* this gives us the offset in dwords */
   307 	offset = (port->bufsz / 4) - (GET16(dev, port->reg_bufsz) + 1);
   236 	offset = (port->bufsz / 4) - (GET16(dev, port->reg_bufsz) + 1);
   308 
   237 
   309 	/* check for wrap - note that the count is given in dwords */
   238 	/* check for wrap - note that the count is given in dwords */
   312 	} else {
   241 	} else {
   313 		count = offset - port->offset;
   242 		count = offset - port->offset;
   314 	}
   243 	}
   315 	port->count += count;
   244 	port->count += count;
   316 	port->offset = offset;
   245 	port->offset = offset;
   317 }
       
   318 
       
   319 static uint64_t
       
   320 cmpci_count(void *arg)
       
   321 {
       
   322 	cmpci_port_t	*port = arg;
       
   323 	cmpci_dev_t	*dev = port->dev;
       
   324 	uint64_t	count;
       
   325 
       
   326 	mutex_enter(&dev->mutex);
       
   327 	cmpci_update_port(port);
       
   328 
       
   329 	/* the count is in dwords */
       
   330 	count = port->count;
   246 	count = port->count;
   331 
   247 
   332 	mutex_exit(&dev->mutex);
   248 	mutex_exit(&dev->mutex);
   333 
   249 
   334 	/*
   250 	/*
   336 	 * divide
   252 	 * divide
   337 	 */
   253 	 */
   338 	return (count / (port->nchan / 2));
   254 	return (count / (port->nchan / 2));
   339 }
   255 }
   340 
   256 
   341 
       
   342 static int
       
   343 cmpci_setup_interrupts(cmpci_dev_t *dev)
       
   344 {
       
   345 	int actual;
       
   346 	uint_t ipri;
       
   347 
       
   348 	if ((ddi_intr_alloc(dev->dip, &dev->ihandle, DDI_INTR_TYPE_FIXED,
       
   349 	    0, 1, &actual, DDI_INTR_ALLOC_NORMAL) != DDI_SUCCESS) ||
       
   350 	    (actual != 1)) {
       
   351 		audio_dev_warn(dev->adev, "can't alloc intr handle");
       
   352 		return (DDI_FAILURE);
       
   353 	}
       
   354 
       
   355 	if (ddi_intr_get_pri(dev->ihandle, &ipri) != DDI_SUCCESS) {
       
   356 		audio_dev_warn(dev->adev,  "can't determine intr priority");
       
   357 		(void) ddi_intr_free(dev->ihandle);
       
   358 		dev->ihandle = NULL;
       
   359 		return (DDI_FAILURE);
       
   360 	}
       
   361 
       
   362 	if (ddi_intr_add_handler(dev->ihandle, cmpci_intr, dev,
       
   363 	    NULL) != DDI_SUCCESS) {
       
   364 		audio_dev_warn(dev->adev, "can't add intr handler");
       
   365 		(void) ddi_intr_free(dev->ihandle);
       
   366 		dev->ihandle = NULL;
       
   367 		return (DDI_FAILURE);
       
   368 	}
       
   369 
       
   370 	mutex_init(&dev->mutex, NULL, MUTEX_DRIVER, DDI_INTR_PRI(ipri));
       
   371 
       
   372 	return (DDI_SUCCESS);
       
   373 }
       
   374 
       
   375 
       
   376 #define	MASK(nbits)	((1 << (nbits)) - 1)
   257 #define	MASK(nbits)	((1 << (nbits)) - 1)
   377 #define	SCALE(val, nbits)	\
   258 #define	SCALE(val, nbits)	\
   378 	((uint8_t)((((val) * MASK(nbits)) / 100)) << (8 - (nbits)))
   259 	((uint8_t)((((val) * MASK(nbits)) / 100)) << (8 - (nbits)))
   379 
   260 
   380 #define	LEFT(dev, ctl)	min(((dev->controls[ctl].value) >> 8), 100)
   261 #define	LEFT(dev, ctl)	min(((dev->controls[ctl].value) >> 8), 100)
   402 	uint64_t	left, right;
   283 	uint64_t	left, right;
   403 	uint8_t		outmix;
   284 	uint8_t		outmix;
   404 	uint8_t		inmix[2];
   285 	uint8_t		inmix[2];
   405 	uint64_t	recsrcs;
   286 	uint64_t	recsrcs;
   406 	uint64_t	monsrcs;
   287 	uint64_t	monsrcs;
   407 
       
   408 	if (dev->suspended)
       
   409 		return;
       
   410 
   288 
   411 	/* reset all mix values */
   289 	/* reset all mix values */
   412 	outmix = inmix[0] = inmix[1] = 0;
   290 	outmix = inmix[0] = inmix[1] = 0;
   413 
   291 
   414 	outmix = OUTMIX_MIC |
   292 	outmix = OUTMIX_MIC |
   812 
   690 
   813 audio_engine_ops_t cmpci_engine_ops = {
   691 audio_engine_ops_t cmpci_engine_ops = {
   814 	AUDIO_ENGINE_VERSION,		/* version number */
   692 	AUDIO_ENGINE_VERSION,		/* version number */
   815 	cmpci_open,
   693 	cmpci_open,
   816 	cmpci_close,
   694 	cmpci_close,
   817 	NULL,		/* start */
   695 	cmpci_start,
   818 	NULL,		/* stop */
   696 	cmpci_stop,
   819 	cmpci_count,
   697 	cmpci_count,
   820 	cmpci_format,
   698 	cmpci_format,
   821 	cmpci_channels,
   699 	cmpci_channels,
   822 	cmpci_rate,
   700 	cmpci_rate,
   823 	cmpci_sync,
   701 	cmpci_sync,
   829 static int
   707 static int
   830 cmpci_init(cmpci_dev_t *dev)
   708 cmpci_init(cmpci_dev_t *dev)
   831 {
   709 {
   832 	audio_dev_t	*adev = dev->adev;
   710 	audio_dev_t	*adev = dev->adev;
   833 	int		playch;
   711 	int		playch;
   834 	int		intrs;
       
   835 
       
   836 	dev->pintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip,
       
   837 	    DDI_PROP_DONTPASS, "play-interrupts", DEFINTS);
       
   838 
       
   839 	dev->rintrs = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip,
       
   840 	    DDI_PROP_DONTPASS, "record-interrupts", DEFINTS);
       
   841 
   712 
   842 	playch  = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip,
   713 	playch  = ddi_prop_get_int(DDI_DEV_T_ANY, dev->dip,
   843 	    DDI_PROP_DONTPASS, "channels", dev->maxch);
   714 	    DDI_PROP_DONTPASS, "channels", dev->maxch);
   844 
   715 
   845 	if ((playch % 2) || (playch < 2) || (playch > dev->maxch)) {
   716 	if ((playch % 2) || (playch < 2) || (playch > dev->maxch)) {
   875 
   746 
   876 		switch (i) {
   747 		switch (i) {
   877 		case 0:
   748 		case 0:
   878 			caps = ENGINE_INPUT_CAP;
   749 			caps = ENGINE_INPUT_CAP;
   879 			dmaflags = DDI_DMA_READ | DDI_DMA_CONSISTENT;
   750 			dmaflags = DDI_DMA_READ | DDI_DMA_CONSISTENT;
   880 			port->callb = audio_engine_produce;
       
   881 			port->reg_paddr = REG_CH0_PADDR;
   751 			port->reg_paddr = REG_CH0_PADDR;
   882 			port->reg_bufsz = REG_CH0_BUFSZ;
   752 			port->reg_bufsz = REG_CH0_BUFSZ;
   883 			port->reg_fragsz = REG_CH0_FRAGSZ;
   753 			port->reg_fragsz = REG_CH0_FRAGSZ;
   884 			port->fc0_rst_bit = FUNCTRL0_CH0_RST;
   754 			port->fc0_rst_bit = FUNCTRL0_CH0_RST;
   885 			port->fc0_rec_bit = FUNCTRL0_CH0_REC;
   755 			port->fc0_rec_bit = FUNCTRL0_CH0_REC;
   886 			port->fc0_en_bit = FUNCTRL0_CH0_EN;
   756 			port->fc0_en_bit = FUNCTRL0_CH0_EN;
   887 			port->int_en_bit = INTCTRL_CH0_EN;
       
   888 			port->sync_dir = DDI_DMA_SYNC_FORKERNEL;
   757 			port->sync_dir = DDI_DMA_SYNC_FORKERNEL;
   889 			port->capture = B_TRUE;
   758 			port->capture = B_TRUE;
   890 			port->fc1_rate_mask = FUNCTRL1_ADC_RATE_48K;
   759 			port->fc1_rate_mask = FUNCTRL1_ADC_RATE_48K;
   891 			port->chformat_mask = CHFORMAT_CH0_16ST;
   760 			port->chformat_mask = CHFORMAT_CH0_16ST;
   892 			port->nchan = 2;
   761 			port->nchan = 2;
   893 			intrs = dev->rintrs;
       
   894 			break;
   762 			break;
   895 
   763 
   896 		case 1:
   764 		case 1:
   897 			caps = ENGINE_OUTPUT_CAP;
   765 			caps = ENGINE_OUTPUT_CAP;
   898 			dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT;
   766 			dmaflags = DDI_DMA_WRITE | DDI_DMA_CONSISTENT;
   899 			port->callb = audio_engine_consume;
       
   900 			port->reg_paddr = REG_CH1_PADDR;
   767 			port->reg_paddr = REG_CH1_PADDR;
   901 			port->reg_bufsz = REG_CH1_BUFSZ;
   768 			port->reg_bufsz = REG_CH1_BUFSZ;
   902 			port->reg_fragsz = REG_CH1_FRAGSZ;
   769 			port->reg_fragsz = REG_CH1_FRAGSZ;
   903 			port->fc0_rst_bit = FUNCTRL0_CH1_RST;
   770 			port->fc0_rst_bit = FUNCTRL0_CH1_RST;
   904 			port->fc0_rec_bit = FUNCTRL0_CH1_REC;
   771 			port->fc0_rec_bit = FUNCTRL0_CH1_REC;
   905 			port->fc0_en_bit = FUNCTRL0_CH1_EN;
   772 			port->fc0_en_bit = FUNCTRL0_CH1_EN;
   906 			port->int_en_bit = INTCTRL_CH1_EN;
       
   907 			port->sync_dir = DDI_DMA_SYNC_FORDEV;
   773 			port->sync_dir = DDI_DMA_SYNC_FORDEV;
   908 			port->capture = B_FALSE;
   774 			port->capture = B_FALSE;
   909 			port->fc1_rate_mask = FUNCTRL1_DAC_RATE_48K;
   775 			port->fc1_rate_mask = FUNCTRL1_DAC_RATE_48K;
   910 			port->chformat_mask = CHFORMAT_CH1_16ST;
   776 			port->chformat_mask = CHFORMAT_CH1_16ST;
   911 			port->nchan = playch;
   777 			port->nchan = playch;
   912 			intrs = dev->pintrs;
       
   913 			break;
   778 			break;
   914 		}
   779 		}
   915 
       
   916 		/*
       
   917 		 * Calculate fragfr, nfrags, buf.
       
   918 		 *
       
   919 		 * 48 as minimum is chosen to ensure that we will have
       
   920 		 * at least 4 fragments.  512 is just an arbitrary
       
   921 		 * limit, and at the smallest frame size will result
       
   922 		 * in no more than 176 fragments.
       
   923 		 */
       
   924 		intrs = min(512, max(48, intrs));
       
   925 
       
   926 		/*
       
   927 		 * Two fragments are enough to get ping-pong buffers.
       
   928 		 * The hardware could support considerably more than
       
   929 		 * this, but it just wastes memory.
       
   930 		 */
       
   931 		port->nfrags = 2;
       
   932 
   780 
   933 		/*
   781 		/*
   934 		 * For efficiency, we'd like to have the fragments
   782 		 * For efficiency, we'd like to have the fragments
   935 		 * evenly divisble by 64 bytes.  Since frames are
   783 		 * evenly divisble by 64 bytes.  Since frames are
   936 		 * already evenly divisble by 4 (16-bit stereo), this
   784 		 * already evenly divisble by 4 (16-bit stereo), this
   937 		 * is adequate.  For a typical configuration (175 Hz
   785 		 * is adequate.  For a typical configuration (175 Hz
   938 		 * requested) this will translate to 166 Hz.
   786 		 * requested) this will translate to 166 Hz.
   939 		 */
   787 		 */
   940 		port->fragfr = P2ROUNDUP((48000 / intrs), 16);
   788 		port->nframes = 2048;
   941 		port->nframes = port->nfrags * port->fragfr;
       
   942 		port->bufsz = port->nframes * port->nchan * 2;
   789 		port->bufsz = port->nframes * port->nchan * 2;
   943 
   790 
   944 		if (ddi_dma_alloc_handle(dev->dip, &dma_attr, DDI_DMA_DONTWAIT,
   791 		if (ddi_dma_alloc_handle(dev->dip, &dma_attr, DDI_DMA_DONTWAIT,
   945 		    NULL, &port->dmah) != DDI_SUCCESS) {
   792 		    NULL, &port->dmah) != DDI_SUCCESS) {
   946 			audio_dev_warn(adev, "ch%d: dma hdl alloc failed", i);
   793 			audio_dev_warn(adev, "ch%d: dma hdl alloc failed", i);
   971 		audio_dev_add_engine(adev, port->engine);
   818 		audio_dev_add_engine(adev, port->engine);
   972 	}
   819 	}
   973 
   820 
   974 	cmpci_add_controls(dev);
   821 	cmpci_add_controls(dev);
   975 
   822 
   976 	dev->ksp = kstat_create(ddi_driver_name(dev->dip),
       
   977 	    ddi_get_instance(dev->dip), ddi_driver_name(dev->dip),
       
   978 	    "controller", KSTAT_TYPE_INTR, 1, KSTAT_FLAG_PERSISTENT);
       
   979 	if (dev->ksp != NULL) {
       
   980 		kstat_install(dev->ksp);
       
   981 	}
       
   982 
       
   983 	cmpci_reset(dev);
   823 	cmpci_reset(dev);
   984 	cmpci_configure_mixer(dev);
   824 	cmpci_configure_mixer(dev);
   985 
   825 
   986 	if (audio_dev_register(adev) != DDI_SUCCESS) {
   826 	if (audio_dev_register(adev) != DDI_SUCCESS) {
   987 		audio_dev_warn(adev, "audio_dev_register failed");
   827 		audio_dev_warn(adev, "audio_dev_register failed");
   992 }
   832 }
   993 
   833 
   994 void
   834 void
   995 cmpci_destroy(cmpci_dev_t *dev)
   835 cmpci_destroy(cmpci_dev_t *dev)
   996 {
   836 {
   997 	if (dev->ihandle != NULL) {
   837 	mutex_destroy(&dev->mutex);
   998 		(void) ddi_intr_disable(dev->ihandle);
       
   999 		(void) ddi_intr_remove_handler(dev->ihandle);
       
  1000 		(void) ddi_intr_free(dev->ihandle);
       
  1001 		mutex_destroy(&dev->mutex);
       
  1002 	}
       
  1003 
       
  1004 	if (dev->ksp != NULL) {
       
  1005 		kstat_delete(dev->ksp);
       
  1006 	}
       
  1007 
   838 
  1008 	/* free up ports, including DMA resources for ports */
   839 	/* free up ports, including DMA resources for ports */
  1009 	for (int i = 0; i < PORT_MAX; i++) {
   840 	for (int i = 0; i < PORT_MAX; i++) {
  1010 		cmpci_port_t	*port = &dev->port[i];
   841 		cmpci_port_t	*port = &dev->port[i];
  1011 
   842 
  1067 
   898 
  1068 	pci_config_teardown(&pcih);
   899 	pci_config_teardown(&pcih);
  1069 
   900 
  1070 	dev = kmem_zalloc(sizeof (*dev), KM_SLEEP);
   901 	dev = kmem_zalloc(sizeof (*dev), KM_SLEEP);
  1071 	dev->dip = dip;
   902 	dev->dip = dip;
       
   903 	mutex_init(&dev->mutex, NULL, MUTEX_DRIVER, NULL);
  1072 
   904 
  1073 	ddi_set_driver_private(dip, dev);
   905 	ddi_set_driver_private(dip, dev);
  1074 
   906 
  1075 	if ((adev = audio_dev_alloc(dip, 0)) == NULL) {
   907 	if ((adev = audio_dev_alloc(dip, 0)) == NULL) {
  1076 		goto err_exit;
   908 		goto err_exit;
  1128 	case CMEDIA_CM8338B:
   960 	case CMEDIA_CM8338B:
  1129 		audio_dev_set_version(dev->adev, "CMI-8338B");
   961 		audio_dev_set_version(dev->adev, "CMI-8338B");
  1130 		break;
   962 		break;
  1131 	}
   963 	}
  1132 
   964 
  1133 	if (cmpci_setup_interrupts(dev) != DDI_SUCCESS) {
       
  1134 		audio_dev_warn(dev->adev, "can't register interrupts");
       
  1135 		goto err_exit;
       
  1136 	}
       
  1137 
       
  1138 	if (cmpci_init(dev) != DDI_SUCCESS) {
   965 	if (cmpci_init(dev) != DDI_SUCCESS) {
  1139 		audio_dev_warn(dev->adev, "can't init device");
   966 		audio_dev_warn(dev->adev, "can't init device");
  1140 		goto err_exit;
   967 		goto err_exit;
  1141 	}
   968 	}
  1142 
   969 
  1143 	(void) ddi_intr_enable(dev->ihandle);
       
  1144 	return (DDI_SUCCESS);
   970 	return (DDI_SUCCESS);
  1145 
   971 
  1146 err_exit:
   972 err_exit:
  1147 	cmpci_destroy(dev);
   973 	cmpci_destroy(dev);
  1148 	return (DDI_FAILURE);
   974 	return (DDI_FAILURE);
  1149 }
   975 }
  1150 
   976 
  1151 static int
   977 static int
  1152 cmpci_resume(cmpci_dev_t *dev)
   978 cmpci_resume(cmpci_dev_t *dev)
  1153 {
   979 {
  1154 	audio_engine_reset(dev->port[0].engine);
       
  1155 	audio_engine_reset(dev->port[1].engine);
       
  1156 
       
  1157 	mutex_enter(&dev->mutex);
   980 	mutex_enter(&dev->mutex);
  1158 	dev->suspended = B_FALSE;
       
  1159 
       
  1160 	cmpci_reset(dev);
   981 	cmpci_reset(dev);
  1161 	/* wait one millisecond, to give reset a chance to get up */
   982 	/* wait one millisecond, to give reset a chance to get up */
  1162 	drv_usecwait(1000);
   983 	drv_usecwait(1000);
  1163 
       
  1164 	cmpci_configure_mixer(dev);
       
  1165 
       
  1166 	for (int i = 0; i < PORT_MAX; i++) {
       
  1167 		cmpci_port_t *port = &dev->port[i];
       
  1168 
       
  1169 		cmpci_reset_port(port);
       
  1170 		if (port->open) {
       
  1171 			cmpci_start_port(port);
       
  1172 		}
       
  1173 	}
       
  1174 	mutex_exit(&dev->mutex);
   984 	mutex_exit(&dev->mutex);
       
   985 
       
   986 	audio_dev_resume(dev->adev);
       
   987 
  1175 	return (DDI_SUCCESS);
   988 	return (DDI_SUCCESS);
  1176 }
   989 }
  1177 
   990 
  1178 static int
   991 static int
  1179 cmpci_detach(cmpci_dev_t *dev)
   992 cmpci_detach(cmpci_dev_t *dev)
  1181 	if (audio_dev_unregister(dev->adev) != DDI_SUCCESS)
   994 	if (audio_dev_unregister(dev->adev) != DDI_SUCCESS)
  1182 		return (DDI_FAILURE);
   995 		return (DDI_FAILURE);
  1183 
   996 
  1184 	mutex_enter(&dev->mutex);
   997 	mutex_enter(&dev->mutex);
  1185 
   998 
  1186 	/* disable interrupts */
       
  1187 	CLR32(dev, REG_INTCTRL, INTCTRL_CH1_EN | INTCTRL_CH0_EN);
       
  1188 
       
  1189 	/* disable channels */
   999 	/* disable channels */
  1190 	PUT32(dev, REG_FUNCTRL0, 0);
  1000 	PUT32(dev, REG_FUNCTRL0, 0);
  1191 
  1001 
  1192 	mutex_exit(&dev->mutex);
  1002 	mutex_exit(&dev->mutex);
  1193 
  1003 
  1195 
  1005 
  1196 	return (DDI_SUCCESS);
  1006 	return (DDI_SUCCESS);
  1197 }
  1007 }
  1198 
  1008 
  1199 static int
  1009 static int
  1200 cmpci_suspend(cmpci_dev_t *dev)
       
  1201 {
       
  1202 	mutex_enter(&dev->mutex);
       
  1203 
       
  1204 	cmpci_update_port(&dev->port[0]);
       
  1205 	cmpci_stop_port(&dev->port[0]);
       
  1206 
       
  1207 	cmpci_update_port(&dev->port[1]);
       
  1208 	cmpci_stop_port(&dev->port[1]);
       
  1209 
       
  1210 	dev->suspended = B_TRUE;
       
  1211 	mutex_exit(&dev->mutex);
       
  1212 
       
  1213 	return (DDI_SUCCESS);
       
  1214 }
       
  1215 
       
  1216 static int
       
  1217 cmpci_quiesce(dev_info_t *dip)
  1010 cmpci_quiesce(dev_info_t *dip)
  1218 {
  1011 {
  1219 	cmpci_dev_t	*dev;
  1012 	cmpci_dev_t	*dev;
  1220 
  1013 
  1221 	if ((dev = ddi_get_driver_private(dip)) == NULL) {
  1014 	if ((dev = ddi_get_driver_private(dip)) == NULL) {
  1222 		return (DDI_FAILURE);
  1015 		return (DDI_FAILURE);
  1223 	}
  1016 	}
  1224 
       
  1225 	/* disable interrupts */
       
  1226 	PUT32(dev, REG_INTCTRL, 0);
       
  1227 
  1017 
  1228 	/* disable channels */
  1018 	/* disable channels */
  1229 	PUT32(dev, REG_FUNCTRL0, 0);
  1019 	PUT32(dev, REG_FUNCTRL0, 0);
  1230 
  1020 
  1231 	return (DDI_SUCCESS);
  1021 	return (DDI_SUCCESS);
  1263 	switch (cmd) {
  1053 	switch (cmd) {
  1264 	case DDI_DETACH:
  1054 	case DDI_DETACH:
  1265 		return (cmpci_detach(dev));
  1055 		return (cmpci_detach(dev));
  1266 
  1056 
  1267 	case DDI_SUSPEND:
  1057 	case DDI_SUSPEND:
  1268 		return (cmpci_suspend(dev));
  1058 		audio_dev_suspend(dev->adev);
       
  1059 		return (DDI_SUCCESS);
       
  1060 
  1269 	default:
  1061 	default:
  1270 		return (DDI_FAILURE);
  1062 		return (DDI_FAILURE);
  1271 	}
  1063 	}
  1272 }
  1064 }
  1273 
  1065