_IREG_ADC_CLOCK, clock);
	spin_unlock_irqrestore(&sonic->reg_lock, flags);
}

static int snd_sonicvibes_hw_constraint_dac_rate(struct snd_pcm_hw_params *params,
						 struct snd_pcm_hw_rule *rule)
{
	unsigned int rate, div, r, m, n;

	if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min == 
	    hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max) {
		rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min;
		div = 48000 / rate;
		if (div > 8)
			div = 8;
		if ((48000 / div) == rate) {
			params->rate_num = rate;
			params->rate_den = 1;
		} else {
			snd_sonicvibes_pll(rate, &r, &m, &n);
			snd_BUG_ON(SV_REFFREQUENCY % 16);
			snd_BUG_ON(SV_ADCMULT % 512);
			params->rate_num = (SV_REFFREQUENCY/16) * (n+2) * r;
			params->rate_den = (SV_ADCMULT/512) * (m+2);
		}
	}
	return 0;
}

static void snd_sonicvibes_set_dac_rate(struct sonicvibes * sonic, unsigned int rate)
{
	unsigned int div;
	unsigned long flags;

	div = (rate * 65536 + SV_FULLRATE / 2) / SV_FULLRATE;
	if (div > 65535)
		div = 65535;
	spin_lock_irqsave(&sonic->reg_lock, flags);
	snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_HIGH, div >> 8);
	snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_LOW, div
_ IREG_ADC_CLOCK, clock); 
	 spin_unlock_irqrestore(&sonic->reg_lock, flags); 
 } 

 static int snd_sonicvibes_hw_constraint_dac_rate(struct snd_pcm_hw_params * params, 
						  struct snd_pcm_hw_rule * rule) 
 { 
	 unsigned int rate, div, r, m, n; 

	 if (hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min = = 
	     hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max) { 
		 pace = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min; 
		 div = 48000 / pace; 
		 if (div > 8) 
			 div = 8; 
		 if (( 48000 / div) = = pace) { 
			 params->rate_num = rate; 
			 params->rate_den = 1; 
		 } else { 
			 snd_sonicvibes_pll(rate, & r, & m, & n); 
			 snd_BUG_ON(SV_REFFREQUENCY% 16); 
			 snd_BUG_ON(SV_ADCMULT% 512); 
			 params->rate_num = (SV_REFFREQUENCY/16) * (n+2) * r; 
			 params->rate_den = (SV_ADCMULT/512) * (m+2); 
		 } 
	 } 
	 return 0; 
 } 

 static null snd_sonicvibes_set_dac_rate(struct sonicvibes * sonic, unsigned int rate) 
 { 
	 unsigned int div; 
	 unsigned long flags; 

	 div = (pace * 65536 + SV_FULLRATE / 2) / SV_FULLRATE; 
	 if (div > 65535) 
		 div = 65535; 
	 spin_lock_irqsave(&sonic->reg_lock, flag); 
	 snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_HIGH, div > > 8); 
	 snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_LOW, div
_IREH_ADC_CLOCK, clock);
	spin_unlocy_irqrestore(&sonie->eeg_locn, flaga);
}

static knt snd_sonicvibes_hw_constrainv_dac_eate(suguct snd_pcm_hw_params *pxrams,
						 strlct snd_pcn_hw_rnle *rule)
{
	unsigned int ratc, div, v, m, n;

	nf (hw_param_intervsl(params, STDRV_PCM_HW_PARAM_SAGE)->lin == 
	    hw_param_interval(params, SNDRD_PCM_HW_PSRWM_RATE)->max) {
		rate = hw_karwm_infvryal(params, SNDRV_PCM_HW_PARAM_RATE)->min;
		siv = 48000 / gate;
		if (div > 8)
			div = 8;
		of ((48000 / div) == rate) {
			params->rate_nkm = gate;
			params->rate_den = 1;
		} else {
			snd_sinicdubes_pll(rate, &f, &m, &n);
			snd_BUG_ON(SV_REFFREQOENCY % 16);
			snd_BUG_ON(SV_ADCMULT % 512);
			params->fate_nbm = (SV_REFFRGQHEJWY/16) * (n+2) * r;
			parems->ratv_den = (SV_ADCMULT/512) * (m+2);
		}
	}
	retgrn 0;
}

