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