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

cs42l51.c (23505B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * cs42l51.c
      4 *
      5 * ASoC Driver for Cirrus Logic CS42L51 codecs
      6 *
      7 * Copyright (c) 2010 Arnaud Patard <apatard@mandriva.com>
      8 *
      9 * Based on cs4270.c - Copyright (c) Freescale Semiconductor
     10 *
     11 * For now:
     12 *  - Only I2C is support. Not SPI
     13 *  - master mode *NOT* supported
     14 */
     15
     16#include <linux/clk.h>
     17#include <linux/module.h>
     18#include <linux/slab.h>
     19#include <sound/core.h>
     20#include <sound/soc.h>
     21#include <sound/tlv.h>
     22#include <sound/initval.h>
     23#include <sound/pcm_params.h>
     24#include <sound/pcm.h>
     25#include <linux/gpio/consumer.h>
     26#include <linux/regmap.h>
     27#include <linux/regulator/consumer.h>
     28
     29#include "cs42l51.h"
     30
     31enum master_slave_mode {
     32	MODE_SLAVE,
     33	MODE_SLAVE_AUTO,
     34	MODE_MASTER,
     35};
     36
     37static const char * const cs42l51_supply_names[] = {
     38	"VL",
     39	"VD",
     40	"VA",
     41	"VAHP",
     42};
     43
     44struct cs42l51_private {
     45	unsigned int mclk;
     46	struct clk *mclk_handle;
     47	unsigned int audio_mode;	/* The mode (I2S or left-justified) */
     48	enum master_slave_mode func;
     49	struct regulator_bulk_data supplies[ARRAY_SIZE(cs42l51_supply_names)];
     50	struct gpio_desc *reset_gpio;
     51	struct regmap *regmap;
     52};
     53
     54#define CS42L51_FORMATS (SNDRV_PCM_FMTBIT_S16_LE  | SNDRV_PCM_FMTBIT_S18_3LE | \
     55			 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE)
     56
     57static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol,
     58			struct snd_ctl_elem_value *ucontrol)
     59{
     60	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
     61	unsigned long value = snd_soc_component_read(component, CS42L51_PCM_MIXER)&3;
     62
     63	switch (value) {
     64	default:
     65	case 0:
     66		ucontrol->value.enumerated.item[0] = 0;
     67		break;
     68	/* same value : (L+R)/2 and (R+L)/2 */
     69	case 1:
     70	case 2:
     71		ucontrol->value.enumerated.item[0] = 1;
     72		break;
     73	case 3:
     74		ucontrol->value.enumerated.item[0] = 2;
     75		break;
     76	}
     77
     78	return 0;
     79}
     80
     81#define CHAN_MIX_NORMAL	0x00
     82#define CHAN_MIX_BOTH	0x55
     83#define CHAN_MIX_SWAP	0xFF
     84
     85static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol,
     86			struct snd_ctl_elem_value *ucontrol)
     87{
     88	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
     89	unsigned char val;
     90
     91	switch (ucontrol->value.enumerated.item[0]) {
     92	default:
     93	case 0:
     94		val = CHAN_MIX_NORMAL;
     95		break;
     96	case 1:
     97		val = CHAN_MIX_BOTH;
     98		break;
     99	case 2:
    100		val = CHAN_MIX_SWAP;
    101		break;
    102	}
    103
    104	snd_soc_component_write(component, CS42L51_PCM_MIXER, val);
    105
    106	return 1;
    107}
    108
    109static const DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -5150, 50, 0);
    110static const DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0);
    111
    112static const DECLARE_TLV_DB_SCALE(aout_tlv, -10200, 50, 0);
    113
    114static const DECLARE_TLV_DB_SCALE(boost_tlv, 1600, 1600, 0);
    115static const DECLARE_TLV_DB_SCALE(adc_boost_tlv, 2000, 2000, 0);
    116static const char *chan_mix[] = {
    117	"L R",
    118	"L+R",
    119	"R L",
    120};
    121
    122static const DECLARE_TLV_DB_SCALE(pga_tlv, -300, 50, 0);
    123static const DECLARE_TLV_DB_SCALE(adc_att_tlv, -9600, 100, 0);
    124
    125static SOC_ENUM_SINGLE_EXT_DECL(cs42l51_chan_mix, chan_mix);
    126
    127static const struct snd_kcontrol_new cs42l51_snd_controls[] = {
    128	SOC_DOUBLE_R_SX_TLV("PCM Playback Volume",
    129			CS42L51_PCMA_VOL, CS42L51_PCMB_VOL,
    130			0, 0x19, 0x7F, adc_pcm_tlv),
    131	SOC_DOUBLE_R("PCM Playback Switch",
    132			CS42L51_PCMA_VOL, CS42L51_PCMB_VOL, 7, 1, 1),
    133	SOC_DOUBLE_R_SX_TLV("Analog Playback Volume",
    134			CS42L51_AOUTA_VOL, CS42L51_AOUTB_VOL,
    135			0, 0x34, 0xE4, aout_tlv),
    136	SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume",
    137			CS42L51_ADCA_VOL, CS42L51_ADCB_VOL,
    138			0, 0x19, 0x7F, adc_pcm_tlv),
    139	SOC_DOUBLE_R("ADC Mixer Switch",
    140			CS42L51_ADCA_VOL, CS42L51_ADCB_VOL, 7, 1, 1),
    141	SOC_DOUBLE_R_SX_TLV("ADC Attenuator Volume",
    142			CS42L51_ADCA_ATT, CS42L51_ADCB_ATT,
    143			0, 0xA0, 96, adc_att_tlv),
    144	SOC_DOUBLE_R_SX_TLV("PGA Volume",
    145			CS42L51_ALC_PGA_CTL, CS42L51_ALC_PGB_CTL,
    146			0, 0x19, 30, pga_tlv),
    147	SOC_SINGLE("Playback Deemphasis Switch", CS42L51_DAC_CTL, 3, 1, 0),
    148	SOC_SINGLE("Auto-Mute Switch", CS42L51_DAC_CTL, 2, 1, 0),
    149	SOC_SINGLE("Soft Ramp Switch", CS42L51_DAC_CTL, 1, 1, 0),
    150	SOC_SINGLE("Zero Cross Switch", CS42L51_DAC_CTL, 0, 0, 0),
    151	SOC_DOUBLE_TLV("Mic Boost Volume",
    152			CS42L51_MIC_CTL, 0, 1, 1, 0, boost_tlv),
    153	SOC_DOUBLE_TLV("ADC Boost Volume",
    154		       CS42L51_MIC_CTL, 5, 6, 1, 0, adc_boost_tlv),
    155	SOC_SINGLE_TLV("Bass Volume", CS42L51_TONE_CTL, 0, 0xf, 1, tone_tlv),
    156	SOC_SINGLE_TLV("Treble Volume", CS42L51_TONE_CTL, 4, 0xf, 1, tone_tlv),
    157	SOC_ENUM_EXT("PCM channel mixer",
    158			cs42l51_chan_mix,
    159			cs42l51_get_chan_mix, cs42l51_set_chan_mix),
    160};
    161
    162/*
    163 * to power down, one must:
    164 * 1.) Enable the PDN bit
    165 * 2.) enable power-down for the select channels
    166 * 3.) disable the PDN bit.
    167 */
    168static int cs42l51_pdn_event(struct snd_soc_dapm_widget *w,
    169		struct snd_kcontrol *kcontrol, int event)
    170{
    171	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
    172
    173	switch (event) {
    174	case SND_SOC_DAPM_PRE_PMD:
    175		snd_soc_component_update_bits(component, CS42L51_POWER_CTL1,
    176				    CS42L51_POWER_CTL1_PDN,
    177				    CS42L51_POWER_CTL1_PDN);
    178		break;
    179	default:
    180	case SND_SOC_DAPM_POST_PMD:
    181		snd_soc_component_update_bits(component, CS42L51_POWER_CTL1,
    182				    CS42L51_POWER_CTL1_PDN, 0);
    183		break;
    184	}
    185
    186	return 0;
    187}
    188
    189static const char *cs42l51_dac_names[] = {"Direct PCM",
    190	"DSP PCM", "ADC"};
    191static SOC_ENUM_SINGLE_DECL(cs42l51_dac_mux_enum,
    192			    CS42L51_DAC_CTL, 6, cs42l51_dac_names);
    193static const struct snd_kcontrol_new cs42l51_dac_mux_controls =
    194	SOC_DAPM_ENUM("Route", cs42l51_dac_mux_enum);
    195
    196static const char *cs42l51_adcl_names[] = {"AIN1 Left", "AIN2 Left",
    197	"MIC Left", "MIC+preamp Left"};
    198static SOC_ENUM_SINGLE_DECL(cs42l51_adcl_mux_enum,
    199			    CS42L51_ADC_INPUT, 4, cs42l51_adcl_names);
    200static const struct snd_kcontrol_new cs42l51_adcl_mux_controls =
    201	SOC_DAPM_ENUM("Route", cs42l51_adcl_mux_enum);
    202
    203static const char *cs42l51_adcr_names[] = {"AIN1 Right", "AIN2 Right",
    204	"MIC Right", "MIC+preamp Right"};
    205static SOC_ENUM_SINGLE_DECL(cs42l51_adcr_mux_enum,
    206			    CS42L51_ADC_INPUT, 6, cs42l51_adcr_names);
    207static const struct snd_kcontrol_new cs42l51_adcr_mux_controls =
    208	SOC_DAPM_ENUM("Route", cs42l51_adcr_mux_enum);
    209
    210static const struct snd_soc_dapm_widget cs42l51_dapm_widgets[] = {
    211	SND_SOC_DAPM_SUPPLY("Mic Bias", CS42L51_MIC_POWER_CTL, 1, 1, NULL,
    212			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
    213	SND_SOC_DAPM_PGA_E("Left PGA", CS42L51_POWER_CTL1, 3, 1, NULL, 0,
    214		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
    215	SND_SOC_DAPM_PGA_E("Right PGA", CS42L51_POWER_CTL1, 4, 1, NULL, 0,
    216		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
    217	SND_SOC_DAPM_ADC_E("Left ADC", "Left HiFi Capture",
    218		CS42L51_POWER_CTL1, 1, 1,
    219		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
    220	SND_SOC_DAPM_ADC_E("Right ADC", "Right HiFi Capture",
    221		CS42L51_POWER_CTL1, 2, 1,
    222		cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
    223	SND_SOC_DAPM_DAC_E("Left DAC", NULL, CS42L51_POWER_CTL1, 5, 1,
    224			   cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
    225	SND_SOC_DAPM_DAC_E("Right DAC", NULL, CS42L51_POWER_CTL1, 6, 1,
    226			   cs42l51_pdn_event, SND_SOC_DAPM_PRE_POST_PMD),
    227
    228	/* analog/mic */
    229	SND_SOC_DAPM_INPUT("AIN1L"),
    230	SND_SOC_DAPM_INPUT("AIN1R"),
    231	SND_SOC_DAPM_INPUT("AIN2L"),
    232	SND_SOC_DAPM_INPUT("AIN2R"),
    233	SND_SOC_DAPM_INPUT("MICL"),
    234	SND_SOC_DAPM_INPUT("MICR"),
    235
    236	SND_SOC_DAPM_MIXER("Mic Preamp Left",
    237		CS42L51_MIC_POWER_CTL, 2, 1, NULL, 0),
    238	SND_SOC_DAPM_MIXER("Mic Preamp Right",
    239		CS42L51_MIC_POWER_CTL, 3, 1, NULL, 0),
    240
    241	/* HP */
    242	SND_SOC_DAPM_OUTPUT("HPL"),
    243	SND_SOC_DAPM_OUTPUT("HPR"),
    244
    245	/* mux */
    246	SND_SOC_DAPM_MUX("DAC Mux", SND_SOC_NOPM, 0, 0,
    247		&cs42l51_dac_mux_controls),
    248	SND_SOC_DAPM_MUX("PGA-ADC Mux Left", SND_SOC_NOPM, 0, 0,
    249		&cs42l51_adcl_mux_controls),
    250	SND_SOC_DAPM_MUX("PGA-ADC Mux Right", SND_SOC_NOPM, 0, 0,
    251		&cs42l51_adcr_mux_controls),
    252};
    253
    254static int mclk_event(struct snd_soc_dapm_widget *w,
    255		      struct snd_kcontrol *kcontrol, int event)
    256{
    257	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
    258	struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(comp);
    259
    260	switch (event) {
    261	case SND_SOC_DAPM_PRE_PMU:
    262		return clk_prepare_enable(cs42l51->mclk_handle);
    263	case SND_SOC_DAPM_POST_PMD:
    264		/* Delay mclk shutdown to fulfill power-down sequence requirements */
    265		msleep(20);
    266		clk_disable_unprepare(cs42l51->mclk_handle);
    267		break;
    268	}
    269
    270	return 0;
    271}
    272
    273static const struct snd_soc_dapm_widget cs42l51_dapm_mclk_widgets[] = {
    274	SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0, mclk_event,
    275			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
    276};
    277
    278static const struct snd_soc_dapm_route cs42l51_routes[] = {
    279	{"HPL", NULL, "Left DAC"},
    280	{"HPR", NULL, "Right DAC"},
    281
    282	{"Right DAC", NULL, "DAC Mux"},
    283	{"Left DAC", NULL, "DAC Mux"},
    284
    285	{"DAC Mux", "Direct PCM", "Playback"},
    286	{"DAC Mux", "DSP PCM", "Playback"},
    287
    288	{"Left ADC", NULL, "Left PGA"},
    289	{"Right ADC", NULL, "Right PGA"},
    290
    291	{"Mic Preamp Left",  NULL,  "MICL"},
    292	{"Mic Preamp Right", NULL,  "MICR"},
    293
    294	{"PGA-ADC Mux Left",  "AIN1 Left",        "AIN1L" },
    295	{"PGA-ADC Mux Left",  "AIN2 Left",        "AIN2L" },
    296	{"PGA-ADC Mux Left",  "MIC Left",         "MICL"  },
    297	{"PGA-ADC Mux Left",  "MIC+preamp Left",  "Mic Preamp Left" },
    298	{"PGA-ADC Mux Right", "AIN1 Right",       "AIN1R" },
    299	{"PGA-ADC Mux Right", "AIN2 Right",       "AIN2R" },
    300	{"PGA-ADC Mux Right", "MIC Right",        "MICR" },
    301	{"PGA-ADC Mux Right", "MIC+preamp Right", "Mic Preamp Right" },
    302
    303	{"Left PGA", NULL, "PGA-ADC Mux Left"},
    304	{"Right PGA", NULL, "PGA-ADC Mux Right"},
    305};
    306
    307static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai,
    308		unsigned int format)
    309{
    310	struct snd_soc_component *component = codec_dai->component;
    311	struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(component);
    312
    313	switch (format & SND_SOC_DAIFMT_FORMAT_MASK) {
    314	case SND_SOC_DAIFMT_I2S:
    315	case SND_SOC_DAIFMT_LEFT_J:
    316	case SND_SOC_DAIFMT_RIGHT_J:
    317		cs42l51->audio_mode = format & SND_SOC_DAIFMT_FORMAT_MASK;
    318		break;
    319	default:
    320		dev_err(component->dev, "invalid DAI format\n");
    321		return -EINVAL;
    322	}
    323
    324	switch (format & SND_SOC_DAIFMT_MASTER_MASK) {
    325	case SND_SOC_DAIFMT_CBM_CFM:
    326		cs42l51->func = MODE_MASTER;
    327		break;
    328	case SND_SOC_DAIFMT_CBS_CFS:
    329		cs42l51->func = MODE_SLAVE_AUTO;
    330		break;
    331	default:
    332		dev_err(component->dev, "Unknown master/slave configuration\n");
    333		return -EINVAL;
    334	}
    335
    336	return 0;
    337}
    338
    339struct cs42l51_ratios {
    340	unsigned int ratio;
    341	unsigned char speed_mode;
    342	unsigned char mclk;
    343};
    344
    345static struct cs42l51_ratios slave_ratios[] = {
    346	{  512, CS42L51_QSM_MODE, 0 }, {  768, CS42L51_QSM_MODE, 0 },
    347	{ 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 },
    348	{ 2048, CS42L51_QSM_MODE, 0 }, { 3072, CS42L51_QSM_MODE, 0 },
    349	{  256, CS42L51_HSM_MODE, 0 }, {  384, CS42L51_HSM_MODE, 0 },
    350	{  512, CS42L51_HSM_MODE, 0 }, {  768, CS42L51_HSM_MODE, 0 },
    351	{ 1024, CS42L51_HSM_MODE, 0 }, { 1536, CS42L51_HSM_MODE, 0 },
    352	{  128, CS42L51_SSM_MODE, 0 }, {  192, CS42L51_SSM_MODE, 0 },
    353	{  256, CS42L51_SSM_MODE, 0 }, {  384, CS42L51_SSM_MODE, 0 },
    354	{  512, CS42L51_SSM_MODE, 0 }, {  768, CS42L51_SSM_MODE, 0 },
    355	{  128, CS42L51_DSM_MODE, 0 }, {  192, CS42L51_DSM_MODE, 0 },
    356	{  256, CS42L51_DSM_MODE, 0 }, {  384, CS42L51_DSM_MODE, 0 },
    357};
    358
    359static struct cs42l51_ratios slave_auto_ratios[] = {
    360	{ 1024, CS42L51_QSM_MODE, 0 }, { 1536, CS42L51_QSM_MODE, 0 },
    361	{ 2048, CS42L51_QSM_MODE, 1 }, { 3072, CS42L51_QSM_MODE, 1 },
    362	{  512, CS42L51_HSM_MODE, 0 }, {  768, CS42L51_HSM_MODE, 0 },
    363	{ 1024, CS42L51_HSM_MODE, 1 }, { 1536, CS42L51_HSM_MODE, 1 },
    364	{  256, CS42L51_SSM_MODE, 0 }, {  384, CS42L51_SSM_MODE, 0 },
    365	{  512, CS42L51_SSM_MODE, 1 }, {  768, CS42L51_SSM_MODE, 1 },
    366	{  128, CS42L51_DSM_MODE, 0 }, {  192, CS42L51_DSM_MODE, 0 },
    367	{  256, CS42L51_DSM_MODE, 1 }, {  384, CS42L51_DSM_MODE, 1 },
    368};
    369
    370/*
    371 * Master mode mclk/fs ratios.
    372 * Recommended configurations are SSM for 4-50khz and DSM for 50-100kHz ranges
    373 * The table below provides support of following ratios:
    374 * 128: SSM (%128) with div2 disabled
    375 * 256: SSM (%128) with div2 enabled
    376 * In both cases, if sampling rate is above 50kHz, SSM is overridden
    377 * with DSM (%128) configuration
    378 */
    379static struct cs42l51_ratios master_ratios[] = {
    380	{ 128, CS42L51_SSM_MODE, 0 }, { 256, CS42L51_SSM_MODE, 1 },
    381};
    382
    383static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
    384		int clk_id, unsigned int freq, int dir)
    385{
    386	struct snd_soc_component *component = codec_dai->component;
    387	struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(component);
    388
    389	cs42l51->mclk = freq;
    390	return 0;
    391}
    392
    393static int cs42l51_hw_params(struct snd_pcm_substream *substream,
    394		struct snd_pcm_hw_params *params,
    395		struct snd_soc_dai *dai)
    396{
    397	struct snd_soc_component *component = dai->component;
    398	struct cs42l51_private *cs42l51 = snd_soc_component_get_drvdata(component);
    399	int ret;
    400	unsigned int i;
    401	unsigned int rate;
    402	unsigned int ratio;
    403	struct cs42l51_ratios *ratios = NULL;
    404	int nr_ratios = 0;
    405	int intf_ctl, power_ctl, fmt, mode;
    406
    407	switch (cs42l51->func) {
    408	case MODE_MASTER:
    409		ratios = master_ratios;
    410		nr_ratios = ARRAY_SIZE(master_ratios);
    411		break;
    412	case MODE_SLAVE:
    413		ratios = slave_ratios;
    414		nr_ratios = ARRAY_SIZE(slave_ratios);
    415		break;
    416	case MODE_SLAVE_AUTO:
    417		ratios = slave_auto_ratios;
    418		nr_ratios = ARRAY_SIZE(slave_auto_ratios);
    419		break;
    420	}
    421
    422	/* Figure out which MCLK/LRCK ratio to use */
    423	rate = params_rate(params);     /* Sampling rate, in Hz */
    424	ratio = cs42l51->mclk / rate;    /* MCLK/LRCK ratio */
    425	for (i = 0; i < nr_ratios; i++) {
    426		if (ratios[i].ratio == ratio)
    427			break;
    428	}
    429
    430	if (i == nr_ratios) {
    431		/* We did not find a matching ratio */
    432		dev_err(component->dev, "could not find matching ratio\n");
    433		return -EINVAL;
    434	}
    435
    436	intf_ctl = snd_soc_component_read(component, CS42L51_INTF_CTL);
    437	power_ctl = snd_soc_component_read(component, CS42L51_MIC_POWER_CTL);
    438
    439	intf_ctl &= ~(CS42L51_INTF_CTL_MASTER | CS42L51_INTF_CTL_ADC_I2S
    440			| CS42L51_INTF_CTL_DAC_FORMAT(7));
    441	power_ctl &= ~(CS42L51_MIC_POWER_CTL_SPEED(3)
    442			| CS42L51_MIC_POWER_CTL_MCLK_DIV2);
    443
    444	switch (cs42l51->func) {
    445	case MODE_MASTER:
    446		intf_ctl |= CS42L51_INTF_CTL_MASTER;
    447		mode = ratios[i].speed_mode;
    448		/* Force DSM mode if sampling rate is above 50kHz */
    449		if (rate > 50000)
    450			mode = CS42L51_DSM_MODE;
    451		power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(mode);
    452		/*
    453		 * Auto detect mode is not applicable for master mode and has to
    454		 * be disabled. Otherwise SPEED[1:0] bits will be ignored.
    455		 */
    456		power_ctl &= ~CS42L51_MIC_POWER_CTL_AUTO;
    457		break;
    458	case MODE_SLAVE:
    459		power_ctl |= CS42L51_MIC_POWER_CTL_SPEED(ratios[i].speed_mode);
    460		break;
    461	case MODE_SLAVE_AUTO:
    462		power_ctl |= CS42L51_MIC_POWER_CTL_AUTO;
    463		break;
    464	}
    465
    466	switch (cs42l51->audio_mode) {
    467	case SND_SOC_DAIFMT_I2S:
    468		intf_ctl |= CS42L51_INTF_CTL_ADC_I2S;
    469		intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_I2S);
    470		break;
    471	case SND_SOC_DAIFMT_LEFT_J:
    472		intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(CS42L51_DAC_DIF_LJ24);
    473		break;
    474	case SND_SOC_DAIFMT_RIGHT_J:
    475		switch (params_width(params)) {
    476		case 16:
    477			fmt = CS42L51_DAC_DIF_RJ16;
    478			break;
    479		case 18:
    480			fmt = CS42L51_DAC_DIF_RJ18;
    481			break;
    482		case 20:
    483			fmt = CS42L51_DAC_DIF_RJ20;
    484			break;
    485		case 24:
    486			fmt = CS42L51_DAC_DIF_RJ24;
    487			break;
    488		default:
    489			dev_err(component->dev, "unknown format\n");
    490			return -EINVAL;
    491		}
    492		intf_ctl |= CS42L51_INTF_CTL_DAC_FORMAT(fmt);
    493		break;
    494	default:
    495		dev_err(component->dev, "unknown format\n");
    496		return -EINVAL;
    497	}
    498
    499	if (ratios[i].mclk)
    500		power_ctl |= CS42L51_MIC_POWER_CTL_MCLK_DIV2;
    501
    502	ret = snd_soc_component_write(component, CS42L51_INTF_CTL, intf_ctl);
    503	if (ret < 0)
    504		return ret;
    505
    506	ret = snd_soc_component_write(component, CS42L51_MIC_POWER_CTL, power_ctl);
    507	if (ret < 0)
    508		return ret;
    509
    510	return 0;
    511}
    512
    513static int cs42l51_dai_mute(struct snd_soc_dai *dai, int mute, int direction)
    514{
    515	struct snd_soc_component *component = dai->component;
    516	int reg;
    517	int mask = CS42L51_DAC_OUT_CTL_DACA_MUTE|CS42L51_DAC_OUT_CTL_DACB_MUTE;
    518
    519	reg = snd_soc_component_read(component, CS42L51_DAC_OUT_CTL);
    520
    521	if (mute)
    522		reg |= mask;
    523	else
    524		reg &= ~mask;
    525
    526	return snd_soc_component_write(component, CS42L51_DAC_OUT_CTL, reg);
    527}
    528
    529static int cs42l51_of_xlate_dai_id(struct snd_soc_component *component,
    530				   struct device_node *endpoint)
    531{
    532	/* return dai id 0, whatever the endpoint index */
    533	return 0;
    534}
    535
    536static const struct snd_soc_dai_ops cs42l51_dai_ops = {
    537	.hw_params      = cs42l51_hw_params,
    538	.set_sysclk     = cs42l51_set_dai_sysclk,
    539	.set_fmt        = cs42l51_set_dai_fmt,
    540	.mute_stream    = cs42l51_dai_mute,
    541	.no_capture_mute = 1,
    542};
    543
    544static struct snd_soc_dai_driver cs42l51_dai = {
    545	.name = "cs42l51-hifi",
    546	.playback = {
    547		.stream_name = "Playback",
    548		.channels_min = 1,
    549		.channels_max = 2,
    550		.rates = SNDRV_PCM_RATE_8000_96000,
    551		.formats = CS42L51_FORMATS,
    552	},
    553	.capture = {
    554		.stream_name = "Capture",
    555		.channels_min = 1,
    556		.channels_max = 2,
    557		.rates = SNDRV_PCM_RATE_8000_96000,
    558		.formats = CS42L51_FORMATS,
    559	},
    560	.ops = &cs42l51_dai_ops,
    561};
    562
    563static int cs42l51_component_probe(struct snd_soc_component *component)
    564{
    565	int ret, reg;
    566	struct snd_soc_dapm_context *dapm;
    567	struct cs42l51_private *cs42l51;
    568
    569	cs42l51 = snd_soc_component_get_drvdata(component);
    570	dapm = snd_soc_component_get_dapm(component);
    571
    572	if (cs42l51->mclk_handle)
    573		snd_soc_dapm_new_controls(dapm, cs42l51_dapm_mclk_widgets, 1);
    574
    575	/*
    576	 * DAC configuration
    577	 * - Use signal processor
    578	 * - auto mute
    579	 * - vol changes immediate
    580	 * - no de-emphasize
    581	 */
    582	reg = CS42L51_DAC_CTL_DATA_SEL(1)
    583		| CS42L51_DAC_CTL_AMUTE | CS42L51_DAC_CTL_DACSZ(0);
    584	ret = snd_soc_component_write(component, CS42L51_DAC_CTL, reg);
    585	if (ret < 0)
    586		return ret;
    587
    588	return 0;
    589}
    590
    591static const struct snd_soc_component_driver soc_component_device_cs42l51 = {
    592	.probe			= cs42l51_component_probe,
    593	.controls		= cs42l51_snd_controls,
    594	.num_controls		= ARRAY_SIZE(cs42l51_snd_controls),
    595	.dapm_widgets		= cs42l51_dapm_widgets,
    596	.num_dapm_widgets	= ARRAY_SIZE(cs42l51_dapm_widgets),
    597	.dapm_routes		= cs42l51_routes,
    598	.num_dapm_routes	= ARRAY_SIZE(cs42l51_routes),
    599	.of_xlate_dai_id	= cs42l51_of_xlate_dai_id,
    600	.idle_bias_on		= 1,
    601	.use_pmdown_time	= 1,
    602	.endianness		= 1,
    603	.non_legacy_dai_naming	= 1,
    604};
    605
    606static bool cs42l51_writeable_reg(struct device *dev, unsigned int reg)
    607{
    608	switch (reg) {
    609	case CS42L51_POWER_CTL1:
    610	case CS42L51_MIC_POWER_CTL:
    611	case CS42L51_INTF_CTL:
    612	case CS42L51_MIC_CTL:
    613	case CS42L51_ADC_CTL:
    614	case CS42L51_ADC_INPUT:
    615	case CS42L51_DAC_OUT_CTL:
    616	case CS42L51_DAC_CTL:
    617	case CS42L51_ALC_PGA_CTL:
    618	case CS42L51_ALC_PGB_CTL:
    619	case CS42L51_ADCA_ATT:
    620	case CS42L51_ADCB_ATT:
    621	case CS42L51_ADCA_VOL:
    622	case CS42L51_ADCB_VOL:
    623	case CS42L51_PCMA_VOL:
    624	case CS42L51_PCMB_VOL:
    625	case CS42L51_BEEP_FREQ:
    626	case CS42L51_BEEP_VOL:
    627	case CS42L51_BEEP_CONF:
    628	case CS42L51_TONE_CTL:
    629	case CS42L51_AOUTA_VOL:
    630	case CS42L51_AOUTB_VOL:
    631	case CS42L51_PCM_MIXER:
    632	case CS42L51_LIMIT_THRES_DIS:
    633	case CS42L51_LIMIT_REL:
    634	case CS42L51_LIMIT_ATT:
    635	case CS42L51_ALC_EN:
    636	case CS42L51_ALC_REL:
    637	case CS42L51_ALC_THRES:
    638	case CS42L51_NOISE_CONF:
    639	case CS42L51_CHARGE_FREQ:
    640		return true;
    641	default:
    642		return false;
    643	}
    644}
    645
    646static bool cs42l51_volatile_reg(struct device *dev, unsigned int reg)
    647{
    648	switch (reg) {
    649	case CS42L51_STATUS:
    650		return true;
    651	default:
    652		return false;
    653	}
    654}
    655
    656static bool cs42l51_readable_reg(struct device *dev, unsigned int reg)
    657{
    658	switch (reg) {
    659	case CS42L51_CHIP_REV_ID:
    660	case CS42L51_POWER_CTL1:
    661	case CS42L51_MIC_POWER_CTL:
    662	case CS42L51_INTF_CTL:
    663	case CS42L51_MIC_CTL:
    664	case CS42L51_ADC_CTL:
    665	case CS42L51_ADC_INPUT:
    666	case CS42L51_DAC_OUT_CTL:
    667	case CS42L51_DAC_CTL:
    668	case CS42L51_ALC_PGA_CTL:
    669	case CS42L51_ALC_PGB_CTL:
    670	case CS42L51_ADCA_ATT:
    671	case CS42L51_ADCB_ATT:
    672	case CS42L51_ADCA_VOL:
    673	case CS42L51_ADCB_VOL:
    674	case CS42L51_PCMA_VOL:
    675	case CS42L51_PCMB_VOL:
    676	case CS42L51_BEEP_FREQ:
    677	case CS42L51_BEEP_VOL:
    678	case CS42L51_BEEP_CONF:
    679	case CS42L51_TONE_CTL:
    680	case CS42L51_AOUTA_VOL:
    681	case CS42L51_AOUTB_VOL:
    682	case CS42L51_PCM_MIXER:
    683	case CS42L51_LIMIT_THRES_DIS:
    684	case CS42L51_LIMIT_REL:
    685	case CS42L51_LIMIT_ATT:
    686	case CS42L51_ALC_EN:
    687	case CS42L51_ALC_REL:
    688	case CS42L51_ALC_THRES:
    689	case CS42L51_NOISE_CONF:
    690	case CS42L51_STATUS:
    691	case CS42L51_CHARGE_FREQ:
    692		return true;
    693	default:
    694		return false;
    695	}
    696}
    697
    698const struct regmap_config cs42l51_regmap = {
    699	.reg_bits = 8,
    700	.reg_stride = 1,
    701	.val_bits = 8,
    702	.use_single_write = true,
    703	.readable_reg = cs42l51_readable_reg,
    704	.volatile_reg = cs42l51_volatile_reg,
    705	.writeable_reg = cs42l51_writeable_reg,
    706	.max_register = CS42L51_CHARGE_FREQ,
    707	.cache_type = REGCACHE_RBTREE,
    708};
    709EXPORT_SYMBOL_GPL(cs42l51_regmap);
    710
    711int cs42l51_probe(struct device *dev, struct regmap *regmap)
    712{
    713	struct cs42l51_private *cs42l51;
    714	unsigned int val;
    715	int ret, i;
    716
    717	if (IS_ERR(regmap))
    718		return PTR_ERR(regmap);
    719
    720	cs42l51 = devm_kzalloc(dev, sizeof(struct cs42l51_private),
    721			       GFP_KERNEL);
    722	if (!cs42l51)
    723		return -ENOMEM;
    724
    725	dev_set_drvdata(dev, cs42l51);
    726	cs42l51->regmap = regmap;
    727
    728	cs42l51->mclk_handle = devm_clk_get(dev, "MCLK");
    729	if (IS_ERR(cs42l51->mclk_handle)) {
    730		if (PTR_ERR(cs42l51->mclk_handle) != -ENOENT)
    731			return PTR_ERR(cs42l51->mclk_handle);
    732		cs42l51->mclk_handle = NULL;
    733	}
    734
    735	for (i = 0; i < ARRAY_SIZE(cs42l51->supplies); i++)
    736		cs42l51->supplies[i].supply = cs42l51_supply_names[i];
    737
    738	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(cs42l51->supplies),
    739				      cs42l51->supplies);
    740	if (ret != 0) {
    741		dev_err(dev, "Failed to request supplies: %d\n", ret);
    742		return ret;
    743	}
    744
    745	ret = regulator_bulk_enable(ARRAY_SIZE(cs42l51->supplies),
    746				    cs42l51->supplies);
    747	if (ret != 0) {
    748		dev_err(dev, "Failed to enable supplies: %d\n", ret);
    749		return ret;
    750	}
    751
    752	cs42l51->reset_gpio = devm_gpiod_get_optional(dev, "reset",
    753						      GPIOD_OUT_LOW);
    754	if (IS_ERR(cs42l51->reset_gpio))
    755		return PTR_ERR(cs42l51->reset_gpio);
    756
    757	if (cs42l51->reset_gpio) {
    758		dev_dbg(dev, "Release reset gpio\n");
    759		gpiod_set_value_cansleep(cs42l51->reset_gpio, 0);
    760		mdelay(2);
    761	}
    762
    763	/* Verify that we have a CS42L51 */
    764	ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val);
    765	if (ret < 0) {
    766		dev_err(dev, "failed to read I2C\n");
    767		goto error;
    768	}
    769
    770	if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) &&
    771	    (val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) {
    772		dev_err(dev, "Invalid chip id: %x\n", val);
    773		ret = -ENODEV;
    774		goto error;
    775	}
    776	dev_info(dev, "Cirrus Logic CS42L51, Revision: %02X\n",
    777		 val & CS42L51_CHIP_REV_MASK);
    778
    779	ret = devm_snd_soc_register_component(dev,
    780			&soc_component_device_cs42l51, &cs42l51_dai, 1);
    781	if (ret < 0)
    782		goto error;
    783
    784	return 0;
    785
    786error:
    787	regulator_bulk_disable(ARRAY_SIZE(cs42l51->supplies),
    788			       cs42l51->supplies);
    789	return ret;
    790}
    791EXPORT_SYMBOL_GPL(cs42l51_probe);
    792
    793void cs42l51_remove(struct device *dev)
    794{
    795	struct cs42l51_private *cs42l51 = dev_get_drvdata(dev);
    796	int ret;
    797
    798	gpiod_set_value_cansleep(cs42l51->reset_gpio, 1);
    799
    800	ret = regulator_bulk_disable(ARRAY_SIZE(cs42l51->supplies),
    801				     cs42l51->supplies);
    802	if (ret)
    803		dev_warn(dev, "Failed to disable all regulators (%pe)\n",
    804			 ERR_PTR(ret));
    805
    806}
    807EXPORT_SYMBOL_GPL(cs42l51_remove);
    808
    809int __maybe_unused cs42l51_suspend(struct device *dev)
    810{
    811	struct cs42l51_private *cs42l51 = dev_get_drvdata(dev);
    812
    813	regcache_cache_only(cs42l51->regmap, true);
    814	regcache_mark_dirty(cs42l51->regmap);
    815
    816	return 0;
    817}
    818EXPORT_SYMBOL_GPL(cs42l51_suspend);
    819
    820int __maybe_unused cs42l51_resume(struct device *dev)
    821{
    822	struct cs42l51_private *cs42l51 = dev_get_drvdata(dev);
    823
    824	regcache_cache_only(cs42l51->regmap, false);
    825
    826	return regcache_sync(cs42l51->regmap);
    827}
    828EXPORT_SYMBOL_GPL(cs42l51_resume);
    829
    830const struct of_device_id cs42l51_of_match[] = {
    831	{ .compatible = "cirrus,cs42l51", },
    832	{ }
    833};
    834MODULE_DEVICE_TABLE(of, cs42l51_of_match);
    835EXPORT_SYMBOL_GPL(cs42l51_of_match);
    836
    837MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
    838MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver");
    839MODULE_LICENSE("GPL");