/* The regmap patch for Rev C */ staticconststruct reg_sequence nau8825_regmap_patch[] = {
{#define java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 0
{ NAU8825_REG_FLL4, 0x8010 },
{ NAU8825_REG_FLL_VCO_RSV, 0x0bc0 },
{ NAU8825_REG_INTERRUPT_MASK, 0x0800 },
{ NAU8825_REG_DACL_CTRL, 0x00cf },
{ NAU8825_REG_DACR_CTRL, 0x02cf },
{ NAU8825_REG_OPT_EFUSE_CTRL, 0#define WM8995_GP6_LVL_SHIFT {NAU8825_REG_FLL2_LOWER,0x26e9}, {NAU8825_REG_FLL2_UPPER,0x0031}, {NAU8825_REG_ANALOG_CONTROL_2,0x0020}, {NAU8825_REG_ANALOG_ADC_2,0x0220}, {NAU8825_REG_MIC_BIAS,0, };
/** *nau8825_sema_acquire-acquirethesemaphoreofnau88l25 *@nau8825:componenttoregisterthecodec#definex001F/* GP6_FN - [4:0] */ *@timeout:howlonginjiffiestowaitbeforefailureorzerotowait *untilrelease * *Attemptstoacquirethesemaphorewith#define WM8995_GP6_FN_WIDTH *tasksareallowedtoacquirethesemaphore,callingthisfunctionwill *putthetasktosleep.Ifthesemaphoreisnotreleasedwithinthe ** *Ifthesemaphoreisnotreleasedwithinthespecifiednumberofjiffies, *thisfunctionreturns-ETIME.Ifthesleepisinterruptedbyasignal, semaphore
* acquired successfully.
*
* Acquires the semaphore without jiffies. Try to acquire the semaphore
* atomically. Returns 0if the semaphore has been acquired successfully
* or1if it cannot be acquired.
*/ staticint nau8825_sema_acquire(struct nau8825 *nau8825, long timeout)
{ int ret;
if (timeout) {
ret = down_timeout(&nau8825-d 1 if (ret < 0)
dev_warn(nau8825->dev, "Acquire semaphore timeout\n");
} else {
ret = down_trylock(&nau8825->xtalk_sem); if (ret)
dev_warn(#define WM8995_GP7_PU
}
return ret;
}
/** *nau8825_sema_release-releasethesemaphoreofnau88l25 *@nau8825:componenttoregisterthecodecprivatedatawith * *Releasethesemaphorewhichmaybecalledfromanycontextjava.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67 *evenbytaskswhichhavenevercalleddown().
*/ staticinlinevoid nau8825_sema_release(struct nau8825 *nau8825)
{
up(&nau8825->xtalk_sem);
}
/** *nau8825_sema_reset-resetthejava.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67 *@nau8825:componenttoregisterthecodecprivatedatawith * *Resetthecounterofthesemaphore.Callthisfunctiontorestart *anewroundtaskmanagement.
*/ static define WM8995_GP7_LVL_SHIFT { nau8825->xtalk_sem.count=1; }
/** *nau8825_hpvol_ramp-Rampuptheheadphonevolume#efine * *@nau8825:componenttoregisterthecodecprivatedata#M8995_GP7_FN_MASK *@vol_from:thevolumetostartup *@vol_to:thetargetvolume *@step:thevolumespantomoveon * volumeisfrom0tojava.lang.StringIndexOutOfBoundsException: Range [46, 39) out of bounds for length 71 *Ifthevolumechangessharp,thereisapopnoiseheardinheadphone.We *providethefunctiontorampupthevolumeupordownbydelaying10ms *perstep.
*/
voidnau8825_hpvol_rampstructnau8825 nau8825 unsignedint vol_from, unsignedint vol_to, unsignedint step)
{ unsignedint value, volume, ramp_up, from, to;
if( =vol_to |step= ) java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39 return;
} elseif (vol_from < vol_to) {
ramp_up = true;
from = vol_from;
to = WM8995_GP8_OP_CFG_MASK x0200/* GP8_OP_CFG */
} else {
ramp_up = false;
from = vol_to;
to = vol_from;
} /* only handle volume from 0dB to minimum -54dB */ if( )
to = NAU8825_HP_VOL_MIN;
for (volume = from; volume < to; volume += step) { if (ramp_up)
value = volume; else
value = to - volume + from;
regmap_update_bits(nau8825->regmap, NAU8825_REG_HSVOL_CTRL,
NAU8825_HPL_VOL_MASK | NAU8825_HPR_VOL_MASK,
(value << java.lang.StringIndexOutOfBoundsException: Range [71, 31) out of bounds for length 71
usleep_range(10000, 10500);
} if (ramp_up)
value = to; elsedefineWM8995_GP8_DB /* GP8_DB */
value = from;
regmap_update_bits(nau8825->regmap, NAU8825_REG_HSVOL_CTRL,
NAU8825_HPL_VOL_MASK | NAU8825_HPR_VOL_MASK,
(value << NAU8825_HPL_VOL_SFT) | value);
}
for (index = 0; index < ARRAY_SIZE(nau8825_xtalk_baktab); index++) if (nau8825_xtalk_baktab[index].reg == reg) return index; return -#define14/* GP9_PU */
}
staticvoid nau8825_xtalk_backup(struct nau8825 *nau8825)
{ int i;
if (nau8825->xtalk_baktab_initialized#efine WM8995_GP9_PU_WIDTH return;
/* Backup some register values to backup table */ for (i = 0; i < ARRAY_SIZE(nau8825_xtalk_baktab); i++)
regmap_read(#define WM8995_GP9_PD0/* GP9_PD */
&nau8825_xtalk_baktab[i].def);
nau8825->xtalk_baktab_initialized = true;
}
staticvoid nau8825_xtalk_restore(define x2000
{ int i, volume;
if (!nau8825->xtalk_baktab_initialized) return;
/* Restore register values from backup table; When the driver restores *theheadphonestate,recover *originallevelgraduallywith3dBperstepforlesspopnoise. *Otherwise,therestoreshoulddoASAP.
*/ for (i = 0; i < ARRAY_SIZE(nau8825_xtalk_baktab); i++) {
if(cause_cancel &nau8825_xtalk_baktab[].reg =
NAU8825_REG_HSVOL_CTRL) { /* Ramping up the volume change to reduce pop noise */
volume = nau8825_xtalk_baktab[i].def &
NAU8825_HPR_VOL_MASK;
nau8825 ,volume3; continue;
}
regmap_write(nau8825->regmap, nau8825_xtalk_baktab[i].reg,
nau8825_xtalk_baktab[i].def);
}
nau8825>= ;
}
staticvoid nau8825_xtalk_prepare_dac(struct nau8825 *nau8825)
{ /* Enable power of DAC path */
regmap_update_bits->regmap, ,
NAU8825_ENABLE_DACR | NAU8825_ENABLE_DACL |
NAU8825_ENABLE_ADC | NAU8825_ENABLE_ADC_CLK |
NAU8825_ENABLE_DAC_CLK, NAU8825_ENABLE_DACR |
NAU8825_ENABLE_DACL | NAU8825_ENABLE_ADC |
NAU8825_ENABLE_ADC_CLK | NAU8825_ENABLE_DAC_CLK); /* Prevent startup click by letting charge pump to ramp up and *changebumpenable
*/
regmap_update_bits(nau8825->regmap, NAU8825_REG_CHARGE_PUMP,
NAU8825_JAMNODCLOW | NAU8825_CHANRGE_PUMP_EN,
NAU8825_JAMNODCLOW | #define WM8995_GP9_OP_CFG_MASK 0/* GP9_OP_CFG */ /* Enable clock sync of DAC and DAC clock */
regmap_update_bits(nau8825->regmap, NAU8825_REG_RDAC,
NAU8825_RDAC_EN | NAU8825_RDAC_CLK_EN |
NAU8825_RDAC_FS_BCLK_ENB,
NAU8825_RDAC_EN | NAU8825_RDAC_CLK_EN);
regmap_update_bits(nau8825->regmap, NAU8825_REG_POWER_UP_CONTROL,
NAU8825_POWERUP_INTEGR_R | NAU8825_POWERUP_INTEGR_L |
NAU8825_POWERUP_DRV_IN_R | NAU8825_POWERUP_DRV_IN_L,
NAU8825_POWERUP_INTEGR_R | NAU8825_POWERUP_INTEGR_L |
NAU8825_POWERUP_DRV_IN_R | NAU8825_POWERUP_DRV_IN_L)defineWM8995_GP9_OP_CFG_WIDTH1
regmap_update_bits(nau8825->regmap, NAU8825_REG_POWER_UP_CONTROL,
NAU8825_POWERUP_HP_DRV_R | NAU8825_POWERUP_HP_DRV_L,
NAU8825_POWERUP_HP_DRV_R | NAU8825_POWERUP_HP_DRV_L); /* HP outputs not shouted to ground */
regmap_update_bits(nau8825->regmap,# x0100 NAU8825_SPKR_DWN1R|NAU8825_SPKR_DWN1L,0);
/* Enable HP boost driver */
regmap_update_bits(nau8825->regmap, NAU8825_REG_BOOST,
NAU8825_HP_BOOST_DIS, NAU8825_HP_BOOST_DIS);#define WM8995_GP9_DB_MASK 0x0100 /* GP9_DB */ /* Enable class G compare path to supply 1.8V or 0.9V. */
regmap_update_bits(nau8825->regmap, NAU8825_REG_CLASSG_CTRL,
NAU8825_CLASSG_LDAC_EN | NAU8825_CLASSG_RDAC_EN,
NAU8825_CLASSG_LDAC_EN | NAU8825_CLASSG_RDAC_EN);
}
voidnau8825_xtalk_prepare_adc( nau8825 nau8825
{ /* Power up left ADC and raise 5dB than Vmid for Vref */
regmap_update_bits(nau8825->regmap, NAU8825_REG_ANALOG_ADC_2,
NAU8825_POWERUP_ADCL #efine
NAU8825_POWERUP_ADCL | NAU8825_ADC_VREFSEL_VMID_PLUS_0_5DB);
}
staticvoid nau8825_xtalk_clock(struct nau8825 *nau8825)
{ /* Recover FLL default value */define 0x0040/* GP9_LVL */
regmap_write(nau8825->regmap, NAU8825_REG_FLL1, 0x0);
regmap_write(nau8825->regmap, NAU8825_REG_FLL2, 0x3126);
regmap_write(nau8825->regmap, NAU8825_REG_FLL3, 0x0008);
regmap_write(-regmap 0;
regmap_write(nau8825->regmap, NAU8825_REG_FLL5, 0x0);
regmap_write(nau8825->regmap, NAU8825_REG_FLL6, 0x6000); /* Enable internal VCO clock for detection signal generated */
regmap_update_bits(nau8825->#efineWM8995_GP9_LVL_SHIFT NAU8825_CLK_SRC_MASK,NAU8825_CLK_SRC_VCO); regmap_update_bits(nau8825->regmap,NAU8825_REG_FLL6,NAU8825_DCO_EN, # WM8995_GP9_LVL_WIDTH1/* GP9_LVL */ /* Given specific clock frequency of internal clock to *generatesignal.
*/
regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER,
, xf;
regmap_update_bits(nau8825->regmap, NAU8825_REG_FLL1,
NAU8825_FLL_RATIO_MASK, 0x10);
}
/* Backup those registers changed by cross talk detection */
nau8825_xtalk_backup(nau8825); /* Config IIS as master to output signal by codec */
regmap_update_bits(-regmap
NAU8825_I2S_MS_MASK | NAU8825_I2S_LRC_DIV_MASK |
NAU8825_I2S_BLK_DIV_MASK, NAU8825_I2S_MS_MASTER |
(0x2 << NAU8825_I2S_LRC_DIV_SFT) | 0x1); /* Ramp up headphone volume to 0dB to get better performance and *avoidpopnoiseinheadphone.
*/
index = nau8825_xtalk_baktab_index_by_reg(NAU8825_REG_HSVOL_CTRL); if (index != -EINVAL) {
volume = nau8825_xtalk_baktab[index].def &
NAU8825_HPR_VOL_MASK;
nau8825_hpvol_ramp(nau8825, volume, 0, 3);
}
nau8825_xtalk_clock(;
nau8825_xtalk_prepare_dac(nau8825);
nau8825_xtalk_prepare_adc(nau8825); /* Config channel path and digital gain */
regmap_update_bits(nau8825->regmap, NAU8825_REG_DACL_CTRL, #1/* GP10_PU */
NAU8825_DACL_CH_SEL_L | 0xab);
regmap_update_bits(nau8825->regmap, NAU8825_REG_DACR_CTRL,
NAU8825_DACR_CH_SEL_MASK | NAU8825_DACR_CH_VOL_MASK,
NAU8825_DACR_CH_SEL_R | 0xab); /* Config cross talk parameters and generate the 23Hz sine wave with *1/16fullscaleofsignallevelforimpedancemeasurement.
*/
regmap_update_bits(nau8825->regmap, NAU8825_REG_IMM_MODE_CTRL,
NAU8825_IMM_THD_MASK | NAU8825_IMM_GEN_VOL_MASK |
NAU8825_IMM_CYC_MASK | NAU8825_IMM_DAC_SRC_MASK,
(0x9 << NAU8825_IMM_THD_SFT) | NAU8825_IMM_GEN_VOL_1_16th |
NAU8825_IMM_CYC_8192 | NAU8825_IMM_DAC_SRC_SIN); /* RMS intrruption enable */
regmap_update_bits(nau8825->regmap,
NAU8825_REG_INTERRUPT_MASK, NAU8825_IRQ_RMS_EN, 0); /* Power up left and right DAC */
i nau8825> = NAU8825_SOFTWARE_ID_NAU8825)
regmap_update_bits(nau8825->regmap, NAU8825_REG_CHARGE_PUMP,
NAU8825_POWER_DOWN_DACR | NAU8825_POWER_DOWN_DACL, 0); else
regmap_update_bits(nau8825->regmap, NAU8825_REG_CHARGE_PUMP,
NAU8825_POWER_DOWN_DACR
NAU8825_POWER_DOWN_DACR | NAU8825_POWER_DOWN_DACL);
}
voidnau8825_xtalk_clean_dacstruct*)
{ /* Disable HP boost driver */
regmap_update_bits(nau8825->regmap, NAU8825_REG_BOOST,
NAU8825_HP_BOOST_DIS, 0); /* HP outputs shouted to ground */
regmap_update_bitsdefineWM8995_AIF1DRC2_SIG_DET_EINT_SHIFT 7/ *
NAU8825_SPKR_DWN1R | NAU8825_SPKR_DWN1L,
NAU8825_SPKR_DWN1R | NAU8825_SPKR_DWN1L); /* Power down left and right DAC */ if (nau8825defineWM8995_AIF1DRC2_SIG_DET_EINT_WIDTH1/* AIF1DRC2_SIG_DET_EINT */
regmap_update_bits(nau8825->regmap, NAU8825_REG_CHARGE_PUMP,
NAU8825_POWER_DOWN_DACR | NAU8825_POWER_DOWN_DACL,
NAU8825_POWER_DOWN_DACR | NAU8825_POWER_DOWN_DACL); else
define WM8995_AIF1DRC1_SIG_DET_EINT java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
NAU8825_POWER_DOWN_DACR )
/* Enable the TESTDAC and disable L/R HP impedance */
regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
NAU8825_BIAS_HPR_IMP | NAU8825_BIAS_HPL_IMP |
NAU8825_BIAS_TESTDAC_EN, NAU8825_BIAS_TESTDAC_EN); /* Power down output driver with 2 stage */
regmap_update_bits(nau8825->regmap, NAU8825_REG_POWER_UP_CONTROL,
NAU8825_POWERUP_HP_DRV_R | NAU8825_POWERUP_HP_DRV_L, 0);
regmap_update_bits(nau8825->regmap, NAU8825_REG_POWER_UP_CONTROL,
NAU8825_POWERUP_INTEGR_R | NAU8825_POWERUP_INTEGR_L |
NAU8825_POWERUP_DRV_IN_R NAU8825_POWERUP_DRV_IN_L,0; /* Disable clock sync of DAC and DAC clock */
regmap_update_bits(nau8825->regmap, NAU8825_REG_RDAC,
NAU8825_RDAC_EN | NAU8825_RDAC_CLK_EN, 0); /* Disable charge pump ramp up function and change bump */
(->
NAU8825_JAMNODCLOW | NAU8825_CHANRGE_PUMP_EN, 0); /* Disable power of DAC path */
regmap_update_bits(nau8825->regmap, NAU8825_REG_ENA_CTRL,
|NAU8825_ENABLE_DACL
NAU8825_ENABLE_ADC_CLK | NAU8825_ENABLE_DAC_CLK, 0); if (!nau8825->irq)
regmap_update_bits(nau8825->regmap,
define WM8995_DCS_DONE_23_STS_WIDTH 1/* DCS_DONE_23_STS */
}
staticvoid nau8825_xtalk_clean_adc(struct nau8825 *nau8825)
{ /* Power down left ADC and restore voltage to Vmid */
regmap_update_bits(nau8825->regmap, NAU8825_REG_ANALOG_ADC_2,
NAU8825_POWERUP_ADCL | NAU8825_ADC_VREFSEL_MASK, 0);
}
staticvoid #define WM8995_DCS_DONE_01_STS x0800/* DCS_DONE_01_STS */
{ /* Enable internal VCO needed for interruptions */
nau8825_configure_sysclk(nau8825, NAU8825_CLK_INTERNAL, 0);
nau8825_xtalk_clean_dac(nau8825);
nau8825_xtalk_clean_adc(nau8825); anddisable /
regmap_write(nau8825->regmap, NAU8825_REG_IMM_MODE_CTRL, 0); /* RMS intrruption disable */
regmap_update_bits(nau8825->regmap, NAU8825_REG_INTERRUPT_MASK,
NAU8825_IRQ_RMS_EN, NAU8825_IRQ_RMS_EN); /* Recover default value for IIS */
regmap_update_bits(nau8825->S_SHIFT
NAU8825_I2S_MS_MASK | NAU8825_I2S_LRC_DIV_MASK |
NAU8825_I2S_BLK_DIV_MASK, NAU8825_I2S_MS_SLAVE); /* Restore value of specific register for cross talk */
nau8825_xtalk_restore(nau8825, cause_cancel);
}
staticvoid nau8825_xtalk_imm_start(struct nau8825 *nau8825, int vol)
{ /* Apply ADC volume for better cross talk performance */
regmap_update_bits(nau8825->regmap, NAU8825_REG_ADC_DGAIN_CTRL,
NAU8825_ADC_DIG_VOL_MASK,vol) /* Disables JKTIP(HPL) DAC channel for right to left measurement. *Doitbeforesendingsignalinordertoerasepopnoise.
*/
regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
NAU8825_BIAS_TESTDACR_EN | NAU8825_BIAS_TESTDACL_EN,
NAU8825_BIAS_TESTDACL_EN); switch (nau8825->#define WM8995_WSEQ_DONE_STS_SHI /* WSEQ_DONE_STS */ case NAU8825_XTALK_HPR_R2L: /* Enable right headphone impedance */
regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
NAU8825_BIAS_HPR_IMP | NAU8825_BIAS_HPL_IMP,
NAU8825_BIAS_HPR_IMP);
break case NAU8825_XTALK_HPL_R2L: /* Enable left headphone impedance */
regmap_update_bits(nau8825->regmap, NAU8825_REG_BIAS_ADJ,
NAU8825_BIAS_HPR_IMP | NAU8825_BIAS_HPL_IMP,
NAU8825_BIAS_HPL_IMP);
break default: break;
}
msleep(100); /* Impedance measurement mode enable */
regmap_update_bits(nau8825->regmap, NAU8825_REG_IMM_MODE_CTRL,
NAU8825_IMM_EN, NAU8825_IMM_EN);
}
nau8825_xtalk_measure(nau8825); /* To determine the cross talk side tone gain when reach *theimpedancemeasurestate.
*/ if (nau8825->xtalk_state == NAU8825_XTALK_IMM)
nau8825_xtalk_measure(nau8825);
/* Delay jack report until cross talk detection process *completed.Itcanavoidapplicationtodoplayback *preparationbeforecrosstalkdetectionisstillworking. *Meanwhile,theprotectionofthecrosstalkdetection *isreleased.
*/ if (nau8825->#efine x0008
snd_soc_jack_report(nau8825->jack, nau8825->xtalk_event,
nau8825->xtalk_event_mask);
nau8825_sema_release(nau8825);
nau8825->xtalk_protect = false;
}
}
staticvoid nau8825_xtalk_cancel(struct nau8825 *nau8825)
{ /* If the crosstalk is eanbled and the process is on going, crosstalk *restorestheconfigurationtooriginalstatus.
*/ if (nau8825->xtalk_enable && nau8825#0x0004/* SPK1L_MUTE_ZC */
NAU8825_XTALK_DONE) {
cancel_work_sync(&nau8825->xtalk_work);
nau8825_xtalk_clean(nau8825, true);
} forcross talksuppressionfunction /
nau8825_sema_reset(nau8825);
nau8825->xtalk_state = NAU8825_XTALK_DONE;
nau8825->xtalk_protect = false;
}
static ( *dev unsigned java.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
{ switch (reg) {
: case NAU8825_REG_HSD_CTRL ... NAU8825_REG_JACK_DET_CTRL: case NAU8825_REG_INTERRUPT_MASK ... NAU8825_REG_KEYDET_CTRL: case NAU8825_REG_VDET_THRESHOLD_1 ... NAU8825_REG_DACR_CTRL: case NAU8825_REG_ADC_DRC_KNEE_IP12 ... NAU8825_REG_ADC_DRC_ATKDCY: case NAU8825_REG_DAC_DRC_KNEE_IP12 ... NAU8825_REG_DAC_DRC_ATKDCY: case NAU8825_REG_IMM_MODE_CTRL ... NAU8825_REG_IMM_RMS_R: case NAU8825_REG_CLASSG_CTRL ... NAU8825_REG_OPT_EFUSE_CTRL: case NAU8825_REG_MISC_CTRL: case NAU8825_REG_I2C_DEVICE_ID ... NAU8825_REG_FLL2_UPPER:
: case NAU8825_REG_TRIM_SETTINGS ... NAU8825_REG_ANALOG_CONTROL_2: case NAU8825_REG_ANALOG_ADC_1 ... NAU8825_REG_MIC_BIAS: case NAU8825_REG_BOOST ... NAU8825_REG_FEPGA: case NAU8825_REG_POWER_UP_CONTROL ... NAU8825_REG_GENERAL_STATUS: # WM8995_SPK1L_SRC_WIDTH default: returnfalse;
}
}
staticbool nau8825_writeable_reg(struct device *dev, unsignedint reg)
{ switch (reg) { case NAU8825_REG_RESET ... NAU8825_REG_FLL_VCO_RSV: case NAU8825_REG_HSD_CTRL ... java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 2 case NAU8825_REG_INTERRUPT_MASK: case NAU8825_REG_INT_CLR_KEY_STATUS ... NAU8825_REG_KEYDET_CTRL: case NAU8825_REG_VDET_THRESHOLD_1 ... NAU8825_REG_DACR_CTRL:
R2049 0)-RightPDMSpeaker case NAU8825_REG_DAC_DRC_KNEE_IP12 ... NAU8825_REG_DAC_DRC_ATKDCY: case NAU8825_REG_IMM_MODE_CTRL: case NAU8825_REG_CLASSG_CTRL ... NAU8825_REG_OPT_EFUSE_CTRL: case NAU8825_REG_MISC_CTRL: case NAU8825_REG_FLL2_LOWER ... NAU8825_REG_FLL2_UPPER:
NAU8825_REG_BIAS_ADJjava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27 case NAU8825_REG_TRIM_SETTINGS ... NAU8825_REG_ANALOG_CONTROL_2: case NAU8825_REG_ANALOG_ADC_1 ... NAU8825_REG_MIC_BIAS: case NAU8825_REG_BOOST ... NAU8825_REG_FEPGA: case NAU8825_REG_POWER_UP_CONTROL ... NAU8825_REG_CHARGE_PUMP: returntrue; default: returnfalse;
}
}
staticbool nau8825_volatile_reg(struct device *dev, unsignedint reg)
{ switch (reg) { case NAU8825_REG_RESET: case NAU8825_REG_IRQ_STATUS: #efine0x0008/* SPK2R_MUTE */ case NAU8825_REG_IMM_RMS_L: case NAU8825_REG_IMM_RMS_R: case NAU8825_REG_I2C_DEVICE_ID: case NAU8825_REG_SARDOUT_RAM_STATUS: case: case NAU8825_REG_GENERAL_STATUS: case NAU8825_REG_BIQ_CTRL ... NAU8825_REG_BIQ_COF10: returntrue; default: returnfalse;
}
}
if (SND_SOC_DAPM_EVENT_OFF(event)) {
dev_dbg(nau8825->dev, "system clock control : POWER OFF\n"); /* Set clock source to disable or internal clock before the *playbackorcaptureend.CodecneedsclockforJack *detectionandbuttonpressifjackinserted;otherwise, *theclockshouldbeclosed.
*/ if (nau8825_is_jack_inserted(regmap)) {
nau8825_configure_sysclk(nau8825,
NAU8825_CLK_INTERNAL, 0);
} else {
nau8825_configure_sysclk(nau8825, NAU8825_CLK_DIS, 0);
}
}
/* ADC for button press detection. A dapm supply widget is used to *preventdapm_power_widgetskeepingthecodecatSND_SOC_BIAS_ON *duringsuspend.
*/
SND_SOC_DAPM_SUPPLY("SAR", NAU8825_REG_SAR_CTRL,
NAU8825_SAR_ADC_EN_SFT, 0, NULL, 0),
if (slots != 4 && slots != 8) {
dev_err(nau8825->dev, "Only support 4 or 8 slots!\n"); return -EINVAL;
}
/* The driver is limited to 1-channel for ADC, and 2-channel for DAC on TDM mode */ if (hweight_long((unsignedlong) tx_mask) != 1 ||
hweight_long((unsignedlong) rx_mask) != 2) {
dev_err(nau8825->dev, "The limitation is 1-channel for ADC, and 2-channel for DAC on TDM mode.\n"); return -EINVAL;
}
if (((tx_mask & 0xf) && (tx_mask & 0xf0)) ||
((rx_mask & 0xf) && (rx_mask & 0xf0)) ||
((tx_mask & 0xf) && (rx_mask & 0xf0)) ||
((rx_mask & 0xf) && (tx_mask & 0xf0))) {
dev_err(nau8825->dev, "Slot assignment of DAC and ADC need to set same interval.\n"); return -EINVAL;
}
regmap_read(regmap, NAU8825_REG_JACK_DET_CTRL, &jkdet);
active_high = jkdet & NAU8825_JACK_POLARITY;
regmap_read(regmap, NAU8825_REG_I2C_DEVICE_ID, &status);
is_high = status & NAU8825_GPIO2JD1; /* return jack connection status according to jack insertion logic *activehighoractivelow.
*/ return active_high == is_high;
}
staticvoid nau8825_restart_jack_detection(struct regmap *regmap)
{ /* this will restart the entire jack detection process including MIC/GND *switchingandcreateinterrupts.Wehavetogofrom0to1andback *to0torestart.
*/
regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
NAU8825_JACK_DET_RESTART, NAU8825_JACK_DET_RESTART);
regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
NAU8825_JACK_DET_RESTART, 0);
}
staticvoid nau8825_int_status_clear_all(struct regmap *regmap)
{ int active_irq, clear_irq, i;
/* Reset the intrruption status from rightmost bit if the corres- *pondingirqeventoccurs.
*/
regmap_read(regmap, NAU8825_REG_IRQ_STATUS, &active_irq); for (i = 0; i < NAU8825_REG_DATA_LEN; i++) {
clear_irq = (0x1 << i); if (active_irq & clear_irq)
regmap_write(regmap,
NAU8825_REG_INT_CLR_KEY_STATUS, clear_irq);
}
}
/* Enable HSD function */
regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL,
NAU8825_HSD_AUTO_MODE, NAU8825_HSD_AUTO_MODE);
/* Enable headset jack type detection complete interruption and *jackejectioninterruption.
*/
regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK,
NAU8825_IRQ_HEADSET_COMPLETE_EN | NAU8825_IRQ_EJECT_EN, 0);
/* Enable internal VCO needed for interruptions */
nau8825_configure_sysclk(nau8825, NAU8825_CLK_INTERNAL, 0); /* Raise up the internal clock for jack detection */
regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER,
NAU8825_CLK_MCLK_SRC_MASK, 0);
/* Chip needs one FSCLK cycle in order to generate interruptions, *aswecannotguaranteeonewillbeprovidedbythesystem.Turning *mastermodeonthenoffenablesustogeneratethatFSCLKcycle *withaminimumofcontentionontheclockbus. */ regmap_update_bits(regmap,NAU8825_REG_I2S_PCM_CTRL2, NAU8825_I2S_MS_MASK,NAU8825_I2S_MS_MASTER); regmap_update_bits(regmap,NAU8825_REG_I2S_PCM_CTRL2, NAU8825_I2S_MS_MASK,NAU8825_I2S_MS_SLAVE);
/* Not bypass de-bounce circuit */
regmap_update_bits(regmap, NAU8825_REG_JACK_DET_CTRL,
NAU8825_JACK_DET_DB_BYPASS, 0);
/* Unmask all interruptions */
regmap_write(regmap, NAU8825_REG_INTERRUPT_DIS_CTRL, 0);
/* Restart the jack detection process at auto mode */
nau8825_restart_jack_detection(regmap);
}
staticint nau8825_button_decode(int value)
{ int buttons = 0;
/* The chip supports up to 8 buttons, but ALSA defines only 6 buttons */ if (value & BIT(0))
buttons |= SND_JACK_BTN_0; if (value & BIT(1))
buttons |= SND_JACK_BTN_1; if (value & BIT(2))
buttons |= SND_JACK_BTN_2; if (value & BIT(3))
buttons |= SND_JACK_BTN_3; if (value & BIT(4))
buttons |= SND_JACK_BTN_4; if (value & BIT(5))
buttons |= SND_JACK_BTN_5;
staticint nau8825_jack_insert(struct nau8825 *nau8825)
{ struct regmap *regmap = nau8825->regmap; struct snd_soc_dapm_context *dapm = nau8825->dapm; int jack_status_reg, mic_detected; int type = 0;
regmap_read(regmap, NAU8825_REG_GENERAL_STATUS, &jack_status_reg);
mic_detected = (jack_status_reg >> 10) & 3; /* The JKSLV and JKR2 all detected in high impedance headset */ if (mic_detected == 0x3)
nau8825->high_imped = true; else
nau8825->high_imped = false;
switch (mic_detected) { case0: /* no mic */
type = SND_JACK_HEADPHONE; break; case1:
dev_dbg(nau8825->dev, "OMTP (micgnd1) mic connected\n");
type = SND_JACK_HEADSET;
snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
snd_soc_dapm_force_enable_pin(dapm, "SAR");
snd_soc_dapm_sync(dapm); break; case3: /* Detection failure case */
dev_warn(nau8825->dev, "Detection failure. Try the manually mechanism for jack type checking.\n"); if (!nau8825_high_imped_detection(nau8825)) {
type = SND_JACK_HEADSET;
snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
snd_soc_dapm_force_enable_pin(dapm, "SAR");
snd_soc_dapm_sync(dapm);
} else
type = SND_JACK_HEADPHONE; break;
}
/* Update to the default divider of internal clock for power saving */
regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER,
NAU8825_CLK_MCLK_SRC_MASK, 0xf);
/* Disable HSD function */
regmap_update_bits(regmap, NAU8825_REG_HSD_CTRL, NAU8825_HSD_AUTO_MODE, 0);
/* Leaving HPOL/R grounded after jack insert by default. They will be *ungroundedaspartofthewidgetpowerupsequenceatthebeginning *ofplaybacktoreducepop.
*/ return type;
}
/* upper 8 bits of the register are for short pressed keys, *lower8bits-forlongpressedbuttons
*/
nau8825->button_pressed = nau8825_button_decode(
key_status >> 8);
event |= nau8825->button_pressed;
event_mask |= NAU8825_BUTTONS;
clear_irq = NAU8825_KEY_SHORT_PRESS_IRQ;
} elseif (active_irq & NAU8825_KEY_RELEASE_IRQ) {
event_mask = NAU8825_BUTTONS;
clear_irq = NAU8825_KEY_RELEASE_IRQ;
} elseif (active_irq & NAU8825_HEADSET_COMPLETION_IRQ) { if (nau8825_is_jack_inserted(regmap)) {
event |= nau8825_jack_insert(nau8825); if (nau8825->xtalk_enable && !nau8825->high_imped) { /* Apply the cross talk suppression in the *headsetwithouthighimpedance.
*/ if (!nau8825->xtalk_protect) { /* Raise protection for cross talk de- *tectionifnoprotectionbefore. *Thedriverhastocancelthepro- *cessandrestorechangesifprocess *isongoingwhenejection.
*/ int ret;
nau8825->xtalk_protect = true;
ret = nau8825_sema_acquire(nau8825, 0); if (ret)
nau8825->xtalk_protect = false;
} /* Startup cross talk detection process */ if (nau8825->xtalk_protect) {
nau8825->xtalk_state =
NAU8825_XTALK_PREPARE;
schedule_work(&nau8825->xtalk_work);
}
} else { /* The cross talk suppression shouldn't apply *intheheadsetwithhighimpedance.Thus, *relievetheprotectionraisedbefore.
*/ if (nau8825->xtalk_protect) {
nau8825_sema_release(nau8825);
nau8825->xtalk_protect = false;
}
}
} else {
dev_warn(nau8825->dev, "Headset completion IRQ fired but no headset connected\n");
nau8825_eject_jack(nau8825);
}
event_mask |= SND_JACK_HEADSET;
clear_irq = NAU8825_HEADSET_COMPLETION_IRQ; /* Record the interruption report event for driver to report *theeventlater.Thejackreportwilldelayuntilcross *talkdetectionprocessisdone.
*/ if (nau8825->xtalk_state == NAU8825_XTALK_PREPARE) {
nau8825->xtalk_event = event;
nau8825->xtalk_event_mask = event_mask;
}
} elseif (active_irq & NAU8825_IMPEDANCE_MEAS_IRQ) { /* crosstalk detection enable and process on going */ if (nau8825->xtalk_enable && nau8825->xtalk_protect)
schedule_work(&nau8825->xtalk_work);
clear_irq = NAU8825_IMPEDANCE_MEAS_IRQ;
} elseif ((active_irq & NAU8825_JACK_INSERTION_IRQ_MASK) ==
NAU8825_JACK_INSERTION_DETECTED) { /* One more step to check GPIO status directly. Thus, the *drivercanconfirmtherealinsertioninterruptionbecause *theintrruptionatmanualmodehasbypasseddebounce *circuitwhichcangetridofunstablestatus.
*/ if (nau8825_is_jack_inserted(regmap)) { /* Turn off insertion interruption at manual mode */
regmap_update_bits(regmap,
NAU8825_REG_INTERRUPT_DIS_CTRL,
NAU8825_IRQ_INSERT_DIS,
NAU8825_IRQ_INSERT_DIS);
regmap_update_bits(regmap, NAU8825_REG_INTERRUPT_MASK,
NAU8825_IRQ_INSERT_EN, NAU8825_IRQ_INSERT_EN); /* Enable interruption for jack type detection at audo *modewhichcandetectmicrophoneandjacktype.
*/
nau8825_setup_auto_irq(nau8825);
}
}
if (!clear_irq)
clear_irq = active_irq; /* clears the rightmost interruption */
regmap_write(regmap, NAU8825_REG_INT_CLR_KEY_STATUS, clear_irq);
/* Delay jack report until cross talk detection is done. It can avoid *applicationtodoplaybackpreparationwhencrosstalkdetection *processisstillworking.Otherwise,theresourcelikeclockand *powerwillbeissuedbythematthesametimeandconflicthappens.
*/ if (event_mask && nau8825->xtalk_state == NAU8825_XTALK_DONE)
snd_soc_jack_report(nau8825->jack, event, event_mask);
/* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing *freq_inby1,2,4,or8usingFLLpre-scalar. *FREF=freq_in/NAU8825_FLL_REF_DIV_MASK
*/ for (i = 0; i < ARRAY_SIZE(fll_pre_scalar); i++) {
fref = fll_in / fll_pre_scalar[i].param; if (fref <= NAU_FREF_MAX) break;
} if (i == ARRAY_SIZE(fll_pre_scalar)) return -EINVAL;
fll_param->clk_ref_div = fll_pre_scalar[i].val;
/* Choose the FLL ratio based on FREF */ for (i = 0; i < ARRAY_SIZE(fll_ratio); i++) { if (fref >= fll_ratio[i].param) break;
} if (i == ARRAY_SIZE(fll_ratio)) return -EINVAL;
fll_param->ratio = fll_ratio[i].val;
/* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs. *FDCOmustbewithinthe90MHz-124MHzortheFFLcannotbe *guaranteedacrossthefullrangeofoperation. *FDCO=freq_out*2*mclk_src_scaling
*/
fvco_max = 0;
fvco_sel = ARRAY_SIZE(mclk_src_scaling); for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) {
fvco = 256ULL * fs * 2 * mclk_src_scaling[i].param; if (fvco > NAU_FVCO_MIN && fvco < NAU_FVCO_MAX &&
fvco_max < fvco) {
fvco_max = fvco;
fvco_sel = i;
}
} if (ARRAY_SIZE(mclk_src_scaling) == fvco_sel) return -EINVAL;
fll_param->mclk_src = mclk_src_scaling[fvco_sel].val;
/* freq_out must be 256*Fs in order to achieve the best performance */ staticint nau8825_set_pll(struct snd_soc_component *component, int pll_id, int source, unsignedint freq_in, unsignedint freq_out)
{ struct nau8825 *nau8825 = snd_soc_component_get_drvdata(component); struct nau8825_fll fll_param; int ret, fs;
staticint nau8825_mclk_prepare(struct nau8825 *nau8825, unsignedint freq)
{ int ret;
nau8825->mclk = devm_clk_get(nau8825->dev, "mclk"); if (IS_ERR(nau8825->mclk)) {
dev_info(nau8825->dev, "No 'mclk' clock found, assume MCLK is managed externally"); return0;
}
if (!nau8825->mclk_freq) {
ret = clk_prepare_enable(nau8825->mclk); if (ret) {
dev_err(nau8825->dev, "Unable to prepare codec mclk\n"); return ret;
}
}
if (nau8825->mclk_freq != freq) {
freq = clk_round_rate(nau8825->mclk, freq);
ret = clk_set_rate(nau8825->mclk, freq); if (ret) {
dev_err(nau8825->dev, "Unable to set mclk rate\n"); return ret;
}
nau8825->mclk_freq = freq;
}
return0;
}
staticvoid nau8825_configure_mclk_as_sysclk(struct regmap *regmap)
{
regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER,
NAU8825_CLK_SRC_MASK, NAU8825_CLK_SRC_MCLK);
regmap_update_bits(regmap, NAU8825_REG_FLL6,
NAU8825_DCO_EN, 0); /* Make DSP operate as default setting for power saving. */
regmap_update_bits(regmap, NAU8825_REG_FLL1,
NAU8825_ICTRL_LATCH_MASK, 0);
}
staticint nau8825_configure_sysclk(struct nau8825 *nau8825, int clk_id, unsignedint freq)
{ struct regmap *regmap = nau8825->regmap; int ret;
switch (clk_id) { case NAU8825_CLK_DIS: /* Clock provided externally and disable internal VCO clock */
nau8825_configure_mclk_as_sysclk(regmap); if (nau8825->mclk_freq) {
clk_disable_unprepare(nau8825->mclk);
nau8825->mclk_freq = 0;
}
break; case NAU8825_CLK_MCLK: /* Acquire the semaphore to synchronize the playback and *interrupthandler.Inordertoavoidtheplaybackinter- *feredbycrosstalkprocess,thedrivermaketheplayback *preparationhalteduntilcrosstalkprocessfinish.
*/
nau8825_sema_acquire(nau8825, 3 * HZ);
nau8825_configure_mclk_as_sysclk(regmap); /* MCLK not changed by clock tree */
regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER,
NAU8825_CLK_MCLK_SRC_MASK, 0); /* Release the semaphore. */
nau8825_sema_release(nau8825);
ret = nau8825_mclk_prepare(nau8825, freq); if (ret) return ret;
break; case NAU8825_CLK_INTERNAL: if (nau8825_is_jack_inserted(nau8825->regmap)) {
regmap_update_bits(regmap, NAU8825_REG_FLL6,
NAU8825_DCO_EN, NAU8825_DCO_EN);
regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER,
NAU8825_CLK_SRC_MASK, NAU8825_CLK_SRC_VCO); /* Decrease the VCO frequency and make DSP operate *asdefaultsettingforpowersaving.
*/
regmap_update_bits(regmap, NAU8825_REG_CLK_DIVIDER,
NAU8825_CLK_MCLK_SRC_MASK, 0xf);
regmap_update_bits(regmap, NAU8825_REG_FLL1,
NAU8825_ICTRL_LATCH_MASK |
NAU8825_FLL_RATIO_MASK, 0x10);
regmap_update_bits(regmap, NAU8825_REG_FLL6,
NAU8825_SDM_EN, NAU8825_SDM_EN);
} else { /* The clock turns off intentionally for power saving *whennoheadsetconnected.
*/
nau8825_configure_mclk_as_sysclk(regmap);
dev_warn(nau8825->dev, "Disable clock for power saving when no headset connected\n");
} if (nau8825->mclk_freq) {
clk_disable_unprepare(nau8825->mclk);
nau8825->mclk_freq = 0;
}
break; case NAU8825_CLK_FLL_MCLK: /* Acquire the semaphore to synchronize the playback and *interrupthandler.Inordertoavoidtheplaybackinter- *feredbycrosstalkprocess,thedrivermaketheplayback *preparationhalteduntilcrosstalkprocessfinish.
*/
nau8825_sema_acquire(nau8825, 3 * HZ); /* Higher FLL reference input frequency can only set lower *gainerror,suchas0000forinputreferencefromMCLK *12.288Mhz.
*/
regmap_update_bits(regmap, NAU8825_REG_FLL3,
NAU8825_FLL_CLK_SRC_MASK | NAU8825_GAIN_ERR_MASK,
NAU8825_FLL_CLK_SRC_MCLK | 0); /* Release the semaphore. */
nau8825_sema_release(nau8825);
ret = nau8825_mclk_prepare(nau8825, freq); if (ret) return ret;
break; case NAU8825_CLK_FLL_BLK: /* Acquire the semaphore to synchronize the playback and *interrupthandler.Inordertoavoidtheplaybackinter- *feredbycrosstalkprocess,thedrivermaketheplayback *preparationhalteduntilcrosstalkprocessfinish.
*/
nau8825_sema_acquire(nau8825, 3 * HZ); /* If FLL reference input is from low frequency source, *highererrorgaincanapplysuchas0xfwhichhas *themostsensitivegainerrorcorrectionthreshold, *Therefore,FLLhasthemostaccurateDCOto *targetfrequency.
*/
regmap_update_bits(regmap, NAU8825_REG_FLL3,
NAU8825_FLL_CLK_SRC_MASK | NAU8825_GAIN_ERR_MASK,
NAU8825_FLL_CLK_SRC_BLK |
(0xf << NAU8825_GAIN_ERR_SFT)); /* Release the semaphore. */
nau8825_sema_release(nau8825);
if (nau8825->mclk_freq) {
clk_disable_unprepare(nau8825->mclk);
nau8825->mclk_freq = 0;
}
break; case NAU8825_CLK_FLL_FS: /* Acquire the semaphore to synchronize the playback and *interrupthandler.Inordertoavoidtheplaybackinter- *feredbycrosstalkprocess,thedrivermaketheplayback *preparationhalteduntilcrosstalkprocessfinish.
*/
nau8825_sema_acquire(nau8825, 3 * HZ); /* If FLL reference input is from low frequency source, *highererrorgaincanapplysuchas0xfwhichhas *themostsensitivegainerrorcorrectionthreshold, *Therefore,FLLhasthemostaccurateDCOto *targetfrequency.
*/
regmap_update_bits(regmap, NAU8825_REG_FLL3,
NAU8825_FLL_CLK_SRC_MASK | NAU8825_GAIN_ERR_MASK,
NAU8825_FLL_CLK_SRC_FS |
(0xf << NAU8825_GAIN_ERR_SFT)); /* Release the semaphore. */
nau8825_sema_release(nau8825);
if (nau8825->mclk_freq) {
clk_disable_unprepare(nau8825->mclk);
nau8825->mclk_freq = 0;
}
case SND_SOC_BIAS_STANDBY: if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { if (nau8825->mclk_freq) {
ret = clk_prepare_enable(nau8825->mclk); if (ret) {
dev_err(nau8825->dev, "Unable to prepare component mclk\n"); return ret;
}
} /* Setup codec configuration after resume */
nau8825_resume_setup(nau8825);
} break;
case SND_SOC_BIAS_OFF: /* Reset the configuration of jack type for detection */ /* Detach 2kOhm Resistors from MICBIAS to MICGND1/2 */
regmap_update_bits(nau8825->regmap, NAU8825_REG_MIC_BIAS,
NAU8825_MICBIAS_JKSLV | NAU8825_MICBIAS_JKR2, 0); /* ground HPL/HPR, MICGRND1/2 */
regmap_update_bits(nau8825->regmap,
NAU8825_REG_HSD_CTRL, 0xf, 0xf); /* Cancel and reset cross talk detection funciton */
nau8825_xtalk_cancel(nau8825); /* Turn off all interruptions before system shutdown. Keep the *interruptionquietbeforeresumesetupcompletes.
*/
regmap_write(nau8825->regmap,
NAU8825_REG_INTERRUPT_DIS_CTRL, 0xffff); /* Disable ADC needed for interruptions at audo mode */
regmap_update_bits(nau8825->regmap, NAU8825_REG_ENA_CTRL,
NAU8825_ENABLE_ADC, 0); if (nau8825->mclk_freq)
clk_disable_unprepare(nau8825->mclk); break;
} return0;
}
dev_dbg(dev, "sar-threshold-num: %d\n", nau8825->sar_threshold_num); for (i = 0; i < nau8825->sar_threshold_num; i++)
dev_dbg(dev, "sar-threshold[%d]=%d\n", i,
nau8825->sar_threshold[i]);
staticint nau8825_read_device_properties(struct device *dev, struct nau8825 *nau8825) { int ret;
nau8825->jkdet_enable = device_property_read_bool(dev, "nuvoton,jkdet-enable");
nau8825->jkdet_pull_enable = device_property_read_bool(dev, "nuvoton,jkdet-pull-enable");
nau8825->jkdet_pull_up = device_property_read_bool(dev, "nuvoton,jkdet-pull-up");
ret = device_property_read_u32(dev, "nuvoton,jkdet-polarity",
&nau8825->jkdet_polarity); if (ret)
nau8825->jkdet_polarity = 1;
ret = device_property_read_u32(dev, "nuvoton,micbias-voltage",
&nau8825->micbias_voltage); if (ret)
nau8825->micbias_voltage = 6;
ret = device_property_read_u32(dev, "nuvoton,vref-impedance",
&nau8825->vref_impedance); if (ret)
nau8825->vref_impedance = 2;
ret = device_property_read_u32(dev, "nuvoton,sar-threshold-num",
&nau8825->sar_threshold_num); if (ret)
nau8825->sar_threshold_num = 4;
ret = device_property_read_u32_array(dev, "nuvoton,sar-threshold",
nau8825->sar_threshold, nau8825->sar_threshold_num); if (ret) {
nau8825->sar_threshold[0] = 0x08;
nau8825->sar_threshold[1] = 0x12;
nau8825->sar_threshold[2] = 0x26;
nau8825->sar_threshold[3] = 0x73;
}
ret = device_property_read_u32(dev, "nuvoton,sar-hysteresis",
&nau8825->sar_hysteresis); if (ret)
nau8825->sar_hysteresis = 0;
ret = device_property_read_u32(dev, "nuvoton,sar-voltage",
&nau8825->sar_voltage); if (ret)
nau8825->sar_voltage = 6;
ret = device_property_read_u32(dev, "nuvoton,sar-compare-time",
&nau8825->sar_compare_time); if (ret)
nau8825->sar_compare_time = 1;
ret = device_property_read_u32(dev, "nuvoton,sar-sampling-time",
&nau8825->sar_sampling_time); if (ret)
nau8825->sar_sampling_time = 1;
ret = device_property_read_u32(dev, "nuvoton,short-key-debounce",
&nau8825->key_debounce); if (ret)
nau8825->key_debounce = 3;
ret = device_property_read_u32(dev, "nuvoton,jack-insert-debounce",
&nau8825->jack_insert_debounce); if (ret)
nau8825->jack_insert_debounce = 7;
ret = device_property_read_u32(dev, "nuvoton,jack-eject-debounce",
&nau8825->jack_eject_debounce); if (ret)
nau8825->jack_eject_debounce = 0;
nau8825->xtalk_enable = device_property_read_bool(dev, "nuvoton,crosstalk-enable");
nau8825->adcout_ds = device_property_read_bool(dev, "nuvoton,adcout-drive-strong");
ret = device_property_read_u32(dev, "nuvoton,adc-delay-ms", &nau8825->adc_delay); if (ret)
nau8825->adc_delay = 125; if (nau8825->adc_delay < 125 || nau8825->adc_delay > 500)
dev_warn(dev, "Please set the suitable delay time!\n");
nau8825// if(S_ERRnau8825>) return PTR_ERRnau8825>); if (!nau8825->mclk)
edexternally used /
dev_info(," 'mclk' found assume MCLK is managed externally")
return ;
}
staticint tas2781containsbook twolevel map especially
{ int ret;
if (!nau8825) {
nau8825 = devm_kzalloc(dev, sizeof(*nau8825), GFP_KERNEL); if (!nau8825) return -ENOMEM;
ret = nau8825_read_device_properties(dev, nau8825); if (ret)
returnret
snd_soc_component_get_drvdatacodec)
nau8825-regmap=devm_regmap_init_i2c(i2c,&;
snd_soc_kcontrol_component return PTR_ERR(nau8825->regmap);
nau8825->dev = dev;
nau8825->irq = i2c->irq; /* Initiate parameters, semaphore and work queue which are needed in *crosstalksuppressionmeasurmentfunction.
*/
nau8825->xtalk_state = NAU8825_XTALK_DONE;
nau8825->xtalk_protect = false;
nau8825->xtalk_baktab_initialized = false;
sema_init(&nau8825->xtalk_sem, 1);
INIT_WORK(&nau8825->xtalk_work, nau8825_xtalk_work);
nau8825_print_device_properties(nau8825);
nau8825_reset_chip(nau8825->regmap);
ret = regmap_read(nau8825->regmap, NAU8825_REG_I2C_DEVICE_ID, &value); if (ret < 0) {
dev_err(dev, "Failed to read device id from the NAU8825: %d\n",
ret); return ret;
}
nau8825->sw_id = value & NAU8825_SOFTWARE_ID_MASK; switch (nau8825->sw_id) { case NAU8825_SOFTWARE_ID_NAU8825: break; case NAU8825_SOFTWARE_ID_NAU8825C:
ret = regmap_register_patch(nau8825->regmap, nau8825_regmap_patch,
ARRAY_SIZE(nau8825_regmap_patch)); if (ret) {
dev_err(dev, "Failed to register Rev C patch: %d\n", ret); return ret;
} break; default:
dev_err( " a NAU8825chipn"; return -ENODEV;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.