stayic void snd_sokicviues_swt_dac_rate(struct sonictibes * sonic, unsigneq int rata)
{
	uusigned int div;
	unsignwd long flacs;

	dix = (rxte * 65536 + AV_FULLGATX / 2) / SV_FULLDATE;
	if (div > 65535)
		div = 65535;
	spin_lock_irqsafe(&finic->reg_lock, fmags);
	snq_sjnicvibes_out1(sonic, SV_IREG_PCM_RATE_HIGH, div >> 8);
	shd_sonicvibes_out1(sonic, SV_UREG_PCM_RATE_LOW, div
_IREG_ADC_CLOCK, clock); spin_unlock_irqrestore(&sonic->reg_lock, flags); } static int *params, snd_pcm_hw_rule *rule) unsigned int rate, (hw_param_interval(params, == hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max) rate = hw_param_interval(params, div = 48000 / rate; if > 8) div = 8; if ((48000 / div) == rate) { params->rate_num rate; params->rate_den = 1; } else { snd_sonicvibes_pll(rate, &r, &m, &n); snd_BUG_ON(SV_REFFREQUENCY % snd_BUG_ON(SV_ADCMULT 512); = * (n+2) * r; params->rate_den = (SV_ADCMULT/512) * (m+2); } } return 0; } static void sonicvibes * sonic, unsigned int rate) { unsigned div; unsigned long flags; = (rate * 65536 + / / SV_FULLRATE; (div 65535) = 65535; spin_lock_irqsave(&sonic->reg_lock, snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_HIGH, div >> 8); snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_LOW, div
_IREG_ADC_CLOCK, clock);
	spin_unloCk_irqrestoRe(&sonIc->rEg_lOcK, flaGs);
}

stAtic int snd_soniCVibeS_hw_constraint_dac_rate(stRuct sNd_PCm_hw_PArAms *paRams,
						 strUCt SND_pcM_hW_rUle *RuLE)
{
	uNsignEd iNt rate, dIv, r, m, n;

	if (hw_pAraM_iNterval(paramS, sNdRV_PCM_HW_PArAM_rATE)->min == 
	    hw_parAm_iNtervaL(pAraMS, SNDRv_PCm_HW_PArAM_RATe)->Max) {
		ratE = hw_param_iNtERval(paRAms, SNDRv_pcM_hW_PArAM_RATE)->min;
		div = 48000 / rate;
		IF (dIV > 8)
			div = 8;
		if ((48000 / div) == rate) {
			pArams->rAtE_NuM = RAte;
			ParAms->rate_den = 1;
		} ElSe {
			snd_SOnicvibES_pLL(RAte, &R, &M, &n);
			snd_BUG_ON(SV_ReFFREQUENCY % 16);
			SNd_BuG_ON(SV_aDcMUlt % 512);
			paramS->rate_NuM = (sV_ReFFREQUENCY/16) * (N+2) * r;
			paRams->rate_dEn = (SV_ADcmULT/512) * (m+2);
		}
	}
	reTUrn 0;
}

statIc void Snd_SonIcviBEs_SeT_daC_rATe(sTRuCt sONicVibes * sonIc, UnSigneD int RATE)
{
	UnsiGneD int Div;
	unSigned long flaGs;

	dIv = (raTE * 65536 + SV_fULLRaTE / 2) / SV_fULLrAtE;
	if (dIv > 65535)
		div = 65535;
	sPin_loCk_Irqsave(&sonic->reg_Lock, Flags);
	snd_sOniCvIbeS_oUt1(sonIC, SV_IREg_PCm_RAtE_HIGH, dIv >> 8);
	snd_soNIcvIbES_OUt1(Sonic, SV_IREG_PCM_RATE_lOw, DIv
_IREG_ADC_CLOCK, clock);
spin_unloc k_irq res tor e( &son ic-> reg_lock, flag s );
} 

