ASoC: ak5558: Add support for ak5552
AK5552 is a 32-bit 2ch ADC and has the same register map as AK5558. Signed-off-by: Viorel Suman <viorel.suman@nxp.com> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com> Link: https://lore.kernel.org/r/1617176686-25528-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
875c40eadf
commit
d8c5c82e4e
1 changed files with 90 additions and 7 deletions
|
@ -9,6 +9,7 @@
|
||||||
#include <linux/gpio/consumer.h>
|
#include <linux/gpio/consumer.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/of_device.h>
|
||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
|
@ -23,6 +24,11 @@
|
||||||
|
|
||||||
#include "ak5558.h"
|
#include "ak5558.h"
|
||||||
|
|
||||||
|
enum ak555x_type {
|
||||||
|
AK5558,
|
||||||
|
AK5552,
|
||||||
|
};
|
||||||
|
|
||||||
#define AK5558_NUM_SUPPLIES 2
|
#define AK5558_NUM_SUPPLIES 2
|
||||||
static const char *ak5558_supply_names[AK5558_NUM_SUPPLIES] = {
|
static const char *ak5558_supply_names[AK5558_NUM_SUPPLIES] = {
|
||||||
"DVDD",
|
"DVDD",
|
||||||
|
@ -59,6 +65,15 @@ static const struct soc_enum ak5558_mono_enum[] = {
|
||||||
ARRAY_SIZE(mono_texts), mono_texts),
|
ARRAY_SIZE(mono_texts), mono_texts),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char * const mono_5552_texts[] = {
|
||||||
|
"2 Slot", "1 Slot (Fixed)", "2 Slot", "1 Slot (Optimal)",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct soc_enum ak5552_mono_enum[] = {
|
||||||
|
SOC_ENUM_SINGLE(AK5558_01_POWER_MANAGEMENT2, 1,
|
||||||
|
ARRAY_SIZE(mono_5552_texts), mono_5552_texts),
|
||||||
|
};
|
||||||
|
|
||||||
static const char * const digfil_texts[] = {
|
static const char * const digfil_texts[] = {
|
||||||
"Sharp Roll-Off", "Show Roll-Off",
|
"Sharp Roll-Off", "Show Roll-Off",
|
||||||
"Short Delay Sharp Roll-Off", "Short Delay Show Roll-Off",
|
"Short Delay Sharp Roll-Off", "Short Delay Show Roll-Off",
|
||||||
|
@ -70,8 +85,13 @@ static const struct soc_enum ak5558_adcset_enum[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_kcontrol_new ak5558_snd_controls[] = {
|
static const struct snd_kcontrol_new ak5558_snd_controls[] = {
|
||||||
SOC_ENUM("AK5558 Monaural Mode", ak5558_mono_enum[0]),
|
SOC_ENUM("Monaural Mode", ak5558_mono_enum[0]),
|
||||||
SOC_ENUM("AK5558 Digital Filter", ak5558_adcset_enum[0]),
|
SOC_ENUM("Digital Filter", ak5558_adcset_enum[0]),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snd_kcontrol_new ak5552_snd_controls[] = {
|
||||||
|
SOC_ENUM("Monaural Mode", ak5552_mono_enum[0]),
|
||||||
|
SOC_ENUM("Digital Filter", ak5558_adcset_enum[0]),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct snd_soc_dapm_widget ak5558_dapm_widgets[] = {
|
static const struct snd_soc_dapm_widget ak5558_dapm_widgets[] = {
|
||||||
|
@ -97,6 +117,17 @@ static const struct snd_soc_dapm_widget ak5558_dapm_widgets[] = {
|
||||||
SND_SOC_DAPM_AIF_OUT("SDTO", "Capture", 0, SND_SOC_NOPM, 0, 0),
|
SND_SOC_DAPM_AIF_OUT("SDTO", "Capture", 0, SND_SOC_NOPM, 0, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct snd_soc_dapm_widget ak5552_dapm_widgets[] = {
|
||||||
|
/* Analog Input */
|
||||||
|
SND_SOC_DAPM_INPUT("AIN1"),
|
||||||
|
SND_SOC_DAPM_INPUT("AIN2"),
|
||||||
|
|
||||||
|
SND_SOC_DAPM_ADC("ADC Ch1", NULL, AK5558_00_POWER_MANAGEMENT1, 0, 0),
|
||||||
|
SND_SOC_DAPM_ADC("ADC Ch2", NULL, AK5558_00_POWER_MANAGEMENT1, 1, 0),
|
||||||
|
|
||||||
|
SND_SOC_DAPM_AIF_OUT("SDTO", "Capture", 0, SND_SOC_NOPM, 0, 0),
|
||||||
|
};
|
||||||
|
|
||||||
static const struct snd_soc_dapm_route ak5558_intercon[] = {
|
static const struct snd_soc_dapm_route ak5558_intercon[] = {
|
||||||
{"ADC Ch1", NULL, "AIN1"},
|
{"ADC Ch1", NULL, "AIN1"},
|
||||||
{"SDTO", NULL, "ADC Ch1"},
|
{"SDTO", NULL, "ADC Ch1"},
|
||||||
|
@ -123,6 +154,14 @@ static const struct snd_soc_dapm_route ak5558_intercon[] = {
|
||||||
{"SDTO", NULL, "ADC Ch8"},
|
{"SDTO", NULL, "ADC Ch8"},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct snd_soc_dapm_route ak5552_intercon[] = {
|
||||||
|
{"ADC Ch1", NULL, "AIN1"},
|
||||||
|
{"SDTO", NULL, "ADC Ch1"},
|
||||||
|
|
||||||
|
{"ADC Ch2", NULL, "AIN2"},
|
||||||
|
{"SDTO", NULL, "ADC Ch2"},
|
||||||
|
};
|
||||||
|
|
||||||
static int ak5558_set_mcki(struct snd_soc_component *component)
|
static int ak5558_set_mcki(struct snd_soc_component *component)
|
||||||
{
|
{
|
||||||
return snd_soc_component_update_bits(component, AK5558_02_CONTROL1, AK5558_CKS,
|
return snd_soc_component_update_bits(component, AK5558_02_CONTROL1, AK5558_CKS,
|
||||||
|
@ -267,6 +306,18 @@ static struct snd_soc_dai_driver ak5558_dai = {
|
||||||
.ops = &ak5558_dai_ops,
|
.ops = &ak5558_dai_ops,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct snd_soc_dai_driver ak5552_dai = {
|
||||||
|
.name = "ak5558-aif",
|
||||||
|
.capture = {
|
||||||
|
.stream_name = "Capture",
|
||||||
|
.channels_min = 1,
|
||||||
|
.channels_max = 2,
|
||||||
|
.rates = SNDRV_PCM_RATE_KNOT,
|
||||||
|
.formats = AK5558_FORMATS,
|
||||||
|
},
|
||||||
|
.ops = &ak5558_dai_ops,
|
||||||
|
};
|
||||||
|
|
||||||
static void ak5558_power_off(struct ak5558_priv *ak5558)
|
static void ak5558_power_off(struct ak5558_priv *ak5558)
|
||||||
{
|
{
|
||||||
if (!ak5558->reset_gpiod)
|
if (!ak5558->reset_gpiod)
|
||||||
|
@ -354,6 +405,21 @@ static const struct snd_soc_component_driver soc_codec_dev_ak5558 = {
|
||||||
.non_legacy_dai_naming = 1,
|
.non_legacy_dai_naming = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct snd_soc_component_driver soc_codec_dev_ak5552 = {
|
||||||
|
.probe = ak5558_probe,
|
||||||
|
.remove = ak5558_remove,
|
||||||
|
.controls = ak5552_snd_controls,
|
||||||
|
.num_controls = ARRAY_SIZE(ak5552_snd_controls),
|
||||||
|
.dapm_widgets = ak5552_dapm_widgets,
|
||||||
|
.num_dapm_widgets = ARRAY_SIZE(ak5552_dapm_widgets),
|
||||||
|
.dapm_routes = ak5552_intercon,
|
||||||
|
.num_dapm_routes = ARRAY_SIZE(ak5552_intercon),
|
||||||
|
.idle_bias_on = 1,
|
||||||
|
.use_pmdown_time = 1,
|
||||||
|
.endianness = 1,
|
||||||
|
.non_legacy_dai_naming = 1,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct regmap_config ak5558_regmap = {
|
static const struct regmap_config ak5558_regmap = {
|
||||||
.reg_bits = 8,
|
.reg_bits = 8,
|
||||||
.val_bits = 8,
|
.val_bits = 8,
|
||||||
|
@ -368,6 +434,7 @@ static int ak5558_i2c_probe(struct i2c_client *i2c)
|
||||||
{
|
{
|
||||||
struct ak5558_priv *ak5558;
|
struct ak5558_priv *ak5558;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
int dev_id;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ak5558 = devm_kzalloc(&i2c->dev, sizeof(*ak5558), GFP_KERNEL);
|
ak5558 = devm_kzalloc(&i2c->dev, sizeof(*ak5558), GFP_KERNEL);
|
||||||
|
@ -396,11 +463,26 @@ static int ak5558_i2c_probe(struct i2c_client *i2c)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = devm_snd_soc_register_component(&i2c->dev,
|
dev_id = (uintptr_t)of_device_get_match_data(&i2c->dev);
|
||||||
&soc_codec_dev_ak5558,
|
switch (dev_id) {
|
||||||
&ak5558_dai, 1);
|
case AK5552:
|
||||||
if (ret)
|
ret = devm_snd_soc_register_component(&i2c->dev,
|
||||||
|
&soc_codec_dev_ak5552,
|
||||||
|
&ak5552_dai, 1);
|
||||||
|
break;
|
||||||
|
case AK5558:
|
||||||
|
ret = devm_snd_soc_register_component(&i2c->dev,
|
||||||
|
&soc_codec_dev_ak5558,
|
||||||
|
&ak5558_dai, 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_err(&i2c->dev, "unexpected device type\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (ret < 0) {
|
||||||
|
dev_err(&i2c->dev, "failed to register component: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
pm_runtime_enable(&i2c->dev);
|
pm_runtime_enable(&i2c->dev);
|
||||||
regcache_cache_only(ak5558->regmap, true);
|
regcache_cache_only(ak5558->regmap, true);
|
||||||
|
@ -416,7 +498,8 @@ static int ak5558_i2c_remove(struct i2c_client *i2c)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id ak5558_i2c_dt_ids[] __maybe_unused = {
|
static const struct of_device_id ak5558_i2c_dt_ids[] __maybe_unused = {
|
||||||
{ .compatible = "asahi-kasei,ak5558"},
|
{ .compatible = "asahi-kasei,ak5558", .data = (void *) AK5558 },
|
||||||
|
{ .compatible = "asahi-kasei,ak5552", .data = (void *) AK5552 },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, ak5558_i2c_dt_ids);
|
MODULE_DEVICE_TABLE(of, ak5558_i2c_dt_ids);
|
||||||
|
|
Loading…
Add table
Reference in a new issue