adau1977
static int adau1977_reset(struct adau1977 *adau1977)
regcache_cache_bypass(adau1977->regmap, true);
ret = regmap_write(adau1977->regmap, ADAU1977_REG_POWER,
regcache_cache_bypass(adau1977->regmap, false);
static int adau1977_lookup_mcs(struct adau1977 *adau1977, unsigned int rate,
if (adau1977->sysclk % rate != 0)
mcs = adau1977->sysclk / rate;
struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
if (adau1977->sysclk_src == ADAU1977_SYSCLK_SRC_MCLK) {
mcs = adau1977_lookup_mcs(adau1977, rate, fs);
if (adau1977->right_j) {
if (adau1977->clock_provider) {
if (adau1977->slot_width)
slot_width = adau1977->slot_width;
ret = regmap_update_bits(adau1977->regmap,
ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0,
return regmap_update_bits(adau1977->regmap, ADAU1977_REG_PLL,
static int adau1977_power_disable(struct adau1977 *adau1977)
if (!adau1977->enabled)
ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER,
regcache_mark_dirty(adau1977->regmap);
gpiod_set_value_cansleep(adau1977->reset_gpio, 0);
regcache_cache_only(adau1977->regmap, true);
regulator_disable(adau1977->avdd_reg);
if (adau1977->dvdd_reg)
regulator_disable(adau1977->dvdd_reg);
adau1977->enabled = false;
static int adau1977_power_enable(struct adau1977 *adau1977)
if (adau1977->enabled)
ret = regulator_enable(adau1977->avdd_reg);
if (adau1977->dvdd_reg) {
ret = regulator_enable(adau1977->dvdd_reg);
gpiod_set_value_cansleep(adau1977->reset_gpio, 1);
regcache_cache_only(adau1977->regmap, false);
if (adau1977->switch_mode)
adau1977->switch_mode(adau1977->dev);
ret = adau1977_reset(adau1977);
ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER,
ret = regcache_sync(adau1977->regmap);
ret = regmap_read(adau1977->regmap, ADAU1977_REG_PLL, &val);
regcache_cache_bypass(adau1977->regmap, true);
ret = regmap_write(adau1977->regmap, ADAU1977_REG_PLL,
regcache_cache_bypass(adau1977->regmap, false);
adau1977->enabled = true;
if (adau1977->dvdd_reg)
regulator_disable(adau1977->dvdd_reg);
regulator_disable(adau1977->avdd_reg);
struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
ret = adau1977_power_enable(adau1977);
ret = adau1977_power_disable(adau1977);
struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
adau1977->slot_width = 0;
adau1977->max_clock_provider_fs = 192000;
return regmap_update_bits(adau1977->regmap,
if (adau1977->clock_provider)
ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_OVERTEMP,
ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP12,
ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP34,
ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0,
ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1,
adau1977->slot_width = width;
adau1977->max_clock_provider_fs = min(192000, 24576000 / width / slots);
struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
return regmap_update_bits(adau1977->regmap, ADAU1977_REG_MISC_CONTROL,
struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
adau1977->clock_provider = false;
adau1977->clock_provider = true;
adau1977->right_j = false;
adau1977->right_j = true;
ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI,
ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0,
return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1,
struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
if (adau1977->slot_width == 16)
else if (adau1977->right_j || adau1977->slot_width == 24)
SNDRV_PCM_HW_PARAM_RATE, &adau1977->constraints);
if (adau1977->clock_provider)
adau1977->max_clock_provider_fs);
struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);
return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_OVERTEMP,
struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_PLL,
adau1977->constraints.mask = mask;
adau1977->sysclk_src = source;
adau1977->sysclk = freq;
struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);
switch (adau1977->type) {
static int adau1977_setup_micbias(struct adau1977 *adau1977)
if (device_property_read_u32(adau1977->dev, "adi,micbias", &micbias))
dev_err(adau1977->dev, "Invalid value for 'adi,micbias'\n");
return regmap_update_bits(adau1977->regmap, ADAU1977_REG_MICBIAS,
struct adau1977 *adau1977;
adau1977 = devm_kzalloc(dev, sizeof(*adau1977), GFP_KERNEL);
if (adau1977 == NULL)
adau1977->dev = dev;
adau1977->type = type;
adau1977->regmap = regmap;
adau1977->switch_mode = switch_mode;
adau1977->max_clock_provider_fs = 192000;
adau1977->constraints.list = adau1977_rates;
adau1977->constraints.count = ARRAY_SIZE(adau1977_rates);
adau1977->avdd_reg = devm_regulator_get(dev, "AVDD");
if (IS_ERR(adau1977->avdd_reg))
return PTR_ERR(adau1977->avdd_reg);
adau1977->dvdd_reg = devm_regulator_get_optional(dev, "DVDD");
if (IS_ERR(adau1977->dvdd_reg)) {
if (PTR_ERR(adau1977->dvdd_reg) != -ENODEV)
return PTR_ERR(adau1977->dvdd_reg);
adau1977->dvdd_reg = NULL;
adau1977->reset_gpio = devm_gpiod_get_optional(dev, "reset",
if (IS_ERR(adau1977->reset_gpio))
return PTR_ERR(adau1977->reset_gpio);
dev_set_drvdata(dev, adau1977);
if (adau1977->reset_gpio)
ret = adau1977_power_enable(adau1977);
ret = adau1977_setup_micbias(adau1977);
if (adau1977->dvdd_reg)
ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI,
ret = adau1977_power_disable(adau1977);
adau1977_power_disable(adau1977);