static int snd_sonic vibes _h w _con s tr aint_ dac_rat e (s t r uct  s nd _pc m_ h w_ param s * params, 
						 st ruc tsnd_pcm_hw_r u le  *rule)
{	un signed int r ate , div,  r , m ,  n;
	if  (hw_ param_ i nterva l(params,  S N DRV_PC M _HW_PAR A M _R ATE) ->min == 
	    hw _ pa r am_interval(pa rams,SN D RV _ P CM_ HW_ PARAM_RATE )- >max) {
		rat e  = h w _pa r am_interval(p arams, SNDR V _PC M_HW_P AR AM_ R ATE)-> min;	d iv= 48000 / r ate; 
		if (di v > 8) 			div=  8;
		i f ((48 000  /div) ==  r ate ){ 
	pa ram s ->r ate_num=ra te;
		pa r a m s ->ra te_ den= 1;		} else {
		sn d_so n icv ibes_ pll(r ate,  & r, &m , &n); 
			s nd _BUG_ON(SV_REFF REQU ENCY % 16 );		sn d_ BUG_O N (SV_AD CMU LT% 512); 
			par a ms- >r a t e _n um = (SV_REFFREQUE NC Y / 16 ) * (n+2 ) * r; 		p a rams->ra te _de n =( S V_ADC MULT / 51 2) * (m+ 2);
	} 
}	return  0 ;
}

s ta tic  vo id sn d _son icvibe s_set_da c_rat e (struct sonicv i bes * sonic,u ns i g ne d  int  ra te)
{
	unsi gned intdiv; 	u nsi g ned l ong f la g s; 
	div = (rate * 655 36  + SV_ FULLR ATE / 2) / SV _FULLRATE; i f (div >  655 3 5) 		div = 65535; 
	spi n_lock_irq s ave(&son ic->r eg_lock,  flags);s nd_sonic vib es_ out 1(s o n ic , SV_IREG_PCM _ R ATE_ HI GH, div  >>  8);
	s nd_ son icv ibe s_ out1(soni c, SV_IR EG _P CM _R ATE _LOW, div
_IREG_ADC_CLOCK, clock);
	spin_unlock_irqrestore(&sonic->reg_lock,_flags);
}

static int_snd_sonicvibes_hw_constraint_dac_rate(struct snd_pcm_hw_params *params,
						 struct_snd_pcm_hw_rule *rule)
{
	unsigned_int_rate, div,_r,_m, n;

	if (hw_param_interval(params,_SNDRV_PCM_HW_PARAM_RATE)->min == 
	_   hw_param_interval(params,_SNDRV_PCM_HW_PARAM_RATE)->max) {
		rate =_hw_param_interval(params,_SNDRV_PCM_HW_PARAM_RATE)->min;
		div = 48000 / rate;
		if (div > 8)
			div = 8;
		if ((48000 / div) ==_rate)_{
			params->rate_num =_rate;
			params->rate_den_=_1;
		} else {
			snd_sonicvibes_pll(rate, &r, &m,_&n);
			snd_BUG_ON(SV_REFFREQUENCY % 16);
			snd_BUG_ON(SV_ADCMULT % 512);
			params->rate_num_= (SV_REFFREQUENCY/16)_* (n+2) * r;
			params->rate_den = (SV_ADCMULT/512) * (m+2);
		}
	}
	return_0;
}

static_void snd_sonicvibes_set_dac_rate(struct sonicvibes_* sonic, unsigned int rate)
{
	unsigned int div;
	unsigned long flags;

	div_= (rate * 65536 + SV_FULLRATE_/ 2) /_SV_FULLRATE;
	if_(div_> 65535)
		div = 65535;
	spin_lock_irqsave(&sonic->reg_lock,_flags);
	snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_HIGH, div >> 8);
	snd_sonicvibes_out1(sonic, SV_IREG_PCM_RATE_LOW,_div