diff options
Diffstat (limited to 'sound/soc/codecs/cs42l52.c')
-rw-r--r-- | sound/soc/codecs/cs42l52.c | 105 |
1 files changed, 75 insertions, 30 deletions
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 8b427c9..0bac6d5 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -17,7 +17,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/delay.h> -#include <linux/gpio.h> +#include <linux/of_gpio.h> #include <linux/pm.h> #include <linux/i2c.h> #include <linux/input.h> @@ -50,7 +50,7 @@ struct cs42l52_private { u8 mclksel; u32 mclk; u8 flags; -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) +#if IS_ENABLED(CONFIG_INPUT) struct input_dev *beep; struct work_struct beep_work; int beep_rate; @@ -233,7 +233,7 @@ static const struct soc_enum mic_bias_level_enum = SOC_ENUM_SINGLE(CS42L52_IFACE_CTL2, 0, ARRAY_SIZE(mic_bias_level_text), mic_bias_level_text); -static const char * const cs42l52_mic_text[] = { "Single", "Differential" }; +static const char * const cs42l52_mic_text[] = { "MIC1", "MIC2" }; static const struct soc_enum mica_enum = SOC_ENUM_SINGLE(CS42L52_MICA_CTL, 5, @@ -243,12 +243,6 @@ static const struct soc_enum micb_enum = SOC_ENUM_SINGLE(CS42L52_MICB_CTL, 5, ARRAY_SIZE(cs42l52_mic_text), cs42l52_mic_text); -static const struct snd_kcontrol_new mica_mux = - SOC_DAPM_ENUM("Left Mic Input Capture Mux", mica_enum); - -static const struct snd_kcontrol_new micb_mux = - SOC_DAPM_ENUM("Right Mic Input Capture Mux", micb_enum); - static const char * const digital_output_mux_text[] = {"ADC", "DSP"}; static const struct soc_enum digital_output_mux_enum = @@ -531,6 +525,30 @@ static const struct snd_kcontrol_new cs42l52_snd_controls[] = { }; +static const struct snd_kcontrol_new cs42l52_mica_controls[] = { + SOC_ENUM("MICA Select", mica_enum), +}; + +static const struct snd_kcontrol_new cs42l52_micb_controls[] = { + SOC_ENUM("MICB Select", micb_enum), +}; + +static int cs42l52_add_mic_controls(struct snd_soc_codec *codec) +{ + struct cs42l52_private *cs42l52 = snd_soc_codec_get_drvdata(codec); + struct cs42l52_platform_data *pdata = &cs42l52->pdata; + + if (!pdata->mica_diff_cfg) + snd_soc_add_codec_controls(codec, cs42l52_mica_controls, + ARRAY_SIZE(cs42l52_mica_controls)); + + if (!pdata->micb_diff_cfg) + snd_soc_add_codec_controls(codec, cs42l52_micb_controls, + ARRAY_SIZE(cs42l52_micb_controls)); + + return 0; +} + static const struct snd_soc_dapm_widget cs42l52_dapm_widgets[] = { SND_SOC_DAPM_INPUT("AIN1L"), @@ -550,9 +568,6 @@ static const struct snd_soc_dapm_widget cs42l52_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("AIFOUTR", NULL, 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_MUX("MICA Mux", SND_SOC_NOPM, 0, 0, &mica_mux), - SND_SOC_DAPM_MUX("MICB Mux", SND_SOC_NOPM, 0, 0, &micb_mux), - SND_SOC_DAPM_ADC("ADC Left", NULL, CS42L52_PWRCTL1, 1, 1), SND_SOC_DAPM_ADC("ADC Right", NULL, CS42L52_PWRCTL1, 2, 1), SND_SOC_DAPM_PGA("PGA Left", CS42L52_PWRCTL1, 3, 1, NULL, 0), @@ -953,7 +968,7 @@ static int cs42l52_resume(struct snd_soc_codec *codec) return 0; } -#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) +#if IS_ENABLED(CONFIG_INPUT) static int beep_rates[] = { 261, 522, 585, 667, 706, 774, 889, 1000, 1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182 @@ -1110,6 +1125,8 @@ static int cs42l52_probe(struct snd_soc_codec *codec) } regcache_cache_only(cs42l52->regmap, true); + cs42l52_add_mic_controls(codec); + cs42l52_init_beep(codec); cs42l52_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -1176,6 +1193,7 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, int ret; unsigned int devid = 0; unsigned int reg; + u32 val32; cs42l52 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l52_private), GFP_KERNEL); @@ -1189,9 +1207,39 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); return ret; } - - if (pdata) + if (pdata) { + cs42l52->pdata = *pdata; + } else { + pdata = devm_kzalloc(&i2c_client->dev, + sizeof(struct cs42l52_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_bool(i2c_client->dev.of_node, + "cirrus,mica-differential-cfg")) + pdata->mica_diff_cfg = true; + + if (of_property_read_bool(i2c_client->dev.of_node, + "cirrus,micb-differential-cfg")) + pdata->micb_diff_cfg = true; + + if (of_property_read_u32(i2c_client->dev.of_node, + "cirrus,micbias-lvl", &val32) >= 0) + pdata->micbias_lvl = val32; + + if (of_property_read_u32(i2c_client->dev.of_node, + "cirrus,chgfreq-divisor", &val32) >= 0) + pdata->chgfreq = val32; + + pdata->reset_gpio = + of_get_named_gpio(i2c_client->dev.of_node, + "cirrus,reset-gpio", 0); + } cs42l52->pdata = *pdata; + } if (cs42l52->pdata.reset_gpio) { ret = gpio_request_one(cs42l52->pdata.reset_gpio, @@ -1227,29 +1275,18 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, reg & 0xFF); /* Set Platform Data */ - if (cs42l52->pdata.mica_cfg) + if (cs42l52->pdata.mica_diff_cfg) regmap_update_bits(cs42l52->regmap, CS42L52_MICA_CTL, CS42L52_MIC_CTL_TYPE_MASK, - cs42l52->pdata.mica_cfg << + cs42l52->pdata.mica_diff_cfg << CS42L52_MIC_CTL_TYPE_SHIFT); - if (cs42l52->pdata.micb_cfg) + if (cs42l52->pdata.micb_diff_cfg) regmap_update_bits(cs42l52->regmap, CS42L52_MICB_CTL, CS42L52_MIC_CTL_TYPE_MASK, - cs42l52->pdata.micb_cfg << + cs42l52->pdata.micb_diff_cfg << CS42L52_MIC_CTL_TYPE_SHIFT); - if (cs42l52->pdata.mica_sel) - regmap_update_bits(cs42l52->regmap, CS42L52_MICA_CTL, - CS42L52_MIC_CTL_MIC_SEL_MASK, - cs42l52->pdata.mica_sel << - CS42L52_MIC_CTL_MIC_SEL_SHIFT); - if (cs42l52->pdata.micb_sel) - regmap_update_bits(cs42l52->regmap, CS42L52_MICB_CTL, - CS42L52_MIC_CTL_MIC_SEL_MASK, - cs42l52->pdata.micb_sel << - CS42L52_MIC_CTL_MIC_SEL_SHIFT); - if (cs42l52->pdata.chgfreq) regmap_update_bits(cs42l52->regmap, CS42L52_CHARGE_PUMP, CS42L52_CHARGE_PUMP_MASK, @@ -1274,6 +1311,13 @@ static int cs42l52_i2c_remove(struct i2c_client *client) return 0; } +static const struct of_device_id cs42l52_of_match[] = { + { .compatible = "cirrus,cs42l52", }, + {}, +}; +MODULE_DEVICE_TABLE(of, cs42l52_of_match); + + static const struct i2c_device_id cs42l52_id[] = { { "cs42l52", 0 }, { } @@ -1284,6 +1328,7 @@ static struct i2c_driver cs42l52_i2c_driver = { .driver = { .name = "cs42l52", .owner = THIS_MODULE, + .of_match_table = cs42l52_of_match, }, .id_table = cs42l52_id, .probe = cs42l52_i2c_probe, |