mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
ASoC: codecs: Add tda7803 amplifier driver support
Add driver to support TDA7803 amplifier devices. Change-Id: Iceb83a801d7a9f4a7faa7b7617be63f93c57be76 Signed-off-by: Jun Zeng <jun.zeng@rock-chips.com>
This commit is contained in:
@@ -216,6 +216,7 @@ config SND_SOC_ALL_CODECS
|
||||
imply SND_SOC_TAS5720
|
||||
imply SND_SOC_TAS6424
|
||||
imply SND_SOC_TDA7419
|
||||
imply SND_SOC_TDA7803
|
||||
imply SND_SOC_TFA9879
|
||||
imply SND_SOC_TLV320ADCX140
|
||||
imply SND_SOC_TLV320AIC23_I2C
|
||||
@@ -1442,6 +1443,11 @@ config SND_SOC_TDA7419
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
|
||||
config SND_SOC_TDA7803
|
||||
tristate "ST TDA7803 audio processor"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
|
||||
config SND_SOC_TFA9879
|
||||
tristate "NXP Semiconductors TFA9879 amplifier"
|
||||
depends on I2C
|
||||
|
||||
@@ -232,6 +232,7 @@ snd-soc-tas571x-objs := tas571x.o
|
||||
snd-soc-tas5720-objs := tas5720.o
|
||||
snd-soc-tas6424-objs := tas6424.o
|
||||
snd-soc-tda7419-objs := tda7419.o
|
||||
snd-soc-tda7803-objs := tda7803.o
|
||||
snd-soc-tas2770-objs := tas2770.o
|
||||
snd-soc-tfa9879-objs := tfa9879.o
|
||||
snd-soc-tlv320aic23-objs := tlv320aic23.o
|
||||
@@ -560,6 +561,7 @@ obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o
|
||||
obj-$(CONFIG_SND_SOC_TAS5720) += snd-soc-tas5720.o
|
||||
obj-$(CONFIG_SND_SOC_TAS6424) += snd-soc-tas6424.o
|
||||
obj-$(CONFIG_SND_SOC_TDA7419) += snd-soc-tda7419.o
|
||||
obj-$(CONFIG_SND_SOC_TDA7803) += snd-soc-tda7803.o
|
||||
obj-$(CONFIG_SND_SOC_TAS2770) += snd-soc-tas2770.o
|
||||
obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
|
||||
|
||||
171
sound/soc/codecs/tda7803.c
Normal file
171
sound/soc/codecs/tda7803.c
Normal file
@@ -0,0 +1,171 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/control.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include "tda7803.h"
|
||||
|
||||
#define TDA7803_SAMPLE_RATE \
|
||||
(SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
|
||||
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000)
|
||||
|
||||
struct tda7803_priv {
|
||||
struct regmap *regmap;
|
||||
u32 input_format;
|
||||
};
|
||||
|
||||
static int tda7803_startup(struct snd_pcm_substream *substream,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
struct tda7803_priv *tda7803 = snd_soc_component_get_drvdata(component);
|
||||
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
||||
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
|
||||
int val = 0;
|
||||
|
||||
snd_soc_component_write(component, TDA7803_REG2, DIGITAL_MUTE_OFF |
|
||||
CH2_4_UMUTE | CH1_3_UMUTE |
|
||||
MUTE_TIME_SETTING_1_45MS);
|
||||
snd_soc_component_write(component, TDA7803_REG7, AMPLIEFIR_SWITCH_ON);
|
||||
|
||||
switch (tda7803->input_format) {
|
||||
case 0:
|
||||
val = INPUT_FORMAT_TDM_8CH_MODEL1;
|
||||
break;
|
||||
case 1:
|
||||
val = INPUT_FORMAT_TDM_8CH_MODEL2;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
snd_soc_dai_set_fmt(codec_dai, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tda7803_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
int val = 0;
|
||||
|
||||
switch (params_rate(params)) {
|
||||
case 44100:
|
||||
val = SAMPLE_FREQUENCY_RANGE_44100HZ;
|
||||
break;
|
||||
case 48000:
|
||||
val = SAMPLE_FREQUENCY_RANGE_48000HZ;
|
||||
break;
|
||||
case 96000:
|
||||
val = SAMPLE_FREQUENCY_RANGE_96000HZ;
|
||||
break;
|
||||
case 192000:
|
||||
val = SAMPLE_FREQUENCY_RANGE_192000HZ;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
snd_soc_component_write(component, TDA7803_REG3, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tda7803_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
{
|
||||
struct snd_soc_component *component = dai->component;
|
||||
|
||||
snd_soc_component_write(component, TDA7803_REG3, fmt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dai_ops tda7803_ops = {
|
||||
.startup = tda7803_startup,
|
||||
.hw_params = tda7803_hw_params,
|
||||
.set_fmt = tda7803_set_fmt,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver tda7803_dai = {
|
||||
.name = "tda7803-hifi",
|
||||
.playback = {
|
||||
.stream_name = "Playback",
|
||||
.channels_min = 2,
|
||||
.channels_max = 8,
|
||||
.rates = TDA7803_SAMPLE_RATE,
|
||||
.formats = SNDRV_PCM_FMTBIT_S32_LE |
|
||||
SNDRV_PCM_FMTBIT_S24_LE |
|
||||
SNDRV_PCM_FMTBIT_S16_LE,
|
||||
},
|
||||
.ops = &tda7803_ops,
|
||||
};
|
||||
|
||||
static const struct snd_soc_component_driver soc_codec_dev_tda7803 = {
|
||||
.name = "tda7803",
|
||||
};
|
||||
|
||||
static const struct regmap_config tda7803_i2c_regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = TDA7803_REGMAX,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static int tda7803_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct tda7803_priv *tda7803;
|
||||
int val;
|
||||
|
||||
tda7803 = devm_kzalloc(&i2c->dev, sizeof(*tda7803), GFP_KERNEL);
|
||||
if (!tda7803)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(i2c, tda7803);
|
||||
|
||||
tda7803->regmap = devm_regmap_init_i2c(i2c, &tda7803_i2c_regmap);
|
||||
if (IS_ERR(tda7803->regmap))
|
||||
return PTR_ERR(tda7803->regmap);
|
||||
|
||||
if (!device_property_read_u32(&i2c->dev, "st,tda7803-format", &val))
|
||||
tda7803->input_format = val;
|
||||
|
||||
return devm_snd_soc_register_component(&i2c->dev,
|
||||
&soc_codec_dev_tda7803,
|
||||
&tda7803_dai, 1);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id tda7803_i2c_id[] = {
|
||||
{ "tda7803", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, tda7803_i2c_id);
|
||||
|
||||
static const struct of_device_id tda7803_of_match[] = {
|
||||
{ .compatible = "st,tda7803" },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct i2c_driver tda7803_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "tda7803",
|
||||
.of_match_table = of_match_ptr(tda7803_of_match),
|
||||
},
|
||||
.probe = tda7803_i2c_probe,
|
||||
.id_table = tda7803_i2c_id,
|
||||
};
|
||||
module_i2c_driver(tda7803_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("Jun Zeng <jun.zeng@rock-chips.com>");
|
||||
MODULE_DESCRIPTION("TDA7803 audio processor driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
138
sound/soc/codecs/tda7803.h
Normal file
138
sound/soc/codecs/tda7803.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __TDA7803_H__
|
||||
#define __TDA7803_H__
|
||||
|
||||
/* tda7803 registers space*/
|
||||
#define TDA7803_REG0 (0x00)
|
||||
#define CH1_AMP_SBI_MODE (0x00 << 0)
|
||||
#define CH1_AMP_ABI_MODE (0x01 << 0)
|
||||
#define CH2_AMP_SBI_MODE (0x00 << 1)
|
||||
#define CH2_AMP_ABI_MODE (0x01 << 1)
|
||||
#define CH3_AMP_SBI_MODE (0x00 << 2)
|
||||
#define CH3_AMP_ABI_MODE (0x01 << 2)
|
||||
#define CH4_AMP_SBI_MODE (0x00 << 3)
|
||||
#define CH4_AMP_ABI_MODE (0x01 << 3)
|
||||
#define CH1_TRI_MODE_OFF (0x00 << 4)
|
||||
#define CH1_TRI_MODE_ON (0x01 << 4)
|
||||
#define CH2_TRI_MODE_OFF (0x00 << 5)
|
||||
#define CH2_TRI_MODE_ON (0x01 << 5)
|
||||
#define CH3_TRI_MODE_OFF (0x00 << 6)
|
||||
#define CH3_TRI_MODE_ON (0x01 << 6)
|
||||
#define CH4_TRI_MODE_OFF (0x00 << 7)
|
||||
#define CH4_TRI_MODE_ON (0x01 << 7)
|
||||
|
||||
#define TDA7803_REG1 (0x01)
|
||||
#define CH2_4_GAIN_GV1 (0x00 << 0)
|
||||
#define CH2_4_GAIN_GV2 (0x01 << 0)
|
||||
#define CH2_4_GAIN_GV3 (0x02 << 0)
|
||||
#define CH2_4_GAIN_GV4 (0x03 << 0)
|
||||
#define CH1_3_GAIN_GV1 (0x00 << 2)
|
||||
#define CH1_3_GAIN_GV2 (0x01 << 2)
|
||||
#define CH1_3_GAIN_GV3 (0x02 << 2)
|
||||
#define CH1_3_GAIN_GV4 (0x03 << 2)
|
||||
#define GAIN_SELECT_NO (0x00 << 4)
|
||||
#define GAIN_SELECT_6DB (0x01 << 4)
|
||||
#define GAIN_SELECT_12DB (0x02 << 4)
|
||||
#define GAIN_SELECT_NOT_USED (0x03 << 4)
|
||||
#define IMPEDANCE_OPTIMIZER_REAR_2OHM (0x00 << 6)
|
||||
#define IMPEDANCE_OPTIMIZER_REAR_4OHM (0x01 << 6)
|
||||
#define IMPEDANCE_OPTIMIZER_FRONT_2OHM (0x00 << 7)
|
||||
#define IMPEDANCE_OPTIMIZER_FRONT_4OHM (0x01 << 7)
|
||||
|
||||
#define TDA7803_REG2 (0x02)
|
||||
#define LOW_BATTERY_MUTE_THRESHOLD_1 (0x00 << 0)
|
||||
#define LOW_BATTERY_MUTE_THRESHOLD_2 (0x01 << 0)
|
||||
#define DIGITAL_MUTE_ON (0x00 << 2)
|
||||
#define DIGITAL_MUTE_OFF (0x01 << 2)
|
||||
#define CH2_4_MUTE (0x00 << 3)
|
||||
#define CH2_4_UMUTE (0x01 << 3)
|
||||
#define CH1_3_MUTE (0x00 << 4)
|
||||
#define CH1_3_UMUTE (0x01 << 4)
|
||||
#define MUTE_TIME_SETTING_1_45MS (0x00 << 5)
|
||||
#define MUTE_TIME_SETTING_5_8MS (0x01 << 5)
|
||||
#define MUTE_TIME_SETTING_11_6MS (0x02 << 5)
|
||||
#define MUTE_TIME_SETTING_23_2MS (0x03 << 5)
|
||||
#define MUTE_TIME_SETTING_46_4MS (0x04 << 5)
|
||||
#define MUTE_TIME_SETTING_92_8MS (0x05 << 5)
|
||||
#define MUTE_TIME_SETTING_185_5MS (0x06 << 5)
|
||||
#define MUTE_TIME_SETTING_371_1MS (0x07 << 5)
|
||||
|
||||
#define TDA7803_REG3 (0x03)
|
||||
#define HIGH_PASS_FILTER_DISABLE (0x00 << 0)
|
||||
#define HIGH_PASS_FILTER_ENABLE (0x01 << 0)
|
||||
#define INPUT_OFFSET_DETECTION_DIS (0x00 << 1)
|
||||
#define INPUT_OFFSET_DETECTION_EN (0x01 << 1)
|
||||
#define NOISE_GATING_FUNCTION_EN (0x00 << 2)
|
||||
#define NOISE_GATING_FUNCTION_DIS (0x01 << 2)
|
||||
#define INPUT_FORMAT_I2S_STD (0x00 << 3)
|
||||
#define INPUT_FORMAT_TDM_4CH (0x01 << 3)
|
||||
#define INPUT_FORMAT_TDM_8CH_MODEL1 (0x02 << 3)
|
||||
#define INPUT_FORMAT_TDM_8CH_MODEL2 (0x03 << 3)
|
||||
#define INPUT_FORMAT_TDM_16CH_MODEL1 (0x04 << 3)
|
||||
#define INPUT_FORMAT_TDM_16CH_MODEL2 (0x05 << 3)
|
||||
#define INPUT_FORMAT_TDM_16CH_MODEL3 (0x06 << 3)
|
||||
#define INPUT_FORMAT_TDM_16CH_MODEL4 (0x07 << 3)
|
||||
#define SAMPLE_FREQUENCY_RANGE_44100HZ (0x00 << 6)
|
||||
#define SAMPLE_FREQUENCY_RANGE_48000HZ (0x01 << 6)
|
||||
#define SAMPLE_FREQUENCY_RANGE_96000HZ (0x02 << 6)
|
||||
#define SAMPLE_FREQUENCY_RANGE_192000HZ (0x03 << 6)
|
||||
|
||||
#define TDA7803_REG4 (0x04)
|
||||
#define DIAGNOSTIC_MODE_DISABLE (0x00 << 0)
|
||||
#define DIAGNOSTIC_MODE_ENABLE (0x01 << 0)
|
||||
#define CH2_4_SPEAKER_MODE (0x00 << 1)
|
||||
#define CH2_4_LINE_DRIVER_MODE (0x01 << 1)
|
||||
#define CH1_3_SPEAKER_MODE (0x00 << 2)
|
||||
#define CH1_3_LINE_DRIVER_MODE (0x01 << 2)
|
||||
#define DIAGNOSTIC_DISABLE (0X00 << 3)
|
||||
#define DIAGNOSTIC_ENABLE (0X01 << 3)
|
||||
#define DIAGNOSTIC_CURRENT_THRESHOLD_HIGH (0X00 << 4)
|
||||
#define DIAGNOSTIC_CURRENT_THRESHOLD_LOW (0X01 << 4)
|
||||
#define OFFSET_INFORMATION_YES (0X00 << 5)
|
||||
#define OFFSET_INFORMATION_NO (0X01 << 5)
|
||||
#define SHORT_FAULT_INFORMATION_YES (0X00 << 6)
|
||||
#define SHORT_FAULT_INFORMATION_NO (0X01 << 6)
|
||||
|
||||
#define TDA7803_REG5 (0x05)
|
||||
#define CAPABILITY_ENHANCER_DISABLE (0x00 << 1)
|
||||
#define CAPABILITY_ENHANCER_ENABLE (0x0F << 1)
|
||||
#define THERMAL_THRESHOLD_DEFAULT (0x00 << 6)
|
||||
#define THERMAL_THRESHOLD_TW_NEGATIVE_10 (0x01 << 6)
|
||||
#define THERMAL_THRESHOLD_TW_NEGATIVE_20 (0x02 << 6)
|
||||
|
||||
#define TDA7803_REG6 (0x06)
|
||||
#define PARALLEL_MODE_CONFIG_MODE_1 (0x00 << 2)
|
||||
#define PARALLEL_MODE_CONFIG_MODE_2 (0x01 << 2)
|
||||
#define PARALLEL_MODE_CONFIG_MODE_3 (0x02 << 2)
|
||||
#define PARALLEL_MODE_CONFIG_MODE_4 (0x03 << 2)
|
||||
#define DIAGNOSITC_PULSE_STRETCH_MODE_1 (0x00 << 5)
|
||||
#define DIAGNOSITC_PULSE_STRETCH_MODE_2 (0x01 << 5)
|
||||
#define DIAGNOSITC_PULSE_STRETCH_MODE_3 (0x02 << 5)
|
||||
#define DIAGNOSITC_PULSE_STRETCH_MODE_4 (0x03 << 5)
|
||||
#define DIAGNOSITC_PULSE_STRETCH_MODE_5 (0x04 << 5)
|
||||
#define DIAGNOSITC_PULSE_STRETCH_DEFAULT (0x05 << 5)
|
||||
|
||||
#define TDA7803_REG7 (0x07)
|
||||
#define AMPLIEFIR_SWITCH_OFF (0x00 << 0)
|
||||
#define AMPLIEFIR_SWITCH_ON (0x01 << 0)
|
||||
#define CLIPP_LEVEL_1_REAR_CHANNELS2_4 (0x00 << 1)
|
||||
#define CLIPP_LEVEL_2_REAR_CHANNELS2_4 (0x01 << 1)
|
||||
#define CLIPP_LEVEL_3_REAR_CHANNELS2_4 (0x02 << 1)
|
||||
#define NOT_CLIPP_FOR_REAR_CHANNELS2_4 (0x03 << 1)
|
||||
#define CLIPP_LEVEL_1_REAR_CHANNELS1_3 (0x00 << 3)
|
||||
#define CLIPP_LEVEL_2_REAR_CHANNELS1_3 (0x01 << 3)
|
||||
#define CLIPP_LEVEL_3_REAR_CHANNELS1_3 (0x02 << 3)
|
||||
#define NOT_CLIPP_FOR_REAR_CHANNELS1_3 (0x03 << 3)
|
||||
#define TEMPERATURE_WARNING_TW1 (0x00 << 5)
|
||||
#define TEMPERATURE_WARNING_TW2 (0x01 << 5)
|
||||
#define TEMPERATURE_WARNING_TW3 (0x02 << 5)
|
||||
#define TEMPERATURE_WARNING_TW4 (0x03 << 5)
|
||||
#define NOT_TEMPERATURE_WARNING (0x04 << 5)
|
||||
|
||||
#define TDA7803_REGMAX (0x08)
|
||||
#endif /* __TDA7803_H__ */
|
||||
Reference in New Issue
Block a user