// SPDX-License-Identifier: GPL-2.0-only
/*
* cs53l30.c -- CS53l30 ALSA Soc Audio driver
*
* Copyright 2015 Cirrus Logic, Inc.
*
* Authors: Paul Handrigan <Paul.Handrigan@cirrus.com>,
* Tim Howe <Tim.Howe@cirrus.com>
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include "cs53l30.h"
#include "cirrus_legacy.h"
#define CS53L30_NUM_SUPPLIES 2
static const char *const cs53l30_supply_names[CS53L30_NUM_SUPPLIES] = {
"VA",
"VP",
};
struct cs53l30_private {
struct regulator_bulk_data supplies[CS53L30_NUM_SUPPLIES];
struct regmap *regmap;
struct gpio_desc *reset_gpio;
struct gpio_desc *mute_gpio;
struct clk *mclk;
bool use_sdout2;
u32 mclk_rate;
};
static const struct reg_default cs53l30_reg_defaults[] = {
{ CS53L30_PWRCTL, CS53L30_PWRCTL_DEFAULT },
{ CS53L30_MCLKCTL, CS53L30_MCLKCTL_DEFAULT },
{ CS53L30_INT_SR_CTL, CS53L30_INT_SR_CTL_DEFAULT },
{ CS53L30_MICBIAS_CTL, CS53L30_MICBIAS_CTL_DEFAULT },
{ CS53L30_ASPCFG_CTL, CS53L30_ASPCFG_CTL_DEFAULT },
{ CS53L30_ASP_CTL1, CS53L30_ASP_CTL1_DEFAULT },
{ CS53L30_ASP_TDMTX_CTL1, CS53L30_ASP_TDMTX_CTLx_DEFAULT },
{ CS53L30_ASP_TDMTX_CTL2, CS53L30_ASP_TDMTX_CTLx_DEFAULT },
{ CS53L30_ASP_TDMTX_CTL3, CS53L30_ASP_TDMTX_CTLx_DEFAULT },
{ CS53L30_ASP_TDMTX_CTL4, CS53L30_ASP_TDMTX_CTLx_DEFAULT },
{ CS53L30_ASP_TDMTX_EN1, CS53L30_ASP_TDMTX_ENx_DEFAULT },
{ CS53L30_ASP_TDMTX_EN2, CS53L30_ASP_TDMTX_ENx_DEFAULT },
{ CS53L30_ASP_TDMTX_EN3, CS53L30_ASP_TDMTX_ENx_DEFAULT },
{ CS53L30_ASP_TDMTX_EN4, CS53L30_ASP_TDMTX_ENx_DEFAULT },
{ CS53L30_ASP_TDMTX_EN5, CS53L30_ASP_TDMTX_ENx_DEFAULT },
{ CS53L30_ASP_TDMTX_EN6, CS53L30_ASP_TDMTX_ENx_DEFAULT },
{ CS53L30_ASP_CTL2, CS53L30_ASP_CTL2_DEFAULT },
{ CS53L30_SFT_RAMP, CS53L30_SFT_RMP_DEFAULT },
{ CS53L30_LRCK_CTL1, CS53L30_LRCK_CTLx_DEFAULT },
{ CS53L30_LRCK_CTL2, CS53L30_LRCK_CTLx_DEFAULT },
{ CS53L30_MUTEP_CTL1, CS53L30_MUTEP_CTL1_DEFAULT },
{ CS53L30_MUTEP_CTL2, CS53L30_MUTEP_CTL2_DEFAULT },
{ CS53L30_INBIAS_CTL1, CS53L30_INBIAS_CTL1_DEFAULT },
{ CS53L30_INBIAS_CTL2, CS53L30_INBIAS_CTL2_DEFAULT },
{ CS53L30_DMIC1_STR_CTL, CS53L30_DMIC1_STR_CTL_DEFAULT },
{ CS53L30_DMIC2_STR_CTL, CS53L30_DMIC2_STR_CTL_DEFAULT },
{ CS53L30_ADCDMIC1_CTL1, CS53L30_ADCDMICx_CTL1_DEFAULT },
{ CS53L30_ADCDMIC1_CTL2, CS53L30_ADCDMIC1_CTL2_DEFAULT },
{ CS53L30_ADC1_CTL3, CS53L30_ADCx_CTL3_DEFAULT },
{ CS53L30_ADC1_NG_CTL, CS53L30_ADCx_NG_CTL_DEFAULT },
{ CS53L30_ADC1A_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT },
{ CS53L30_ADC1B_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT },
{ CS53L30_ADC1A_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT },
{ CS53L30_ADC1B_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT },
{ CS53L30_ADCDMIC2_CTL1, CS53L30_ADCDMICx_CTL1_DEFAULT },
{ CS53L30_ADCDMIC2_CTL2, CS53L30_ADCDMIC1_CTL2_DEFAULT },
{ CS53L30_ADC2_CTL3, CS53L30_ADCx_CTL3_DEFAULT },
{ CS53L30_ADC2_NG_CTL, CS53L30_ADCx_NG_CTL_DEFAULT },
{ CS53L30_ADC2A_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT },
{ CS53L30_ADC2B_AFE_CTL, CS53L30_ADCxy_AFE_CTL_DEFAULT },
{ CS53L30_ADC2A_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT },
{ CS53L30_ADC2B_DIG_VOL, CS53L30_ADCxy_DIG_VOL_DEFAULT },
{ CS53L30_INT_MASK, CS53L30_DEVICE_INT_MASK },
};
static bool cs53l30_volatile_register(struct device *dev, unsigned int reg)
{
if (reg == CS53L30_IS)
return true;
else
return false;
}
static bool cs53l30_writeable_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case CS53L30_DEVID_AB:
case CS53L30_DEVID_CD:
case CS53L30_DEVID_E:
case CS53L30_REVID:
case CS53L30_IS:
return false;
default:
return true;
}
}
static bool cs53l30_readable_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case CS53L30_DEVID_AB:
case CS53L30_DEVID_CD:
case CS53L30_DEVID_E:
case CS53L30_REVID:
case CS53L30_PWRCTL:
case CS53L30_MCLKCTL:
case CS53L30_INT_SR_CTL:
case CS53L30_MICBIAS_CTL:
case CS53L30_ASPCFG_CTL:
case CS53L30_ASP_CTL1:
case CS53L30_ASP_TDMTX_CTL1:
case CS53L30_ASP_TDMTX_CTL2:
case CS53L30_ASP_TDMTX_CTL3:
case CS53L30_ASP_TDMTX_CTL4:
case CS53L30_ASP_TDMTX_EN1:
case CS53L30_ASP_TDMTX_EN2:
case CS53L30_ASP_TDMTX_EN3:
case CS53L30_ASP_TDMTX_EN4:
case CS53L30_ASP_TDMTX_EN5:
case CS53L30_ASP_TDMTX_EN6:
case CS53L30_ASP_CTL2:
case CS53L30_SFT_RAMP:
case CS53L30_LRCK_CTL1:
case CS53L30_LRCK_CTL2:
case CS53L30_MUTEP_CTL1:
case CS53L30_MUTEP_CTL2:
case CS53L30_INBIAS_CTL1:
case CS53L30_INBIAS_CTL2:
case CS53L30_DMIC1_STR_CTL:
case CS53L30_DMIC2_STR_CTL:
case CS53L30_ADCDMIC1_CTL1:
case CS53L30_ADCDMIC1_CTL2:
case CS53L30_ADC1_CTL3:
case CS53L30_ADC1_NG_CTL:
case CS53L30_ADC1A_AFE_CTL:
case CS53L30_ADC1B_AFE_CTL:
case CS53L30_ADC1A_DIG_VOL:
case CS53L30_ADC1B_DIG_VOL:
case CS53L30_ADCDMIC2_CTL1:
case CS53L30_ADCDMIC2_CTL2:
case CS53L30_ADC2_CTL3:
case CS53L30_ADC2_NG_CTL:
case CS53L30_ADC2A_AFE_CTL:
case CS53L30_ADC2B_AFE_CTL<