diff options
Diffstat (limited to 'sound/soc/codecs/cs42l73.c')
-rw-r--r-- | sound/soc/codecs/cs42l73.c | 114 |
1 files changed, 37 insertions, 77 deletions
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 549d5d6..3b20c86 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -17,7 +17,6 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/delay.h> -#include <linux/of_gpio.h> #include <linux/pm.h> #include <linux/i2c.h> #include <linux/regmap.h> @@ -29,7 +28,6 @@ #include <sound/soc-dapm.h> #include <sound/initval.h> #include <sound/tlv.h> -#include <sound/cs42l73.h> #include "cs42l73.h" struct sp_config { @@ -37,7 +35,6 @@ struct sp_config { u32 srate; }; struct cs42l73_private { - struct cs42l73_platform_data pdata; struct sp_config config[3]; struct regmap *regmap; u32 sysclk; @@ -313,6 +310,15 @@ static const struct soc_enum ng_delay_enum = SOC_ENUM_SINGLE(CS42L73_NGCAB, 0, ARRAY_SIZE(cs42l73_ng_delay_text), cs42l73_ng_delay_text); +static const char * const charge_pump_freq_text[] = { + "0", "1", "2", "3", "4", + "5", "6", "7", "8", "9", + "10", "11", "12", "13", "14", "15" }; + +static const struct soc_enum charge_pump_enum = + SOC_ENUM_SINGLE(CS42L73_CPFCHC, 4, + ARRAY_SIZE(charge_pump_freq_text), charge_pump_freq_text); + static const char * const cs42l73_mono_mix_texts[] = { "Left", "Right", "Mono Mix"}; @@ -505,6 +511,8 @@ static const struct snd_kcontrol_new cs42l73_snd_controls[] = { SOC_SINGLE("NG Threshold", CS42L73_NGCAB, 2, 7, 0), SOC_ENUM("NG Delay", ng_delay_enum), + SOC_ENUM("Charge Pump Frequency", charge_pump_enum), + SOC_DOUBLE_R_TLV("XSP-IP Volume", CS42L73_XSPAIPAA, CS42L73_XSPBIPBA, 0, 0x3F, 1, attn_tlv), @@ -1047,11 +1055,11 @@ static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBM_CFM: - mmcc |= CS42L73_MS_MASTER; + mmcc |= MS_MASTER; break; case SND_SOC_DAIFMT_CBS_CFS: - mmcc &= ~CS42L73_MS_MASTER; + mmcc &= ~MS_MASTER; break; default: @@ -1063,11 +1071,11 @@ static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) switch (format) { case SND_SOC_DAIFMT_I2S: - spc &= ~CS42L73_SPDIF_PCM; + spc &= ~SPDIF_PCM; break; case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_B: - if (mmcc & CS42L73_MS_MASTER) { + if (mmcc & MS_MASTER) { dev_err(codec->dev, "PCM format in slave mode only\n"); return -EINVAL; @@ -1077,25 +1085,25 @@ static int cs42l73_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) "PCM format is not supported on ASP port\n"); return -EINVAL; } - spc |= CS42L73_SPDIF_PCM; + spc |= SPDIF_PCM; break; default: return -EINVAL; } - if (spc & CS42L73_SPDIF_PCM) { + if (spc & SPDIF_PCM) { /* Clear PCM mode, clear PCM_BIT_ORDER bit for MSB->LSB */ - spc &= ~(CS42L73_PCM_MODE_MASK | CS42L73_PCM_BIT_ORDER); + spc &= ~(PCM_MODE_MASK | PCM_BIT_ORDER); switch (format) { case SND_SOC_DAIFMT_DSP_B: if (inv == SND_SOC_DAIFMT_IB_IF) - spc |= CS42L73_PCM_MODE0; + spc |= PCM_MODE0; if (inv == SND_SOC_DAIFMT_IB_NF) - spc |= CS42L73_PCM_MODE1; + spc |= PCM_MODE1; break; case SND_SOC_DAIFMT_DSP_A: if (inv == SND_SOC_DAIFMT_IB_IF) - spc |= CS42L73_PCM_MODE1; + spc |= PCM_MODE1; break; default: return -EINVAL; @@ -1155,7 +1163,7 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream, int mclk_coeff; int srate = params_rate(params); - if (priv->config[id].mmcc & CS42L73_MS_MASTER) { + if (priv->config[id].mmcc & MS_MASTER) { /* CS42L73 Master */ /* MCLK -> srate */ mclk_coeff = @@ -1174,13 +1182,13 @@ static int cs42l73_pcm_hw_params(struct snd_pcm_substream *substream, priv->config[id].spc &= 0xFC; /* Use SCLK=64*Fs if internal MCLK >= 6.4MHz */ if (priv->mclk >= 6400000) - priv->config[id].spc |= CS42L73_MCK_SCLK_64FS; + priv->config[id].spc |= MCK_SCLK_64FS; else - priv->config[id].spc |= CS42L73_MCK_SCLK_MCLK; + priv->config[id].spc |= MCK_SCLK_MCLK; } else { /* CS42L73 Slave */ priv->config[id].spc &= 0xFC; - priv->config[id].spc |= CS42L73_MCK_SCLK_64FS; + priv->config[id].spc |= MCK_SCLK_64FS; } /* Update ASRCs */ priv->config[id].srate = srate; @@ -1200,8 +1208,8 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec, switch (level) { case SND_SOC_BIAS_ON: - snd_soc_update_bits(codec, CS42L73_DMMCC, CS42L73_MCLKDIS, 0); - snd_soc_update_bits(codec, CS42L73_PWRCTL1, CS42L73_PDN, 0); + snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 0); + snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 0); break; case SND_SOC_BIAS_PREPARE: @@ -1212,11 +1220,11 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec, regcache_cache_only(cs42l73->regmap, false); regcache_sync(cs42l73->regmap); } - snd_soc_update_bits(codec, CS42L73_PWRCTL1, CS42L73_PDN, 1); + snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1); break; case SND_SOC_BIAS_OFF: - snd_soc_update_bits(codec, CS42L73_PWRCTL1, CS42L73_PDN, 1); + snd_soc_update_bits(codec, CS42L73_PWRCTL1, PDN, 1); if (cs42l73->shutdwn_delay > 0) { mdelay(cs42l73->shutdwn_delay); cs42l73->shutdwn_delay = 0; @@ -1225,7 +1233,7 @@ static int cs42l73_set_bias_level(struct snd_soc_codec *codec, * down. */ } - snd_soc_update_bits(codec, CS42L73_DMMCC, CS42L73_MCLKDIS, 1); + snd_soc_update_bits(codec, CS42L73_DMMCC, MCLKDIS, 1); break; } codec->dapm.bias_level = level; @@ -1359,16 +1367,11 @@ static int cs42l73_probe(struct snd_soc_codec *codec) return ret; } - cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + regcache_cache_only(cs42l73->regmap, true); - /* Set Charge Pump Frequency */ - if (cs42l73->pdata.chgfreq) - snd_soc_update_bits(codec, CS42L73_CPFCHC, - CS42L73_CHARGEPUMP_MASK, - cs42l73->pdata.chgfreq << 4); + cs42l73_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - /* MCLK1 as master clk */ - cs42l73->mclksel = CS42L73_CLKID_MCLK1; + cs42l73->mclksel = CS42L73_CLKID_MCLK1; /* MCLK1 as master clk */ cs42l73->mclk = 0; return ret; @@ -1412,11 +1415,9 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client, const struct i2c_device_id *id) { struct cs42l73_private *cs42l73; - struct cs42l73_platform_data *pdata = dev_get_platdata(&i2c_client->dev); int ret; unsigned int devid = 0; unsigned int reg; - u32 val32; cs42l73 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l73_private), GFP_KERNEL); @@ -1425,49 +1426,14 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client, return -ENOMEM; } + i2c_set_clientdata(i2c_client, cs42l73); + cs42l73->regmap = devm_regmap_init_i2c(i2c_client, &cs42l73_regmap); if (IS_ERR(cs42l73->regmap)) { ret = PTR_ERR(cs42l73->regmap); dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); return ret; } - - if (pdata) { - cs42l73->pdata = *pdata; - } else { - pdata = devm_kzalloc(&i2c_client->dev, - sizeof(struct cs42l73_platform_data), - GFP_KERNEL); - if (!pdata) { - dev_err(&i2c_client->dev, "could not allocate pdata\n"); - return -ENOMEM; - } - if (i2c_client->dev.of_node) { - if (of_property_read_u32(i2c_client->dev.of_node, - "chgfreq", &val32) >= 0) - pdata->chgfreq = val32; - } - pdata->reset_gpio = of_get_named_gpio(i2c_client->dev.of_node, - "reset-gpio", 0); - cs42l73->pdata = *pdata; - } - - i2c_set_clientdata(i2c_client, cs42l73); - - if (cs42l73->pdata.reset_gpio) { - ret = gpio_request_one(cs42l73->pdata.reset_gpio, - GPIOF_OUT_INIT_HIGH, "CS42L73 /RST"); - if (ret < 0) { - dev_err(&i2c_client->dev, "Failed to request /RST %d: %d\n", - cs42l73->pdata.reset_gpio, ret); - return ret; - } - gpio_set_value_cansleep(cs42l73->pdata.reset_gpio, 0); - gpio_set_value_cansleep(cs42l73->pdata.reset_gpio, 1); - } - - regcache_cache_bypass(cs42l73->regmap, true); - /* initialize codec */ ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, ®); devid = (reg & 0xFF) << 12; @@ -1478,6 +1444,7 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client, ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_E, ®); devid |= (reg & 0xF0) >> 4; + if (devid != CS42L73_DEVID) { ret = -ENODEV; dev_err(&i2c_client->dev, @@ -1495,7 +1462,7 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client, dev_info(&i2c_client->dev, "Cirrus Logic CS42L73, Revision: %02X\n", reg & 0xFF); - regcache_cache_bypass(cs42l73->regmap, false); + regcache_cache_only(cs42l73->regmap, true); ret = snd_soc_register_codec(&i2c_client->dev, &soc_codec_dev_cs42l73, cs42l73_dai, @@ -1511,12 +1478,6 @@ static int cs42l73_i2c_remove(struct i2c_client *client) return 0; } -static const struct of_device_id cs42l73_of_match[] = { - { .compatible = "cirrus,cs42l73", }, - {}, -}; -MODULE_DEVICE_TABLE(of, cs42l73_of_match); - static const struct i2c_device_id cs42l73_id[] = { {"cs42l73", 0}, {} @@ -1528,7 +1489,6 @@ static struct i2c_driver cs42l73_i2c_driver = { .driver = { .name = "cs42l73", .owner = THIS_MODULE, - .of_match_table = cs42l73_of_match, }, .id_table = cs42l73_id, .probe = cs42l73_i2c_probe, |