axg-tdm-formatter.c (9981B)
1// SPDX-License-Identifier: (GPL-2.0 OR MIT) 2// 3// Copyright (c) 2018 BayLibre, SAS. 4// Author: Jerome Brunet <jbrunet@baylibre.com> 5 6#include <linux/clk.h> 7#include <linux/module.h> 8#include <linux/of_platform.h> 9#include <linux/regmap.h> 10#include <linux/reset.h> 11#include <sound/soc.h> 12 13#include "axg-tdm-formatter.h" 14 15struct axg_tdm_formatter { 16 struct list_head list; 17 struct axg_tdm_stream *stream; 18 const struct axg_tdm_formatter_driver *drv; 19 struct clk *pclk; 20 struct clk *sclk; 21 struct clk *lrclk; 22 struct clk *sclk_sel; 23 struct clk *lrclk_sel; 24 struct reset_control *reset; 25 bool enabled; 26 struct regmap *map; 27}; 28 29int axg_tdm_formatter_set_channel_masks(struct regmap *map, 30 struct axg_tdm_stream *ts, 31 unsigned int offset) 32{ 33 unsigned int val, ch = ts->channels; 34 unsigned long mask; 35 int i, j; 36 37 /* 38 * Distribute the channels of the stream over the available slots 39 * of each TDM lane 40 */ 41 for (i = 0; i < AXG_TDM_NUM_LANES; i++) { 42 val = 0; 43 mask = ts->mask[i]; 44 45 for (j = find_first_bit(&mask, 32); 46 (j < 32) && ch; 47 j = find_next_bit(&mask, 32, j + 1)) { 48 val |= 1 << j; 49 ch -= 1; 50 } 51 52 regmap_write(map, offset, val); 53 offset += regmap_get_reg_stride(map); 54 } 55 56 /* 57 * If we still have channel left at the end of the process, it means 58 * the stream has more channels than we can accommodate and we should 59 * have caught this earlier. 60 */ 61 if (WARN_ON(ch != 0)) { 62 pr_err("channel mask error\n"); 63 return -EINVAL; 64 } 65 66 return 0; 67} 68EXPORT_SYMBOL_GPL(axg_tdm_formatter_set_channel_masks); 69 70static int axg_tdm_formatter_enable(struct axg_tdm_formatter *formatter) 71{ 72 struct axg_tdm_stream *ts = formatter->stream; 73 bool invert; 74 int ret; 75 76 /* Do nothing if the formatter is already enabled */ 77 if (formatter->enabled) 78 return 0; 79 80 /* 81 * On the g12a (and possibly other SoCs), when a stream using 82 * multiple lanes is restarted, it will sometimes not start 83 * from the first lane, but randomly from another used one. 84 * The result is an unexpected and random channel shift. 85 * 86 * The hypothesis is that an HW counter is not properly reset 87 * and the formatter simply starts on the lane it stopped 88 * before. Unfortunately, there does not seems to be a way to 89 * reset this through the registers of the block. 90 * 91 * However, the g12a has indenpendent reset lines for each audio 92 * devices. Using this reset before each start solves the issue. 93 */ 94 ret = reset_control_reset(formatter->reset); 95 if (ret) 96 return ret; 97 98 /* 99 * If sclk is inverted, it means the bit should latched on the 100 * rising edge which is what our HW expects. If not, we need to 101 * invert it before the formatter. 102 */ 103 invert = axg_tdm_sclk_invert(ts->iface->fmt); 104 ret = clk_set_phase(formatter->sclk, invert ? 0 : 180); 105 if (ret) 106 return ret; 107 108 /* Setup the stream parameter in the formatter */ 109 ret = formatter->drv->ops->prepare(formatter->map, 110 formatter->drv->quirks, 111 formatter->stream); 112 if (ret) 113 return ret; 114 115 /* Enable the signal clocks feeding the formatter */ 116 ret = clk_prepare_enable(formatter->sclk); 117 if (ret) 118 return ret; 119 120 ret = clk_prepare_enable(formatter->lrclk); 121 if (ret) { 122 clk_disable_unprepare(formatter->sclk); 123 return ret; 124 } 125 126 /* Finally, actually enable the formatter */ 127 formatter->drv->ops->enable(formatter->map); 128 formatter->enabled = true; 129 130 return 0; 131} 132 133static void axg_tdm_formatter_disable(struct axg_tdm_formatter *formatter) 134{ 135 /* Do nothing if the formatter is already disabled */ 136 if (!formatter->enabled) 137 return; 138 139 formatter->drv->ops->disable(formatter->map); 140 clk_disable_unprepare(formatter->lrclk); 141 clk_disable_unprepare(formatter->sclk); 142 formatter->enabled = false; 143} 144 145static int axg_tdm_formatter_attach(struct axg_tdm_formatter *formatter) 146{ 147 struct axg_tdm_stream *ts = formatter->stream; 148 int ret = 0; 149 150 mutex_lock(&ts->lock); 151 152 /* Catch up if the stream is already running when we attach */ 153 if (ts->ready) { 154 ret = axg_tdm_formatter_enable(formatter); 155 if (ret) { 156 pr_err("failed to enable formatter\n"); 157 goto out; 158 } 159 } 160 161 list_add_tail(&formatter->list, &ts->formatter_list); 162out: 163 mutex_unlock(&ts->lock); 164 return ret; 165} 166 167static void axg_tdm_formatter_dettach(struct axg_tdm_formatter *formatter) 168{ 169 struct axg_tdm_stream *ts = formatter->stream; 170 171 mutex_lock(&ts->lock); 172 list_del(&formatter->list); 173 mutex_unlock(&ts->lock); 174 175 axg_tdm_formatter_disable(formatter); 176} 177 178static int axg_tdm_formatter_power_up(struct axg_tdm_formatter *formatter, 179 struct snd_soc_dapm_widget *w) 180{ 181 struct axg_tdm_stream *ts = formatter->drv->ops->get_stream(w); 182 int ret; 183 184 /* 185 * If we don't get a stream at this stage, it would mean that the 186 * widget is powering up but is not attached to any backend DAI. 187 * It should not happen, ever ! 188 */ 189 if (WARN_ON(!ts)) 190 return -ENODEV; 191 192 /* Clock our device */ 193 ret = clk_prepare_enable(formatter->pclk); 194 if (ret) 195 return ret; 196 197 /* Reparent the bit clock to the TDM interface */ 198 ret = clk_set_parent(formatter->sclk_sel, ts->iface->sclk); 199 if (ret) 200 goto disable_pclk; 201 202 /* Reparent the sample clock to the TDM interface */ 203 ret = clk_set_parent(formatter->lrclk_sel, ts->iface->lrclk); 204 if (ret) 205 goto disable_pclk; 206 207 formatter->stream = ts; 208 ret = axg_tdm_formatter_attach(formatter); 209 if (ret) 210 goto disable_pclk; 211 212 return 0; 213 214disable_pclk: 215 clk_disable_unprepare(formatter->pclk); 216 return ret; 217} 218 219static void axg_tdm_formatter_power_down(struct axg_tdm_formatter *formatter) 220{ 221 axg_tdm_formatter_dettach(formatter); 222 clk_disable_unprepare(formatter->pclk); 223 formatter->stream = NULL; 224} 225 226int axg_tdm_formatter_event(struct snd_soc_dapm_widget *w, 227 struct snd_kcontrol *control, 228 int event) 229{ 230 struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm); 231 struct axg_tdm_formatter *formatter = snd_soc_component_get_drvdata(c); 232 int ret = 0; 233 234 switch (event) { 235 case SND_SOC_DAPM_PRE_PMU: 236 ret = axg_tdm_formatter_power_up(formatter, w); 237 break; 238 239 case SND_SOC_DAPM_PRE_PMD: 240 axg_tdm_formatter_power_down(formatter); 241 break; 242 243 default: 244 dev_err(c->dev, "Unexpected event %d\n", event); 245 return -EINVAL; 246 } 247 248 return ret; 249} 250EXPORT_SYMBOL_GPL(axg_tdm_formatter_event); 251 252int axg_tdm_formatter_probe(struct platform_device *pdev) 253{ 254 struct device *dev = &pdev->dev; 255 const struct axg_tdm_formatter_driver *drv; 256 struct axg_tdm_formatter *formatter; 257 void __iomem *regs; 258 259 drv = of_device_get_match_data(dev); 260 if (!drv) { 261 dev_err(dev, "failed to match device\n"); 262 return -ENODEV; 263 } 264 265 formatter = devm_kzalloc(dev, sizeof(*formatter), GFP_KERNEL); 266 if (!formatter) 267 return -ENOMEM; 268 platform_set_drvdata(pdev, formatter); 269 formatter->drv = drv; 270 271 regs = devm_platform_ioremap_resource(pdev, 0); 272 if (IS_ERR(regs)) 273 return PTR_ERR(regs); 274 275 formatter->map = devm_regmap_init_mmio(dev, regs, drv->regmap_cfg); 276 if (IS_ERR(formatter->map)) { 277 dev_err(dev, "failed to init regmap: %ld\n", 278 PTR_ERR(formatter->map)); 279 return PTR_ERR(formatter->map); 280 } 281 282 /* Peripharal clock */ 283 formatter->pclk = devm_clk_get(dev, "pclk"); 284 if (IS_ERR(formatter->pclk)) 285 return dev_err_probe(dev, PTR_ERR(formatter->pclk), "failed to get pclk\n"); 286 287 /* Formatter bit clock */ 288 formatter->sclk = devm_clk_get(dev, "sclk"); 289 if (IS_ERR(formatter->sclk)) 290 return dev_err_probe(dev, PTR_ERR(formatter->sclk), "failed to get sclk\n"); 291 292 /* Formatter sample clock */ 293 formatter->lrclk = devm_clk_get(dev, "lrclk"); 294 if (IS_ERR(formatter->lrclk)) 295 return dev_err_probe(dev, PTR_ERR(formatter->lrclk), "failed to get lrclk\n"); 296 297 /* Formatter bit clock input multiplexer */ 298 formatter->sclk_sel = devm_clk_get(dev, "sclk_sel"); 299 if (IS_ERR(formatter->sclk_sel)) 300 return dev_err_probe(dev, PTR_ERR(formatter->sclk_sel), "failed to get sclk_sel\n"); 301 302 /* Formatter sample clock input multiplexer */ 303 formatter->lrclk_sel = devm_clk_get(dev, "lrclk_sel"); 304 if (IS_ERR(formatter->lrclk_sel)) 305 return dev_err_probe(dev, PTR_ERR(formatter->lrclk_sel), 306 "failed to get lrclk_sel\n"); 307 308 /* Formatter dedicated reset line */ 309 formatter->reset = devm_reset_control_get_optional_exclusive(dev, NULL); 310 if (IS_ERR(formatter->reset)) 311 return dev_err_probe(dev, PTR_ERR(formatter->reset), "failed to get reset\n"); 312 313 return devm_snd_soc_register_component(dev, drv->component_drv, 314 NULL, 0); 315} 316EXPORT_SYMBOL_GPL(axg_tdm_formatter_probe); 317 318int axg_tdm_stream_start(struct axg_tdm_stream *ts) 319{ 320 struct axg_tdm_formatter *formatter; 321 int ret = 0; 322 323 mutex_lock(&ts->lock); 324 ts->ready = true; 325 326 /* Start all the formatters attached to the stream */ 327 list_for_each_entry(formatter, &ts->formatter_list, list) { 328 ret = axg_tdm_formatter_enable(formatter); 329 if (ret) { 330 pr_err("failed to start tdm stream\n"); 331 goto out; 332 } 333 } 334 335out: 336 mutex_unlock(&ts->lock); 337 return ret; 338} 339EXPORT_SYMBOL_GPL(axg_tdm_stream_start); 340 341void axg_tdm_stream_stop(struct axg_tdm_stream *ts) 342{ 343 struct axg_tdm_formatter *formatter; 344 345 mutex_lock(&ts->lock); 346 ts->ready = false; 347 348 /* Stop all the formatters attached to the stream */ 349 list_for_each_entry(formatter, &ts->formatter_list, list) { 350 axg_tdm_formatter_disable(formatter); 351 } 352 353 mutex_unlock(&ts->lock); 354} 355EXPORT_SYMBOL_GPL(axg_tdm_stream_stop); 356 357struct axg_tdm_stream *axg_tdm_stream_alloc(struct axg_tdm_iface *iface) 358{ 359 struct axg_tdm_stream *ts; 360 361 ts = kzalloc(sizeof(*ts), GFP_KERNEL); 362 if (ts) { 363 INIT_LIST_HEAD(&ts->formatter_list); 364 mutex_init(&ts->lock); 365 ts->iface = iface; 366 } 367 368 return ts; 369} 370EXPORT_SYMBOL_GPL(axg_tdm_stream_alloc); 371 372void axg_tdm_stream_free(struct axg_tdm_stream *ts) 373{ 374 /* 375 * If the list is not empty, it would mean that one of the formatter 376 * widget is still powered and attached to the interface while we 377 * are removing the TDM DAI. It should not be possible 378 */ 379 WARN_ON(!list_empty(&ts->formatter_list)); 380 mutex_destroy(&ts->lock); 381 kfree(ts); 382} 383EXPORT_SYMBOL_GPL(axg_tdm_stream_free); 384 385MODULE_DESCRIPTION("Amlogic AXG TDM formatter driver"); 386MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>"); 387MODULE_LICENSE("GPL v2");