Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
0002 //
0003 // Copyright (c) 2018 BayLibre, SAS.
0004 // Author: Jerome Brunet <jbrunet@baylibre.com>
0005 
0006 #include <linux/clk.h>
0007 #include <linux/module.h>
0008 #include <linux/of_platform.h>
0009 #include <linux/regmap.h>
0010 #include <linux/reset.h>
0011 #include <sound/soc.h>
0012 
0013 #include "axg-tdm-formatter.h"
0014 
0015 struct axg_tdm_formatter {
0016     struct list_head list;
0017     struct axg_tdm_stream *stream;
0018     const struct axg_tdm_formatter_driver *drv;
0019     struct clk *pclk;
0020     struct clk *sclk;
0021     struct clk *lrclk;
0022     struct clk *sclk_sel;
0023     struct clk *lrclk_sel;
0024     struct reset_control *reset;
0025     bool enabled;
0026     struct regmap *map;
0027 };
0028 
0029 int axg_tdm_formatter_set_channel_masks(struct regmap *map,
0030                     struct axg_tdm_stream *ts,
0031                     unsigned int offset)
0032 {
0033     unsigned int val, ch = ts->channels;
0034     unsigned long mask;
0035     int i, j;
0036 
0037     /*
0038      * Distribute the channels of the stream over the available slots
0039      * of each TDM lane
0040      */
0041     for (i = 0; i < AXG_TDM_NUM_LANES; i++) {
0042         val = 0;
0043         mask = ts->mask[i];
0044 
0045         for (j = find_first_bit(&mask, 32);
0046              (j < 32) && ch;
0047              j = find_next_bit(&mask, 32, j + 1)) {
0048             val |= 1 << j;
0049             ch -= 1;
0050         }
0051 
0052         regmap_write(map, offset, val);
0053         offset += regmap_get_reg_stride(map);
0054     }
0055 
0056     /*
0057      * If we still have channel left at the end of the process, it means
0058      * the stream has more channels than we can accommodate and we should
0059      * have caught this earlier.
0060      */
0061     if (WARN_ON(ch != 0)) {
0062         pr_err("channel mask error\n");
0063         return -EINVAL;
0064     }
0065 
0066     return 0;
0067 }
0068 EXPORT_SYMBOL_GPL(axg_tdm_formatter_set_channel_masks);
0069 
0070 static int axg_tdm_formatter_enable(struct axg_tdm_formatter *formatter)
0071 {
0072     struct axg_tdm_stream *ts = formatter->stream;
0073     bool invert;
0074     int ret;
0075 
0076     /* Do nothing if the formatter is already enabled */
0077     if (formatter->enabled)
0078         return 0;
0079 
0080     /*
0081      * On the g12a (and possibly other SoCs), when a stream using
0082      * multiple lanes is restarted, it will sometimes not start
0083      * from the first lane, but randomly from another used one.
0084      * The result is an unexpected and random channel shift.
0085      *
0086      * The hypothesis is that an HW counter is not properly reset
0087      * and the formatter simply starts on the lane it stopped
0088      * before. Unfortunately, there does not seems to be a way to
0089      * reset this through the registers of the block.
0090      *
0091      * However, the g12a has indenpendent reset lines for each audio
0092      * devices. Using this reset before each start solves the issue.
0093      */
0094     ret = reset_control_reset(formatter->reset);
0095     if (ret)
0096         return ret;
0097 
0098     /*
0099      * If sclk is inverted, it means the bit should latched on the
0100      * rising edge which is what our HW expects. If not, we need to
0101      * invert it before the formatter.
0102      */
0103     invert = axg_tdm_sclk_invert(ts->iface->fmt);
0104     ret = clk_set_phase(formatter->sclk, invert ? 0 : 180);
0105     if (ret)
0106         return ret;
0107 
0108     /* Setup the stream parameter in the formatter */
0109     ret = formatter->drv->ops->prepare(formatter->map,
0110                        formatter->drv->quirks,
0111                        formatter->stream);
0112     if (ret)
0113         return ret;
0114 
0115     /* Enable the signal clocks feeding the formatter */
0116     ret = clk_prepare_enable(formatter->sclk);
0117     if (ret)
0118         return ret;
0119 
0120     ret = clk_prepare_enable(formatter->lrclk);
0121     if (ret) {
0122         clk_disable_unprepare(formatter->sclk);
0123         return ret;
0124     }
0125 
0126     /* Finally, actually enable the formatter */
0127     formatter->drv->ops->enable(formatter->map);
0128     formatter->enabled = true;
0129 
0130     return 0;
0131 }
0132 
0133 static void axg_tdm_formatter_disable(struct axg_tdm_formatter *formatter)
0134 {
0135     /* Do nothing if the formatter is already disabled */
0136     if (!formatter->enabled)
0137         return;
0138 
0139     formatter->drv->ops->disable(formatter->map);
0140     clk_disable_unprepare(formatter->lrclk);
0141     clk_disable_unprepare(formatter->sclk);
0142     formatter->enabled = false;
0143 }
0144 
0145 static int axg_tdm_formatter_attach(struct axg_tdm_formatter *formatter)
0146 {
0147     struct axg_tdm_stream *ts = formatter->stream;
0148     int ret = 0;
0149 
0150     mutex_lock(&ts->lock);
0151 
0152     /* Catch up if the stream is already running when we attach */
0153     if (ts->ready) {
0154         ret = axg_tdm_formatter_enable(formatter);
0155         if (ret) {
0156             pr_err("failed to enable formatter\n");
0157             goto out;
0158         }
0159     }
0160 
0161     list_add_tail(&formatter->list, &ts->formatter_list);
0162 out:
0163     mutex_unlock(&ts->lock);
0164     return ret;
0165 }
0166 
0167 static void axg_tdm_formatter_dettach(struct axg_tdm_formatter *formatter)
0168 {
0169     struct axg_tdm_stream *ts = formatter->stream;
0170 
0171     mutex_lock(&ts->lock);
0172     list_del(&formatter->list);
0173     mutex_unlock(&ts->lock);
0174 
0175     axg_tdm_formatter_disable(formatter);
0176 }
0177 
0178 static int axg_tdm_formatter_power_up(struct axg_tdm_formatter *formatter,
0179                       struct snd_soc_dapm_widget *w)
0180 {
0181     struct axg_tdm_stream *ts = formatter->drv->ops->get_stream(w);
0182     int ret;
0183 
0184     /*
0185      * If we don't get a stream at this stage, it would mean that the
0186      * widget is powering up but is not attached to any backend DAI.
0187      * It should not happen, ever !
0188      */
0189     if (WARN_ON(!ts))
0190         return -ENODEV;
0191 
0192     /* Clock our device */
0193     ret = clk_prepare_enable(formatter->pclk);
0194     if (ret)
0195         return ret;
0196 
0197     /* Reparent the bit clock to the TDM interface */
0198     ret = clk_set_parent(formatter->sclk_sel, ts->iface->sclk);
0199     if (ret)
0200         goto disable_pclk;
0201 
0202     /* Reparent the sample clock to the TDM interface */
0203     ret = clk_set_parent(formatter->lrclk_sel, ts->iface->lrclk);
0204     if (ret)
0205         goto disable_pclk;
0206 
0207     formatter->stream = ts;
0208     ret = axg_tdm_formatter_attach(formatter);
0209     if (ret)
0210         goto disable_pclk;
0211 
0212     return 0;
0213 
0214 disable_pclk:
0215     clk_disable_unprepare(formatter->pclk);
0216     return ret;
0217 }
0218 
0219 static void axg_tdm_formatter_power_down(struct axg_tdm_formatter *formatter)
0220 {
0221     axg_tdm_formatter_dettach(formatter);
0222     clk_disable_unprepare(formatter->pclk);
0223     formatter->stream = NULL;
0224 }
0225 
0226 int axg_tdm_formatter_event(struct snd_soc_dapm_widget *w,
0227                 struct snd_kcontrol *control,
0228                 int event)
0229 {
0230     struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
0231     struct axg_tdm_formatter *formatter = snd_soc_component_get_drvdata(c);
0232     int ret = 0;
0233 
0234     switch (event) {
0235     case SND_SOC_DAPM_PRE_PMU:
0236         ret = axg_tdm_formatter_power_up(formatter, w);
0237         break;
0238 
0239     case SND_SOC_DAPM_PRE_PMD:
0240         axg_tdm_formatter_power_down(formatter);
0241         break;
0242 
0243     default:
0244         dev_err(c->dev, "Unexpected event %d\n", event);
0245         return -EINVAL;
0246     }
0247 
0248     return ret;
0249 }
0250 EXPORT_SYMBOL_GPL(axg_tdm_formatter_event);
0251 
0252 int axg_tdm_formatter_probe(struct platform_device *pdev)
0253 {
0254     struct device *dev = &pdev->dev;
0255     const struct axg_tdm_formatter_driver *drv;
0256     struct axg_tdm_formatter *formatter;
0257     void __iomem *regs;
0258 
0259     drv = of_device_get_match_data(dev);
0260     if (!drv) {
0261         dev_err(dev, "failed to match device\n");
0262         return -ENODEV;
0263     }
0264 
0265     formatter = devm_kzalloc(dev, sizeof(*formatter), GFP_KERNEL);
0266     if (!formatter)
0267         return -ENOMEM;
0268     platform_set_drvdata(pdev, formatter);
0269     formatter->drv = drv;
0270 
0271     regs = devm_platform_ioremap_resource(pdev, 0);
0272     if (IS_ERR(regs))
0273         return PTR_ERR(regs);
0274 
0275     formatter->map = devm_regmap_init_mmio(dev, regs, drv->regmap_cfg);
0276     if (IS_ERR(formatter->map)) {
0277         dev_err(dev, "failed to init regmap: %ld\n",
0278             PTR_ERR(formatter->map));
0279         return PTR_ERR(formatter->map);
0280     }
0281 
0282     /* Peripharal clock */
0283     formatter->pclk = devm_clk_get(dev, "pclk");
0284     if (IS_ERR(formatter->pclk))
0285         return dev_err_probe(dev, PTR_ERR(formatter->pclk), "failed to get pclk\n");
0286 
0287     /* Formatter bit clock */
0288     formatter->sclk = devm_clk_get(dev, "sclk");
0289     if (IS_ERR(formatter->sclk))
0290         return dev_err_probe(dev, PTR_ERR(formatter->sclk), "failed to get sclk\n");
0291 
0292     /* Formatter sample clock */
0293     formatter->lrclk = devm_clk_get(dev, "lrclk");
0294     if (IS_ERR(formatter->lrclk))
0295         return dev_err_probe(dev, PTR_ERR(formatter->lrclk), "failed to get lrclk\n");
0296 
0297     /* Formatter bit clock input multiplexer */
0298     formatter->sclk_sel = devm_clk_get(dev, "sclk_sel");
0299     if (IS_ERR(formatter->sclk_sel))
0300         return dev_err_probe(dev, PTR_ERR(formatter->sclk_sel), "failed to get sclk_sel\n");
0301 
0302     /* Formatter sample clock input multiplexer */
0303     formatter->lrclk_sel = devm_clk_get(dev, "lrclk_sel");
0304     if (IS_ERR(formatter->lrclk_sel))
0305         return dev_err_probe(dev, PTR_ERR(formatter->lrclk_sel),
0306                      "failed to get lrclk_sel\n");
0307 
0308     /* Formatter dedicated reset line */
0309     formatter->reset = devm_reset_control_get_optional_exclusive(dev, NULL);
0310     if (IS_ERR(formatter->reset))
0311         return dev_err_probe(dev, PTR_ERR(formatter->reset), "failed to get reset\n");
0312 
0313     return devm_snd_soc_register_component(dev, drv->component_drv,
0314                            NULL, 0);
0315 }
0316 EXPORT_SYMBOL_GPL(axg_tdm_formatter_probe);
0317 
0318 int axg_tdm_stream_start(struct axg_tdm_stream *ts)
0319 {
0320     struct axg_tdm_formatter *formatter;
0321     int ret = 0;
0322 
0323     mutex_lock(&ts->lock);
0324     ts->ready = true;
0325 
0326     /* Start all the formatters attached to the stream */
0327     list_for_each_entry(formatter, &ts->formatter_list, list) {
0328         ret = axg_tdm_formatter_enable(formatter);
0329         if (ret) {
0330             pr_err("failed to start tdm stream\n");
0331             goto out;
0332         }
0333     }
0334 
0335 out:
0336     mutex_unlock(&ts->lock);
0337     return ret;
0338 }
0339 EXPORT_SYMBOL_GPL(axg_tdm_stream_start);
0340 
0341 void axg_tdm_stream_stop(struct axg_tdm_stream *ts)
0342 {
0343     struct axg_tdm_formatter *formatter;
0344 
0345     mutex_lock(&ts->lock);
0346     ts->ready = false;
0347 
0348     /* Stop all the formatters attached to the stream */
0349     list_for_each_entry(formatter, &ts->formatter_list, list) {
0350         axg_tdm_formatter_disable(formatter);
0351     }
0352 
0353     mutex_unlock(&ts->lock);
0354 }
0355 EXPORT_SYMBOL_GPL(axg_tdm_stream_stop);
0356 
0357 struct axg_tdm_stream *axg_tdm_stream_alloc(struct axg_tdm_iface *iface)
0358 {
0359     struct axg_tdm_stream *ts;
0360 
0361     ts = kzalloc(sizeof(*ts), GFP_KERNEL);
0362     if (ts) {
0363         INIT_LIST_HEAD(&ts->formatter_list);
0364         mutex_init(&ts->lock);
0365         ts->iface = iface;
0366     }
0367 
0368     return ts;
0369 }
0370 EXPORT_SYMBOL_GPL(axg_tdm_stream_alloc);
0371 
0372 void axg_tdm_stream_free(struct axg_tdm_stream *ts)
0373 {
0374     /*
0375      * If the list is not empty, it would mean that one of the formatter
0376      * widget is still powered and attached to the interface while we
0377      * are removing the TDM DAI. It should not be possible
0378      */
0379     WARN_ON(!list_empty(&ts->formatter_list));
0380     mutex_destroy(&ts->lock);
0381     kfree(ts);
0382 }
0383 EXPORT_SYMBOL_GPL(axg_tdm_stream_free);
0384 
0385 MODULE_DESCRIPTION("Amlogic AXG TDM formatter driver");
0386 MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
0387 MODULE_LICENSE("GPL v2");