Lines Matching +full:channel +full:- +full:3
1 // SPDX-License-Identifier: GPL-2.0-or-later
8 * - implement DAPM and input muxing
9 * - implement modulation limit
10 * - implement non-default PWM start
13 * because the registers are of unequal size, and multi-byte registers
18 * it doesn't matter because the entire map can be accessed as 8-bit
21 * routines have to be open-coded.
70 #define TAS5086_CHANNEL_VOL(X) (0x08 + (X)) /* Channel 1-6 volume */
88 * Default TAS5086 power-up configuration
172 size = tas5086_register_size(&client->dev, reg); in tas5086_reg_write()
174 return -EINVAL; in tas5086_reg_write()
178 for (i = size; i >= 1; --i) { in tas5086_reg_write()
189 return -EIO; in tas5086_reg_write()
202 size = tas5086_register_size(&client->dev, reg); in tas5086_reg_read()
204 return -EINVAL; in tas5086_reg_read()
208 msgs[0].addr = client->addr; in tas5086_reg_read()
213 msgs[1].addr = client->addr; in tas5086_reg_read()
218 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); in tas5086_reg_read()
222 return -EIO; in tas5086_reg_read()
245 /* Current sample rate for de-emphasis control */
259 if (priv->deemph) { in tas5086_set_deemph()
261 if (tas5086_deemph[i] == priv->rate) { in tas5086_set_deemph()
268 return regmap_update_bits(priv->regmap, TAS5086_SYS_CONTROL_1, in tas5086_set_deemph()
278 ucontrol->value.integer.value[0] = priv->deemph; in tas5086_get_deemph()
289 priv->deemph = ucontrol->value.integer.value[0]; in tas5086_put_deemph()
298 struct snd_soc_component *component = codec_dai->component; in tas5086_set_dai_sysclk()
303 priv->mclk = freq; in tas5086_set_dai_sysclk()
306 priv->sclk = freq; in tas5086_set_dai_sysclk()
316 struct snd_soc_component *component = codec_dai->component; in tas5086_set_dai_fmt()
321 dev_err(component->dev, "Invalid clocking mode\n"); in tas5086_set_dai_fmt()
322 return -EINVAL; in tas5086_set_dai_fmt()
326 priv->format = format; in tas5086_set_dai_fmt()
347 return -ENOENT; in index_in_array()
354 struct snd_soc_component *component = dai->component; in tas5086_hw_params()
359 priv->rate = params_rate(params); in tas5086_hw_params()
363 ARRAY_SIZE(tas5086_sample_rates), priv->rate); in tas5086_hw_params()
366 dev_err(component->dev, "Invalid sample rate\n"); in tas5086_hw_params()
367 return -EINVAL; in tas5086_hw_params()
370 ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL, in tas5086_hw_params()
378 priv->mclk / priv->rate); in tas5086_hw_params()
380 dev_err(component->dev, "Invalid MCLK / Fs ratio\n"); in tas5086_hw_params()
381 return -EINVAL; in tas5086_hw_params()
384 ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL, in tas5086_hw_params()
391 ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL, in tas5086_hw_params()
393 (priv->sclk == 48 * priv->rate) ? in tas5086_hw_params()
401 * a logical bit-boundary. Hence, we have to refer to the format passed in tas5086_hw_params()
406 switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { in tas5086_hw_params()
417 dev_err(component->dev, "Invalid DAI format\n"); in tas5086_hw_params()
418 return -EINVAL; in tas5086_hw_params()
433 dev_err(component->dev, "Invalid bit width\n"); in tas5086_hw_params()
434 return -EINVAL; in tas5086_hw_params()
437 ret = regmap_write(priv->regmap, TAS5086_SERIAL_DATA_IF, val); in tas5086_hw_params()
442 ret = regmap_update_bits(priv->regmap, TAS5086_CLOCK_CONTROL, in tas5086_hw_params()
452 struct snd_soc_component *component = dai->component; in tas5086_mute_stream()
459 return regmap_write(priv->regmap, TAS5086_SOFT_MUTE, val); in tas5086_mute_stream()
464 if (priv->reset) { in tas5086_reset()
465 /* Reset codec - minimum assertion time is 400ns */ in tas5086_reset()
466 gpiod_set_value_cansleep(priv->reset, 1); in tas5086_reset()
468 gpiod_set_value_cansleep(priv->reset, 0); in tas5086_reset()
487 * If any of the channels is configured to start in Mid-Z mode, in tas5086_init()
488 * configure 'part 1' of the PWM starts to use Mid-Z, and tell in tas5086_init()
489 * all configured mid-z channels to start under 'part 1'. in tas5086_init()
491 if (priv->pwm_start_mid_z) in tas5086_init()
492 regmap_write(priv->regmap, TAS5086_PWM_START, in tas5086_init()
494 priv->pwm_start_mid_z); in tas5086_init()
496 /* lookup and set split-capacitor charge period */ in tas5086_init()
497 if (priv->charge_period == 0) { in tas5086_init()
498 regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE, 0); in tas5086_init()
502 priv->charge_period); in tas5086_init()
504 regmap_write(priv->regmap, TAS5086_SPLIT_CAP_CHARGE, in tas5086_init()
508 "Invalid split-cap charge period of %d ns.\n", in tas5086_init()
509 priv->charge_period); in tas5086_init()
513 ret = regmap_write(priv->regmap, TAS5086_OSC_TRIM, 0x00); in tas5086_init()
518 ret = regmap_write(priv->regmap, TAS5086_SYS_CONTROL_2, 0x20); in tas5086_init()
523 ret = regmap_write(priv->regmap, TAS5086_SOFT_MUTE, in tas5086_init()
532 static const DECLARE_TLV_DB_SCALE(tas5086_dac_tlv, -10350, 50, 1);
537 SOC_DOUBLE_R_TLV("Channel 1/2 Playback Volume",
540 SOC_DOUBLE_R_TLV("Channel 3/4 Playback Volume",
541 TAS5086_CHANNEL_VOL(2), TAS5086_CHANNEL_VOL(3),
543 SOC_DOUBLE_R_TLV("Channel 5/6 Playback Volume",
546 SOC_SINGLE_BOOL_EXT("De-emphasis Switch", 0,
553 "SDIN1-L", "SDIN1-R", "SDIN2-L", "SDIN2-R",
554 "SDIN3-L", "SDIN3-R", "Ground (0)", "nc"
567 SOC_DAPM_ENUM("Channel 1 input", tas5086_dapm_input_mux_enum[0]),
568 SOC_DAPM_ENUM("Channel 2 input", tas5086_dapm_input_mux_enum[1]),
569 SOC_DAPM_ENUM("Channel 3 input", tas5086_dapm_input_mux_enum[2]),
570 SOC_DAPM_ENUM("Channel 4 input", tas5086_dapm_input_mux_enum[3]),
571 SOC_DAPM_ENUM("Channel 5 input", tas5086_dapm_input_mux_enum[4]),
572 SOC_DAPM_ENUM("Channel 6 input", tas5086_dapm_input_mux_enum[5]),
577 { "Channel 1 Mux", "Channel 2 Mux", "Channel 3 Mux",
578 "Channel 4 Mux", "Channel 5 Mux", "Channel 6 Mux" };
593 SOC_DAPM_ENUM("PWM4 Output", tas5086_dapm_output_mux_enum[3]),
599 SND_SOC_DAPM_INPUT("SDIN1-L"),
600 SND_SOC_DAPM_INPUT("SDIN1-R"),
601 SND_SOC_DAPM_INPUT("SDIN2-L"),
602 SND_SOC_DAPM_INPUT("SDIN2-R"),
603 SND_SOC_DAPM_INPUT("SDIN3-L"),
604 SND_SOC_DAPM_INPUT("SDIN3-R"),
605 SND_SOC_DAPM_INPUT("SDIN4-L"),
606 SND_SOC_DAPM_INPUT("SDIN4-R"),
615 SND_SOC_DAPM_MUX("Channel 1 Mux", SND_SOC_NOPM, 0, 0,
617 SND_SOC_DAPM_MUX("Channel 2 Mux", SND_SOC_NOPM, 0, 0,
619 SND_SOC_DAPM_MUX("Channel 3 Mux", SND_SOC_NOPM, 0, 0,
621 SND_SOC_DAPM_MUX("Channel 4 Mux", SND_SOC_NOPM, 0, 0,
622 &tas5086_dapm_input_mux_controls[3]),
623 SND_SOC_DAPM_MUX("Channel 5 Mux", SND_SOC_NOPM, 0, 0,
625 SND_SOC_DAPM_MUX("Channel 6 Mux", SND_SOC_NOPM, 0, 0,
635 &tas5086_dapm_output_mux_controls[3]),
643 /* SDIN inputs -> channel muxes */
644 { "Channel 1 Mux", "SDIN1-L", "SDIN1-L" },
645 { "Channel 1 Mux", "SDIN1-R", "SDIN1-R" },
646 { "Channel 1 Mux", "SDIN2-L", "SDIN2-L" },
647 { "Channel 1 Mux", "SDIN2-R", "SDIN2-R" },
648 { "Channel 1 Mux", "SDIN3-L", "SDIN3-L" },
649 { "Channel 1 Mux", "SDIN3-R", "SDIN3-R" },
651 { "Channel 2 Mux", "SDIN1-L", "SDIN1-L" },
652 { "Channel 2 Mux", "SDIN1-R", "SDIN1-R" },
653 { "Channel 2 Mux", "SDIN2-L", "SDIN2-L" },
654 { "Channel 2 Mux", "SDIN2-R", "SDIN2-R" },
655 { "Channel 2 Mux", "SDIN3-L", "SDIN3-L" },
656 { "Channel 2 Mux", "SDIN3-R", "SDIN3-R" },
658 { "Channel 2 Mux", "SDIN1-L", "SDIN1-L" },
659 { "Channel 2 Mux", "SDIN1-R", "SDIN1-R" },
660 { "Channel 2 Mux", "SDIN2-L", "SDIN2-L" },
661 { "Channel 2 Mux", "SDIN2-R", "SDIN2-R" },
662 { "Channel 2 Mux", "SDIN3-L", "SDIN3-L" },
663 { "Channel 2 Mux", "SDIN3-R", "SDIN3-R" },
665 { "Channel 3 Mux", "SDIN1-L", "SDIN1-L" },
666 { "Channel 3 Mux", "SDIN1-R", "SDIN1-R" },
667 { "Channel 3 Mux", "SDIN2-L", "SDIN2-L" },
668 { "Channel 3 Mux", "SDIN2-R", "SDIN2-R" },
669 { "Channel 3 Mux", "SDIN3-L", "SDIN3-L" },
670 { "Channel 3 Mux", "SDIN3-R", "SDIN3-R" },
672 { "Channel 4 Mux", "SDIN1-L", "SDIN1-L" },
673 { "Channel 4 Mux", "SDIN1-R", "SDIN1-R" },
674 { "Channel 4 Mux", "SDIN2-L", "SDIN2-L" },
675 { "Channel 4 Mux", "SDIN2-R", "SDIN2-R" },
676 { "Channel 4 Mux", "SDIN3-L", "SDIN3-L" },
677 { "Channel 4 Mux", "SDIN3-R", "SDIN3-R" },
679 { "Channel 5 Mux", "SDIN1-L", "SDIN1-L" },
680 { "Channel 5 Mux", "SDIN1-R", "SDIN1-R" },
681 { "Channel 5 Mux", "SDIN2-L", "SDIN2-L" },
682 { "Channel 5 Mux", "SDIN2-R", "SDIN2-R" },
683 { "Channel 5 Mux", "SDIN3-L", "SDIN3-L" },
684 { "Channel 5 Mux", "SDIN3-R", "SDIN3-R" },
686 { "Channel 6 Mux", "SDIN1-L", "SDIN1-L" },
687 { "Channel 6 Mux", "SDIN1-R", "SDIN1-R" },
688 { "Channel 6 Mux", "SDIN2-L", "SDIN2-L" },
689 { "Channel 6 Mux", "SDIN2-R", "SDIN2-R" },
690 { "Channel 6 Mux", "SDIN3-L", "SDIN3-L" },
691 { "Channel 6 Mux", "SDIN3-R", "SDIN3-R" },
693 /* Channel muxes -> PWM muxes */
694 { "PWM1 Mux", "Channel 1 Mux", "Channel 1 Mux" },
695 { "PWM2 Mux", "Channel 1 Mux", "Channel 1 Mux" },
696 { "PWM3 Mux", "Channel 1 Mux", "Channel 1 Mux" },
697 { "PWM4 Mux", "Channel 1 Mux", "Channel 1 Mux" },
698 { "PWM5 Mux", "Channel 1 Mux", "Channel 1 Mux" },
699 { "PWM6 Mux", "Channel 1 Mux", "Channel 1 Mux" },
701 { "PWM1 Mux", "Channel 2 Mux", "Channel 2 Mux" },
702 { "PWM2 Mux", "Channel 2 Mux", "Channel 2 Mux" },
703 { "PWM3 Mux", "Channel 2 Mux", "Channel 2 Mux" },
704 { "PWM4 Mux", "Channel 2 Mux", "Channel 2 Mux" },
705 { "PWM5 Mux", "Channel 2 Mux", "Channel 2 Mux" },
706 { "PWM6 Mux", "Channel 2 Mux", "Channel 2 Mux" },
708 { "PWM1 Mux", "Channel 3 Mux", "Channel 3 Mux" },
709 { "PWM2 Mux", "Channel 3 Mux", "Channel 3 Mux" },
710 { "PWM3 Mux", "Channel 3 Mux", "Channel 3 Mux" },
711 { "PWM4 Mux", "Channel 3 Mux", "Channel 3 Mux" },
712 { "PWM5 Mux", "Channel 3 Mux", "Channel 3 Mux" },
713 { "PWM6 Mux", "Channel 3 Mux", "Channel 3 Mux" },
715 { "PWM1 Mux", "Channel 4 Mux", "Channel 4 Mux" },
716 { "PWM2 Mux", "Channel 4 Mux", "Channel 4 Mux" },
717 { "PWM3 Mux", "Channel 4 Mux", "Channel 4 Mux" },
718 { "PWM4 Mux", "Channel 4 Mux", "Channel 4 Mux" },
719 { "PWM5 Mux", "Channel 4 Mux", "Channel 4 Mux" },
720 { "PWM6 Mux", "Channel 4 Mux", "Channel 4 Mux" },
722 { "PWM1 Mux", "Channel 5 Mux", "Channel 5 Mux" },
723 { "PWM2 Mux", "Channel 5 Mux", "Channel 5 Mux" },
724 { "PWM3 Mux", "Channel 5 Mux", "Channel 5 Mux" },
725 { "PWM4 Mux", "Channel 5 Mux", "Channel 5 Mux" },
726 { "PWM5 Mux", "Channel 5 Mux", "Channel 5 Mux" },
727 { "PWM6 Mux", "Channel 5 Mux", "Channel 5 Mux" },
729 { "PWM1 Mux", "Channel 6 Mux", "Channel 6 Mux" },
730 { "PWM2 Mux", "Channel 6 Mux", "Channel 6 Mux" },
731 { "PWM3 Mux", "Channel 6 Mux", "Channel 6 Mux" },
732 { "PWM4 Mux", "Channel 6 Mux", "Channel 6 Mux" },
733 { "PWM5 Mux", "Channel 6 Mux", "Channel 6 Mux" },
734 { "PWM6 Mux", "Channel 6 Mux", "Channel 6 Mux" },
754 .name = "tas5086-hifi",
772 ret = regmap_write(priv->regmap, TAS5086_SYS_CONTROL_2, 0x60); in tas5086_soc_suspend()
776 regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies); in tas5086_soc_suspend()
786 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies); in tas5086_soc_resume()
791 regcache_mark_dirty(priv->regmap); in tas5086_soc_resume()
793 ret = tas5086_init(component->dev, priv); in tas5086_soc_resume()
797 ret = regcache_sync(priv->regmap); in tas5086_soc_resume()
821 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies); in tas5086_probe()
823 dev_err(component->dev, "Failed to enable regulators: %d\n", ret); in tas5086_probe()
827 priv->pwm_start_mid_z = 0; in tas5086_probe()
828 priv->charge_period = 1300000; /* hardware default is 1300 ms */ in tas5086_probe()
830 if (of_match_device(of_match_ptr(tas5086_dt_ids), component->dev)) { in tas5086_probe()
831 struct device_node *of_node = component->dev->of_node; in tas5086_probe()
833 of_property_read_u32(of_node, "ti,charge-period", in tas5086_probe()
834 &priv->charge_period); in tas5086_probe()
840 "ti,mid-z-channel-%d", i + 1); in tas5086_probe()
843 priv->pwm_start_mid_z |= 1 << i; in tas5086_probe()
848 ret = tas5086_init(component->dev, priv); in tas5086_probe()
853 ret = regmap_write(priv->regmap, TAS5086_MASTER_VOL, 0x30); in tas5086_probe()
860 regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies); in tas5086_probe()
869 if (priv->reset) { in tas5086_remove()
871 gpiod_set_value_cansleep(priv->reset, 1); in tas5086_remove()
874 regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies); in tas5086_remove()
916 struct device *dev = &i2c->dev; in tas5086_i2c_probe()
921 return -ENOMEM; in tas5086_i2c_probe()
924 priv->supplies[i].supply = supply_names[i]; in tas5086_i2c_probe()
926 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(priv->supplies), in tas5086_i2c_probe()
927 priv->supplies); in tas5086_i2c_probe()
933 priv->regmap = devm_regmap_init(dev, NULL, i2c, &tas5086_regmap); in tas5086_i2c_probe()
934 if (IS_ERR(priv->regmap)) { in tas5086_i2c_probe()
935 ret = PTR_ERR(priv->regmap); in tas5086_i2c_probe()
936 dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret); in tas5086_i2c_probe()
943 priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); in tas5086_i2c_probe()
944 if (IS_ERR(priv->reset)) in tas5086_i2c_probe()
945 return PTR_ERR(priv->reset); in tas5086_i2c_probe()
946 gpiod_set_consumer_name(priv->reset, "TAS5086 Reset"); in tas5086_i2c_probe()
948 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies); in tas5086_i2c_probe()
957 ret = regmap_read(priv->regmap, TAS5086_DEV_ID, &i); in tas5086_i2c_probe()
961 ret = -ENODEV; in tas5086_i2c_probe()
968 regulator_bulk_disable(ARRAY_SIZE(priv->supplies), priv->supplies); in tas5086_i2c_probe()
971 ret = devm_snd_soc_register_component(&i2c->dev, in tas5086_i2c_probe()