• Home
  • Raw
  • Download

Lines Matching +full:tdm +full:- +full:invert +full:- +full:sync

1 // SPDX-License-Identifier: GPL-2.0-only
111 static const char *const pcm3168a_con[] = { "Differential", "Single-Ended" };
129 /* -100db to 0db, register values 0-54 cause mute */
130 static const DECLARE_TLV_DB_SCALE(pcm3168a_dac_tlv, -10050, 50, 1);
132 /* -100db to 20db, register values 0-14 cause mute */
133 static const DECLARE_TLV_DB_SCALE(pcm3168a_adc_tlv, -10050, 50, 1);
136 SOC_SINGLE("DAC Power-Save Switch", PCM3168A_DAC_PWR_MST_FMT,
138 SOC_ENUM("DAC1 Digital Filter roll-off", pcm3168a_d1_roll_off),
139 SOC_ENUM("DAC2 Digital Filter roll-off", pcm3168a_d2_roll_off),
140 SOC_ENUM("DAC3 Digital Filter roll-off", pcm3168a_d3_roll_off),
141 SOC_ENUM("DAC4 Digital Filter roll-off", pcm3168a_d4_roll_off),
142 SOC_DOUBLE("DAC1 Invert Switch", PCM3168A_DAC_INV, 0, 1, 1, 0),
143 SOC_DOUBLE("DAC2 Invert Switch", PCM3168A_DAC_INV, 2, 3, 1, 0),
144 SOC_DOUBLE("DAC3 Invert Switch", PCM3168A_DAC_INV, 4, 5, 1, 0),
145 SOC_DOUBLE("DAC4 Invert Switch", PCM3168A_DAC_INV, 6, 7, 1, 0),
148 SOC_ENUM("DAC De-Emphasis", pcm3168a_dac_demp),
170 SOC_SINGLE("ADC1 High-Pass Filter Switch", PCM3168A_ADC_PWR_HPFB,
172 SOC_SINGLE("ADC2 High-Pass Filter Switch", PCM3168A_ADC_PWR_HPFB,
174 SOC_SINGLE("ADC3 High-Pass Filter Switch", PCM3168A_ADC_PWR_HPFB,
179 SOC_DOUBLE("ADC1 Invert Switch", PCM3168A_ADC_INV, 0, 1, 1, 0),
180 SOC_DOUBLE("ADC2 Invert Switch", PCM3168A_ADC_INV, 2, 3, 1, 0),
181 SOC_DOUBLE("ADC3 Invert Switch", PCM3168A_ADC_INV, 4, 5, 1, 0),
274 #define PCM3168A_NUM_SCKI_RATIOS_ADC (ARRAY_SIZE(pcm3168a_scki_ratios) - 2)
282 ret = regmap_write(pcm3168a->regmap, PCM3168A_RST_SMODE, 0); in pcm3168a_reset()
286 /* Internal reset is de-asserted after 3846 SCKI cycles */ in pcm3168a_reset()
287 msleep(DIV_ROUND_UP(3846 * 1000, pcm3168a->sysclk)); in pcm3168a_reset()
289 return regmap_write(pcm3168a->regmap, PCM3168A_RST_SMODE, in pcm3168a_reset()
295 struct snd_soc_component *component = dai->component; in pcm3168a_mute()
298 regmap_write(pcm3168a->regmap, PCM3168A_DAC_MUTE, mute ? 0xff : 0); in pcm3168a_mute()
306 struct pcm3168a_priv *pcm3168a = snd_soc_component_get_drvdata(dai->component); in pcm3168a_set_dai_sysclk()
317 return -EINVAL; in pcm3168a_set_dai_sysclk()
319 ret = clk_set_rate(pcm3168a->scki, freq); in pcm3168a_set_dai_sysclk()
323 pcm3168a->sysclk = freq; in pcm3168a_set_dai_sysclk()
330 struct snd_soc_component *component = dai->component; in pcm3168a_update_fixup_pcm_stream()
333 unsigned int channel_max = dai->id == PCM3168A_DAI_DAC ? 8 : 6; in pcm3168a_update_fixup_pcm_stream()
335 if (pcm3168a->io_params[dai->id].fmt == PCM3168A_FMT_RIGHT_J) { in pcm3168a_update_fixup_pcm_stream()
341 * two channels (no TDM support) in pcm3168a_update_fixup_pcm_stream()
343 if (pcm3168a->io_params[dai->id].tdm_slots != 2) in pcm3168a_update_fixup_pcm_stream()
347 if (dai->id == PCM3168A_DAI_DAC) { in pcm3168a_update_fixup_pcm_stream()
348 dai->driver->playback.channels_max = channel_max; in pcm3168a_update_fixup_pcm_stream()
349 dai->driver->playback.formats = formats; in pcm3168a_update_fixup_pcm_stream()
351 dai->driver->capture.channels_max = channel_max; in pcm3168a_update_fixup_pcm_stream()
352 dai->driver->capture.formats = formats; in pcm3168a_update_fixup_pcm_stream()
358 struct snd_soc_component *component = dai->component; in pcm3168a_set_dai_fmt()
380 dev_err(component->dev, "unsupported dai format\n"); in pcm3168a_set_dai_fmt()
381 return -EINVAL; in pcm3168a_set_dai_fmt()
392 dev_err(component->dev, "unsupported master/slave mode\n"); in pcm3168a_set_dai_fmt()
393 return -EINVAL; in pcm3168a_set_dai_fmt()
400 return -EINVAL; in pcm3168a_set_dai_fmt()
403 if (dai->id == PCM3168A_DAI_DAC) { in pcm3168a_set_dai_fmt()
413 pcm3168a->io_params[dai->id].master_mode = master_mode; in pcm3168a_set_dai_fmt()
414 pcm3168a->io_params[dai->id].fmt = fmt; in pcm3168a_set_dai_fmt()
416 regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift); in pcm3168a_set_dai_fmt()
427 struct snd_soc_component *component = dai->component; in pcm3168a_set_tdm_slot()
429 struct pcm3168a_io_params *io_params = &pcm3168a->io_params[dai->id]; in pcm3168a_set_tdm_slot()
432 dev_err(component->dev, in pcm3168a_set_tdm_slot()
433 "Bad tdm mask tx: 0x%08x rx: 0x%08x slots %d\n", in pcm3168a_set_tdm_slot()
435 return -EINVAL; in pcm3168a_set_tdm_slot()
440 dev_err(component->dev, "Unsupported slot_width %d\n", in pcm3168a_set_tdm_slot()
442 return -EINVAL; in pcm3168a_set_tdm_slot()
445 io_params->tdm_slots = slots; in pcm3168a_set_tdm_slot()
446 io_params->slot_width = slot_width; in pcm3168a_set_tdm_slot()
448 if (dai->id == PCM3168A_DAI_DAC) in pcm3168a_set_tdm_slot()
449 io_params->tdm_mask = tx_mask; in pcm3168a_set_tdm_slot()
451 io_params->tdm_mask = rx_mask; in pcm3168a_set_tdm_slot()
462 struct snd_soc_component *component = dai->component; in pcm3168a_hw_params()
464 struct pcm3168a_io_params *io_params = &pcm3168a->io_params[dai->id]; in pcm3168a_hw_params()
473 ratio = pcm3168a->sysclk / rate; in pcm3168a_hw_params()
475 if (dai->id == PCM3168A_DAI_DAC) { in pcm3168a_hw_params()
487 master_mode = io_params->master_mode; in pcm3168a_hw_params()
488 fmt = io_params->fmt; in pcm3168a_hw_params()
496 dev_err(component->dev, "unsupported sysclk ratio\n"); in pcm3168a_hw_params()
497 return -EINVAL; in pcm3168a_hw_params()
500 if (io_params->slot_width) in pcm3168a_hw_params()
501 slot_width = io_params->slot_width; in pcm3168a_hw_params()
508 … dev_err(component->dev, "16-bit slots are supported only for slave mode using right justified\n"); in pcm3168a_hw_params()
509 return -EINVAL; in pcm3168a_hw_params()
515 dev_err(component->dev, "24-bit slots not supported in master mode, or slave mode using DSP\n"); in pcm3168a_hw_params()
516 return -EINVAL; in pcm3168a_hw_params()
522 dev_err(component->dev, "unsupported frame size: %d\n", slot_width); in pcm3168a_hw_params()
523 return -EINVAL; in pcm3168a_hw_params()
526 if (io_params->tdm_slots) in pcm3168a_hw_params()
527 tdm_slots = io_params->tdm_slots; in pcm3168a_hw_params()
532 * Switch the codec to TDM mode when more than 2 TDM slots are needed in pcm3168a_hw_params()
534 * If pcm3168a->tdm_slots is not set or set to more than 2 (8/6 usually) in pcm3168a_hw_params()
535 * then DIN1/DOUT1 is used in TDM mode. in pcm3168a_hw_params()
536 * If pcm3168a->tdm_slots is set to 2 then DIN1/2/3/4 and DOUT1/2/3 is in pcm3168a_hw_params()
537 * used in normal mode, no need to switch to TDM modes. in pcm3168a_hw_params()
550 dev_err(component->dev, in pcm3168a_hw_params()
551 "TDM is supported under DSP/I2S/Left_J only\n"); in pcm3168a_hw_params()
552 return -EINVAL; in pcm3168a_hw_params()
561 regmap_update_bits(pcm3168a->regmap, reg, mask, val); in pcm3168a_hw_params()
563 if (dai->id == PCM3168A_DAI_DAC) { in pcm3168a_hw_params()
571 regmap_update_bits(pcm3168a->regmap, reg, mask, fmt << shift); in pcm3168a_hw_params()
587 .name = "pcm3168a-dac",
599 .name = "pcm3168a-adc",
713 return -ENOMEM; in pcm3168a_probe()
725 pcm3168a->gpio_rst = devm_gpiod_get_optional(dev, "reset", in pcm3168a_probe()
728 if (IS_ERR(pcm3168a->gpio_rst)) { in pcm3168a_probe()
729 ret = PTR_ERR(pcm3168a->gpio_rst); in pcm3168a_probe()
730 if (ret != -EPROBE_DEFER ) in pcm3168a_probe()
736 pcm3168a->scki = devm_clk_get(dev, "scki"); in pcm3168a_probe()
737 if (IS_ERR(pcm3168a->scki)) { in pcm3168a_probe()
738 ret = PTR_ERR(pcm3168a->scki); in pcm3168a_probe()
739 if (ret != -EPROBE_DEFER) in pcm3168a_probe()
744 ret = clk_prepare_enable(pcm3168a->scki); in pcm3168a_probe()
750 pcm3168a->sysclk = clk_get_rate(pcm3168a->scki); in pcm3168a_probe()
752 for (i = 0; i < ARRAY_SIZE(pcm3168a->supplies); i++) in pcm3168a_probe()
753 pcm3168a->supplies[i].supply = pcm3168a_supply_names[i]; in pcm3168a_probe()
756 ARRAY_SIZE(pcm3168a->supplies), pcm3168a->supplies); in pcm3168a_probe()
758 if (ret != -EPROBE_DEFER) in pcm3168a_probe()
763 ret = regulator_bulk_enable(ARRAY_SIZE(pcm3168a->supplies), in pcm3168a_probe()
764 pcm3168a->supplies); in pcm3168a_probe()
770 pcm3168a->regmap = regmap; in pcm3168a_probe()
771 if (IS_ERR(pcm3168a->regmap)) { in pcm3168a_probe()
772 ret = PTR_ERR(pcm3168a->regmap); in pcm3168a_probe()
777 if (pcm3168a->gpio_rst) { in pcm3168a_probe()
780 * 3846 SCKI clock cycles for the internal reset de-assertion in pcm3168a_probe()
782 msleep(DIV_ROUND_UP(3846 * 1000, pcm3168a->sysclk)); in pcm3168a_probe()
795 memcpy(pcm3168a->dai_drv, pcm3168a_dais, sizeof(pcm3168a->dai_drv)); in pcm3168a_probe()
797 pcm3168a->dai_drv, in pcm3168a_probe()
798 ARRAY_SIZE(pcm3168a->dai_drv)); in pcm3168a_probe()
807 regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies), in pcm3168a_probe()
808 pcm3168a->supplies); in pcm3168a_probe()
810 clk_disable_unprepare(pcm3168a->scki); in pcm3168a_probe()
820 regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies), in pcm3168a_disable()
821 pcm3168a->supplies); in pcm3168a_disable()
822 clk_disable_unprepare(pcm3168a->scki); in pcm3168a_disable()
835 gpiod_set_value_cansleep(pcm3168a->gpio_rst, 1); in pcm3168a_remove()
849 ret = clk_prepare_enable(pcm3168a->scki); in pcm3168a_rt_resume()
855 ret = regulator_bulk_enable(ARRAY_SIZE(pcm3168a->supplies), in pcm3168a_rt_resume()
856 pcm3168a->supplies); in pcm3168a_rt_resume()
868 regcache_cache_only(pcm3168a->regmap, false); in pcm3168a_rt_resume()
870 regcache_mark_dirty(pcm3168a->regmap); in pcm3168a_rt_resume()
872 ret = regcache_sync(pcm3168a->regmap); in pcm3168a_rt_resume()
874 dev_err(dev, "Failed to sync regmap: %d\n", ret); in pcm3168a_rt_resume()
881 regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies), in pcm3168a_rt_resume()
882 pcm3168a->supplies); in pcm3168a_rt_resume()
884 clk_disable_unprepare(pcm3168a->scki); in pcm3168a_rt_resume()
893 regcache_cache_only(pcm3168a->regmap, true); in pcm3168a_rt_suspend()