Lines Matching +full:comparator +full:- +full:invert
1 // SPDX-License-Identifier: GPL-2.0-only
3 * cs42l42.c -- CS42L42 ALSA SoC audio driver
29 #include <sound/soc-dapm.h>
32 #include <dt-bindings/sound/cs42l42.h>
400 static DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 100, true);
401 static DECLARE_TLV_DB_SCALE(mixer_tlv, -6300, 100, true);
410 switch (ucontrol->value.integer.value[0]) {
418 return -EINVAL;
448 SOC_SINGLE("ADC Invert Switch", CS42L42_ADC_CTL,
452 SOC_SINGLE_S8_TLV("ADC Volume", CS42L42_ADC_VOLUME, -97, 12, adc_tlv),
461 SOC_SINGLE("DACA Invert Switch", CS42L42_DAC_CTL1,
463 SOC_SINGLE("DACB Invert Switch", CS42L42_DAC_CTL1,
479 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
484 cs42l42->hp_adc_up_pending = true;
487 /* Only need one delay if HP and ADC are both powering-up */
488 if (cs42l42->hp_adc_up_pending) {
491 cs42l42->hp_adc_up_pending = false;
568 mutex_lock(&cs42l42->irq_lock);
569 cs42l42->jack = jk;
572 switch (cs42l42->hs_type) {
584 mutex_unlock(&cs42l42->irq_lock);
634 * Table 4-5 from the Datasheet
671 if (cs42l42->stream_use) {
672 if (pll_ratio_table[cs42l42->pll_config].sclk == clk)
675 return -EBUSY;
684 cs42l42->pll_config = i;
700 /* Configure PLL per table 4-5 */
749 return -EINVAL;
759 if (cs42l42->stream_use)
794 dev_err(component->dev,
798 return -EINVAL;
804 CS42L42_FRAC0_VAL(fsync - 1) <<
809 CS42L42_FRAC1_VAL(fsync - 1) <<
816 CS42L42_FRAC0_VAL(fsync - 1) <<
821 CS42L42_FRAC1_VAL(fsync - 1) <<
829 struct snd_soc_component *component = codec_dai->component;
842 return -EINVAL;
862 return -EINVAL;
891 struct snd_soc_component *component = dai->component;
895 * Sample rates < 44.1 kHz would produce an out-of-range SCLK with
899 if (cs42l42->sclk)
903 return snd_pcm_hw_constraint_minmax(substream->runtime,
912 struct snd_soc_component *component = dai->component;
915 unsigned int width = (params_width(params) / 8) - 1;
922 if (cs42l42->bclk_ratio) {
923 /* machine driver has set the BCLK/samp-rate ratio */
924 bclk = cs42l42->bclk_ratio * params_rate(params);
925 } else if (cs42l42->sclk) {
927 bclk = cs42l42->sclk;
930 * Assume 24-bit samples are in 32-bit slots, to prevent SCLK being
940 switch (substream->stream) {
966 (channels - 1) << CS42L42_SP_RX_CHB_SEL_SHIFT);
994 struct snd_soc_component *component = dai->component;
999 cs42l42->sclk = 0;
1005 cs42l42->sclk = freq;
1010 dev_err(component->dev, "SCLK %u not supported\n", freq);
1012 return -EINVAL;
1018 struct snd_soc_component *component = dai->component;
1021 cs42l42->bclk_ratio = bclk_ratio;
1028 struct snd_soc_component *component = dai->component;
1042 cs42l42->stream_use &= ~(1 << stream);
1043 if (!cs42l42->stream_use) {
1049 regmap_multi_reg_write(cs42l42->regmap, cs42l42_to_osc_seq,
1063 if (!cs42l42->stream_use) {
1068 * DAPM widgets power-up before stream unmute so at least
1070 * powered-up.
1072 if (pll_ratio_table[cs42l42->pll_config].mclk_src_sel) {
1076 if (pll_ratio_table[cs42l42->pll_config].n > 1) {
1079 regval = pll_ratio_table[cs42l42->pll_config].pll_divout;
1086 ret = regmap_read_poll_timeout(cs42l42->regmap,
1093 dev_warn(component->dev, "PLL failed to lock: %d\n", ret);
1103 regmap_multi_reg_write(cs42l42->regmap, cs42l42_to_sclk_seq,
1106 cs42l42->stream_use |= 1 << stream;
1109 /* Un-mute the headphone */
1164 regmap_update_bits(cs42l42->regmap,
1175 /* Configure HS DET comparator reference levels. */
1176 regmap_update_bits(cs42l42->regmap,
1184 regmap_write(cs42l42->regmap, CS42L42_HS_SWITCH_CTL, CS42L42_HSDET_SW_COMP1);
1188 regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status);
1196 regmap_write(cs42l42->regmap, CS42L42_HS_SWITCH_CTL, CS42L42_HSDET_SW_COMP2);
1200 regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status);
1207 /* Use Comparator 1 with 1.25V Threshold. */
1210 cs42l42->hs_type = CS42L42_PLUG_CTIA;
1214 cs42l42->hs_type = CS42L42_PLUG_OMTP;
1218 /* Fallback to Comparator 2 with 1.75V Threshold. */
1221 cs42l42->hs_type = CS42L42_PLUG_CTIA;
1225 cs42l42->hs_type = CS42L42_PLUG_OMTP;
1230 cs42l42->hs_type = CS42L42_PLUG_HEADPHONE;
1237 regmap_write(cs42l42->regmap, CS42L42_HS_SWITCH_CTL, hs_det_sw);
1240 regmap_update_bits(cs42l42->regmap,
1251 /* Configure HS DET comparator reference levels. */
1252 regmap_update_bits(cs42l42->regmap,
1266 regmap_read(cs42l42->regmap, CS42L42_HS_DET_STATUS, &hs_det_status);
1269 regmap_update_bits(cs42l42->regmap,
1277 cs42l42->hs_type = (hs_det_status & CS42L42_HSDET_TYPE_MASK) >>
1281 regmap_update_bits(cs42l42->regmap,
1293 * We Re-Run with Manual Detection if the original detection was invalid or headphones,
1296 if (cs42l42->hs_type == CS42L42_PLUG_INVALID ||
1297 cs42l42->hs_type == CS42L42_PLUG_HEADPHONE) {
1298 dev_dbg(cs42l42->dev, "Running Manual Detection Fallback\n");
1303 if ((cs42l42->hs_type == CS42L42_PLUG_CTIA) ||
1304 (cs42l42->hs_type == CS42L42_PLUG_OMTP)) {
1306 regmap_update_bits(cs42l42->regmap,
1318 regmap_update_bits(cs42l42->regmap,
1325 (cs42l42->bias_thresholds[0] <<
1329 regmap_update_bits(cs42l42->regmap,
1335 (cs42l42->hs_bias_sense_en << CS42L42_HSBIAS_SENSE_EN_SHIFT) |
1341 regmap_update_bits(cs42l42->regmap,
1348 msleep(cs42l42->btn_det_init_dbnce);
1351 regmap_read(cs42l42->regmap, CS42L42_DET_INT_STATUS2,
1355 regmap_update_bits(cs42l42->regmap,
1369 regmap_update_bits(cs42l42->regmap,
1377 regmap_update_bits(cs42l42->regmap,
1391 regmap_update_bits(cs42l42->regmap,
1402 regmap_update_bits(cs42l42->regmap,
1410 regmap_update_bits(cs42l42->regmap,
1418 regmap_update_bits(cs42l42->regmap,
1430 regmap_update_bits(cs42l42->regmap,
1441 regmap_update_bits(cs42l42->regmap,
1455 regmap_update_bits(cs42l42->regmap,
1463 msleep(cs42l42->hs_bias_ramp_time);
1466 regmap_update_bits(cs42l42->regmap,
1474 regmap_update_bits(cs42l42->regmap,
1489 regmap_update_bits(cs42l42->regmap,
1503 regmap_update_bits(cs42l42->regmap,
1511 regmap_update_bits(cs42l42->regmap,
1523 regmap_update_bits(cs42l42->regmap,
1541 regmap_update_bits(cs42l42->regmap,
1554 usleep_range(cs42l42->btn_det_event_dbnce * 1000,
1555 cs42l42->btn_det_event_dbnce * 2000);
1561 regmap_update_bits(cs42l42->regmap,
1568 (cs42l42->bias_thresholds[bias_level] <<
1571 regmap_read(cs42l42->regmap, CS42L42_DET_STATUS2,
1579 dev_dbg(cs42l42->dev, "Function C button press\n");
1583 dev_dbg(cs42l42->dev, "Function B button press\n");
1587 dev_dbg(cs42l42->dev, "Function D button press\n");
1591 dev_dbg(cs42l42->dev, "Function A button press\n");
1599 regmap_update_bits(cs42l42->regmap,
1606 (cs42l42->bias_thresholds[0] << CS42L42_HS_DET_LEVEL_SHIFT));
1609 regmap_read(cs42l42->regmap, CS42L42_DET_INT_STATUS2,
1613 regmap_update_bits(cs42l42->regmap,
1671 pm_runtime_get_sync(cs42l42->dev);
1672 mutex_lock(&cs42l42->irq_lock);
1673 if (cs42l42->suspended || !cs42l42->init_done) {
1674 mutex_unlock(&cs42l42->irq_lock);
1675 pm_runtime_put_autosuspend(cs42l42->dev);
1681 regmap_read(cs42l42->regmap, irq_params_table[i].status_addr,
1683 regmap_read(cs42l42->regmap, irq_params_table[i].mask_addr,
1701 * Check auto-detect status. Don't assume a previous unplug event has
1708 switch (cs42l42->hs_type) {
1711 snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADSET,
1717 snd_soc_jack_report(cs42l42->jack, SND_JACK_HEADPHONE,
1725 dev_dbg(cs42l42->dev, "Auto detect done (%d)\n", cs42l42->hs_type);
1733 if (cs42l42->plug_state != CS42L42_TS_PLUG) {
1734 cs42l42->plug_state = CS42L42_TS_PLUG;
1740 if (cs42l42->plug_state != CS42L42_TS_UNPLUG) {
1741 cs42l42->plug_state = CS42L42_TS_UNPLUG;
1744 snd_soc_jack_report(cs42l42->jack, 0,
1749 dev_dbg(cs42l42->dev, "Unplug event\n");
1754 cs42l42->plug_state = CS42L42_TS_TRANS;
1759 if (cs42l42->plug_state == CS42L42_TS_PLUG && ((~masks[7]) & irq_params_table[7].mask)) {
1764 dev_dbg(cs42l42->dev, "Button released\n");
1765 snd_soc_jack_report(cs42l42->jack, 0,
1769 snd_soc_jack_report(cs42l42->jack,
1777 mutex_unlock(&cs42l42->irq_lock);
1778 pm_runtime_mark_last_busy(cs42l42->dev);
1779 pm_runtime_put_autosuspend(cs42l42->dev);
1787 regmap_update_bits(cs42l42->regmap, CS42L42_ADC_OVFL_INT_MASK,
1791 regmap_update_bits(cs42l42->regmap, CS42L42_MIXER_INT_MASK,
1801 regmap_update_bits(cs42l42->regmap, CS42L42_SRC_INT_MASK,
1811 regmap_update_bits(cs42l42->regmap, CS42L42_ASP_RX_INT_MASK,
1823 regmap_update_bits(cs42l42->regmap, CS42L42_ASP_TX_INT_MASK,
1833 regmap_update_bits(cs42l42->regmap, CS42L42_CODEC_INT_MASK,
1839 regmap_update_bits(cs42l42->regmap, CS42L42_SRCPL_INT_MASK,
1849 regmap_update_bits(cs42l42->regmap, CS42L42_DET_INT1_MASK,
1857 regmap_update_bits(cs42l42->regmap, CS42L42_DET_INT2_MASK,
1869 regmap_update_bits(cs42l42->regmap, CS42L42_VPMON_INT_MASK,
1873 regmap_update_bits(cs42l42->regmap, CS42L42_PLL_LOCK_INT_MASK,
1877 regmap_update_bits(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK,
1892 cs42l42->hs_type = CS42L42_PLUG_INVALID;
1898 regmap_update_bits(cs42l42->regmap, CS42L42_MISC_DET_CTL,
1902 regmap_update_bits(cs42l42->regmap, CS42L42_MIC_DET_CTL1,
1908 (cs42l42->bias_thresholds[0] <<
1911 /* Remove ground noise-suppression clamps */
1912 regmap_update_bits(cs42l42->regmap,
1918 regmap_update_bits(cs42l42->regmap, CS42L42_TSENSE_CTL,
1921 regmap_update_bits(cs42l42->regmap, CS42L42_TIPSENSE_CTL,
1926 (!cs42l42->ts_inv << CS42L42_TIP_SENSE_INV_SHIFT) |
1930 regmap_read(cs42l42->regmap,
1933 cs42l42->plug_state = (((char) reg) &
1953 ret = device_property_read_u32(dev, "cirrus,ts-inv", &val);
1958 cs42l42->ts_inv = val;
1962 "Wrong cirrus,ts-inv DT value %d\n",
1964 cs42l42->ts_inv = CS42L42_TS_INV_DIS;
1967 cs42l42->ts_inv = CS42L42_TS_INV_DIS;
1970 ret = device_property_read_u32(dev, "cirrus,ts-dbnc-rise", &val);
1981 cs42l42->ts_dbnc_rise = val;
1985 "Wrong cirrus,ts-dbnc-rise DT value %d\n",
1987 cs42l42->ts_dbnc_rise = CS42L42_TS_DBNCE_1000;
1990 cs42l42->ts_dbnc_rise = CS42L42_TS_DBNCE_1000;
1993 regmap_update_bits(cs42l42->regmap, CS42L42_TSENSE_CTL,
1995 (cs42l42->ts_dbnc_rise <<
1998 ret = device_property_read_u32(dev, "cirrus,ts-dbnc-fall", &val);
2009 cs42l42->ts_dbnc_fall = val;
2013 "Wrong cirrus,ts-dbnc-fall DT value %d\n",
2015 cs42l42->ts_dbnc_fall = CS42L42_TS_DBNCE_0;
2018 cs42l42->ts_dbnc_fall = CS42L42_TS_DBNCE_0;
2021 regmap_update_bits(cs42l42->regmap, CS42L42_TSENSE_CTL,
2023 (cs42l42->ts_dbnc_fall <<
2026 ret = device_property_read_u32(dev, "cirrus,btn-det-init-dbnce", &val);
2029 cs42l42->btn_det_init_dbnce = val;
2032 "Wrong cirrus,btn-det-init-dbnce DT value %d\n",
2034 cs42l42->btn_det_init_dbnce =
2038 cs42l42->btn_det_init_dbnce =
2042 ret = device_property_read_u32(dev, "cirrus,btn-det-event-dbnce", &val);
2045 cs42l42->btn_det_event_dbnce = val;
2048 "Wrong cirrus,btn-det-event-dbnce DT value %d\n", val);
2049 cs42l42->btn_det_event_dbnce =
2053 cs42l42->btn_det_event_dbnce =
2057 ret = device_property_read_u32_array(dev, "cirrus,bias-lvls",
2062 cs42l42->bias_thresholds[i] = thresholds[i];
2065 "Wrong cirrus,bias-lvls[%d] DT value %d\n", i,
2067 cs42l42->bias_thresholds[i] = threshold_defaults[i];
2072 cs42l42->bias_thresholds[i] = threshold_defaults[i];
2075 ret = device_property_read_u32(dev, "cirrus,hs-bias-ramp-rate", &val);
2079 cs42l42->hs_bias_ramp_rate = val;
2080 cs42l42->hs_bias_ramp_time = CS42L42_HSBIAS_RAMP_TIME0;
2083 cs42l42->hs_bias_ramp_rate = val;
2084 cs42l42->hs_bias_ramp_time = CS42L42_HSBIAS_RAMP_TIME1;
2087 cs42l42->hs_bias_ramp_rate = val;
2088 cs42l42->hs_bias_ramp_time = CS42L42_HSBIAS_RAMP_TIME2;
2091 cs42l42->hs_bias_ramp_rate = val;
2092 cs42l42->hs_bias_ramp_time = CS42L42_HSBIAS_RAMP_TIME3;
2096 "Wrong cirrus,hs-bias-ramp-rate DT value %d\n",
2098 cs42l42->hs_bias_ramp_rate = CS42L42_HSBIAS_RAMP_SLOW;
2099 cs42l42->hs_bias_ramp_time = CS42L42_HSBIAS_RAMP_TIME2;
2102 cs42l42->hs_bias_ramp_rate = CS42L42_HSBIAS_RAMP_SLOW;
2103 cs42l42->hs_bias_ramp_time = CS42L42_HSBIAS_RAMP_TIME2;
2106 regmap_update_bits(cs42l42->regmap, CS42L42_HS_BIAS_CTL,
2108 (cs42l42->hs_bias_ramp_rate <<
2111 if (device_property_read_bool(dev, "cirrus,hs-bias-sense-disable"))
2112 cs42l42->hs_bias_sense_en = 0;
2114 cs42l42->hs_bias_sense_en = 1;
2159 if (!cs42l42->init_done)
2167 mutex_lock(&cs42l42->irq_lock);
2168 cs42l42->suspended = true;
2172 regmap_read(cs42l42->regmap, cs42l42_shutdown_seq[i].reg, ®);
2177 regmap_multi_reg_write(cs42l42->regmap,
2182 mutex_unlock(&cs42l42->irq_lock);
2184 /* Wait for power-down complete */
2186 ret = regmap_read_poll_timeout(cs42l42->regmap,
2195 regmap_update_bits(cs42l42->regmap, CS42L42_PWR_CTL2,
2198 regcache_cache_only(cs42l42->regmap, true);
2199 gpiod_set_value_cansleep(cs42l42->reset_gpio, 0);
2200 regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies);
2204 regmap_write(cs42l42->regmap, cs42l42_shutdown_seq[i].reg, save_regs[i]);
2207 regcache_drop_region(cs42l42->regmap, CS42L42_PAGE_REGISTER, CS42L42_PAGE_REGISTER);
2221 if (!cs42l42->init_done)
2225 * If jack was unplugged and re-plugged during suspend it could
2226 * have changed type but the tip-sense state hasn't changed.
2227 * Force a plugged state to be re-evaluated.
2229 if (cs42l42->plug_state != CS42L42_TS_UNPLUG)
2230 cs42l42->plug_state = CS42L42_TS_TRANS;
2232 ret = regulator_bulk_enable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies);
2238 gpiod_set_value_cansleep(cs42l42->reset_gpio, 1);
2251 regcache_cache_only(cs42l42->regmap, false);
2252 regcache_mark_dirty(cs42l42->regmap);
2254 mutex_lock(&cs42l42->irq_lock);
2256 regcache_sync_region(cs42l42->regmap, CS42L42_MIC_DET_CTL1, CS42L42_MIC_DET_CTL1);
2257 regcache_sync(cs42l42->regmap);
2259 cs42l42->suspended = false;
2260 mutex_unlock(&cs42l42->irq_lock);
2285 dev_set_drvdata(cs42l42->dev, cs42l42);
2286 mutex_init(&cs42l42->irq_lock);
2288 BUILD_BUG_ON(ARRAY_SIZE(cs42l42_supply_names) != ARRAY_SIZE(cs42l42->supplies));
2289 for (i = 0; i < ARRAY_SIZE(cs42l42->supplies); i++)
2290 cs42l42->supplies[i].supply = cs42l42_supply_names[i];
2292 ret = devm_regulator_bulk_get(cs42l42->dev,
2293 ARRAY_SIZE(cs42l42->supplies),
2294 cs42l42->supplies);
2296 dev_err(cs42l42->dev,
2301 ret = regulator_bulk_enable(ARRAY_SIZE(cs42l42->supplies),
2302 cs42l42->supplies);
2304 dev_err(cs42l42->dev,
2310 cs42l42->reset_gpio = devm_gpiod_get_optional(cs42l42->dev,
2312 if (IS_ERR(cs42l42->reset_gpio)) {
2313 ret = PTR_ERR(cs42l42->reset_gpio);
2317 if (cs42l42->reset_gpio) {
2318 dev_dbg(cs42l42->dev, "Found reset GPIO\n");
2324 gpiod_set_value_cansleep(cs42l42->reset_gpio, 0);
2335 if (cs42l42->sdw_peripheral)
2336 cs42l42->sdw_waiting_first_unattach = true;
2338 gpiod_set_value_cansleep(cs42l42->reset_gpio, 1);
2343 if (cs42l42->irq) {
2344 ret = request_threaded_irq(cs42l42->irq,
2349 dev_err_probe(cs42l42->dev, ret,
2356 ret = devm_snd_soc_register_component(cs42l42->dev, component_drv, dai, 1);
2363 if (cs42l42->irq)
2364 free_irq(cs42l42->irq, cs42l42);
2367 gpiod_set_value_cansleep(cs42l42->reset_gpio, 0);
2369 regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies);
2381 devid = cirrus_read_device_id(cs42l42->regmap, CS42L42_DEVID_AB);
2384 dev_err(cs42l42->dev, "Failed to read device ID: %d\n", ret);
2388 if (devid != cs42l42->devid) {
2389 ret = -ENODEV;
2390 dev_err(cs42l42->dev,
2392 cs42l42->devid & 0xff, devid, cs42l42->devid);
2396 ret = regmap_read(cs42l42->regmap, CS42L42_REVID, ®);
2398 dev_err(cs42l42->dev, "Get Revision ID failed\n");
2402 dev_info(cs42l42->dev,
2404 cs42l42->devid & 0xff, reg & 0xFF);
2407 regmap_update_bits(cs42l42->regmap, CS42L42_PWR_CTL1,
2423 ret = cs42l42_handle_device_data(cs42l42->dev, cs42l42);
2431 if (cs42l42->sdw_peripheral) {
2432 regmap_update_bits(cs42l42->regmap, CS42L42_PWR_CTL2,
2446 cs42l42->init_done = true;
2454 regmap_write(cs42l42->regmap, CS42L42_CODEC_INT_MASK, 0xff);
2455 regmap_write(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK, 0xff);
2456 regmap_write(cs42l42->regmap, CS42L42_PWR_CTL1, 0xff);
2459 if (cs42l42->irq)
2460 free_irq(cs42l42->irq, cs42l42);
2462 gpiod_set_value_cansleep(cs42l42->reset_gpio, 0);
2463 regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies),
2464 cs42l42->supplies);
2471 if (cs42l42->irq)
2472 free_irq(cs42l42->irq, cs42l42);
2478 if (cs42l42->init_done) {
2479 regmap_write(cs42l42->regmap, CS42L42_CODEC_INT_MASK, 0xff);
2480 regmap_write(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK, 0xff);
2481 regmap_write(cs42l42->regmap, CS42L42_PWR_CTL1, 0xff);
2484 gpiod_set_value_cansleep(cs42l42->reset_gpio, 0);
2485 regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies);