0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/clk.h>
0013 #include <linux/i2c.h>
0014 #include <linux/property.h>
0015 #include <linux/pm_wakeirq.h>
0016 #include <linux/slab.h>
0017 #include <linux/delay.h>
0018 #include <linux/workqueue.h>
0019 #include <sound/soc.h>
0020 #include <sound/jack.h>
0021 #include <sound/da7219.h>
0022
0023 #include "da7219.h"
0024 #include "da7219-aad.h"
0025
0026
0027
0028
0029
0030
0031 void da7219_aad_jack_det(struct snd_soc_component *component, struct snd_soc_jack *jack)
0032 {
0033 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
0034
0035 da7219->aad->jack = jack;
0036 da7219->aad->jack_inserted = false;
0037
0038
0039 snd_soc_jack_report(jack, 0, DA7219_AAD_REPORT_ALL_MASK);
0040
0041
0042 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
0043 DA7219_ACCDET_EN_MASK,
0044 (jack ? DA7219_ACCDET_EN_MASK : 0));
0045 }
0046 EXPORT_SYMBOL_GPL(da7219_aad_jack_det);
0047
0048
0049
0050
0051
0052 static void da7219_aad_btn_det_work(struct work_struct *work)
0053 {
0054 struct da7219_aad_priv *da7219_aad =
0055 container_of(work, struct da7219_aad_priv, btn_det_work);
0056 struct snd_soc_component *component = da7219_aad->component;
0057 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
0058 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
0059 u8 statusa, micbias_ctrl;
0060 bool micbias_up = false;
0061 int retries = 0;
0062
0063
0064 snd_soc_component_update_bits(component, 0xFB, 0x01, 0x00);
0065
0066
0067 snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
0068 DA7219_HP_L_AMP_OE_MASK,
0069 DA7219_HP_L_AMP_OE_MASK);
0070 snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
0071 DA7219_HP_R_AMP_OE_MASK,
0072 DA7219_HP_R_AMP_OE_MASK);
0073
0074
0075 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
0076 snd_soc_dapm_sync(dapm);
0077
0078 do {
0079 statusa = snd_soc_component_read(component, DA7219_ACCDET_STATUS_A);
0080 if (statusa & DA7219_MICBIAS_UP_STS_MASK)
0081 micbias_up = true;
0082 else if (retries++ < DA7219_AAD_MICBIAS_CHK_RETRIES)
0083 msleep(DA7219_AAD_MICBIAS_CHK_DELAY);
0084 } while ((!micbias_up) && (retries < DA7219_AAD_MICBIAS_CHK_RETRIES));
0085
0086 if (retries >= DA7219_AAD_MICBIAS_CHK_RETRIES)
0087 dev_warn(component->dev, "Mic bias status check timed out");
0088
0089 da7219->micbias_on_event = true;
0090
0091
0092
0093
0094
0095 if (da7219_aad->micbias_pulse_lvl && da7219_aad->micbias_pulse_time) {
0096
0097 micbias_ctrl = snd_soc_component_read(component, DA7219_MICBIAS_CTRL);
0098 snd_soc_component_update_bits(component, DA7219_MICBIAS_CTRL,
0099 DA7219_MICBIAS1_LEVEL_MASK,
0100 da7219_aad->micbias_pulse_lvl);
0101 msleep(da7219_aad->micbias_pulse_time);
0102 snd_soc_component_write(component, DA7219_MICBIAS_CTRL, micbias_ctrl);
0103
0104 }
0105
0106 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
0107 DA7219_BUTTON_CONFIG_MASK,
0108 da7219_aad->btn_cfg);
0109 }
0110
0111 static void da7219_aad_hptest_work(struct work_struct *work)
0112 {
0113 struct da7219_aad_priv *da7219_aad =
0114 container_of(work, struct da7219_aad_priv, hptest_work);
0115 struct snd_soc_component *component = da7219_aad->component;
0116 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
0117 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
0118
0119 __le16 tonegen_freq_hptest;
0120 u8 pll_srm_sts, pll_ctrl, gain_ramp_ctrl, accdet_cfg8;
0121 int report = 0, ret;
0122
0123
0124 snd_soc_dapm_mutex_lock(dapm);
0125 mutex_lock(&da7219->ctrl_lock);
0126 mutex_lock(&da7219->pll_lock);
0127
0128
0129 if (da7219->mclk) {
0130 ret = clk_prepare_enable(da7219->mclk);
0131 if (ret) {
0132 dev_err(component->dev, "Failed to enable mclk - %d\n", ret);
0133 mutex_unlock(&da7219->pll_lock);
0134 mutex_unlock(&da7219->ctrl_lock);
0135 snd_soc_dapm_mutex_unlock(dapm);
0136 return;
0137 }
0138 }
0139
0140
0141
0142
0143
0144
0145
0146
0147 pll_srm_sts = snd_soc_component_read(component, DA7219_PLL_SRM_STS);
0148 if (pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) {
0149 tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ);
0150
0151 pll_ctrl = snd_soc_component_read(component, DA7219_PLL_CTRL);
0152 if ((pll_ctrl & DA7219_PLL_MODE_MASK) == DA7219_PLL_MODE_BYPASS)
0153 da7219_set_pll(component, DA7219_SYSCLK_PLL,
0154 DA7219_PLL_FREQ_OUT_98304);
0155 } else {
0156 tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC);
0157 }
0158
0159
0160 snd_soc_component_update_bits(component, 0xFB, 0x01, 0x00);
0161
0162
0163 gain_ramp_ctrl = snd_soc_component_read(component, DA7219_GAIN_RAMP_CTRL);
0164 snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8);
0165
0166
0167 regcache_cache_bypass(da7219->regmap, true);
0168
0169
0170 snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, 0);
0171
0172
0173 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_8,
0174 DA7219_HPTEST_EN_MASK | DA7219_HPTEST_RES_SEL_MASK,
0175 DA7219_HPTEST_EN_MASK |
0176 DA7219_HPTEST_RES_SEL_1KOHMS);
0177
0178
0179 snd_soc_component_write(component, DA7219_DAC_L_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
0180 snd_soc_component_write(component, DA7219_DAC_R_GAIN, DA7219_DAC_DIGITAL_GAIN_0DB);
0181 snd_soc_component_write(component, DA7219_HP_L_GAIN, DA7219_HP_AMP_GAIN_0DB);
0182 snd_soc_component_write(component, DA7219_HP_R_GAIN, DA7219_HP_AMP_GAIN_0DB);
0183
0184
0185 snd_soc_component_update_bits(component, DA7219_DAC_FILTERS1, DA7219_HPF_MODE_MASK,
0186 0);
0187 snd_soc_component_update_bits(component, DA7219_DAC_FILTERS4, DA7219_DAC_EQ_EN_MASK,
0188 0);
0189 snd_soc_component_update_bits(component, DA7219_DAC_FILTERS5,
0190 DA7219_DAC_SOFTMUTE_EN_MASK, 0);
0191
0192
0193 snd_soc_component_update_bits(component, DA7219_CP_CTRL, DA7219_CP_EN_MASK,
0194 DA7219_CP_EN_MASK);
0195 snd_soc_component_update_bits(component, DA7219_DIG_ROUTING_DAC,
0196 DA7219_DAC_L_SRC_MASK | DA7219_DAC_R_SRC_MASK,
0197 DA7219_DAC_L_SRC_TONEGEN |
0198 DA7219_DAC_R_SRC_TONEGEN);
0199 snd_soc_component_update_bits(component, DA7219_DAC_L_CTRL,
0200 DA7219_DAC_L_EN_MASK | DA7219_DAC_L_MUTE_EN_MASK,
0201 DA7219_DAC_L_EN_MASK);
0202 snd_soc_component_update_bits(component, DA7219_DAC_R_CTRL,
0203 DA7219_DAC_R_EN_MASK | DA7219_DAC_R_MUTE_EN_MASK,
0204 DA7219_DAC_R_EN_MASK);
0205 snd_soc_component_update_bits(component, DA7219_MIXOUT_L_SELECT,
0206 DA7219_MIXOUT_L_MIX_SELECT_MASK,
0207 DA7219_MIXOUT_L_MIX_SELECT_MASK);
0208 snd_soc_component_update_bits(component, DA7219_MIXOUT_R_SELECT,
0209 DA7219_MIXOUT_R_MIX_SELECT_MASK,
0210 DA7219_MIXOUT_R_MIX_SELECT_MASK);
0211 snd_soc_component_update_bits(component, DA7219_DROUTING_ST_OUTFILT_1L,
0212 DA7219_OUTFILT_ST_1L_SRC_MASK,
0213 DA7219_DMIX_ST_SRC_OUTFILT1L);
0214 snd_soc_component_update_bits(component, DA7219_DROUTING_ST_OUTFILT_1R,
0215 DA7219_OUTFILT_ST_1R_SRC_MASK,
0216 DA7219_DMIX_ST_SRC_OUTFILT1R);
0217 snd_soc_component_update_bits(component, DA7219_MIXOUT_L_CTRL,
0218 DA7219_MIXOUT_L_AMP_EN_MASK,
0219 DA7219_MIXOUT_L_AMP_EN_MASK);
0220 snd_soc_component_update_bits(component, DA7219_MIXOUT_R_CTRL,
0221 DA7219_MIXOUT_R_AMP_EN_MASK,
0222 DA7219_MIXOUT_R_AMP_EN_MASK);
0223 snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
0224 DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK,
0225 DA7219_HP_L_AMP_OE_MASK | DA7219_HP_L_AMP_EN_MASK);
0226 snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
0227 DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK,
0228 DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK);
0229 msleep(DA7219_SETTLING_DELAY);
0230 snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
0231 DA7219_HP_L_AMP_MUTE_EN_MASK |
0232 DA7219_HP_L_AMP_MIN_GAIN_EN_MASK, 0);
0233 snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
0234 DA7219_HP_R_AMP_MUTE_EN_MASK |
0235 DA7219_HP_R_AMP_MIN_GAIN_EN_MASK, 0);
0236
0237
0238
0239
0240
0241 if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK))
0242 msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
0243
0244
0245 snd_soc_component_write(component, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK);
0246 regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
0247 &tonegen_freq_hptest, sizeof(tonegen_freq_hptest));
0248 snd_soc_component_update_bits(component, DA7219_TONE_GEN_CFG2,
0249 DA7219_SWG_SEL_MASK | DA7219_TONE_GEN_GAIN_MASK,
0250 DA7219_SWG_SEL_SRAMP |
0251 DA7219_TONE_GEN_GAIN_MINUS_15DB);
0252 snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, DA7219_START_STOPN_MASK);
0253
0254 msleep(DA7219_AAD_HPTEST_PERIOD);
0255
0256
0257 accdet_cfg8 = snd_soc_component_read(component, DA7219_ACCDET_CONFIG_8);
0258 if (accdet_cfg8 & DA7219_HPTEST_COMP_MASK)
0259 report |= SND_JACK_HEADPHONE;
0260 else
0261 report |= SND_JACK_LINEOUT;
0262
0263
0264 snd_soc_component_write(component, DA7219_TONE_GEN_CFG1, 0);
0265
0266 msleep(DA7219_AAD_HPTEST_PERIOD);
0267
0268
0269 regcache_mark_dirty(da7219->regmap);
0270 regcache_sync_region(da7219->regmap, DA7219_HP_L_CTRL,
0271 DA7219_HP_R_CTRL);
0272 msleep(DA7219_SETTLING_DELAY);
0273 regcache_sync_region(da7219->regmap, DA7219_MIXOUT_L_CTRL,
0274 DA7219_MIXOUT_R_CTRL);
0275 regcache_sync_region(da7219->regmap, DA7219_DROUTING_ST_OUTFILT_1L,
0276 DA7219_DROUTING_ST_OUTFILT_1R);
0277 regcache_sync_region(da7219->regmap, DA7219_MIXOUT_L_SELECT,
0278 DA7219_MIXOUT_R_SELECT);
0279 regcache_sync_region(da7219->regmap, DA7219_DAC_L_CTRL,
0280 DA7219_DAC_R_CTRL);
0281 regcache_sync_region(da7219->regmap, DA7219_DIG_ROUTING_DAC,
0282 DA7219_DIG_ROUTING_DAC);
0283 regcache_sync_region(da7219->regmap, DA7219_CP_CTRL, DA7219_CP_CTRL);
0284 regcache_sync_region(da7219->regmap, DA7219_DAC_FILTERS5,
0285 DA7219_DAC_FILTERS5);
0286 regcache_sync_region(da7219->regmap, DA7219_DAC_FILTERS4,
0287 DA7219_DAC_FILTERS1);
0288 regcache_sync_region(da7219->regmap, DA7219_HP_L_GAIN,
0289 DA7219_HP_R_GAIN);
0290 regcache_sync_region(da7219->regmap, DA7219_DAC_L_GAIN,
0291 DA7219_DAC_R_GAIN);
0292 regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_ON_PER,
0293 DA7219_TONE_GEN_ON_PER);
0294 regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
0295 DA7219_TONE_GEN_FREQ1_U);
0296 regcache_sync_region(da7219->regmap, DA7219_TONE_GEN_CFG1,
0297 DA7219_TONE_GEN_CFG2);
0298
0299 regcache_cache_bypass(da7219->regmap, false);
0300
0301
0302 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_8,
0303 DA7219_HPTEST_EN_MASK, 0);
0304
0305
0306
0307
0308
0309 if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK))
0310 msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
0311
0312
0313 snd_soc_component_write(component, DA7219_GAIN_RAMP_CTRL, gain_ramp_ctrl);
0314
0315
0316 snd_soc_component_update_bits(component, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK,
0317 DA7219_HP_L_AMP_OE_MASK);
0318 snd_soc_component_update_bits(component, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK,
0319 DA7219_HP_R_AMP_OE_MASK);
0320
0321
0322 if ((pll_srm_sts & DA7219_PLL_SRM_STS_MCLK) &&
0323 ((pll_ctrl & DA7219_PLL_MODE_MASK) == DA7219_PLL_MODE_BYPASS))
0324 da7219_set_pll(component, DA7219_SYSCLK_MCLK, 0);
0325
0326
0327 if (da7219->mclk)
0328 clk_disable_unprepare(da7219->mclk);
0329
0330 mutex_unlock(&da7219->pll_lock);
0331 mutex_unlock(&da7219->ctrl_lock);
0332 snd_soc_dapm_mutex_unlock(dapm);
0333
0334
0335
0336
0337
0338 if (da7219_aad->jack_inserted)
0339 snd_soc_jack_report(da7219_aad->jack, report,
0340 SND_JACK_HEADSET | SND_JACK_LINEOUT);
0341 }
0342
0343
0344
0345
0346
0347
0348 static irqreturn_t da7219_aad_irq_thread(int irq, void *data)
0349 {
0350 struct da7219_aad_priv *da7219_aad = data;
0351 struct snd_soc_component *component = da7219_aad->component;
0352 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
0353 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
0354 u8 events[DA7219_AAD_IRQ_REG_MAX];
0355 u8 statusa;
0356 int i, report = 0, mask = 0;
0357
0358
0359 regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
0360 events, DA7219_AAD_IRQ_REG_MAX);
0361
0362 if (!events[DA7219_AAD_IRQ_REG_A] && !events[DA7219_AAD_IRQ_REG_B])
0363 return IRQ_NONE;
0364
0365
0366 statusa = snd_soc_component_read(component, DA7219_ACCDET_STATUS_A);
0367
0368
0369 regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A,
0370 events, DA7219_AAD_IRQ_REG_MAX);
0371
0372 dev_dbg(component->dev, "IRQ events = 0x%x|0x%x, status = 0x%x\n",
0373 events[DA7219_AAD_IRQ_REG_A], events[DA7219_AAD_IRQ_REG_B],
0374 statusa);
0375
0376 if (statusa & DA7219_JACK_INSERTION_STS_MASK) {
0377
0378 if (events[DA7219_AAD_IRQ_REG_A] &
0379 DA7219_E_JACK_INSERTED_MASK) {
0380 report |= SND_JACK_MECHANICAL;
0381 mask |= SND_JACK_MECHANICAL;
0382 da7219_aad->jack_inserted = true;
0383 }
0384
0385
0386 if (events[DA7219_AAD_IRQ_REG_A] &
0387 DA7219_E_JACK_DETECT_COMPLETE_MASK) {
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400 if (statusa & DA7219_JACK_TYPE_STS_MASK) {
0401 report |= SND_JACK_HEADSET;
0402 mask |= SND_JACK_HEADSET | SND_JACK_LINEOUT;
0403 schedule_work(&da7219_aad->btn_det_work);
0404 } else {
0405 schedule_work(&da7219_aad->hptest_work);
0406 }
0407 }
0408
0409
0410 if (statusa & DA7219_JACK_TYPE_STS_MASK) {
0411 for (i = 0; i < DA7219_AAD_MAX_BUTTONS; ++i) {
0412
0413 if (events[DA7219_AAD_IRQ_REG_B] &
0414 (DA7219_E_BUTTON_A_PRESSED_MASK << i)) {
0415 report |= SND_JACK_BTN_0 >> i;
0416 mask |= SND_JACK_BTN_0 >> i;
0417 }
0418 }
0419 snd_soc_jack_report(da7219_aad->jack, report, mask);
0420
0421 for (i = 0; i < DA7219_AAD_MAX_BUTTONS; ++i) {
0422
0423 if (events[DA7219_AAD_IRQ_REG_B] &
0424 (DA7219_E_BUTTON_A_RELEASED_MASK >> i)) {
0425 report &= ~(SND_JACK_BTN_0 >> i);
0426 mask |= SND_JACK_BTN_0 >> i;
0427 }
0428 }
0429 }
0430 } else {
0431
0432 if (events[DA7219_AAD_IRQ_REG_A] & DA7219_E_JACK_REMOVED_MASK) {
0433 report = 0;
0434 mask |= DA7219_AAD_REPORT_ALL_MASK;
0435 da7219_aad->jack_inserted = false;
0436
0437
0438 cancel_work_sync(&da7219_aad->btn_det_work);
0439 cancel_work_sync(&da7219_aad->hptest_work);
0440
0441
0442 snd_soc_component_update_bits(component, DA7219_HP_R_CTRL,
0443 DA7219_HP_R_AMP_OE_MASK, 0);
0444 snd_soc_component_update_bits(component, DA7219_HP_L_CTRL,
0445 DA7219_HP_L_AMP_OE_MASK, 0);
0446
0447
0448 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
0449 DA7219_BUTTON_CONFIG_MASK, 0);
0450
0451 da7219->micbias_on_event = false;
0452
0453
0454 snd_soc_dapm_disable_pin(dapm, "Mic Bias");
0455 snd_soc_dapm_sync(dapm);
0456
0457
0458 snd_soc_component_update_bits(component, 0xFB, 0x01, 0x01);
0459 }
0460 }
0461
0462 snd_soc_jack_report(da7219_aad->jack, report, mask);
0463
0464 return IRQ_HANDLED;
0465 }
0466
0467
0468
0469
0470
0471 static enum da7219_aad_micbias_pulse_lvl
0472 da7219_aad_fw_micbias_pulse_lvl(struct device *dev, u32 val)
0473 {
0474 switch (val) {
0475 case 2800:
0476 return DA7219_AAD_MICBIAS_PULSE_LVL_2_8V;
0477 case 2900:
0478 return DA7219_AAD_MICBIAS_PULSE_LVL_2_9V;
0479 default:
0480 dev_warn(dev, "Invalid micbias pulse level");
0481 return DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
0482 }
0483 }
0484
0485 static enum da7219_aad_btn_cfg
0486 da7219_aad_fw_btn_cfg(struct device *dev, u32 val)
0487 {
0488 switch (val) {
0489 case 2:
0490 return DA7219_AAD_BTN_CFG_2MS;
0491 case 5:
0492 return DA7219_AAD_BTN_CFG_5MS;
0493 case 10:
0494 return DA7219_AAD_BTN_CFG_10MS;
0495 case 50:
0496 return DA7219_AAD_BTN_CFG_50MS;
0497 case 100:
0498 return DA7219_AAD_BTN_CFG_100MS;
0499 case 200:
0500 return DA7219_AAD_BTN_CFG_200MS;
0501 case 500:
0502 return DA7219_AAD_BTN_CFG_500MS;
0503 default:
0504 dev_warn(dev, "Invalid button config");
0505 return DA7219_AAD_BTN_CFG_10MS;
0506 }
0507 }
0508
0509 static enum da7219_aad_mic_det_thr
0510 da7219_aad_fw_mic_det_thr(struct device *dev, u32 val)
0511 {
0512 switch (val) {
0513 case 200:
0514 return DA7219_AAD_MIC_DET_THR_200_OHMS;
0515 case 500:
0516 return DA7219_AAD_MIC_DET_THR_500_OHMS;
0517 case 750:
0518 return DA7219_AAD_MIC_DET_THR_750_OHMS;
0519 case 1000:
0520 return DA7219_AAD_MIC_DET_THR_1000_OHMS;
0521 default:
0522 dev_warn(dev, "Invalid mic detect threshold");
0523 return DA7219_AAD_MIC_DET_THR_500_OHMS;
0524 }
0525 }
0526
0527 static enum da7219_aad_jack_ins_deb
0528 da7219_aad_fw_jack_ins_deb(struct device *dev, u32 val)
0529 {
0530 switch (val) {
0531 case 5:
0532 return DA7219_AAD_JACK_INS_DEB_5MS;
0533 case 10:
0534 return DA7219_AAD_JACK_INS_DEB_10MS;
0535 case 20:
0536 return DA7219_AAD_JACK_INS_DEB_20MS;
0537 case 50:
0538 return DA7219_AAD_JACK_INS_DEB_50MS;
0539 case 100:
0540 return DA7219_AAD_JACK_INS_DEB_100MS;
0541 case 200:
0542 return DA7219_AAD_JACK_INS_DEB_200MS;
0543 case 500:
0544 return DA7219_AAD_JACK_INS_DEB_500MS;
0545 case 1000:
0546 return DA7219_AAD_JACK_INS_DEB_1S;
0547 default:
0548 dev_warn(dev, "Invalid jack insert debounce");
0549 return DA7219_AAD_JACK_INS_DEB_20MS;
0550 }
0551 }
0552
0553 static enum da7219_aad_jack_det_rate
0554 da7219_aad_fw_jack_det_rate(struct device *dev, const char *str)
0555 {
0556 if (!strcmp(str, "32ms_64ms")) {
0557 return DA7219_AAD_JACK_DET_RATE_32_64MS;
0558 } else if (!strcmp(str, "64ms_128ms")) {
0559 return DA7219_AAD_JACK_DET_RATE_64_128MS;
0560 } else if (!strcmp(str, "128ms_256ms")) {
0561 return DA7219_AAD_JACK_DET_RATE_128_256MS;
0562 } else if (!strcmp(str, "256ms_512ms")) {
0563 return DA7219_AAD_JACK_DET_RATE_256_512MS;
0564 } else {
0565 dev_warn(dev, "Invalid jack detect rate");
0566 return DA7219_AAD_JACK_DET_RATE_256_512MS;
0567 }
0568 }
0569
0570 static enum da7219_aad_jack_rem_deb
0571 da7219_aad_fw_jack_rem_deb(struct device *dev, u32 val)
0572 {
0573 switch (val) {
0574 case 1:
0575 return DA7219_AAD_JACK_REM_DEB_1MS;
0576 case 5:
0577 return DA7219_AAD_JACK_REM_DEB_5MS;
0578 case 10:
0579 return DA7219_AAD_JACK_REM_DEB_10MS;
0580 case 20:
0581 return DA7219_AAD_JACK_REM_DEB_20MS;
0582 default:
0583 dev_warn(dev, "Invalid jack removal debounce");
0584 return DA7219_AAD_JACK_REM_DEB_1MS;
0585 }
0586 }
0587
0588 static enum da7219_aad_btn_avg
0589 da7219_aad_fw_btn_avg(struct device *dev, u32 val)
0590 {
0591 switch (val) {
0592 case 1:
0593 return DA7219_AAD_BTN_AVG_1;
0594 case 2:
0595 return DA7219_AAD_BTN_AVG_2;
0596 case 4:
0597 return DA7219_AAD_BTN_AVG_4;
0598 case 8:
0599 return DA7219_AAD_BTN_AVG_8;
0600 default:
0601 dev_warn(dev, "Invalid button average value");
0602 return DA7219_AAD_BTN_AVG_2;
0603 }
0604 }
0605
0606 static enum da7219_aad_adc_1bit_rpt
0607 da7219_aad_fw_adc_1bit_rpt(struct device *dev, u32 val)
0608 {
0609 switch (val) {
0610 case 1:
0611 return DA7219_AAD_ADC_1BIT_RPT_1;
0612 case 2:
0613 return DA7219_AAD_ADC_1BIT_RPT_2;
0614 case 4:
0615 return DA7219_AAD_ADC_1BIT_RPT_4;
0616 case 8:
0617 return DA7219_AAD_ADC_1BIT_RPT_8;
0618 default:
0619 dev_warn(dev, "Invalid ADC 1-bit repeat value");
0620 return DA7219_AAD_ADC_1BIT_RPT_1;
0621 }
0622 }
0623
0624 static struct da7219_aad_pdata *da7219_aad_fw_to_pdata(struct device *dev)
0625 {
0626 struct i2c_client *i2c = to_i2c_client(dev);
0627 struct fwnode_handle *aad_np;
0628 struct da7219_aad_pdata *aad_pdata;
0629 const char *fw_str;
0630 u32 fw_val32;
0631
0632 aad_np = device_get_named_child_node(dev, "da7219_aad");
0633 if (!aad_np)
0634 return NULL;
0635
0636 aad_pdata = devm_kzalloc(dev, sizeof(*aad_pdata), GFP_KERNEL);
0637 if (!aad_pdata)
0638 return NULL;
0639
0640 aad_pdata->irq = i2c->irq;
0641
0642 if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-lvl",
0643 &fw_val32) >= 0)
0644 aad_pdata->micbias_pulse_lvl =
0645 da7219_aad_fw_micbias_pulse_lvl(dev, fw_val32);
0646 else
0647 aad_pdata->micbias_pulse_lvl = DA7219_AAD_MICBIAS_PULSE_LVL_OFF;
0648
0649 if (fwnode_property_read_u32(aad_np, "dlg,micbias-pulse-time",
0650 &fw_val32) >= 0)
0651 aad_pdata->micbias_pulse_time = fw_val32;
0652
0653 if (fwnode_property_read_u32(aad_np, "dlg,btn-cfg", &fw_val32) >= 0)
0654 aad_pdata->btn_cfg = da7219_aad_fw_btn_cfg(dev, fw_val32);
0655 else
0656 aad_pdata->btn_cfg = DA7219_AAD_BTN_CFG_10MS;
0657
0658 if (fwnode_property_read_u32(aad_np, "dlg,mic-det-thr", &fw_val32) >= 0)
0659 aad_pdata->mic_det_thr =
0660 da7219_aad_fw_mic_det_thr(dev, fw_val32);
0661 else
0662 aad_pdata->mic_det_thr = DA7219_AAD_MIC_DET_THR_500_OHMS;
0663
0664 if (fwnode_property_read_u32(aad_np, "dlg,jack-ins-deb", &fw_val32) >= 0)
0665 aad_pdata->jack_ins_deb =
0666 da7219_aad_fw_jack_ins_deb(dev, fw_val32);
0667 else
0668 aad_pdata->jack_ins_deb = DA7219_AAD_JACK_INS_DEB_20MS;
0669
0670 if (!fwnode_property_read_string(aad_np, "dlg,jack-det-rate", &fw_str))
0671 aad_pdata->jack_det_rate =
0672 da7219_aad_fw_jack_det_rate(dev, fw_str);
0673 else
0674 aad_pdata->jack_det_rate = DA7219_AAD_JACK_DET_RATE_256_512MS;
0675
0676 if (fwnode_property_read_u32(aad_np, "dlg,jack-rem-deb", &fw_val32) >= 0)
0677 aad_pdata->jack_rem_deb =
0678 da7219_aad_fw_jack_rem_deb(dev, fw_val32);
0679 else
0680 aad_pdata->jack_rem_deb = DA7219_AAD_JACK_REM_DEB_1MS;
0681
0682 if (fwnode_property_read_u32(aad_np, "dlg,a-d-btn-thr", &fw_val32) >= 0)
0683 aad_pdata->a_d_btn_thr = (u8) fw_val32;
0684 else
0685 aad_pdata->a_d_btn_thr = 0xA;
0686
0687 if (fwnode_property_read_u32(aad_np, "dlg,d-b-btn-thr", &fw_val32) >= 0)
0688 aad_pdata->d_b_btn_thr = (u8) fw_val32;
0689 else
0690 aad_pdata->d_b_btn_thr = 0x16;
0691
0692 if (fwnode_property_read_u32(aad_np, "dlg,b-c-btn-thr", &fw_val32) >= 0)
0693 aad_pdata->b_c_btn_thr = (u8) fw_val32;
0694 else
0695 aad_pdata->b_c_btn_thr = 0x21;
0696
0697 if (fwnode_property_read_u32(aad_np, "dlg,c-mic-btn-thr", &fw_val32) >= 0)
0698 aad_pdata->c_mic_btn_thr = (u8) fw_val32;
0699 else
0700 aad_pdata->c_mic_btn_thr = 0x3E;
0701
0702 if (fwnode_property_read_u32(aad_np, "dlg,btn-avg", &fw_val32) >= 0)
0703 aad_pdata->btn_avg = da7219_aad_fw_btn_avg(dev, fw_val32);
0704 else
0705 aad_pdata->btn_avg = DA7219_AAD_BTN_AVG_2;
0706
0707 if (fwnode_property_read_u32(aad_np, "dlg,adc-1bit-rpt", &fw_val32) >= 0)
0708 aad_pdata->adc_1bit_rpt =
0709 da7219_aad_fw_adc_1bit_rpt(dev, fw_val32);
0710 else
0711 aad_pdata->adc_1bit_rpt = DA7219_AAD_ADC_1BIT_RPT_1;
0712
0713 return aad_pdata;
0714 }
0715
0716 static void da7219_aad_handle_pdata(struct snd_soc_component *component)
0717 {
0718 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
0719 struct da7219_aad_priv *da7219_aad = da7219->aad;
0720 struct da7219_pdata *pdata = da7219->pdata;
0721
0722 if ((pdata) && (pdata->aad_pdata)) {
0723 struct da7219_aad_pdata *aad_pdata = pdata->aad_pdata;
0724 u8 cfg, mask;
0725
0726 da7219_aad->irq = aad_pdata->irq;
0727
0728 switch (aad_pdata->micbias_pulse_lvl) {
0729 case DA7219_AAD_MICBIAS_PULSE_LVL_2_8V:
0730 case DA7219_AAD_MICBIAS_PULSE_LVL_2_9V:
0731 da7219_aad->micbias_pulse_lvl =
0732 (aad_pdata->micbias_pulse_lvl <<
0733 DA7219_MICBIAS1_LEVEL_SHIFT);
0734 break;
0735 default:
0736 break;
0737 }
0738
0739 da7219_aad->micbias_pulse_time = aad_pdata->micbias_pulse_time;
0740
0741 switch (aad_pdata->btn_cfg) {
0742 case DA7219_AAD_BTN_CFG_2MS:
0743 case DA7219_AAD_BTN_CFG_5MS:
0744 case DA7219_AAD_BTN_CFG_10MS:
0745 case DA7219_AAD_BTN_CFG_50MS:
0746 case DA7219_AAD_BTN_CFG_100MS:
0747 case DA7219_AAD_BTN_CFG_200MS:
0748 case DA7219_AAD_BTN_CFG_500MS:
0749 da7219_aad->btn_cfg = (aad_pdata->btn_cfg <<
0750 DA7219_BUTTON_CONFIG_SHIFT);
0751 }
0752
0753 cfg = 0;
0754 mask = 0;
0755 switch (aad_pdata->mic_det_thr) {
0756 case DA7219_AAD_MIC_DET_THR_200_OHMS:
0757 case DA7219_AAD_MIC_DET_THR_500_OHMS:
0758 case DA7219_AAD_MIC_DET_THR_750_OHMS:
0759 case DA7219_AAD_MIC_DET_THR_1000_OHMS:
0760 cfg |= (aad_pdata->mic_det_thr <<
0761 DA7219_MIC_DET_THRESH_SHIFT);
0762 mask |= DA7219_MIC_DET_THRESH_MASK;
0763 }
0764 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1, mask, cfg);
0765
0766 cfg = 0;
0767 mask = 0;
0768 switch (aad_pdata->jack_ins_deb) {
0769 case DA7219_AAD_JACK_INS_DEB_5MS:
0770 case DA7219_AAD_JACK_INS_DEB_10MS:
0771 case DA7219_AAD_JACK_INS_DEB_20MS:
0772 case DA7219_AAD_JACK_INS_DEB_50MS:
0773 case DA7219_AAD_JACK_INS_DEB_100MS:
0774 case DA7219_AAD_JACK_INS_DEB_200MS:
0775 case DA7219_AAD_JACK_INS_DEB_500MS:
0776 case DA7219_AAD_JACK_INS_DEB_1S:
0777 cfg |= (aad_pdata->jack_ins_deb <<
0778 DA7219_JACKDET_DEBOUNCE_SHIFT);
0779 mask |= DA7219_JACKDET_DEBOUNCE_MASK;
0780 }
0781 switch (aad_pdata->jack_det_rate) {
0782 case DA7219_AAD_JACK_DET_RATE_32_64MS:
0783 case DA7219_AAD_JACK_DET_RATE_64_128MS:
0784 case DA7219_AAD_JACK_DET_RATE_128_256MS:
0785 case DA7219_AAD_JACK_DET_RATE_256_512MS:
0786 cfg |= (aad_pdata->jack_det_rate <<
0787 DA7219_JACK_DETECT_RATE_SHIFT);
0788 mask |= DA7219_JACK_DETECT_RATE_MASK;
0789 }
0790 switch (aad_pdata->jack_rem_deb) {
0791 case DA7219_AAD_JACK_REM_DEB_1MS:
0792 case DA7219_AAD_JACK_REM_DEB_5MS:
0793 case DA7219_AAD_JACK_REM_DEB_10MS:
0794 case DA7219_AAD_JACK_REM_DEB_20MS:
0795 cfg |= (aad_pdata->jack_rem_deb <<
0796 DA7219_JACKDET_REM_DEB_SHIFT);
0797 mask |= DA7219_JACKDET_REM_DEB_MASK;
0798 }
0799 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_2, mask, cfg);
0800
0801 snd_soc_component_write(component, DA7219_ACCDET_CONFIG_3,
0802 aad_pdata->a_d_btn_thr);
0803 snd_soc_component_write(component, DA7219_ACCDET_CONFIG_4,
0804 aad_pdata->d_b_btn_thr);
0805 snd_soc_component_write(component, DA7219_ACCDET_CONFIG_5,
0806 aad_pdata->b_c_btn_thr);
0807 snd_soc_component_write(component, DA7219_ACCDET_CONFIG_6,
0808 aad_pdata->c_mic_btn_thr);
0809
0810 cfg = 0;
0811 mask = 0;
0812 switch (aad_pdata->btn_avg) {
0813 case DA7219_AAD_BTN_AVG_1:
0814 case DA7219_AAD_BTN_AVG_2:
0815 case DA7219_AAD_BTN_AVG_4:
0816 case DA7219_AAD_BTN_AVG_8:
0817 cfg |= (aad_pdata->btn_avg <<
0818 DA7219_BUTTON_AVERAGE_SHIFT);
0819 mask |= DA7219_BUTTON_AVERAGE_MASK;
0820 }
0821 switch (aad_pdata->adc_1bit_rpt) {
0822 case DA7219_AAD_ADC_1BIT_RPT_1:
0823 case DA7219_AAD_ADC_1BIT_RPT_2:
0824 case DA7219_AAD_ADC_1BIT_RPT_4:
0825 case DA7219_AAD_ADC_1BIT_RPT_8:
0826 cfg |= (aad_pdata->adc_1bit_rpt <<
0827 DA7219_ADC_1_BIT_REPEAT_SHIFT);
0828 mask |= DA7219_ADC_1_BIT_REPEAT_MASK;
0829 }
0830 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_7, mask, cfg);
0831 }
0832 }
0833
0834
0835
0836
0837
0838
0839 void da7219_aad_suspend(struct snd_soc_component *component)
0840 {
0841 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
0842 struct da7219_aad_priv *da7219_aad = da7219->aad;
0843 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
0844 u8 micbias_ctrl;
0845
0846 if (da7219_aad->jack) {
0847
0848 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
0849 DA7219_ACCDET_EN_MASK, 0);
0850
0851
0852
0853
0854
0855
0856
0857 if (da7219_aad->jack_inserted) {
0858 micbias_ctrl = snd_soc_component_read(component, DA7219_MICBIAS_CTRL);
0859 if (micbias_ctrl & DA7219_MICBIAS1_EN_MASK) {
0860 snd_soc_dapm_disable_pin(dapm, "Mic Bias");
0861 snd_soc_dapm_sync(dapm);
0862 da7219_aad->micbias_resume_enable = true;
0863 }
0864 }
0865 }
0866 }
0867
0868 void da7219_aad_resume(struct snd_soc_component *component)
0869 {
0870 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
0871 struct da7219_aad_priv *da7219_aad = da7219->aad;
0872 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
0873
0874 if (da7219_aad->jack) {
0875
0876 if (da7219_aad->jack_inserted &&
0877 da7219_aad->micbias_resume_enable) {
0878 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
0879 snd_soc_dapm_sync(dapm);
0880 da7219_aad->micbias_resume_enable = false;
0881 }
0882
0883
0884 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
0885 DA7219_ACCDET_EN_MASK,
0886 DA7219_ACCDET_EN_MASK);
0887 }
0888 }
0889
0890
0891
0892
0893
0894
0895 int da7219_aad_init(struct snd_soc_component *component)
0896 {
0897 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
0898 struct da7219_aad_priv *da7219_aad = da7219->aad;
0899 u8 mask[DA7219_AAD_IRQ_REG_MAX];
0900 int ret;
0901
0902 da7219_aad->component = component;
0903
0904
0905 da7219_aad_handle_pdata(component);
0906
0907
0908 snd_soc_component_update_bits(component, DA7219_ACCDET_CONFIG_1,
0909 DA7219_BUTTON_CONFIG_MASK, 0);
0910
0911
0912 snd_soc_component_update_bits(component, 0xFB, 0x01, 0x01);
0913
0914 INIT_WORK(&da7219_aad->btn_det_work, da7219_aad_btn_det_work);
0915 INIT_WORK(&da7219_aad->hptest_work, da7219_aad_hptest_work);
0916
0917 ret = request_threaded_irq(da7219_aad->irq, NULL,
0918 da7219_aad_irq_thread,
0919 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
0920 "da7219-aad", da7219_aad);
0921 if (ret) {
0922 dev_err(component->dev, "Failed to request IRQ: %d\n", ret);
0923 return ret;
0924 }
0925
0926
0927 memset(mask, 0, DA7219_AAD_IRQ_REG_MAX);
0928 regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_MASK_A,
0929 &mask, DA7219_AAD_IRQ_REG_MAX);
0930
0931 return 0;
0932 }
0933 EXPORT_SYMBOL_GPL(da7219_aad_init);
0934
0935 void da7219_aad_exit(struct snd_soc_component *component)
0936 {
0937 struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component);
0938 struct da7219_aad_priv *da7219_aad = da7219->aad;
0939 u8 mask[DA7219_AAD_IRQ_REG_MAX];
0940
0941
0942 memset(mask, DA7219_BYTE_MASK, DA7219_AAD_IRQ_REG_MAX);
0943 regmap_bulk_write(da7219->regmap, DA7219_ACCDET_IRQ_MASK_A,
0944 mask, DA7219_AAD_IRQ_REG_MAX);
0945
0946 free_irq(da7219_aad->irq, da7219_aad);
0947
0948 cancel_work_sync(&da7219_aad->btn_det_work);
0949 cancel_work_sync(&da7219_aad->hptest_work);
0950 }
0951 EXPORT_SYMBOL_GPL(da7219_aad_exit);
0952
0953
0954
0955
0956
0957 int da7219_aad_probe(struct i2c_client *i2c)
0958 {
0959 struct da7219_priv *da7219 = i2c_get_clientdata(i2c);
0960 struct device *dev = &i2c->dev;
0961 struct da7219_aad_priv *da7219_aad;
0962
0963 da7219_aad = devm_kzalloc(dev, sizeof(*da7219_aad), GFP_KERNEL);
0964 if (!da7219_aad)
0965 return -ENOMEM;
0966
0967 da7219->aad = da7219_aad;
0968
0969
0970 if (da7219->pdata && !da7219->pdata->aad_pdata)
0971 da7219->pdata->aad_pdata = da7219_aad_fw_to_pdata(dev);
0972
0973 return 0;
0974 }
0975 EXPORT_SYMBOL_GPL(da7219_aad_probe);
0976
0977 MODULE_DESCRIPTION("ASoC DA7219 AAD Driver");
0978 MODULE_AUTHOR("Adam Thomson <Adam.Thomson.Opensource@diasemi.com>");
0979 MODULE_LICENSE("GPL");