Lines Matching +full:audio +full:- +full:gain +full:- +full:db

1 // SPDX-License-Identifier: GPL-2.0-only
3 * tas5720.c - ALSA SoC Texas Instruments TAS5720 Mono Audio Amplifier
5 * Copyright (C)2015-2016 Texas Instruments Incorporated - https://www.ti.com
22 #include <sound/soc-dapm.h>
37 "dvdd", /* Digital power supply. Connect to 3.3-V supply. */
38 "pvdd", /* Class-D amp and analog power supply (connected). */
57 struct snd_soc_component *component = dai->component; in tas5720_hw_params()
72 dev_err(component->dev, "unsupported sample rate: %u\n", rate); in tas5720_hw_params()
73 return -EINVAL; in tas5720_hw_params()
79 dev_err(component->dev, "error setting sample rate: %d\n", ret); in tas5720_hw_params()
88 struct snd_soc_component *component = dai->component; in tas5720_set_dai_fmt()
93 dev_vdbg(component->dev, "DAI clocking invalid\n"); in tas5720_set_dai_fmt()
94 return -EINVAL; in tas5720_set_dai_fmt()
127 dev_vdbg(component->dev, "DAI Format is not found\n"); in tas5720_set_dai_fmt()
128 return -EINVAL; in tas5720_set_dai_fmt()
135 dev_err(component->dev, "error setting SAIF format: %d\n", ret); in tas5720_set_dai_fmt()
146 struct snd_soc_component *component = dai->component; in tas5720_set_dai_tdm_slot()
152 dev_err(component->dev, "tx masks must not be 0\n"); in tas5720_set_dai_tdm_slot()
153 return -EINVAL; in tas5720_set_dai_tdm_slot()
164 dev_err(component->dev, "slot selection out of bounds (%u)\n", in tas5720_set_dai_tdm_slot()
166 return -EINVAL; in tas5720_set_dai_tdm_slot()
171 * This is not applicable to TAS5720A-Q1. in tas5720_set_dai_tdm_slot()
173 switch (tas5720->devtype) { in tas5720_set_dai_tdm_slot()
182 /* Configure the TDM slot to process audio from */ in tas5720_set_dai_tdm_slot()
191 switch (tas5720->devtype) { in tas5720_set_dai_tdm_slot()
207 dev_err(component->dev, "error configuring TDM mode: %d\n", ret); in tas5720_set_dai_tdm_slot()
217 switch (tas5720->devtype) { in tas5720_mute_soc_component()
230 dev_err(component->dev, "error (un-)muting device: %d\n", ret); in tas5720_mute_soc_component()
239 return tas5720_mute_soc_component(dai->component, mute); in tas5720_mute()
246 struct device *dev = tas5720->component->dev; in tas5720_fault_check_work()
250 ret = regmap_read(tas5720->regmap, TAS5720_FAULT_REG, &curr_fault); in tas5720_fault_check_work()
265 if ((curr_fault & TAS5720_OCE) && !(tas5720->last_fault & TAS5720_OCE)) in tas5720_fault_check_work()
268 if ((curr_fault & TAS5720_DCE) && !(tas5720->last_fault & TAS5720_DCE)) in tas5720_fault_check_work()
271 if ((curr_fault & TAS5720_OTE) && !(tas5720->last_fault & TAS5720_OTE)) in tas5720_fault_check_work()
275 tas5720->last_fault = curr_fault; in tas5720_fault_check_work()
281 * Periodically toggle SDZ (shutdown bit) H->L->H to clear any latching in tas5720_fault_check_work()
286 ret = regmap_write_bits(tas5720->regmap, TAS5720_POWER_CTRL_REG, in tas5720_fault_check_work()
291 ret = regmap_write_bits(tas5720->regmap, TAS5720_POWER_CTRL_REG, in tas5720_fault_check_work()
298 schedule_delayed_work(&tas5720->fault_check_work, in tas5720_fault_check_work()
308 tas5720->component = component; in tas5720_codec_probe()
310 ret = regulator_bulk_enable(ARRAY_SIZE(tas5720->supplies), in tas5720_codec_probe()
311 tas5720->supplies); in tas5720_codec_probe()
313 dev_err(component->dev, "failed to enable supplies: %d\n", ret); in tas5720_codec_probe()
322 ret = regmap_read(tas5720->regmap, TAS5720_DEVICE_ID_REG, &device_id); in tas5720_codec_probe()
324 dev_err(component->dev, "failed to read device ID register: %d\n", in tas5720_codec_probe()
329 switch (tas5720->devtype) { in tas5720_codec_probe()
340 dev_err(component->dev, "unexpected private driver data\n"); in tas5720_codec_probe()
341 ret = -EINVAL; in tas5720_codec_probe()
346 dev_warn(component->dev, "wrong device ID. expected: %u read: %u\n", in tas5720_codec_probe()
355 switch (tas5720->devtype) { in tas5720_codec_probe()
368 * Enter shutdown mode - our default when not playing audio - to in tas5720_codec_probe()
378 INIT_DELAYED_WORK(&tas5720->fault_check_work, tas5720_fault_check_work); in tas5720_codec_probe()
383 dev_err(component->dev, "error configuring device registers: %d\n", ret); in tas5720_codec_probe()
386 regulator_bulk_disable(ARRAY_SIZE(tas5720->supplies), in tas5720_codec_probe()
387 tas5720->supplies); in tas5720_codec_probe()
396 cancel_delayed_work_sync(&tas5720->fault_check_work); in tas5720_codec_remove()
398 ret = regulator_bulk_disable(ARRAY_SIZE(tas5720->supplies), in tas5720_codec_remove()
399 tas5720->supplies); in tas5720_codec_remove()
401 dev_err(component->dev, "failed to disable supplies: %d\n", ret); in tas5720_codec_remove()
407 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in tas5720_dac_event()
416 dev_err(component->dev, "error waking component: %d\n", ret); in tas5720_dac_event()
421 * Observe codec shutdown-to-active time. The datasheet only in tas5720_dac_event()
422 * lists a nominal value however just use-it as-is without in tas5720_dac_event()
424 * starting to play audio (actually there is other setup done in tas5720_dac_event()
431 tas5720->last_fault = 0; in tas5720_dac_event()
432 schedule_delayed_work(&tas5720->fault_check_work, in tas5720_dac_event()
436 cancel_delayed_work_sync(&tas5720->fault_check_work); in tas5720_dac_event()
442 dev_err(component->dev, "error shutting down component: %d\n", in tas5720_dac_event()
457 regcache_cache_only(tas5720->regmap, true); in tas5720_suspend()
458 regcache_mark_dirty(tas5720->regmap); in tas5720_suspend()
460 ret = regulator_bulk_disable(ARRAY_SIZE(tas5720->supplies), in tas5720_suspend()
461 tas5720->supplies); in tas5720_suspend()
463 dev_err(component->dev, "failed to disable supplies: %d\n", ret); in tas5720_suspend()
473 ret = regulator_bulk_enable(ARRAY_SIZE(tas5720->supplies), in tas5720_resume()
474 tas5720->supplies); in tas5720_resume()
476 dev_err(component->dev, "failed to enable supplies: %d\n", ret); in tas5720_resume()
480 regcache_cache_only(tas5720->regmap, false); in tas5720_resume()
482 ret = regcache_sync(tas5720->regmap); in tas5720_resume()
484 dev_err(component->dev, "failed to sync regcache: %d\n", ret); in tas5720_resume()
534 * DAC analog gain. There are four discrete values to select from, ranging
535 * from 19.2 dB to 26.3dB.
545 * DAC analog gain for TAS5720A-Q1. There are three discrete values to select from, ranging
546 * from 19.2 dB to 25.0dB.
555 * DAC digital volumes. From -103.5 to 24 dB in 0.5 dB or 0.25 dB steps
556 * depending on the device. Note that setting the gain below -100 dB
562 static DECLARE_TLV_DB_SCALE(tas5720_dac_tlv, -10350, 50, 0);
563 static DECLARE_TLV_DB_SCALE(tas5722_dac_tlv, -10350, 25, 0);
572 ucontrol->value.integer.value[0] = val << 1; in tas5722_volume_get()
575 ucontrol->value.integer.value[0] |= val & TAS5722_VOL_CONTROL_LSB; in tas5722_volume_get()
584 unsigned int sel = ucontrol->value.integer.value[0]; in tas5722_volume_set()
596 SOC_SINGLE_TLV("Speaker Driver Analog Gain", TAS5720_ANALOG_CTRL_REG,
605 SOC_SINGLE_TLV("Speaker Driver Analog Gain", TAS5720_ANALOG_CTRL_REG,
614 SOC_SINGLE_TLV("Speaker Driver Analog Gain", TAS5720_ANALOG_CTRL_REG,
707 .name = "tas5720-amplifier",
721 { "tas5720a-q1", TAS5720A_Q1 },
729 struct device *dev = &client->dev; in tas5720_probe()
738 return -ENOMEM; in tas5720_probe()
741 data->tas5720_client = client; in tas5720_probe()
742 data->devtype = id->driver_data; in tas5720_probe()
744 switch (id->driver_data) { in tas5720_probe()
756 return -EINVAL; in tas5720_probe()
758 data->regmap = devm_regmap_init_i2c(client, regmap_config); in tas5720_probe()
759 if (IS_ERR(data->regmap)) { in tas5720_probe()
760 ret = PTR_ERR(data->regmap); in tas5720_probe()
765 for (i = 0; i < ARRAY_SIZE(data->supplies); i++) in tas5720_probe()
766 data->supplies[i].supply = tas5720_supply_names[i]; in tas5720_probe()
768 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->supplies), in tas5720_probe()
769 data->supplies); in tas5720_probe()
777 switch (id->driver_data) { in tas5720_probe()
779 ret = devm_snd_soc_register_component(&client->dev, in tas5720_probe()
785 ret = devm_snd_soc_register_component(&client->dev, in tas5720_probe()
791 ret = devm_snd_soc_register_component(&client->dev, in tas5720_probe()
798 return -EINVAL; in tas5720_probe()
811 { .compatible = "ti,tas5720a-q1", },
830 MODULE_DESCRIPTION("TAS5720 Audio amplifier driver");