Lines Matching +full:tegra30 +full:- +full:hda
1 // SPDX-License-Identifier: GPL-2.0-only
4 * Implementation of primary ALSA driver code base for NVIDIA Tegra HDA.
11 #include <linux/dma-mapping.h>
33 /* Defines for Nvidia Tegra HDA support */
93 "Automatic power-saving timeout (in seconds, 0 = disable).");
100 static void hda_tegra_init(struct hda_tegra *hda) in hda_tegra_init() argument
105 v = readl(hda->regs + HDA_IPFS_CONFIG); in hda_tegra_init()
107 writel(v, hda->regs + HDA_IPFS_CONFIG); in hda_tegra_init()
110 v = readl(hda->regs + HDA_CFG_CMD); in hda_tegra_init()
114 writel(v, hda->regs + HDA_CFG_CMD); in hda_tegra_init()
116 writel(HDA_BAR0_INIT_PROGRAM, hda->regs + HDA_CFG_BAR0); in hda_tegra_init()
117 writel(HDA_BAR0_FINAL_PROGRAM, hda->regs + HDA_CFG_BAR0); in hda_tegra_init()
118 writel(HDA_FPCI_BAR0_START, hda->regs + HDA_IPFS_FPCI_BAR0); in hda_tegra_init()
120 v = readl(hda->regs + HDA_IPFS_INTR_MASK); in hda_tegra_init()
122 writel(v, hda->regs + HDA_IPFS_INTR_MASK); in hda_tegra_init()
157 struct azx *chip = card->private_data; in hda_tegra_runtime_suspend()
158 struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); in hda_tegra_runtime_suspend() local
160 if (chip && chip->running) { in hda_tegra_runtime_suspend()
168 clk_bulk_disable_unprepare(hda->nclocks, hda->clocks); in hda_tegra_runtime_suspend()
176 struct azx *chip = card->private_data; in hda_tegra_runtime_resume()
177 struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); in hda_tegra_runtime_resume() local
180 if (!chip->running) { in hda_tegra_runtime_resume()
181 rc = reset_control_bulk_assert(hda->nresets, hda->resets); in hda_tegra_runtime_resume()
186 rc = clk_bulk_prepare_enable(hda->nclocks, hda->clocks); in hda_tegra_runtime_resume()
189 if (chip->running) { in hda_tegra_runtime_resume()
190 hda_tegra_init(hda); in hda_tegra_runtime_resume()
198 rc = reset_control_bulk_deassert(hda->nresets, hda->resets); in hda_tegra_runtime_resume()
215 struct azx *chip = device->device_data; in hda_tegra_dev_disconnect()
217 chip->bus.shutdown = 1; in hda_tegra_dev_disconnect()
226 struct azx *chip = device->device_data; in hda_tegra_dev_free()
227 struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); in hda_tegra_dev_free() local
229 cancel_work_sync(&hda->probe_work); in hda_tegra_dev_free()
230 if (azx_bus(chip)->chip_init) { in hda_tegra_dev_free()
244 struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); in hda_tegra_init_chip() local
248 hda->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in hda_tegra_init_chip()
249 if (IS_ERR(hda->regs)) in hda_tegra_init_chip()
250 return PTR_ERR(hda->regs); in hda_tegra_init_chip()
252 bus->remap_addr = hda->regs + HDA_BAR0; in hda_tegra_init_chip()
253 bus->addr = res->start + HDA_BAR0; in hda_tegra_init_chip()
255 hda_tegra_init(hda); in hda_tegra_init_chip()
262 struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); in hda_tegra_first_init() local
264 struct snd_card *card = chip->card; in hda_tegra_first_init()
268 const char *sname, *drv_name = "tegra-hda"; in hda_tegra_first_init()
269 struct device_node *np = pdev->dev.of_node; in hda_tegra_first_init()
278 err = devm_request_irq(chip->card->dev, irq_id, azx_interrupt, in hda_tegra_first_init()
281 dev_err(chip->card->dev, in hda_tegra_first_init()
286 bus->irq = irq_id; in hda_tegra_first_init()
287 bus->dma_stop_delay = 100; in hda_tegra_first_init()
288 card->sync_irq = bus->irq; in hda_tegra_first_init()
299 if (of_device_is_compatible(np, "nvidia,tegra194-hda")) { in hda_tegra_first_init()
302 dev_info(card->dev, "Override SDO lines to %u\n", in hda_tegra_first_init()
305 val = readl(hda->regs + FPCI_DBG_CFG_2) & ~FPCI_GCAP_NSDO_MASK; in hda_tegra_first_init()
307 writel(val, hda->regs + FPCI_DBG_CFG_2); in hda_tegra_first_init()
311 dev_dbg(card->dev, "chipset global capabilities = 0x%x\n", gcap); in hda_tegra_first_init()
313 chip->align_buffer_size = 1; in hda_tegra_first_init()
318 chip->capture_streams = (gcap >> 8) & 0x0f; in hda_tegra_first_init()
328 if (of_device_is_compatible(np, "nvidia,tegra234-hda")) in hda_tegra_first_init()
329 chip->capture_streams = 4; in hda_tegra_first_init()
331 chip->playback_streams = (gcap >> 12) & 0x0f; in hda_tegra_first_init()
332 if (!chip->playback_streams && !chip->capture_streams) { in hda_tegra_first_init()
334 chip->playback_streams = NUM_PLAYBACK_SD; in hda_tegra_first_init()
335 chip->capture_streams = NUM_CAPTURE_SD; in hda_tegra_first_init()
337 chip->capture_index_offset = 0; in hda_tegra_first_init()
338 chip->playback_index_offset = chip->capture_streams; in hda_tegra_first_init()
339 chip->num_streams = chip->playback_streams + chip->capture_streams; in hda_tegra_first_init()
344 dev_err(card->dev, "failed to initialize streams: %d\n", err); in hda_tegra_first_init()
350 dev_err(card->dev, "failed to allocate stream pages: %d\n", in hda_tegra_first_init()
359 * Playback (for 44.1K/48K, 2-channel, 16-bps) fails with in hda_tegra_first_init()
372 if (of_device_is_compatible(np, "nvidia,tegra30-hda")) in hda_tegra_first_init()
373 chip->bus.core.sdo_limit = 16; in hda_tegra_first_init()
376 if (!bus->codec_mask) { in hda_tegra_first_init()
377 dev_err(card->dev, "no codecs found!\n"); in hda_tegra_first_init()
378 return -ENODEV; in hda_tegra_first_init()
382 strscpy(card->driver, drv_name, sizeof(card->driver)); in hda_tegra_first_init()
387 if (strlen(sname) > sizeof(card->shortname)) in hda_tegra_first_init()
388 dev_info(card->dev, "truncating shortname for card\n"); in hda_tegra_first_init()
389 strscpy(card->shortname, sname, sizeof(card->shortname)); in hda_tegra_first_init()
392 snprintf(card->longname, sizeof(card->longname), in hda_tegra_first_init()
394 card->shortname, bus->addr, bus->irq); in hda_tegra_first_init()
407 struct hda_tegra *hda) in hda_tegra_create() argument
416 chip = &hda->chip; in hda_tegra_create()
418 mutex_init(&chip->open_mutex); in hda_tegra_create()
419 chip->card = card; in hda_tegra_create()
420 chip->ops = &hda_tegra_ops; in hda_tegra_create()
421 chip->driver_caps = driver_caps; in hda_tegra_create()
422 chip->driver_type = driver_caps & 0xff; in hda_tegra_create()
423 chip->dev_index = 0; in hda_tegra_create()
424 chip->jackpoll_interval = msecs_to_jiffies(5000); in hda_tegra_create()
425 INIT_LIST_HEAD(&chip->pcm_list); in hda_tegra_create()
427 chip->codec_probe_mask = -1; in hda_tegra_create()
429 chip->single_cmd = false; in hda_tegra_create()
430 chip->snoop = true; in hda_tegra_create()
432 INIT_WORK(&hda->probe_work, hda_tegra_probe_work); in hda_tegra_create()
438 chip->bus.core.sync_write = 0; in hda_tegra_create()
439 chip->bus.core.needs_damn_long_delay = 1; in hda_tegra_create()
440 chip->bus.core.aligned_mmio = 1; in hda_tegra_create()
441 chip->bus.jackpoll_in_suspend = 1; in hda_tegra_create()
445 dev_err(card->dev, "Error creating device\n"); in hda_tegra_create()
468 { .compatible = "nvidia,tegra30-hda", .data = &tegra30_data },
469 { .compatible = "nvidia,tegra194-hda", .data = &tegra194_data },
470 { .compatible = "nvidia,tegra234-hda", .data = &tegra234_data },
482 struct hda_tegra *hda; in hda_tegra_probe() local
485 hda = devm_kzalloc(&pdev->dev, sizeof(*hda), GFP_KERNEL); in hda_tegra_probe()
486 if (!hda) in hda_tegra_probe()
487 return -ENOMEM; in hda_tegra_probe()
488 hda->dev = &pdev->dev; in hda_tegra_probe()
489 chip = &hda->chip; in hda_tegra_probe()
491 hda->soc = of_device_get_match_data(&pdev->dev); in hda_tegra_probe()
493 err = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, in hda_tegra_probe()
496 dev_err(&pdev->dev, "Error creating card!\n"); in hda_tegra_probe()
500 hda->resets[hda->nresets++].id = "hda"; in hda_tegra_probe()
506 if (hda->soc->has_hda2hdmi) in hda_tegra_probe()
507 hda->resets[hda->nresets++].id = "hda2hdmi"; in hda_tegra_probe()
514 if (hda->soc->has_hda2codec_2x_reset) in hda_tegra_probe()
515 hda->resets[hda->nresets++].id = "hda2codec_2x"; in hda_tegra_probe()
517 err = devm_reset_control_bulk_get_exclusive(&pdev->dev, hda->nresets, in hda_tegra_probe()
518 hda->resets); in hda_tegra_probe()
522 hda->clocks[hda->nclocks++].id = "hda"; in hda_tegra_probe()
523 if (hda->soc->has_hda2hdmi) in hda_tegra_probe()
524 hda->clocks[hda->nclocks++].id = "hda2hdmi"; in hda_tegra_probe()
525 hda->clocks[hda->nclocks++].id = "hda2codec_2x"; in hda_tegra_probe()
527 err = devm_clk_bulk_get(&pdev->dev, hda->nclocks, hda->clocks); in hda_tegra_probe()
531 err = hda_tegra_create(card, driver_flags, hda); in hda_tegra_probe()
534 card->private_data = chip; in hda_tegra_probe()
536 dev_set_drvdata(&pdev->dev, card); in hda_tegra_probe()
538 pm_runtime_enable(hda->dev); in hda_tegra_probe()
540 pm_runtime_forbid(hda->dev); in hda_tegra_probe()
542 schedule_work(&hda->probe_work); in hda_tegra_probe()
553 struct hda_tegra *hda = container_of(work, struct hda_tegra, probe_work); in hda_tegra_probe_work() local
554 struct azx *chip = &hda->chip; in hda_tegra_probe_work()
555 struct platform_device *pdev = to_platform_device(hda->dev); in hda_tegra_probe_work()
558 pm_runtime_get_sync(hda->dev); in hda_tegra_probe_work()
572 err = snd_card_register(chip->card); in hda_tegra_probe_work()
576 chip->running = 1; in hda_tegra_probe_work()
577 snd_hda_set_power_save(&chip->bus, power_save * 1000); in hda_tegra_probe_work()
580 pm_runtime_put(hda->dev); in hda_tegra_probe_work()
586 snd_card_free(dev_get_drvdata(&pdev->dev)); in hda_tegra_remove()
587 pm_runtime_disable(&pdev->dev); in hda_tegra_remove()
592 struct snd_card *card = dev_get_drvdata(&pdev->dev); in hda_tegra_shutdown()
597 chip = card->private_data; in hda_tegra_shutdown()
598 if (chip && chip->running) in hda_tegra_shutdown()
604 .name = "tegra-hda",
614 MODULE_DESCRIPTION("Tegra HDA bus driver");