cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cs4234.c (27390B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2// cs4234.c -- ALSA SoC CS4234 driver
      3//
      4// Copyright (C) 2020 Cirrus Logic, Inc. and
      5//                    Cirrus Logic International Semiconductor Ltd.
      6//
      7
      8#include <linux/clk.h>
      9#include <linux/completion.h>
     10#include <linux/delay.h>
     11#include <linux/gpio/consumer.h>
     12#include <linux/i2c.h>
     13#include <linux/jiffies.h>
     14#include <linux/mod_devicetable.h>
     15#include <linux/module.h>
     16#include <sound/pcm.h>
     17#include <sound/pcm_params.h>
     18#include <linux/pm_runtime.h>
     19#include <linux/regmap.h>
     20#include <linux/regulator/consumer.h>
     21#include <linux/slab.h>
     22#include <sound/soc.h>
     23#include <sound/tlv.h>
     24#include <linux/workqueue.h>
     25
     26#include "cs4234.h"
     27
     28struct cs4234 {
     29	struct device *dev;
     30	struct regmap *regmap;
     31	struct gpio_desc *reset_gpio;
     32	struct regulator_bulk_data core_supplies[2];
     33	int num_core_supplies;
     34	struct completion vq_ramp_complete;
     35	struct delayed_work vq_ramp_delay;
     36	struct clk *mclk;
     37	unsigned long mclk_rate;
     38	unsigned long lrclk_rate;
     39	unsigned int format;
     40	struct snd_ratnum rate_dividers[2];
     41	struct snd_pcm_hw_constraint_ratnums rate_constraint;
     42};
     43
     44/* -89.92dB to +6.02dB with step of 0.38dB */
     45static const DECLARE_TLV_DB_SCALE(dac_tlv, -8992, 38, 0);
     46
     47static const char * const cs4234_dac14_delay_text[] = {
     48	  "0us", "100us", "150us", "200us", "225us", "250us", "275us", "300us",
     49	"325us", "350us", "375us", "400us", "425us", "450us", "475us", "500us",
     50};
     51static SOC_ENUM_SINGLE_DECL(cs4234_dac14_group_delay, CS4234_TPS_CTRL,
     52			    CS4234_GRP_DELAY_SHIFT, cs4234_dac14_delay_text);
     53
     54static const char * const cs4234_noise_gate_text[] = {
     55	"72dB",  "78dB",  "84dB", "90dB", "96dB", "102dB", "138dB", "Disabled",
     56};
     57static SOC_ENUM_SINGLE_DECL(cs4234_ll_noise_gate, CS4234_LOW_LAT_CTRL1,
     58			    CS4234_LL_NG_SHIFT, cs4234_noise_gate_text);
     59static SOC_ENUM_SINGLE_DECL(cs4234_dac14_noise_gate, CS4234_DAC_CTRL1,
     60			    CS4234_DAC14_NG_SHIFT, cs4234_noise_gate_text);
     61static SOC_ENUM_SINGLE_DECL(cs4234_dac5_noise_gate, CS4234_DAC_CTRL2,
     62			    CS4234_DAC5_NG_SHIFT, cs4234_noise_gate_text);
     63
     64static const char * const cs4234_dac5_config_fltr_sel_text[] = {
     65	"Interpolation Filter", "Sample and Hold"
     66};
     67static SOC_ENUM_SINGLE_DECL(cs4234_dac5_config_fltr_sel, CS4234_DAC_CTRL1,
     68			    CS4234_DAC5_CFG_FLTR_SHIFT,
     69			    cs4234_dac5_config_fltr_sel_text);
     70
     71static const char * const cs4234_mute_delay_text[] = {
     72	"1x",  "4x",  "16x", "64x",
     73};
     74static SOC_ENUM_SINGLE_DECL(cs4234_mute_delay, CS4234_VOLUME_MODE,
     75			    CS4234_MUTE_DELAY_SHIFT, cs4234_mute_delay_text);
     76
     77static const char * const cs4234_minmax_delay_text[] = {
     78	"1x",  "2x",  "4x", "8x", "16x",  "32x", "64x", "128x",
     79};
     80static SOC_ENUM_SINGLE_DECL(cs4234_min_delay, CS4234_VOLUME_MODE,
     81			    CS4234_MIN_DELAY_SHIFT, cs4234_minmax_delay_text);
     82static SOC_ENUM_SINGLE_DECL(cs4234_max_delay, CS4234_VOLUME_MODE,
     83			    CS4234_MAX_DELAY_SHIFT, cs4234_minmax_delay_text);
     84
     85static int cs4234_dac14_grp_delay_put(struct snd_kcontrol *kctrl,
     86				      struct snd_ctl_elem_value *uctrl)
     87{
     88	struct snd_soc_component *component = snd_soc_kcontrol_component(kctrl);
     89	struct cs4234 *cs4234 = snd_soc_component_get_drvdata(component);
     90	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
     91	unsigned int val = 0;
     92	int ret = 0;
     93
     94	snd_soc_dapm_mutex_lock(dapm);
     95
     96	regmap_read(cs4234->regmap, CS4234_ADC_CTRL2, &val);
     97	if ((val & 0x0F) != 0x0F) { // are all the ADCs powerdown
     98		ret = -EBUSY;
     99		dev_err(component->dev, "Can't change group delay while ADC are ON\n");
    100		goto exit;
    101	}
    102
    103	regmap_read(cs4234->regmap, CS4234_DAC_CTRL4, &val);
    104	if ((val & 0x1F) != 0x1F) { // are all the DACs powerdown
    105		ret = -EBUSY;
    106		dev_err(component->dev, "Can't change group delay while DAC are ON\n");
    107		goto exit;
    108	}
    109
    110	ret = snd_soc_put_enum_double(kctrl, uctrl);
    111exit:
    112	snd_soc_dapm_mutex_unlock(dapm);
    113
    114	return ret;
    115}
    116
    117static void cs4234_vq_ramp_done(struct work_struct *work)
    118{
    119	struct delayed_work *dw = to_delayed_work(work);
    120	struct cs4234 *cs4234 = container_of(dw, struct cs4234, vq_ramp_delay);
    121
    122	complete_all(&cs4234->vq_ramp_complete);
    123}
    124
    125static int cs4234_set_bias_level(struct snd_soc_component *component,
    126				 enum snd_soc_bias_level level)
    127{
    128	struct cs4234 *cs4234 = snd_soc_component_get_drvdata(component);
    129
    130	switch (level) {
    131	case SND_SOC_BIAS_PREPARE:
    132		switch (snd_soc_component_get_bias_level(component)) {
    133		case SND_SOC_BIAS_STANDBY:
    134			wait_for_completion(&cs4234->vq_ramp_complete);
    135			break;
    136		default:
    137			break;
    138		}
    139		break;
    140	default:
    141		break;
    142	}
    143
    144	return 0;
    145}
    146
    147static const struct snd_soc_dapm_widget cs4234_dapm_widgets[] = {
    148	SND_SOC_DAPM_AIF_IN("SDRX1", NULL,  0, SND_SOC_NOPM, 0, 0),
    149	SND_SOC_DAPM_AIF_IN("SDRX2", NULL,  1, SND_SOC_NOPM, 0, 0),
    150	SND_SOC_DAPM_AIF_IN("SDRX3", NULL,  2, SND_SOC_NOPM, 0, 0),
    151	SND_SOC_DAPM_AIF_IN("SDRX4", NULL,  3, SND_SOC_NOPM, 0, 0),
    152	SND_SOC_DAPM_AIF_IN("SDRX5", NULL,  4, SND_SOC_NOPM, 0, 0),
    153
    154	SND_SOC_DAPM_DAC("DAC1", NULL, CS4234_DAC_CTRL4, CS4234_PDN_DAC1_SHIFT, 1),
    155	SND_SOC_DAPM_DAC("DAC2", NULL, CS4234_DAC_CTRL4, CS4234_PDN_DAC2_SHIFT, 1),
    156	SND_SOC_DAPM_DAC("DAC3", NULL, CS4234_DAC_CTRL4, CS4234_PDN_DAC3_SHIFT, 1),
    157	SND_SOC_DAPM_DAC("DAC4", NULL, CS4234_DAC_CTRL4, CS4234_PDN_DAC4_SHIFT, 1),
    158	SND_SOC_DAPM_DAC("DAC5", NULL, CS4234_DAC_CTRL4, CS4234_PDN_DAC5_SHIFT, 1),
    159
    160	SND_SOC_DAPM_OUTPUT("AOUT1"),
    161	SND_SOC_DAPM_OUTPUT("AOUT2"),
    162	SND_SOC_DAPM_OUTPUT("AOUT3"),
    163	SND_SOC_DAPM_OUTPUT("AOUT4"),
    164	SND_SOC_DAPM_OUTPUT("AOUT5"),
    165
    166	SND_SOC_DAPM_INPUT("AIN1"),
    167	SND_SOC_DAPM_INPUT("AIN2"),
    168	SND_SOC_DAPM_INPUT("AIN3"),
    169	SND_SOC_DAPM_INPUT("AIN4"),
    170
    171	SND_SOC_DAPM_ADC("ADC1", NULL, CS4234_ADC_CTRL2, CS4234_PDN_ADC1_SHIFT, 1),
    172	SND_SOC_DAPM_ADC("ADC2", NULL, CS4234_ADC_CTRL2, CS4234_PDN_ADC2_SHIFT, 1),
    173	SND_SOC_DAPM_ADC("ADC3", NULL, CS4234_ADC_CTRL2, CS4234_PDN_ADC3_SHIFT, 1),
    174	SND_SOC_DAPM_ADC("ADC4", NULL, CS4234_ADC_CTRL2, CS4234_PDN_ADC4_SHIFT, 1),
    175
    176	SND_SOC_DAPM_AIF_OUT("SDTX1", NULL, 0, SND_SOC_NOPM, 0, 1),
    177	SND_SOC_DAPM_AIF_OUT("SDTX2", NULL, 1, SND_SOC_NOPM, 0, 1),
    178	SND_SOC_DAPM_AIF_OUT("SDTX3", NULL, 2, SND_SOC_NOPM, 0, 1),
    179	SND_SOC_DAPM_AIF_OUT("SDTX4", NULL, 3, SND_SOC_NOPM, 0, 1),
    180};
    181
    182static const struct snd_soc_dapm_route cs4234_dapm_routes[] = {
    183	/* Playback */
    184	{ "AOUT1", NULL, "DAC1" },
    185	{ "AOUT2", NULL, "DAC2" },
    186	{ "AOUT3", NULL, "DAC3" },
    187	{ "AOUT4", NULL, "DAC4" },
    188	{ "AOUT5", NULL, "DAC5" },
    189
    190	{ "DAC1", NULL, "SDRX1" },
    191	{ "DAC2", NULL, "SDRX2" },
    192	{ "DAC3", NULL, "SDRX3" },
    193	{ "DAC4", NULL, "SDRX4" },
    194	{ "DAC5", NULL, "SDRX5" },
    195
    196	{ "SDRX1", NULL, "Playback" },
    197	{ "SDRX2", NULL, "Playback" },
    198	{ "SDRX3", NULL, "Playback" },
    199	{ "SDRX4", NULL, "Playback" },
    200	{ "SDRX5", NULL, "Playback" },
    201
    202	/* Capture */
    203	{ "ADC1", NULL, "AIN1" },
    204	{ "ADC2", NULL, "AIN2" },
    205	{ "ADC3", NULL, "AIN3" },
    206	{ "ADC4", NULL, "AIN4" },
    207
    208	{ "SDTX1", NULL, "ADC1" },
    209	{ "SDTX2", NULL, "ADC2" },
    210	{ "SDTX3", NULL, "ADC3" },
    211	{ "SDTX4", NULL, "ADC4" },
    212
    213	{ "Capture", NULL, "SDTX1" },
    214	{ "Capture", NULL, "SDTX2" },
    215	{ "Capture", NULL, "SDTX3" },
    216	{ "Capture", NULL, "SDTX4" },
    217};
    218
    219static const struct snd_kcontrol_new cs4234_snd_controls[] = {
    220	SOC_SINGLE_TLV("Master Volume", CS4234_MASTER_VOL, 0, 0xff, 1, dac_tlv),
    221	SOC_SINGLE_TLV("DAC1 Volume", CS4234_DAC1_VOL, 0, 0xff, 1, dac_tlv),
    222	SOC_SINGLE_TLV("DAC2 Volume", CS4234_DAC2_VOL, 0, 0xff, 1, dac_tlv),
    223	SOC_SINGLE_TLV("DAC3 Volume", CS4234_DAC3_VOL, 0, 0xff, 1, dac_tlv),
    224	SOC_SINGLE_TLV("DAC4 Volume", CS4234_DAC4_VOL, 0, 0xff, 1, dac_tlv),
    225	SOC_SINGLE_TLV("DAC5 Volume", CS4234_DAC5_VOL, 0, 0xff, 1, dac_tlv),
    226
    227	SOC_SINGLE("DAC5 Soft Ramp Switch", CS4234_DAC_CTRL3, CS4234_DAC5_ATT_SHIFT, 1, 1),
    228	SOC_SINGLE("DAC1-4 Soft Ramp Switch", CS4234_DAC_CTRL3, CS4234_DAC14_ATT_SHIFT, 1, 1),
    229
    230	SOC_SINGLE("ADC HPF Switch", CS4234_ADC_CTRL1, CS4234_ENA_HPF_SHIFT, 1, 0),
    231
    232	SOC_ENUM_EXT("DAC1-4 Group Delay", cs4234_dac14_group_delay,
    233		     snd_soc_get_enum_double, cs4234_dac14_grp_delay_put),
    234
    235	SOC_SINGLE("ADC1 Invert Switch", CS4234_ADC_CTRL1, CS4234_INV_ADC1_SHIFT, 1, 0),
    236	SOC_SINGLE("ADC2 Invert Switch", CS4234_ADC_CTRL1, CS4234_INV_ADC2_SHIFT, 1, 0),
    237	SOC_SINGLE("ADC3 Invert Switch", CS4234_ADC_CTRL1, CS4234_INV_ADC3_SHIFT, 1, 0),
    238	SOC_SINGLE("ADC4 Invert Switch", CS4234_ADC_CTRL1, CS4234_INV_ADC4_SHIFT, 1, 0),
    239
    240	SOC_SINGLE("DAC1 Invert Switch", CS4234_DAC_CTRL2, CS4234_INV_DAC1_SHIFT, 1, 0),
    241	SOC_SINGLE("DAC2 Invert Switch", CS4234_DAC_CTRL2, CS4234_INV_DAC2_SHIFT, 1, 0),
    242	SOC_SINGLE("DAC3 Invert Switch", CS4234_DAC_CTRL2, CS4234_INV_DAC3_SHIFT, 1, 0),
    243	SOC_SINGLE("DAC4 Invert Switch", CS4234_DAC_CTRL2, CS4234_INV_DAC4_SHIFT, 1, 0),
    244	SOC_SINGLE("DAC5 Invert Switch", CS4234_DAC_CTRL2, CS4234_INV_DAC5_SHIFT, 1, 0),
    245
    246	SOC_SINGLE("ADC1 Switch", CS4234_ADC_CTRL2, CS4234_MUTE_ADC1_SHIFT, 1, 1),
    247	SOC_SINGLE("ADC2 Switch", CS4234_ADC_CTRL2, CS4234_MUTE_ADC2_SHIFT, 1, 1),
    248	SOC_SINGLE("ADC3 Switch", CS4234_ADC_CTRL2, CS4234_MUTE_ADC3_SHIFT, 1, 1),
    249	SOC_SINGLE("ADC4 Switch", CS4234_ADC_CTRL2, CS4234_MUTE_ADC4_SHIFT, 1, 1),
    250
    251	SOC_SINGLE("DAC1 Switch", CS4234_DAC_CTRL3, CS4234_MUTE_DAC1_SHIFT, 1, 1),
    252	SOC_SINGLE("DAC2 Switch", CS4234_DAC_CTRL3, CS4234_MUTE_DAC2_SHIFT, 1, 1),
    253	SOC_SINGLE("DAC3 Switch", CS4234_DAC_CTRL3, CS4234_MUTE_DAC3_SHIFT, 1, 1),
    254	SOC_SINGLE("DAC4 Switch", CS4234_DAC_CTRL3, CS4234_MUTE_DAC4_SHIFT, 1, 1),
    255	SOC_SINGLE("DAC5 Switch", CS4234_DAC_CTRL3, CS4234_MUTE_DAC5_SHIFT, 1, 1),
    256	SOC_SINGLE("Low-latency Switch", CS4234_DAC_CTRL3, CS4234_MUTE_LL_SHIFT, 1, 1),
    257
    258	SOC_SINGLE("DAC1 Low-latency Invert Switch", CS4234_LOW_LAT_CTRL1,
    259		   CS4234_INV_LL1_SHIFT, 1, 0),
    260	SOC_SINGLE("DAC2 Low-latency Invert Switch", CS4234_LOW_LAT_CTRL1,
    261		   CS4234_INV_LL2_SHIFT, 1, 0),
    262	SOC_SINGLE("DAC3 Low-latency Invert Switch", CS4234_LOW_LAT_CTRL1,
    263		   CS4234_INV_LL3_SHIFT, 1, 0),
    264	SOC_SINGLE("DAC4 Low-latency Invert Switch", CS4234_LOW_LAT_CTRL1,
    265		   CS4234_INV_LL4_SHIFT, 1, 0),
    266
    267	SOC_ENUM("Low-latency Noise Gate", cs4234_ll_noise_gate),
    268	SOC_ENUM("DAC1-4 Noise Gate", cs4234_dac14_noise_gate),
    269	SOC_ENUM("DAC5 Noise Gate", cs4234_dac5_noise_gate),
    270
    271	SOC_SINGLE("DAC1-4 De-emphasis Switch", CS4234_DAC_CTRL1,
    272		   CS4234_DAC14_DE_SHIFT, 1, 0),
    273	SOC_SINGLE("DAC5 De-emphasis Switch", CS4234_DAC_CTRL1,
    274		   CS4234_DAC5_DE_SHIFT, 1, 0),
    275
    276	SOC_SINGLE("DAC5 Master Controlled Switch", CS4234_DAC_CTRL1,
    277		   CS4234_DAC5_MVC_SHIFT, 1, 0),
    278
    279	SOC_ENUM("DAC5 Filter", cs4234_dac5_config_fltr_sel),
    280
    281	SOC_ENUM("Mute Delay", cs4234_mute_delay),
    282	SOC_ENUM("Ramp Minimum Delay", cs4234_min_delay),
    283	SOC_ENUM("Ramp Maximum Delay", cs4234_max_delay),
    284
    285};
    286
    287static int cs4234_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int format)
    288{
    289	struct snd_soc_component *component = codec_dai->component;
    290	struct cs4234 *cs4234 = snd_soc_component_get_drvdata(component);
    291	unsigned int sp_ctrl = 0;
    292
    293	cs4234->format = format & SND_SOC_DAIFMT_FORMAT_MASK;
    294	switch (cs4234->format) {
    295	case SND_SOC_DAIFMT_LEFT_J:
    296		sp_ctrl |= CS4234_LEFT_J << CS4234_SP_FORMAT_SHIFT;
    297		break;
    298	case SND_SOC_DAIFMT_I2S:
    299		sp_ctrl |= CS4234_I2S << CS4234_SP_FORMAT_SHIFT;
    300		break;
    301	case SND_SOC_DAIFMT_DSP_A: /* TDM mode in datasheet */
    302		sp_ctrl |= CS4234_TDM << CS4234_SP_FORMAT_SHIFT;
    303		break;
    304	default:
    305		dev_err(component->dev, "Unsupported dai format\n");
    306		return -EINVAL;
    307	}
    308
    309	switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
    310	case SND_SOC_DAIFMT_CBS_CFS:
    311		break;
    312	case SND_SOC_DAIFMT_CBM_CFM:
    313		if (cs4234->format == SND_SOC_DAIFMT_DSP_A) {
    314			dev_err(component->dev, "Unsupported DSP A format in master mode\n");
    315			return -EINVAL;
    316		}
    317		sp_ctrl |= CS4234_MST_SLV_MASK;
    318		break;
    319	default:
    320		dev_err(component->dev, "Unsupported master/slave mode\n");
    321		return -EINVAL;
    322	}
    323
    324	switch (format & SND_SOC_DAIFMT_INV_MASK) {
    325	case SND_SOC_DAIFMT_NB_NF:
    326		break;
    327	case SND_SOC_DAIFMT_IB_NF:
    328		sp_ctrl |= CS4234_INVT_SCLK_MASK;
    329		break;
    330	default:
    331		dev_err(component->dev, "Unsupported inverted clock setting\n");
    332		return -EINVAL;
    333	}
    334
    335	regmap_update_bits(cs4234->regmap, CS4234_SP_CTRL,
    336			   CS4234_SP_FORMAT_MASK | CS4234_MST_SLV_MASK | CS4234_INVT_SCLK_MASK,
    337			   sp_ctrl);
    338
    339	return 0;
    340}
    341
    342static int cs4234_dai_hw_params(struct snd_pcm_substream *sub,
    343				struct snd_pcm_hw_params *params,
    344				struct snd_soc_dai *dai)
    345{
    346	struct snd_soc_component *component = dai->component;
    347	struct cs4234 *cs4234 = snd_soc_component_get_drvdata(component);
    348	unsigned int mclk_mult, double_speed = 0;
    349	int ret = 0, rate_ad, sample_width;
    350
    351	cs4234->lrclk_rate = params_rate(params);
    352	mclk_mult = cs4234->mclk_rate / cs4234->lrclk_rate;
    353
    354	if (cs4234->lrclk_rate > 48000) {
    355		double_speed = 1;
    356		mclk_mult *= 2;
    357	}
    358
    359	switch (mclk_mult) {
    360	case 256:
    361	case 384:
    362	case 512:
    363		regmap_update_bits(cs4234->regmap, CS4234_CLOCK_SP,
    364				   CS4234_SPEED_MODE_MASK,
    365				   double_speed << CS4234_SPEED_MODE_SHIFT);
    366		regmap_update_bits(cs4234->regmap, CS4234_CLOCK_SP,
    367				   CS4234_MCLK_RATE_MASK,
    368				   ((mclk_mult / 128) - 2) << CS4234_MCLK_RATE_SHIFT);
    369		break;
    370	default:
    371		dev_err(component->dev, "Unsupported mclk/lrclk rate\n");
    372		return -EINVAL;
    373	}
    374
    375	switch (cs4234->lrclk_rate) {
    376	case 48000:
    377	case 96000:
    378		rate_ad = CS4234_48K;
    379		break;
    380	case 44100:
    381	case 88200:
    382		rate_ad = CS4234_44K1;
    383		break;
    384	case 32000:
    385	case 64000:
    386		rate_ad = CS4234_32K;
    387		break;
    388	default:
    389		dev_err(component->dev, "Unsupported LR clock\n");
    390		return -EINVAL;
    391	}
    392	regmap_update_bits(cs4234->regmap, CS4234_CLOCK_SP, CS4234_BASE_RATE_MASK,
    393			   rate_ad << CS4234_BASE_RATE_SHIFT);
    394
    395	sample_width = params_width(params);
    396	switch (sample_width) {
    397	case 16:
    398		sample_width = 0;
    399		break;
    400	case 18:
    401		sample_width = 1;
    402		break;
    403	case 20:
    404		sample_width = 2;
    405		break;
    406	case 24:
    407		sample_width = 3;
    408		break;
    409	default:
    410		dev_err(component->dev, "Unsupported sample width\n");
    411		return -EINVAL;
    412	}
    413	if (sub->stream == SNDRV_PCM_STREAM_CAPTURE)
    414		regmap_update_bits(cs4234->regmap, CS4234_SAMPLE_WIDTH,
    415				   CS4234_SDOUTX_SW_MASK,
    416				   sample_width << CS4234_SDOUTX_SW_SHIFT);
    417	else
    418		regmap_update_bits(cs4234->regmap, CS4234_SAMPLE_WIDTH,
    419				CS4234_INPUT_SW_MASK | CS4234_LOW_LAT_SW_MASK | CS4234_DAC5_SW_MASK,
    420				sample_width << CS4234_INPUT_SW_SHIFT |
    421				sample_width << CS4234_LOW_LAT_SW_SHIFT |
    422				sample_width << CS4234_DAC5_SW_SHIFT);
    423
    424	return ret;
    425}
    426
    427/* Scale MCLK rate by 64 to avoid overflow in the ratnum calculation */
    428#define CS4234_MCLK_SCALE  64
    429
    430static const struct snd_ratnum cs4234_dividers[] = {
    431	{
    432		.num = 0,
    433		.den_min = 256 / CS4234_MCLK_SCALE,
    434		.den_max = 512 / CS4234_MCLK_SCALE,
    435		.den_step = 128 / CS4234_MCLK_SCALE,
    436	},
    437	{
    438		.num = 0,
    439		.den_min = 128 / CS4234_MCLK_SCALE,
    440		.den_max = 192 / CS4234_MCLK_SCALE,
    441		.den_step = 64 / CS4234_MCLK_SCALE,
    442	},
    443};
    444
    445static int cs4234_dai_rule_rate(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
    446{
    447	struct cs4234 *cs4234 = rule->private;
    448	int mclk = cs4234->mclk_rate;
    449	struct snd_interval ranges[] = {
    450		{ /* Single Speed Mode */
    451			.min = mclk / clamp(mclk / 30000, 256, 512),
    452			.max = mclk / clamp(mclk / 50000, 256, 512),
    453		},
    454		{ /* Double Speed Mode */
    455			.min = mclk / clamp(mclk / 60000,  128, 256),
    456			.max = mclk / clamp(mclk / 100000, 128, 256),
    457		},
    458	};
    459
    460	return snd_interval_ranges(hw_param_interval(params, rule->var),
    461				   ARRAY_SIZE(ranges), ranges, 0);
    462}
    463
    464static int cs4234_dai_startup(struct snd_pcm_substream *sub, struct snd_soc_dai *dai)
    465{
    466	struct snd_soc_component *comp = dai->component;
    467	struct cs4234 *cs4234 = snd_soc_component_get_drvdata(comp);
    468	int i, ret;
    469
    470	switch (cs4234->format) {
    471	case SND_SOC_DAIFMT_LEFT_J:
    472	case SND_SOC_DAIFMT_I2S:
    473		cs4234->rate_constraint.nrats = 2;
    474
    475		/*
    476		 * Playback only supports 24-bit samples in these modes.
    477		 * Note: SNDRV_PCM_HW_PARAM_SAMPLE_BITS constrains the physical
    478		 * width, which we don't care about, so constrain the format.
    479		 */
    480		if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK) {
    481			ret = snd_pcm_hw_constraint_mask64(
    482						sub->runtime,
    483						SNDRV_PCM_HW_PARAM_FORMAT,
    484						SNDRV_PCM_FMTBIT_S24_LE |
    485						SNDRV_PCM_FMTBIT_S24_3LE);
    486			if (ret < 0)
    487				return ret;
    488
    489			ret = snd_pcm_hw_constraint_minmax(sub->runtime,
    490							   SNDRV_PCM_HW_PARAM_CHANNELS,
    491							   1, 4);
    492			if (ret < 0)
    493				return ret;
    494		}
    495
    496		break;
    497	case SND_SOC_DAIFMT_DSP_A:
    498		cs4234->rate_constraint.nrats = 1;
    499		break;
    500	default:
    501		dev_err(comp->dev, "Startup unsupported DAI format\n");
    502		return -EINVAL;
    503	}
    504
    505	for (i = 0; i < cs4234->rate_constraint.nrats; i++)
    506		cs4234->rate_dividers[i].num = cs4234->mclk_rate / CS4234_MCLK_SCALE;
    507
    508	ret = snd_pcm_hw_constraint_ratnums(sub->runtime, 0,
    509					    SNDRV_PCM_HW_PARAM_RATE,
    510					    &cs4234->rate_constraint);
    511	if (ret < 0)
    512		return ret;
    513
    514	/*
    515	 * MCLK/rate may be a valid ratio but out-of-spec (e.g. 24576000/64000)
    516	 * so this rule limits the range of sample rate for given MCLK.
    517	 */
    518	return snd_pcm_hw_rule_add(sub->runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
    519				   cs4234_dai_rule_rate, cs4234, -1);
    520}
    521
    522static int cs4234_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
    523				   unsigned int rx_mask, int slots, int slot_width)
    524{
    525	struct snd_soc_component *component = dai->component;
    526	struct cs4234 *cs4234 = snd_soc_component_get_drvdata(component);
    527	unsigned int slot_offset, dac5_slot, dac5_mask_group;
    528	uint8_t dac5_masks[4];
    529
    530	if (slot_width != 32) {
    531		dev_err(component->dev, "Unsupported slot width\n");
    532		return -EINVAL;
    533	}
    534
    535	/* Either 4 or 5 consecutive bits, DAC5 is optional */
    536	slot_offset = ffs(tx_mask) - 1;
    537	tx_mask >>= slot_offset;
    538	if ((slot_offset % 4) || ((tx_mask != 0x0F) && (tx_mask != 0x1F))) {
    539		dev_err(component->dev, "Unsupported tx slots allocation\n");
    540		return -EINVAL;
    541	}
    542
    543	regmap_update_bits(cs4234->regmap, CS4234_SP_DATA_SEL, CS4234_DAC14_SRC_MASK,
    544			   (slot_offset / 4) << CS4234_DAC14_SRC_SHIFT);
    545	regmap_update_bits(cs4234->regmap, CS4234_SP_DATA_SEL, CS4234_LL_SRC_MASK,
    546			   (slot_offset / 4) << CS4234_LL_SRC_SHIFT);
    547
    548	if (tx_mask == 0x1F) {
    549		dac5_slot = slot_offset + 4;
    550		memset(dac5_masks, 0xFF, sizeof(dac5_masks));
    551		dac5_mask_group = dac5_slot / 8;
    552		dac5_slot %= 8;
    553		dac5_masks[dac5_mask_group] ^= BIT(7 - dac5_slot);
    554		regmap_bulk_write(cs4234->regmap,
    555				  CS4234_SDIN1_MASK1,
    556				  dac5_masks,
    557				  ARRAY_SIZE(dac5_masks));
    558	}
    559
    560	return 0;
    561}
    562
    563static const struct snd_soc_dai_ops cs4234_dai_ops = {
    564	.set_fmt	= cs4234_dai_set_fmt,
    565	.hw_params	= cs4234_dai_hw_params,
    566	.startup	= cs4234_dai_startup,
    567	.set_tdm_slot	= cs4234_dai_set_tdm_slot,
    568};
    569
    570static struct snd_soc_dai_driver cs4234_dai[] = {
    571	{
    572		.name = "cs4234-dai",
    573		.playback = {
    574			.stream_name = "Playback",
    575			.channels_min = 1,
    576			.channels_max = 5,
    577			.rates = CS4234_PCM_RATES,
    578			.formats = CS4234_FORMATS,
    579		},
    580		.capture = {
    581			.stream_name = "Capture",
    582			.channels_min = 1,
    583			.channels_max = 4,
    584			.rates = CS4234_PCM_RATES,
    585			.formats = CS4234_FORMATS,
    586		},
    587		.ops = &cs4234_dai_ops,
    588		.symmetric_rate = 1,
    589	},
    590};
    591
    592static const struct reg_default cs4234_default_reg[] = {
    593	{ CS4234_CLOCK_SP,	 0x04},
    594	{ CS4234_SAMPLE_WIDTH,	 0xFF},
    595	{ CS4234_SP_CTRL,	 0x48},
    596	{ CS4234_SP_DATA_SEL,	 0x01},
    597	{ CS4234_SDIN1_MASK1,	 0xFF},
    598	{ CS4234_SDIN1_MASK2,	 0xFF},
    599	{ CS4234_SDIN2_MASK1,	 0xFF},
    600	{ CS4234_SDIN2_MASK2,	 0xFF},
    601	{ CS4234_TPS_CTRL,	 0x00},
    602	{ CS4234_ADC_CTRL1,	 0xC0},
    603	{ CS4234_ADC_CTRL2,	 0xFF},
    604	{ CS4234_LOW_LAT_CTRL1,	 0xE0},
    605	{ CS4234_DAC_CTRL1,	 0xE0},
    606	{ CS4234_DAC_CTRL2,	 0xE0},
    607	{ CS4234_DAC_CTRL3,	 0xBF},
    608	{ CS4234_DAC_CTRL4,	 0x1F},
    609	{ CS4234_VOLUME_MODE,	 0x87},
    610	{ CS4234_MASTER_VOL,	 0x10},
    611	{ CS4234_DAC1_VOL,	 0x10},
    612	{ CS4234_DAC2_VOL,	 0x10},
    613	{ CS4234_DAC3_VOL,	 0x10},
    614	{ CS4234_DAC4_VOL,	 0x10},
    615	{ CS4234_DAC5_VOL,	 0x10},
    616	{ CS4234_INT_CTRL,	 0x40},
    617	{ CS4234_INT_MASK1,	 0x10},
    618	{ CS4234_INT_MASK2,	 0x20},
    619};
    620
    621static bool cs4234_readable_register(struct device *dev, unsigned int reg)
    622{
    623	switch (reg) {
    624	case CS4234_DEVID_AB ... CS4234_DEVID_EF:
    625	case CS4234_REVID ... CS4234_DAC5_VOL:
    626	case CS4234_INT_CTRL ... CS4234_MAX_REGISTER:
    627		return true;
    628	default:
    629		return false;
    630	}
    631}
    632
    633static bool cs4234_volatile_reg(struct device *dev, unsigned int reg)
    634{
    635	switch (reg) {
    636	case CS4234_INT_NOTIFY1:
    637	case CS4234_INT_NOTIFY2:
    638		return true;
    639	default:
    640		return false;
    641	}
    642}
    643
    644static bool cs4234_writeable_register(struct device *dev, unsigned int reg)
    645{
    646	switch (reg) {
    647	case CS4234_DEVID_AB ... CS4234_REVID:
    648	case CS4234_INT_NOTIFY1 ... CS4234_INT_NOTIFY2:
    649		return false;
    650	default:
    651		return true;
    652	}
    653}
    654
    655static const struct snd_soc_component_driver soc_component_cs4234 = {
    656	.dapm_widgets		= cs4234_dapm_widgets,
    657	.num_dapm_widgets	= ARRAY_SIZE(cs4234_dapm_widgets),
    658	.dapm_routes		= cs4234_dapm_routes,
    659	.num_dapm_routes	= ARRAY_SIZE(cs4234_dapm_routes),
    660	.controls		= cs4234_snd_controls,
    661	.num_controls		= ARRAY_SIZE(cs4234_snd_controls),
    662	.set_bias_level		= cs4234_set_bias_level,
    663	.non_legacy_dai_naming	= 1,
    664	.idle_bias_on		= 1,
    665	.suspend_bias_off	= 1,
    666	.endianness		= 1,
    667};
    668
    669static const struct regmap_config cs4234_regmap = {
    670	.reg_bits = 8,
    671	.val_bits = 8,
    672
    673	.max_register = CS4234_MAX_REGISTER,
    674	.readable_reg = cs4234_readable_register,
    675	.volatile_reg = cs4234_volatile_reg,
    676	.writeable_reg = cs4234_writeable_register,
    677	.reg_defaults = cs4234_default_reg,
    678	.num_reg_defaults = ARRAY_SIZE(cs4234_default_reg),
    679	.cache_type = REGCACHE_RBTREE,
    680	.use_single_read = true,
    681	.use_single_write = true,
    682};
    683
    684static const char * const cs4234_core_supplies[] = {
    685	"VA",
    686	"VL",
    687};
    688
    689static void cs4234_shutdown(struct cs4234 *cs4234)
    690{
    691	cancel_delayed_work_sync(&cs4234->vq_ramp_delay);
    692	reinit_completion(&cs4234->vq_ramp_complete);
    693
    694	regmap_update_bits(cs4234->regmap, CS4234_DAC_CTRL4, CS4234_VQ_RAMP_MASK,
    695			   CS4234_VQ_RAMP_MASK);
    696	msleep(50);
    697	regcache_cache_only(cs4234->regmap, true);
    698	/* Clear VQ Ramp Bit in cache for the next PowerUp */
    699	regmap_update_bits(cs4234->regmap, CS4234_DAC_CTRL4, CS4234_VQ_RAMP_MASK, 0);
    700	gpiod_set_value_cansleep(cs4234->reset_gpio, 0);
    701	regulator_bulk_disable(cs4234->num_core_supplies, cs4234->core_supplies);
    702	clk_disable_unprepare(cs4234->mclk);
    703}
    704
    705static int cs4234_powerup(struct cs4234 *cs4234)
    706{
    707	int ret;
    708
    709	ret = clk_prepare_enable(cs4234->mclk);
    710	if (ret) {
    711		dev_err(cs4234->dev, "Failed to enable mclk: %d\n", ret);
    712		return ret;
    713	}
    714
    715	ret = regulator_bulk_enable(cs4234->num_core_supplies, cs4234->core_supplies);
    716	if (ret) {
    717		dev_err(cs4234->dev, "Failed to enable core supplies: %d\n", ret);
    718		clk_disable_unprepare(cs4234->mclk);
    719		return ret;
    720	}
    721
    722	usleep_range(CS4234_HOLD_RESET_TIME_US, 2 * CS4234_HOLD_RESET_TIME_US);
    723	gpiod_set_value_cansleep(cs4234->reset_gpio, 1);
    724
    725	/* Make sure hardware reset done 2 ms + (3000/MCLK) */
    726	usleep_range(CS4234_BOOT_TIME_US, CS4234_BOOT_TIME_US * 2);
    727
    728	queue_delayed_work(system_power_efficient_wq,
    729			   &cs4234->vq_ramp_delay,
    730			   msecs_to_jiffies(CS4234_VQ_CHARGE_MS));
    731
    732	return 0;
    733}
    734
    735static int cs4234_i2c_probe(struct i2c_client *i2c_client)
    736{
    737	struct cs4234 *cs4234;
    738	struct device *dev = &i2c_client->dev;
    739	unsigned int revid;
    740	uint32_t devid;
    741	uint8_t ids[3];
    742	int ret = 0, i;
    743
    744	cs4234 = devm_kzalloc(dev, sizeof(*cs4234), GFP_KERNEL);
    745	if (!cs4234)
    746		return -ENOMEM;
    747	i2c_set_clientdata(i2c_client, cs4234);
    748	cs4234->dev = dev;
    749	init_completion(&cs4234->vq_ramp_complete);
    750	INIT_DELAYED_WORK(&cs4234->vq_ramp_delay, cs4234_vq_ramp_done);
    751
    752	cs4234->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
    753	if (IS_ERR(cs4234->reset_gpio))
    754		return PTR_ERR(cs4234->reset_gpio);
    755
    756	BUILD_BUG_ON(ARRAY_SIZE(cs4234->core_supplies) < ARRAY_SIZE(cs4234_core_supplies));
    757
    758	cs4234->num_core_supplies = ARRAY_SIZE(cs4234_core_supplies);
    759	for (i = 0; i < ARRAY_SIZE(cs4234_core_supplies); i++)
    760		cs4234->core_supplies[i].supply = cs4234_core_supplies[i];
    761
    762	ret = devm_regulator_bulk_get(dev, cs4234->num_core_supplies, cs4234->core_supplies);
    763	if (ret) {
    764		dev_err(dev, "Failed to request core supplies %d\n", ret);
    765		return ret;
    766	}
    767
    768	cs4234->mclk = devm_clk_get(dev, "mclk");
    769	if (IS_ERR(cs4234->mclk)) {
    770		ret = PTR_ERR(cs4234->mclk);
    771		dev_err(dev, "Failed to get the mclk: %d\n", ret);
    772		return ret;
    773	}
    774	cs4234->mclk_rate = clk_get_rate(cs4234->mclk);
    775
    776	if (cs4234->mclk_rate < 7680000 || cs4234->mclk_rate > 25600000) {
    777		dev_err(dev, "Invalid Master Clock rate\n");
    778		return -EINVAL;
    779	}
    780
    781	cs4234->regmap = devm_regmap_init_i2c(i2c_client, &cs4234_regmap);
    782	if (IS_ERR(cs4234->regmap)) {
    783		ret = PTR_ERR(cs4234->regmap);
    784		dev_err(dev, "regmap_init() failed: %d\n", ret);
    785		return ret;
    786	}
    787
    788	ret = cs4234_powerup(cs4234);
    789	if (ret)
    790		return ret;
    791
    792	ret = regmap_bulk_read(cs4234->regmap, CS4234_DEVID_AB, ids, ARRAY_SIZE(ids));
    793	if (ret < 0) {
    794		dev_err(dev, "Failed to read DEVID: %d\n", ret);
    795		goto fail_shutdown;
    796	}
    797
    798	devid = (ids[0] << 16) | (ids[1] << 8) | ids[2];
    799	if (devid != CS4234_SUPPORTED_ID) {
    800		dev_err(dev, "Unknown device ID: %x\n", devid);
    801		ret = -EINVAL;
    802		goto fail_shutdown;
    803	}
    804
    805	ret = regmap_read(cs4234->regmap, CS4234_REVID, &revid);
    806	if (ret < 0) {
    807		dev_err(dev, "Failed to read CS4234_REVID: %d\n", ret);
    808		goto fail_shutdown;
    809	}
    810
    811	dev_info(dev, "Cirrus Logic CS4234, Alpha Rev: %02X, Numeric Rev: %02X\n",
    812		 (revid & 0xF0) >> 4, revid & 0x0F);
    813
    814	ret = regulator_get_voltage(cs4234->core_supplies[CS4234_SUPPLY_VA].consumer);
    815	switch (ret) {
    816	case 3135000 ... 3650000:
    817		regmap_update_bits(cs4234->regmap, CS4234_ADC_CTRL1,
    818				   CS4234_VA_SEL_MASK,
    819				   CS4234_3V3 << CS4234_VA_SEL_SHIFT);
    820		break;
    821	case 4750000 ... 5250000:
    822		regmap_update_bits(cs4234->regmap, CS4234_ADC_CTRL1,
    823				   CS4234_VA_SEL_MASK,
    824				   CS4234_5V << CS4234_VA_SEL_SHIFT);
    825		break;
    826	default:
    827		dev_err(dev, "Invalid VA voltage\n");
    828		ret = -EINVAL;
    829		goto fail_shutdown;
    830	}
    831
    832	pm_runtime_set_active(&i2c_client->dev);
    833	pm_runtime_enable(&i2c_client->dev);
    834
    835	memcpy(&cs4234->rate_dividers, &cs4234_dividers, sizeof(cs4234_dividers));
    836	cs4234->rate_constraint.rats = cs4234->rate_dividers;
    837
    838	ret = snd_soc_register_component(dev, &soc_component_cs4234, cs4234_dai,
    839					 ARRAY_SIZE(cs4234_dai));
    840	if (ret < 0) {
    841		dev_err(dev, "Failed to register component:%d\n", ret);
    842		pm_runtime_disable(&i2c_client->dev);
    843		goto fail_shutdown;
    844	}
    845
    846	return ret;
    847
    848fail_shutdown:
    849	cs4234_shutdown(cs4234);
    850
    851	return ret;
    852}
    853
    854static int cs4234_i2c_remove(struct i2c_client *i2c_client)
    855{
    856	struct cs4234 *cs4234 = i2c_get_clientdata(i2c_client);
    857	struct device *dev = &i2c_client->dev;
    858
    859	snd_soc_unregister_component(dev);
    860	pm_runtime_disable(dev);
    861	cs4234_shutdown(cs4234);
    862
    863	return 0;
    864}
    865
    866static int __maybe_unused cs4234_runtime_resume(struct device *dev)
    867{
    868	struct cs4234 *cs4234 = dev_get_drvdata(dev);
    869	int ret;
    870
    871	ret = cs4234_powerup(cs4234);
    872	if (ret)
    873		return ret;
    874
    875	regcache_mark_dirty(cs4234->regmap);
    876	regcache_cache_only(cs4234->regmap, false);
    877	ret = regcache_sync(cs4234->regmap);
    878	if (ret) {
    879		dev_err(dev, "Failed to sync regmap: %d\n", ret);
    880		cs4234_shutdown(cs4234);
    881		return ret;
    882	}
    883
    884	return 0;
    885}
    886
    887static int __maybe_unused cs4234_runtime_suspend(struct device *dev)
    888{
    889	struct cs4234 *cs4234 = dev_get_drvdata(dev);
    890
    891	cs4234_shutdown(cs4234);
    892
    893	return 0;
    894}
    895
    896static const struct dev_pm_ops cs4234_pm = {
    897	SET_RUNTIME_PM_OPS(cs4234_runtime_suspend, cs4234_runtime_resume, NULL)
    898};
    899
    900static const struct of_device_id cs4234_of_match[] = {
    901	{ .compatible = "cirrus,cs4234", },
    902	{ }
    903};
    904MODULE_DEVICE_TABLE(of, cs4234_of_match);
    905
    906static struct i2c_driver cs4234_i2c_driver = {
    907	.driver = {
    908		.name = "cs4234",
    909		.pm = &cs4234_pm,
    910		.of_match_table = cs4234_of_match,
    911	},
    912	.probe_new =	cs4234_i2c_probe,
    913	.remove =	cs4234_i2c_remove,
    914};
    915module_i2c_driver(cs4234_i2c_driver);
    916
    917MODULE_DESCRIPTION("ASoC Cirrus Logic CS4234 driver");
    918MODULE_AUTHOR("Lucas Tanure <tanureal@opensource.cirrus.com>");
    919MODULE_LICENSE("GPL v2");