1003 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * ADAU1977/ADAU1978/ADAU1979 driver4 *5 * Copyright 2014 Analog Devices Inc.6 * Author: Lars-Peter Clausen <lars@metafoo.de>7 */8 9#include <linux/delay.h>10#include <linux/device.h>11#include <linux/gpio/consumer.h>12#include <linux/i2c.h>13#include <linux/init.h>14#include <linux/module.h>15#include <linux/regmap.h>16#include <linux/regulator/consumer.h>17#include <linux/slab.h>18 19#include <sound/core.h>20#include <sound/initval.h>21#include <sound/pcm.h>22#include <sound/pcm_params.h>23#include <sound/soc.h>24#include <sound/tlv.h>25 26#include <dt-bindings/sound/adi,adau1977.h>27 28#include "adau1977.h"29 30#define ADAU1977_REG_POWER 0x0031#define ADAU1977_REG_PLL 0x0132#define ADAU1977_REG_BOOST 0x0233#define ADAU1977_REG_MICBIAS 0x0334#define ADAU1977_REG_BLOCK_POWER_SAI 0x0435#define ADAU1977_REG_SAI_CTRL0 0x0536#define ADAU1977_REG_SAI_CTRL1 0x0637#define ADAU1977_REG_CMAP12 0x0738#define ADAU1977_REG_CMAP34 0x0839#define ADAU1977_REG_SAI_OVERTEMP 0x0940#define ADAU1977_REG_POST_ADC_GAIN(x) (0x0a + (x))41#define ADAU1977_REG_MISC_CONTROL 0x0e42#define ADAU1977_REG_DIAG_CONTROL 0x1043#define ADAU1977_REG_STATUS(x) (0x11 + (x))44#define ADAU1977_REG_DIAG_IRQ1 0x1545#define ADAU1977_REG_DIAG_IRQ2 0x1646#define ADAU1977_REG_ADJUST1 0x1747#define ADAU1977_REG_ADJUST2 0x1848#define ADAU1977_REG_ADC_CLIP 0x1949#define ADAU1977_REG_DC_HPF_CAL 0x1a50 51#define ADAU1977_POWER_RESET BIT(7)52#define ADAU1977_POWER_PWUP BIT(0)53 54#define ADAU1977_PLL_CLK_S BIT(4)55#define ADAU1977_PLL_MCS_MASK 0x756 57#define ADAU1977_MICBIAS_MB_VOLTS_MASK 0xf058#define ADAU1977_MICBIAS_MB_VOLTS_OFFSET 459 60#define ADAU1977_BLOCK_POWER_SAI_LR_POL BIT(7)61#define ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE BIT(6)62#define ADAU1977_BLOCK_POWER_SAI_LDO_EN BIT(5)63 64#define ADAU1977_SAI_CTRL0_FMT_MASK (0x3 << 6)65#define ADAU1977_SAI_CTRL0_FMT_I2S (0x0 << 6)66#define ADAU1977_SAI_CTRL0_FMT_LJ (0x1 << 6)67#define ADAU1977_SAI_CTRL0_FMT_RJ_24BIT (0x2 << 6)68#define ADAU1977_SAI_CTRL0_FMT_RJ_16BIT (0x3 << 6)69 70#define ADAU1977_SAI_CTRL0_SAI_MASK (0x7 << 3)71#define ADAU1977_SAI_CTRL0_SAI_I2S (0x0 << 3)72#define ADAU1977_SAI_CTRL0_SAI_TDM_2 (0x1 << 3)73#define ADAU1977_SAI_CTRL0_SAI_TDM_4 (0x2 << 3)74#define ADAU1977_SAI_CTRL0_SAI_TDM_8 (0x3 << 3)75#define ADAU1977_SAI_CTRL0_SAI_TDM_16 (0x4 << 3)76 77#define ADAU1977_SAI_CTRL0_FS_MASK (0x7)78#define ADAU1977_SAI_CTRL0_FS_8000_12000 (0x0)79#define ADAU1977_SAI_CTRL0_FS_16000_24000 (0x1)80#define ADAU1977_SAI_CTRL0_FS_32000_48000 (0x2)81#define ADAU1977_SAI_CTRL0_FS_64000_96000 (0x3)82#define ADAU1977_SAI_CTRL0_FS_128000_192000 (0x4)83 84#define ADAU1977_SAI_CTRL1_SLOT_WIDTH_MASK (0x3 << 5)85#define ADAU1977_SAI_CTRL1_SLOT_WIDTH_32 (0x0 << 5)86#define ADAU1977_SAI_CTRL1_SLOT_WIDTH_24 (0x1 << 5)87#define ADAU1977_SAI_CTRL1_SLOT_WIDTH_16 (0x2 << 5)88#define ADAU1977_SAI_CTRL1_DATA_WIDTH_MASK (0x1 << 4)89#define ADAU1977_SAI_CTRL1_DATA_WIDTH_16BIT (0x1 << 4)90#define ADAU1977_SAI_CTRL1_DATA_WIDTH_24BIT (0x0 << 4)91#define ADAU1977_SAI_CTRL1_LRCLK_PULSE BIT(3)92#define ADAU1977_SAI_CTRL1_MSB BIT(2)93#define ADAU1977_SAI_CTRL1_BCLKRATE_16 (0x1 << 1)94#define ADAU1977_SAI_CTRL1_BCLKRATE_32 (0x0 << 1)95#define ADAU1977_SAI_CTRL1_BCLKRATE_MASK (0x1 << 1)96#define ADAU1977_SAI_CTRL1_MASTER BIT(0)97 98#define ADAU1977_SAI_OVERTEMP_DRV_C(x) BIT(4 + (x))99#define ADAU1977_SAI_OVERTEMP_DRV_HIZ BIT(3)100 101#define ADAU1977_MISC_CONTROL_SUM_MODE_MASK (0x3 << 6)102#define ADAU1977_MISC_CONTROL_SUM_MODE_1CH (0x2 << 6)103#define ADAU1977_MISC_CONTROL_SUM_MODE_2CH (0x1 << 6)104#define ADAU1977_MISC_CONTROL_SUM_MODE_4CH (0x0 << 6)105#define ADAU1977_MISC_CONTROL_MMUTE BIT(4)106#define ADAU1977_MISC_CONTROL_DC_CAL BIT(0)107 108#define ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET 4109#define ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET 0110 111struct adau1977 {112 struct regmap *regmap;113 bool right_j;114 unsigned int sysclk;115 enum adau1977_sysclk_src sysclk_src;116 struct gpio_desc *reset_gpio;117 enum adau1977_type type;118 119 struct regulator *avdd_reg;120 struct regulator *dvdd_reg;121 122 struct snd_pcm_hw_constraint_list constraints;123 124 struct device *dev;125 void (*switch_mode)(struct device *dev);126 127 unsigned int max_clock_provider_fs;128 unsigned int slot_width;129 bool enabled;130 bool clock_provider;131};132 133static const struct reg_default adau1977_reg_defaults[] = {134 { 0x00, 0x00 },135 { 0x01, 0x41 },136 { 0x02, 0x4a },137 { 0x03, 0x7d },138 { 0x04, 0x3d },139 { 0x05, 0x02 },140 { 0x06, 0x00 },141 { 0x07, 0x10 },142 { 0x08, 0x32 },143 { 0x09, 0xf0 },144 { 0x0a, 0xa0 },145 { 0x0b, 0xa0 },146 { 0x0c, 0xa0 },147 { 0x0d, 0xa0 },148 { 0x0e, 0x02 },149 { 0x10, 0x0f },150 { 0x15, 0x20 },151 { 0x16, 0x00 },152 { 0x17, 0x00 },153 { 0x18, 0x00 },154 { 0x1a, 0x00 },155};156 157static const DECLARE_TLV_DB_MINMAX_MUTE(adau1977_adc_gain, -3562, 6000);158 159static const struct snd_soc_dapm_widget adau1977_micbias_dapm_widgets[] = {160 SND_SOC_DAPM_SUPPLY("MICBIAS", ADAU1977_REG_MICBIAS,161 3, 0, NULL, 0)162};163 164static const struct snd_soc_dapm_widget adau1977_dapm_widgets[] = {165 SND_SOC_DAPM_SUPPLY("Vref", ADAU1977_REG_BLOCK_POWER_SAI,166 4, 0, NULL, 0),167 168 SND_SOC_DAPM_ADC("ADC1", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 0, 0),169 SND_SOC_DAPM_ADC("ADC2", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 1, 0),170 SND_SOC_DAPM_ADC("ADC3", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 2, 0),171 SND_SOC_DAPM_ADC("ADC4", "Capture", ADAU1977_REG_BLOCK_POWER_SAI, 3, 0),172 173 SND_SOC_DAPM_INPUT("AIN1"),174 SND_SOC_DAPM_INPUT("AIN2"),175 SND_SOC_DAPM_INPUT("AIN3"),176 SND_SOC_DAPM_INPUT("AIN4"),177 178 SND_SOC_DAPM_OUTPUT("VREF"),179};180 181static const struct snd_soc_dapm_route adau1977_dapm_routes[] = {182 { "ADC1", NULL, "AIN1" },183 { "ADC2", NULL, "AIN2" },184 { "ADC3", NULL, "AIN3" },185 { "ADC4", NULL, "AIN4" },186 187 { "ADC1", NULL, "Vref" },188 { "ADC2", NULL, "Vref" },189 { "ADC3", NULL, "Vref" },190 { "ADC4", NULL, "Vref" },191 192 { "VREF", NULL, "Vref" },193};194 195#define ADAU1977_VOLUME(x) \196 SOC_SINGLE_TLV("ADC" #x " Capture Volume", \197 ADAU1977_REG_POST_ADC_GAIN((x) - 1), \198 0, 255, 1, adau1977_adc_gain)199 200#define ADAU1977_HPF_SWITCH(x) \201 SOC_SINGLE("ADC" #x " Highpass-Filter Capture Switch", \202 ADAU1977_REG_DC_HPF_CAL, (x) - 1, 1, 0)203 204#define ADAU1977_DC_SUB_SWITCH(x) \205 SOC_SINGLE("ADC" #x " DC Subtraction Capture Switch", \206 ADAU1977_REG_DC_HPF_CAL, (x) + 3, 1, 0)207 208static const struct snd_kcontrol_new adau1977_snd_controls[] = {209 ADAU1977_VOLUME(1),210 ADAU1977_VOLUME(2),211 ADAU1977_VOLUME(3),212 ADAU1977_VOLUME(4),213 214 ADAU1977_HPF_SWITCH(1),215 ADAU1977_HPF_SWITCH(2),216 ADAU1977_HPF_SWITCH(3),217 ADAU1977_HPF_SWITCH(4),218 219 ADAU1977_DC_SUB_SWITCH(1),220 ADAU1977_DC_SUB_SWITCH(2),221 ADAU1977_DC_SUB_SWITCH(3),222 ADAU1977_DC_SUB_SWITCH(4),223};224 225static int adau1977_reset(struct adau1977 *adau1977)226{227 int ret;228 229 /*230 * The reset bit is obviously volatile, but we need to be able to cache231 * the other bits in the register, so we can't just mark the whole232 * register as volatile. Since this is the only place where we'll ever233 * touch the reset bit just bypass the cache for this operation.234 */235 regcache_cache_bypass(adau1977->regmap, true);236 ret = regmap_write(adau1977->regmap, ADAU1977_REG_POWER,237 ADAU1977_POWER_RESET);238 regcache_cache_bypass(adau1977->regmap, false);239 240 return ret;241}242 243/*244 * Returns the appropriate setting for ths FS field in the CTRL0 register245 * depending on the rate.246 */247static int adau1977_lookup_fs(unsigned int rate)248{249 if (rate >= 8000 && rate <= 12000)250 return ADAU1977_SAI_CTRL0_FS_8000_12000;251 else if (rate >= 16000 && rate <= 24000)252 return ADAU1977_SAI_CTRL0_FS_16000_24000;253 else if (rate >= 32000 && rate <= 48000)254 return ADAU1977_SAI_CTRL0_FS_32000_48000;255 else if (rate >= 64000 && rate <= 96000)256 return ADAU1977_SAI_CTRL0_FS_64000_96000;257 else if (rate >= 128000 && rate <= 192000)258 return ADAU1977_SAI_CTRL0_FS_128000_192000;259 else260 return -EINVAL;261}262 263static int adau1977_lookup_mcs(struct adau1977 *adau1977, unsigned int rate,264 unsigned int fs)265{266 unsigned int mcs;267 268 /*269 * rate = sysclk / (512 * mcs_lut[mcs]) * 2**fs270 * => mcs_lut[mcs] = sysclk / (512 * rate) * 2**fs271 * => mcs_lut[mcs] = sysclk / ((512 / 2**fs) * rate)272 */273 274 rate *= 512 >> fs;275 276 if (adau1977->sysclk % rate != 0)277 return -EINVAL;278 279 mcs = adau1977->sysclk / rate;280 281 /* The factors configured by MCS are 1, 2, 3, 4, 6 */282 if (mcs < 1 || mcs > 6 || mcs == 5)283 return -EINVAL;284 285 mcs = mcs - 1;286 if (mcs == 5)287 mcs = 4;288 289 return mcs;290}291 292static int adau1977_hw_params(struct snd_pcm_substream *substream,293 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)294{295 struct snd_soc_component *component = dai->component;296 struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);297 unsigned int rate = params_rate(params);298 unsigned int slot_width;299 unsigned int ctrl0, ctrl0_mask;300 unsigned int ctrl1;301 int mcs, fs;302 int ret;303 304 fs = adau1977_lookup_fs(rate);305 if (fs < 0)306 return fs;307 308 if (adau1977->sysclk_src == ADAU1977_SYSCLK_SRC_MCLK) {309 mcs = adau1977_lookup_mcs(adau1977, rate, fs);310 if (mcs < 0)311 return mcs;312 } else {313 mcs = 0;314 }315 316 ctrl0_mask = ADAU1977_SAI_CTRL0_FS_MASK;317 ctrl0 = fs;318 319 if (adau1977->right_j) {320 switch (params_width(params)) {321 case 16:322 ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_16BIT;323 break;324 case 24:325 ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_24BIT;326 break;327 default:328 return -EINVAL;329 }330 ctrl0_mask |= ADAU1977_SAI_CTRL0_FMT_MASK;331 }332 333 if (adau1977->clock_provider) {334 switch (params_width(params)) {335 case 16:336 ctrl1 = ADAU1977_SAI_CTRL1_DATA_WIDTH_16BIT;337 slot_width = 16;338 break;339 case 24:340 case 32:341 ctrl1 = ADAU1977_SAI_CTRL1_DATA_WIDTH_24BIT;342 slot_width = 32;343 break;344 default:345 return -EINVAL;346 }347 348 /* In TDM mode there is a fixed slot width */349 if (adau1977->slot_width)350 slot_width = adau1977->slot_width;351 352 if (slot_width == 16)353 ctrl1 |= ADAU1977_SAI_CTRL1_BCLKRATE_16;354 else355 ctrl1 |= ADAU1977_SAI_CTRL1_BCLKRATE_32;356 357 ret = regmap_update_bits(adau1977->regmap,358 ADAU1977_REG_SAI_CTRL1,359 ADAU1977_SAI_CTRL1_DATA_WIDTH_MASK |360 ADAU1977_SAI_CTRL1_BCLKRATE_MASK,361 ctrl1);362 if (ret < 0)363 return ret;364 }365 366 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0,367 ctrl0_mask, ctrl0);368 if (ret < 0)369 return ret;370 371 return regmap_update_bits(adau1977->regmap, ADAU1977_REG_PLL,372 ADAU1977_PLL_MCS_MASK, mcs);373}374 375static int adau1977_power_disable(struct adau1977 *adau1977)376{377 int ret = 0;378 379 if (!adau1977->enabled)380 return 0;381 382 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER,383 ADAU1977_POWER_PWUP, 0);384 if (ret)385 return ret;386 387 regcache_mark_dirty(adau1977->regmap);388 389 gpiod_set_value_cansleep(adau1977->reset_gpio, 0);390 391 regcache_cache_only(adau1977->regmap, true);392 393 regulator_disable(adau1977->avdd_reg);394 if (adau1977->dvdd_reg)395 regulator_disable(adau1977->dvdd_reg);396 397 adau1977->enabled = false;398 399 return 0;400}401 402static int adau1977_power_enable(struct adau1977 *adau1977)403{404 unsigned int val;405 int ret = 0;406 407 if (adau1977->enabled)408 return 0;409 410 ret = regulator_enable(adau1977->avdd_reg);411 if (ret)412 return ret;413 414 if (adau1977->dvdd_reg) {415 ret = regulator_enable(adau1977->dvdd_reg);416 if (ret)417 goto err_disable_avdd;418 }419 420 gpiod_set_value_cansleep(adau1977->reset_gpio, 1);421 422 regcache_cache_only(adau1977->regmap, false);423 424 if (adau1977->switch_mode)425 adau1977->switch_mode(adau1977->dev);426 427 ret = adau1977_reset(adau1977);428 if (ret)429 goto err_disable_dvdd;430 431 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_POWER,432 ADAU1977_POWER_PWUP, ADAU1977_POWER_PWUP);433 if (ret)434 goto err_disable_dvdd;435 436 ret = regcache_sync(adau1977->regmap);437 if (ret)438 goto err_disable_dvdd;439 440 /*441 * The PLL register is not affected by the software reset. It is442 * possible that the value of the register was changed to the443 * default value while we were in cache only mode. In this case444 * regcache_sync will skip over it and we have to manually sync445 * it.446 */447 ret = regmap_read(adau1977->regmap, ADAU1977_REG_PLL, &val);448 if (ret)449 goto err_disable_dvdd;450 451 if (val == 0x41) {452 regcache_cache_bypass(adau1977->regmap, true);453 ret = regmap_write(adau1977->regmap, ADAU1977_REG_PLL,454 0x41);455 if (ret)456 goto err_disable_dvdd;457 regcache_cache_bypass(adau1977->regmap, false);458 }459 460 adau1977->enabled = true;461 462 return ret;463 464err_disable_dvdd:465 if (adau1977->dvdd_reg)466 regulator_disable(adau1977->dvdd_reg);467err_disable_avdd:468 regulator_disable(adau1977->avdd_reg);469 return ret;470}471 472static int adau1977_set_bias_level(struct snd_soc_component *component,473 enum snd_soc_bias_level level)474{475 struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);476 int ret = 0;477 478 switch (level) {479 case SND_SOC_BIAS_ON:480 break;481 case SND_SOC_BIAS_PREPARE:482 break;483 case SND_SOC_BIAS_STANDBY:484 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)485 ret = adau1977_power_enable(adau1977);486 break;487 case SND_SOC_BIAS_OFF:488 ret = adau1977_power_disable(adau1977);489 break;490 }491 492 return ret;493}494 495static int adau1977_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,496 unsigned int rx_mask, int slots, int width)497{498 struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);499 unsigned int ctrl0, ctrl1, drv;500 unsigned int slot[4];501 unsigned int i;502 int ret;503 504 if (slots == 0) {505 /* 0 = No fixed slot width */506 adau1977->slot_width = 0;507 adau1977->max_clock_provider_fs = 192000;508 return regmap_update_bits(adau1977->regmap,509 ADAU1977_REG_SAI_CTRL0, ADAU1977_SAI_CTRL0_SAI_MASK,510 ADAU1977_SAI_CTRL0_SAI_I2S);511 }512 513 if (rx_mask == 0 || tx_mask != 0)514 return -EINVAL;515 516 drv = 0;517 for (i = 0; i < 4; i++) {518 slot[i] = __ffs(rx_mask);519 drv |= ADAU1977_SAI_OVERTEMP_DRV_C(i);520 rx_mask &= ~(1 << slot[i]);521 if (slot[i] >= slots)522 return -EINVAL;523 if (rx_mask == 0)524 break;525 }526 527 if (rx_mask != 0)528 return -EINVAL;529 530 switch (width) {531 case 16:532 ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_16;533 break;534 case 24:535 /* We can only generate 16 bit or 32 bit wide slots */536 if (adau1977->clock_provider)537 return -EINVAL;538 ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_24;539 break;540 case 32:541 ctrl1 = ADAU1977_SAI_CTRL1_SLOT_WIDTH_32;542 break;543 default:544 return -EINVAL;545 }546 547 switch (slots) {548 case 2:549 ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_2;550 break;551 case 4:552 ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_4;553 break;554 case 8:555 ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_8;556 break;557 case 16:558 ctrl0 = ADAU1977_SAI_CTRL0_SAI_TDM_16;559 break;560 default:561 return -EINVAL;562 }563 564 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_OVERTEMP,565 ADAU1977_SAI_OVERTEMP_DRV_C(0) |566 ADAU1977_SAI_OVERTEMP_DRV_C(1) |567 ADAU1977_SAI_OVERTEMP_DRV_C(2) |568 ADAU1977_SAI_OVERTEMP_DRV_C(3), drv);569 if (ret)570 return ret;571 572 ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP12,573 (slot[1] << ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET) |574 (slot[0] << ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET));575 if (ret)576 return ret;577 578 ret = regmap_write(adau1977->regmap, ADAU1977_REG_CMAP34,579 (slot[3] << ADAU1977_CHAN_MAP_SECOND_SLOT_OFFSET) |580 (slot[2] << ADAU1977_CHAN_MAP_FIRST_SLOT_OFFSET));581 if (ret)582 return ret;583 584 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0,585 ADAU1977_SAI_CTRL0_SAI_MASK, ctrl0);586 if (ret)587 return ret;588 589 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1,590 ADAU1977_SAI_CTRL1_SLOT_WIDTH_MASK, ctrl1);591 if (ret)592 return ret;593 594 adau1977->slot_width = width;595 596 /* In clock provider mode the maximum bitclock is 24.576 MHz */597 adau1977->max_clock_provider_fs = min(192000, 24576000 / width / slots);598 599 return 0;600}601 602static int adau1977_mute(struct snd_soc_dai *dai, int mute, int stream)603{604 struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);605 unsigned int val;606 607 if (mute)608 val = ADAU1977_MISC_CONTROL_MMUTE;609 else610 val = 0;611 612 return regmap_update_bits(adau1977->regmap, ADAU1977_REG_MISC_CONTROL,613 ADAU1977_MISC_CONTROL_MMUTE, val);614}615 616static int adau1977_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)617{618 struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);619 unsigned int ctrl0 = 0, ctrl1 = 0, block_power = 0;620 bool invert_lrclk;621 int ret;622 623 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {624 case SND_SOC_DAIFMT_CBC_CFC:625 adau1977->clock_provider = false;626 break;627 case SND_SOC_DAIFMT_CBP_CFP:628 ctrl1 |= ADAU1977_SAI_CTRL1_MASTER;629 adau1977->clock_provider = true;630 break;631 default:632 return -EINVAL;633 }634 635 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {636 case SND_SOC_DAIFMT_NB_NF:637 invert_lrclk = false;638 break;639 case SND_SOC_DAIFMT_IB_NF:640 block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE;641 invert_lrclk = false;642 break;643 case SND_SOC_DAIFMT_NB_IF:644 invert_lrclk = true;645 break;646 case SND_SOC_DAIFMT_IB_IF:647 block_power |= ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE;648 invert_lrclk = true;649 break;650 default:651 return -EINVAL;652 }653 654 adau1977->right_j = false;655 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {656 case SND_SOC_DAIFMT_I2S:657 ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S;658 break;659 case SND_SOC_DAIFMT_LEFT_J:660 ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ;661 invert_lrclk = !invert_lrclk;662 break;663 case SND_SOC_DAIFMT_RIGHT_J:664 ctrl0 |= ADAU1977_SAI_CTRL0_FMT_RJ_24BIT;665 adau1977->right_j = true;666 invert_lrclk = !invert_lrclk;667 break;668 case SND_SOC_DAIFMT_DSP_A:669 ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE;670 ctrl0 |= ADAU1977_SAI_CTRL0_FMT_I2S;671 invert_lrclk = false;672 break;673 case SND_SOC_DAIFMT_DSP_B:674 ctrl1 |= ADAU1977_SAI_CTRL1_LRCLK_PULSE;675 ctrl0 |= ADAU1977_SAI_CTRL0_FMT_LJ;676 invert_lrclk = false;677 break;678 default:679 return -EINVAL;680 }681 682 if (invert_lrclk)683 block_power |= ADAU1977_BLOCK_POWER_SAI_LR_POL;684 685 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI,686 ADAU1977_BLOCK_POWER_SAI_LR_POL |687 ADAU1977_BLOCK_POWER_SAI_BCLK_EDGE, block_power);688 if (ret)689 return ret;690 691 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL0,692 ADAU1977_SAI_CTRL0_FMT_MASK,693 ctrl0);694 if (ret)695 return ret;696 697 return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_CTRL1,698 ADAU1977_SAI_CTRL1_MASTER | ADAU1977_SAI_CTRL1_LRCLK_PULSE,699 ctrl1);700}701 702static int adau1977_startup(struct snd_pcm_substream *substream,703 struct snd_soc_dai *dai)704{705 struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);706 u64 formats = 0;707 708 if (adau1977->slot_width == 16)709 formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE;710 else if (adau1977->right_j || adau1977->slot_width == 24)711 formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |712 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE;713 714 snd_pcm_hw_constraint_list(substream->runtime, 0,715 SNDRV_PCM_HW_PARAM_RATE, &adau1977->constraints);716 717 if (adau1977->clock_provider)718 snd_pcm_hw_constraint_minmax(substream->runtime,719 SNDRV_PCM_HW_PARAM_RATE, 8000,720 adau1977->max_clock_provider_fs);721 722 if (formats != 0)723 snd_pcm_hw_constraint_mask64(substream->runtime,724 SNDRV_PCM_HW_PARAM_FORMAT, formats);725 726 return 0;727}728 729static int adau1977_set_tristate(struct snd_soc_dai *dai, int tristate)730{731 struct adau1977 *adau1977 = snd_soc_component_get_drvdata(dai->component);732 unsigned int val;733 734 if (tristate)735 val = ADAU1977_SAI_OVERTEMP_DRV_HIZ;736 else737 val = 0;738 739 return regmap_update_bits(adau1977->regmap, ADAU1977_REG_SAI_OVERTEMP,740 ADAU1977_SAI_OVERTEMP_DRV_HIZ, val);741}742 743static const struct snd_soc_dai_ops adau1977_dai_ops = {744 .startup = adau1977_startup,745 .hw_params = adau1977_hw_params,746 .mute_stream = adau1977_mute,747 .set_fmt = adau1977_set_dai_fmt,748 .set_tdm_slot = adau1977_set_tdm_slot,749 .set_tristate = adau1977_set_tristate,750};751 752static struct snd_soc_dai_driver adau1977_dai = {753 .name = "adau1977-hifi",754 .capture = {755 .stream_name = "Capture",756 .channels_min = 1,757 .channels_max = 4,758 .rates = SNDRV_PCM_RATE_KNOT,759 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |760 SNDRV_PCM_FMTBIT_S32_LE,761 .sig_bits = 24,762 },763 .ops = &adau1977_dai_ops,764};765 766static const unsigned int adau1977_rates[] = {767 8000, 16000, 32000, 64000, 128000,768 11025, 22050, 44100, 88200, 172400,769 12000, 24000, 48000, 96000, 192000,770};771 772#define ADAU1977_RATE_CONSTRAINT_MASK_32000 0x001f773#define ADAU1977_RATE_CONSTRAINT_MASK_44100 0x03e0774#define ADAU1977_RATE_CONSTRAINT_MASK_48000 0x7c00775/* All rates >= 32000 */776#define ADAU1977_RATE_CONSTRAINT_MASK_LRCLK 0x739c777 778static bool adau1977_check_sysclk(unsigned int mclk, unsigned int base_freq)779{780 unsigned int mcs;781 782 if (mclk % (base_freq * 128) != 0)783 return false;784 785 mcs = mclk / (128 * base_freq);786 if (mcs < 1 || mcs > 6 || mcs == 5)787 return false;788 789 return true;790}791 792static int adau1977_set_sysclk(struct snd_soc_component *component,793 int clk_id, int source, unsigned int freq, int dir)794{795 struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);796 unsigned int mask = 0;797 unsigned int clk_src;798 unsigned int ret;799 800 if (dir != SND_SOC_CLOCK_IN)801 return -EINVAL;802 803 if (clk_id != ADAU1977_SYSCLK)804 return -EINVAL;805 806 switch (source) {807 case ADAU1977_SYSCLK_SRC_MCLK:808 clk_src = 0;809 break;810 case ADAU1977_SYSCLK_SRC_LRCLK:811 clk_src = ADAU1977_PLL_CLK_S;812 break;813 default:814 return -EINVAL;815 }816 817 if (freq != 0 && source == ADAU1977_SYSCLK_SRC_MCLK) {818 if (freq < 4000000 || freq > 36864000)819 return -EINVAL;820 821 if (adau1977_check_sysclk(freq, 32000))822 mask |= ADAU1977_RATE_CONSTRAINT_MASK_32000;823 if (adau1977_check_sysclk(freq, 44100))824 mask |= ADAU1977_RATE_CONSTRAINT_MASK_44100;825 if (adau1977_check_sysclk(freq, 48000))826 mask |= ADAU1977_RATE_CONSTRAINT_MASK_48000;827 828 if (mask == 0)829 return -EINVAL;830 } else if (source == ADAU1977_SYSCLK_SRC_LRCLK) {831 mask = ADAU1977_RATE_CONSTRAINT_MASK_LRCLK;832 }833 834 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_PLL,835 ADAU1977_PLL_CLK_S, clk_src);836 if (ret)837 return ret;838 839 adau1977->constraints.mask = mask;840 adau1977->sysclk_src = source;841 adau1977->sysclk = freq;842 843 return 0;844}845 846static int adau1977_component_probe(struct snd_soc_component *component)847{848 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);849 struct adau1977 *adau1977 = snd_soc_component_get_drvdata(component);850 int ret;851 852 switch (adau1977->type) {853 case ADAU1977:854 ret = snd_soc_dapm_new_controls(dapm,855 adau1977_micbias_dapm_widgets,856 ARRAY_SIZE(adau1977_micbias_dapm_widgets));857 if (ret < 0)858 return ret;859 break;860 default:861 break;862 }863 864 return 0;865}866 867static const struct snd_soc_component_driver adau1977_component_driver = {868 .probe = adau1977_component_probe,869 .set_bias_level = adau1977_set_bias_level,870 .set_sysclk = adau1977_set_sysclk,871 .controls = adau1977_snd_controls,872 .num_controls = ARRAY_SIZE(adau1977_snd_controls),873 .dapm_widgets = adau1977_dapm_widgets,874 .num_dapm_widgets = ARRAY_SIZE(adau1977_dapm_widgets),875 .dapm_routes = adau1977_dapm_routes,876 .num_dapm_routes = ARRAY_SIZE(adau1977_dapm_routes),877 .use_pmdown_time = 1,878 .endianness = 1,879};880 881static int adau1977_setup_micbias(struct adau1977 *adau1977)882{883 unsigned int micbias;884 885 if (device_property_read_u32(adau1977->dev, "adi,micbias", &micbias))886 micbias = ADAU1977_MICBIAS_8V5;887 888 if (micbias > ADAU1977_MICBIAS_9V0) {889 dev_err(adau1977->dev, "Invalid value for 'adi,micbias'\n");890 return -EINVAL;891 }892 893 return regmap_update_bits(adau1977->regmap, ADAU1977_REG_MICBIAS,894 ADAU1977_MICBIAS_MB_VOLTS_MASK,895 micbias << ADAU1977_MICBIAS_MB_VOLTS_OFFSET);896}897 898int adau1977_probe(struct device *dev, struct regmap *regmap,899 enum adau1977_type type, void (*switch_mode)(struct device *dev))900{901 unsigned int power_off_mask;902 struct adau1977 *adau1977;903 int ret;904 905 if (IS_ERR(regmap))906 return PTR_ERR(regmap);907 908 adau1977 = devm_kzalloc(dev, sizeof(*adau1977), GFP_KERNEL);909 if (adau1977 == NULL)910 return -ENOMEM;911 912 adau1977->dev = dev;913 adau1977->type = type;914 adau1977->regmap = regmap;915 adau1977->switch_mode = switch_mode;916 adau1977->max_clock_provider_fs = 192000;917 918 adau1977->constraints.list = adau1977_rates;919 adau1977->constraints.count = ARRAY_SIZE(adau1977_rates);920 921 adau1977->avdd_reg = devm_regulator_get(dev, "AVDD");922 if (IS_ERR(adau1977->avdd_reg))923 return PTR_ERR(adau1977->avdd_reg);924 925 adau1977->dvdd_reg = devm_regulator_get_optional(dev, "DVDD");926 if (IS_ERR(adau1977->dvdd_reg)) {927 if (PTR_ERR(adau1977->dvdd_reg) != -ENODEV)928 return PTR_ERR(adau1977->dvdd_reg);929 adau1977->dvdd_reg = NULL;930 }931 932 adau1977->reset_gpio = devm_gpiod_get_optional(dev, "reset",933 GPIOD_OUT_LOW);934 if (IS_ERR(adau1977->reset_gpio))935 return PTR_ERR(adau1977->reset_gpio);936 937 dev_set_drvdata(dev, adau1977);938 939 if (adau1977->reset_gpio)940 ndelay(100);941 942 ret = adau1977_power_enable(adau1977);943 if (ret)944 return ret;945 946 if (type == ADAU1977) {947 ret = adau1977_setup_micbias(adau1977);948 if (ret)949 goto err_poweroff;950 }951 952 if (adau1977->dvdd_reg)953 power_off_mask = ~0;954 else955 power_off_mask = (unsigned int)~ADAU1977_BLOCK_POWER_SAI_LDO_EN;956 957 ret = regmap_update_bits(adau1977->regmap, ADAU1977_REG_BLOCK_POWER_SAI,958 power_off_mask, 0x00);959 if (ret)960 goto err_poweroff;961 962 ret = adau1977_power_disable(adau1977);963 if (ret)964 return ret;965 966 return devm_snd_soc_register_component(dev, &adau1977_component_driver,967 &adau1977_dai, 1);968 969err_poweroff:970 adau1977_power_disable(adau1977);971 return ret;972 973}974EXPORT_SYMBOL_GPL(adau1977_probe);975 976static bool adau1977_register_volatile(struct device *dev, unsigned int reg)977{978 switch (reg) {979 case ADAU1977_REG_STATUS(0):980 case ADAU1977_REG_STATUS(1):981 case ADAU1977_REG_STATUS(2):982 case ADAU1977_REG_STATUS(3):983 case ADAU1977_REG_ADC_CLIP:984 return true;985 }986 987 return false;988}989 990const struct regmap_config adau1977_regmap_config = {991 .max_register = ADAU1977_REG_DC_HPF_CAL,992 .volatile_reg = adau1977_register_volatile,993 994 .cache_type = REGCACHE_MAPLE,995 .reg_defaults = adau1977_reg_defaults,996 .num_reg_defaults = ARRAY_SIZE(adau1977_reg_defaults),997};998EXPORT_SYMBOL_GPL(adau1977_regmap_config);999 1000MODULE_DESCRIPTION("ASoC ADAU1977/ADAU1978/ADAU1979 driver");1001MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");1002MODULE_LICENSE("GPL");1003