Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 //
0003 // TSE-850 audio - ASoC driver for the Axentia TSE-850 with a PCM5142 codec
0004 //
0005 // Copyright (C) 2016 Axentia Technologies AB
0006 //
0007 // Author: Peter Rosin <peda@axentia.se>
0008 //
0009 //               loop1 relays
0010 //   IN1 +---o  +------------+  o---+ OUT1
0011 //            \                /
0012 //             +              +
0013 //             |   /          |
0014 //             +--o  +--.     |
0015 //             |  add   |     |
0016 //             |        V     |
0017 //             |      .---.   |
0018 //   DAC +----------->|Sum|---+
0019 //             |      '---'   |
0020 //             |              |
0021 //             +              +
0022 //
0023 //   IN2 +---o--+------------+--o---+ OUT2
0024 //               loop2 relays
0025 //
0026 // The 'loop1' gpio pin controls two relays, which are either in loop
0027 // position, meaning that input and output are directly connected, or
0028 // they are in mixer position, meaning that the signal is passed through
0029 // the 'Sum' mixer. Similarly for 'loop2'.
0030 //
0031 // In the above, the 'loop1' relays are inactive, thus feeding IN1 to the
0032 // mixer (if 'add' is active) and feeding the mixer output to OUT1. The
0033 // 'loop2' relays are active, short-cutting the TSE-850 from channel 2.
0034 // IN1, IN2, OUT1 and OUT2 are TSE-850 connectors and DAC is the PCB name
0035 // of the (filtered) output from the PCM5142 codec.
0036 
0037 #include <linux/clk.h>
0038 #include <linux/gpio.h>
0039 #include <linux/module.h>
0040 #include <linux/of.h>
0041 #include <linux/of_device.h>
0042 #include <linux/of_gpio.h>
0043 #include <linux/regulator/consumer.h>
0044 
0045 #include <sound/soc.h>
0046 #include <sound/pcm_params.h>
0047 
0048 struct tse850_priv {
0049     struct gpio_desc *add;
0050     struct gpio_desc *loop1;
0051     struct gpio_desc *loop2;
0052 
0053     struct regulator *ana;
0054 
0055     int add_cache;
0056     int loop1_cache;
0057     int loop2_cache;
0058 };
0059 
0060 static int tse850_get_mux1(struct snd_kcontrol *kctrl,
0061                struct snd_ctl_elem_value *ucontrol)
0062 {
0063     struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl);
0064     struct snd_soc_card *card = dapm->card;
0065     struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
0066 
0067     ucontrol->value.enumerated.item[0] = tse850->loop1_cache;
0068 
0069     return 0;
0070 }
0071 
0072 static int tse850_put_mux1(struct snd_kcontrol *kctrl,
0073                struct snd_ctl_elem_value *ucontrol)
0074 {
0075     struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl);
0076     struct snd_soc_card *card = dapm->card;
0077     struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
0078     struct soc_enum *e = (struct soc_enum *)kctrl->private_value;
0079     unsigned int val = ucontrol->value.enumerated.item[0];
0080 
0081     if (val >= e->items)
0082         return -EINVAL;
0083 
0084     gpiod_set_value_cansleep(tse850->loop1, val);
0085     tse850->loop1_cache = val;
0086 
0087     return snd_soc_dapm_put_enum_double(kctrl, ucontrol);
0088 }
0089 
0090 static int tse850_get_mux2(struct snd_kcontrol *kctrl,
0091                struct snd_ctl_elem_value *ucontrol)
0092 {
0093     struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl);
0094     struct snd_soc_card *card = dapm->card;
0095     struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
0096 
0097     ucontrol->value.enumerated.item[0] = tse850->loop2_cache;
0098 
0099     return 0;
0100 }
0101 
0102 static int tse850_put_mux2(struct snd_kcontrol *kctrl,
0103                struct snd_ctl_elem_value *ucontrol)
0104 {
0105     struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl);
0106     struct snd_soc_card *card = dapm->card;
0107     struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
0108     struct soc_enum *e = (struct soc_enum *)kctrl->private_value;
0109     unsigned int val = ucontrol->value.enumerated.item[0];
0110 
0111     if (val >= e->items)
0112         return -EINVAL;
0113 
0114     gpiod_set_value_cansleep(tse850->loop2, val);
0115     tse850->loop2_cache = val;
0116 
0117     return snd_soc_dapm_put_enum_double(kctrl, ucontrol);
0118 }
0119 
0120 static int tse850_get_mix(struct snd_kcontrol *kctrl,
0121               struct snd_ctl_elem_value *ucontrol)
0122 {
0123     struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl);
0124     struct snd_soc_card *card = dapm->card;
0125     struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
0126 
0127     ucontrol->value.enumerated.item[0] = tse850->add_cache;
0128 
0129     return 0;
0130 }
0131 
0132 static int tse850_put_mix(struct snd_kcontrol *kctrl,
0133               struct snd_ctl_elem_value *ucontrol)
0134 {
0135     struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl);
0136     struct snd_soc_card *card = dapm->card;
0137     struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
0138     int connect = !!ucontrol->value.integer.value[0];
0139 
0140     if (tse850->add_cache == connect)
0141         return 0;
0142 
0143     /*
0144      * Hmmm, this gpiod_set_value_cansleep call should probably happen
0145      * inside snd_soc_dapm_mixer_update_power in the loop.
0146      */
0147     gpiod_set_value_cansleep(tse850->add, connect);
0148     tse850->add_cache = connect;
0149 
0150     snd_soc_dapm_mixer_update_power(dapm, kctrl, connect, NULL);
0151     return 1;
0152 }
0153 
0154 static int tse850_get_ana(struct snd_kcontrol *kctrl,
0155               struct snd_ctl_elem_value *ucontrol)
0156 {
0157     struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl);
0158     struct snd_soc_card *card = dapm->card;
0159     struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
0160     int ret;
0161 
0162     ret = regulator_get_voltage(tse850->ana);
0163     if (ret < 0)
0164         return ret;
0165 
0166     /*
0167      * Map regulator output values like so:
0168      *      -11.5V to "Low" (enum 0)
0169      * 11.5V-12.5V to "12V" (enum 1)
0170      * 12.5V-13.5V to "13V" (enum 2)
0171      *     ...
0172      * 18.5V-19.5V to "19V" (enum 8)
0173      * 19.5V-      to "20V" (enum 9)
0174      */
0175     if (ret < 11000000)
0176         ret = 11000000;
0177     else if (ret > 20000000)
0178         ret = 20000000;
0179     ret -= 11000000;
0180     ret = (ret + 500000) / 1000000;
0181 
0182     ucontrol->value.enumerated.item[0] = ret;
0183 
0184     return 0;
0185 }
0186 
0187 static int tse850_put_ana(struct snd_kcontrol *kctrl,
0188               struct snd_ctl_elem_value *ucontrol)
0189 {
0190     struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl);
0191     struct snd_soc_card *card = dapm->card;
0192     struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
0193     struct soc_enum *e = (struct soc_enum *)kctrl->private_value;
0194     unsigned int uV = ucontrol->value.enumerated.item[0];
0195     int ret;
0196 
0197     if (uV >= e->items)
0198         return -EINVAL;
0199 
0200     /*
0201      * Map enum zero (Low) to 2 volts on the regulator, do this since
0202      * the ana regulator is supplied by the system 12V voltage and
0203      * requesting anything below the system voltage causes the system
0204      * voltage to be passed through the regulator. Also, the ana
0205      * regulator induces noise when requesting voltages near the
0206      * system voltage. So, by mapping Low to 2V, that noise is
0207      * eliminated when all that is needed is 12V (the system voltage).
0208      */
0209     if (uV)
0210         uV = 11000000 + (1000000 * uV);
0211     else
0212         uV = 2000000;
0213 
0214     ret = regulator_set_voltage(tse850->ana, uV, uV);
0215     if (ret < 0)
0216         return ret;
0217 
0218     return snd_soc_dapm_put_enum_double(kctrl, ucontrol);
0219 }
0220 
0221 static const char * const mux_text[] = { "Mixer", "Loop" };
0222 
0223 static const struct soc_enum mux_enum =
0224     SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(mux_text), mux_text);
0225 
0226 static const struct snd_kcontrol_new mux1 =
0227     SOC_DAPM_ENUM_EXT("MUX1", mux_enum, tse850_get_mux1, tse850_put_mux1);
0228 
0229 static const struct snd_kcontrol_new mux2 =
0230     SOC_DAPM_ENUM_EXT("MUX2", mux_enum, tse850_get_mux2, tse850_put_mux2);
0231 
0232 #define TSE850_DAPM_SINGLE_EXT(xname, reg, shift, max, invert, xget, xput) \
0233 {   .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
0234     .info = snd_soc_info_volsw, \
0235     .get = xget, \
0236     .put = xput, \
0237     .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert, 0) }
0238 
0239 static const struct snd_kcontrol_new mix[] = {
0240     TSE850_DAPM_SINGLE_EXT("IN Switch", SND_SOC_NOPM, 0, 1, 0,
0241                    tse850_get_mix, tse850_put_mix),
0242 };
0243 
0244 static const char * const ana_text[] = {
0245     "Low", "12V", "13V", "14V", "15V", "16V", "17V", "18V", "19V", "20V"
0246 };
0247 
0248 static const struct soc_enum ana_enum =
0249     SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(ana_text), ana_text);
0250 
0251 static const struct snd_kcontrol_new out =
0252     SOC_DAPM_ENUM_EXT("ANA", ana_enum, tse850_get_ana, tse850_put_ana);
0253 
0254 static const struct snd_soc_dapm_widget tse850_dapm_widgets[] = {
0255     SND_SOC_DAPM_LINE("OUT1", NULL),
0256     SND_SOC_DAPM_LINE("OUT2", NULL),
0257     SND_SOC_DAPM_LINE("IN1", NULL),
0258     SND_SOC_DAPM_LINE("IN2", NULL),
0259     SND_SOC_DAPM_INPUT("DAC"),
0260     SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
0261     SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
0262     SOC_MIXER_ARRAY("MIX", SND_SOC_NOPM, 0, 0, mix),
0263     SND_SOC_DAPM_MUX("MUX1", SND_SOC_NOPM, 0, 0, &mux1),
0264     SND_SOC_DAPM_MUX("MUX2", SND_SOC_NOPM, 0, 0, &mux2),
0265     SND_SOC_DAPM_OUT_DRV("OUT", SND_SOC_NOPM, 0, 0, &out, 1),
0266 };
0267 
0268 /*
0269  * These connections are not entirely correct, since both IN1 and IN2
0270  * are always fed to MIX (if the "IN switch" is set so), i.e. without
0271  * regard to the loop1 and loop2 relays that according to this only
0272  * control MUX1 and MUX2 but in fact also control how the input signals
0273  * are routed.
0274  * But, 1) I don't know how to do it right, and 2) it doesn't seem to
0275  * matter in practice since nothing is powered in those sections anyway.
0276  */
0277 static const struct snd_soc_dapm_route tse850_intercon[] = {
0278     { "OUT1", NULL, "MUX1" },
0279     { "OUT2", NULL, "MUX2" },
0280 
0281     { "MUX1", "Loop",  "IN1" },
0282     { "MUX1", "Mixer", "OUT" },
0283 
0284     { "MUX2", "Loop",  "IN2" },
0285     { "MUX2", "Mixer", "OUT" },
0286 
0287     { "OUT", NULL, "MIX" },
0288 
0289     { "MIX", NULL, "DAC" },
0290     { "MIX", "IN Switch", "IN1" },
0291     { "MIX", "IN Switch", "IN2" },
0292 
0293     /* connect board input to the codec left channel output pin */
0294     { "DAC", NULL, "OUTL" },
0295 };
0296 
0297 SND_SOC_DAILINK_DEFS(pcm,
0298     DAILINK_COMP_ARRAY(COMP_EMPTY()),
0299     DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "pcm512x-hifi")),
0300     DAILINK_COMP_ARRAY(COMP_EMPTY()));
0301 
0302 static struct snd_soc_dai_link tse850_dailink = {
0303     .name = "TSE-850",
0304     .stream_name = "TSE-850-PCM",
0305     .dai_fmt = SND_SOC_DAIFMT_I2S
0306          | SND_SOC_DAIFMT_NB_NF
0307          | SND_SOC_DAIFMT_CBP_CFC,
0308     SND_SOC_DAILINK_REG(pcm),
0309 };
0310 
0311 static struct snd_soc_card tse850_card = {
0312     .name = "TSE-850-ASoC",
0313     .owner = THIS_MODULE,
0314     .dai_link = &tse850_dailink,
0315     .num_links = 1,
0316     .dapm_widgets = tse850_dapm_widgets,
0317     .num_dapm_widgets = ARRAY_SIZE(tse850_dapm_widgets),
0318     .dapm_routes = tse850_intercon,
0319     .num_dapm_routes = ARRAY_SIZE(tse850_intercon),
0320     .fully_routed = true,
0321 };
0322 
0323 static int tse850_dt_init(struct platform_device *pdev)
0324 {
0325     struct device_node *np = pdev->dev.of_node;
0326     struct device_node *codec_np, *cpu_np;
0327     struct snd_soc_dai_link *dailink = &tse850_dailink;
0328 
0329     if (!np) {
0330         dev_err(&pdev->dev, "only device tree supported\n");
0331         return -EINVAL;
0332     }
0333 
0334     cpu_np = of_parse_phandle(np, "axentia,cpu-dai", 0);
0335     if (!cpu_np) {
0336         dev_err(&pdev->dev, "failed to get cpu dai\n");
0337         return -EINVAL;
0338     }
0339     dailink->cpus->of_node = cpu_np;
0340     dailink->platforms->of_node = cpu_np;
0341     of_node_put(cpu_np);
0342 
0343     codec_np = of_parse_phandle(np, "axentia,audio-codec", 0);
0344     if (!codec_np) {
0345         dev_err(&pdev->dev, "failed to get codec info\n");
0346         return -EINVAL;
0347     }
0348     dailink->codecs->of_node = codec_np;
0349     of_node_put(codec_np);
0350 
0351     return 0;
0352 }
0353 
0354 static int tse850_probe(struct platform_device *pdev)
0355 {
0356     struct snd_soc_card *card = &tse850_card;
0357     struct device *dev = card->dev = &pdev->dev;
0358     struct tse850_priv *tse850;
0359     int ret;
0360 
0361     tse850 = devm_kzalloc(dev, sizeof(*tse850), GFP_KERNEL);
0362     if (!tse850)
0363         return -ENOMEM;
0364 
0365     snd_soc_card_set_drvdata(card, tse850);
0366 
0367     ret = tse850_dt_init(pdev);
0368     if (ret) {
0369         dev_err(dev, "failed to init dt info\n");
0370         return ret;
0371     }
0372 
0373     tse850->add = devm_gpiod_get(dev, "axentia,add", GPIOD_OUT_HIGH);
0374     if (IS_ERR(tse850->add))
0375         return dev_err_probe(dev, PTR_ERR(tse850->add),
0376                      "failed to get 'add' gpio\n");
0377     tse850->add_cache = 1;
0378 
0379     tse850->loop1 = devm_gpiod_get(dev, "axentia,loop1", GPIOD_OUT_HIGH);
0380     if (IS_ERR(tse850->loop1))
0381         return dev_err_probe(dev, PTR_ERR(tse850->loop1),
0382                      "failed to get 'loop1' gpio\n");
0383     tse850->loop1_cache = 1;
0384 
0385     tse850->loop2 = devm_gpiod_get(dev, "axentia,loop2", GPIOD_OUT_HIGH);
0386     if (IS_ERR(tse850->loop2))
0387         return dev_err_probe(dev, PTR_ERR(tse850->loop2),
0388                      "failed to get 'loop2' gpio\n");
0389     tse850->loop2_cache = 1;
0390 
0391     tse850->ana = devm_regulator_get(dev, "axentia,ana");
0392     if (IS_ERR(tse850->ana))
0393         return dev_err_probe(dev, PTR_ERR(tse850->ana),
0394                      "failed to get 'ana' regulator\n");
0395 
0396     ret = regulator_enable(tse850->ana);
0397     if (ret < 0) {
0398         dev_err(dev, "failed to enable the 'ana' regulator\n");
0399         return ret;
0400     }
0401 
0402     ret = snd_soc_register_card(card);
0403     if (ret) {
0404         dev_err(dev, "snd_soc_register_card failed\n");
0405         goto err_disable_ana;
0406     }
0407 
0408     return 0;
0409 
0410 err_disable_ana:
0411     regulator_disable(tse850->ana);
0412     return ret;
0413 }
0414 
0415 static int tse850_remove(struct platform_device *pdev)
0416 {
0417     struct snd_soc_card *card = platform_get_drvdata(pdev);
0418     struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
0419 
0420     snd_soc_unregister_card(card);
0421     regulator_disable(tse850->ana);
0422 
0423     return 0;
0424 }
0425 
0426 static const struct of_device_id tse850_dt_ids[] = {
0427     { .compatible = "axentia,tse850-pcm5142", },
0428     { /* sentinel */ }
0429 };
0430 MODULE_DEVICE_TABLE(of, tse850_dt_ids);
0431 
0432 static struct platform_driver tse850_driver = {
0433     .driver = {
0434         .name = "axentia-tse850-pcm5142",
0435         .of_match_table = of_match_ptr(tse850_dt_ids),
0436     },
0437     .probe = tse850_probe,
0438     .remove = tse850_remove,
0439 };
0440 
0441 module_platform_driver(tse850_driver);
0442 
0443 /* Module information */
0444 MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
0445 MODULE_DESCRIPTION("ALSA SoC driver for TSE-850 with PCM5142 codec");
0446 MODULE_LICENSE("GPL v2");