• Home
  • Raw
  • Download

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>
32 /* Defines for Nvidia Tegra HDA support */
85 "Automatic power-saving timeout (in seconds, 0 = disable).");
92 static void hda_tegra_init(struct hda_tegra *hda) in hda_tegra_init() argument
97 v = readl(hda->regs + HDA_IPFS_CONFIG); in hda_tegra_init()
99 writel(v, hda->regs + HDA_IPFS_CONFIG); in hda_tegra_init()
102 v = readl(hda->regs + HDA_CFG_CMD); in hda_tegra_init()
106 writel(v, hda->regs + HDA_CFG_CMD); in hda_tegra_init()
108 writel(HDA_BAR0_INIT_PROGRAM, hda->regs + HDA_CFG_BAR0); in hda_tegra_init()
109 writel(HDA_BAR0_FINAL_PROGRAM, hda->regs + HDA_CFG_BAR0); in hda_tegra_init()
110 writel(HDA_FPCI_BAR0_START, hda->regs + HDA_IPFS_FPCI_BAR0); in hda_tegra_init()
112 v = readl(hda->regs + HDA_IPFS_INTR_MASK); in hda_tegra_init()
114 writel(v, hda->regs + HDA_IPFS_INTR_MASK); in hda_tegra_init()
149 struct azx *chip = card->private_data; in hda_tegra_runtime_suspend()
150 struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); in hda_tegra_runtime_suspend() local
152 if (chip && chip->running) { in hda_tegra_runtime_suspend()
160 clk_bulk_disable_unprepare(hda->nclocks, hda->clocks); in hda_tegra_runtime_suspend()
168 struct azx *chip = card->private_data; in hda_tegra_runtime_resume()
169 struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); in hda_tegra_runtime_resume() local
172 if (!chip->running) { in hda_tegra_runtime_resume()
173 rc = reset_control_assert(hda->reset); in hda_tegra_runtime_resume()
178 rc = clk_bulk_prepare_enable(hda->nclocks, hda->clocks); in hda_tegra_runtime_resume()
181 if (chip && chip->running) { in hda_tegra_runtime_resume()
182 hda_tegra_init(hda); in hda_tegra_runtime_resume()
190 rc = reset_control_deassert(hda->reset); in hda_tegra_runtime_resume()
207 struct azx *chip = device->device_data; in hda_tegra_dev_disconnect()
209 chip->bus.shutdown = 1; in hda_tegra_dev_disconnect()
218 struct azx *chip = device->device_data; in hda_tegra_dev_free()
219 struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); in hda_tegra_dev_free() local
221 cancel_work_sync(&hda->probe_work); in hda_tegra_dev_free()
222 if (azx_bus(chip)->chip_init) { in hda_tegra_dev_free()
236 struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); in hda_tegra_init_chip() local
238 struct device *dev = hda->dev; in hda_tegra_init_chip()
242 hda->regs = devm_ioremap_resource(dev, res); in hda_tegra_init_chip()
243 if (IS_ERR(hda->regs)) in hda_tegra_init_chip()
244 return PTR_ERR(hda->regs); in hda_tegra_init_chip()
246 bus->remap_addr = hda->regs + HDA_BAR0; in hda_tegra_init_chip()
247 bus->addr = res->start + HDA_BAR0; in hda_tegra_init_chip()
249 hda_tegra_init(hda); in hda_tegra_init_chip()
256 struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); in hda_tegra_first_init() local
258 struct snd_card *card = chip->card; in hda_tegra_first_init()
262 const char *sname, *drv_name = "tegra-hda"; in hda_tegra_first_init()
263 struct device_node *np = pdev->dev.of_node; in hda_tegra_first_init()
272 err = devm_request_irq(chip->card->dev, irq_id, azx_interrupt, in hda_tegra_first_init()
275 dev_err(chip->card->dev, in hda_tegra_first_init()
280 bus->irq = irq_id; in hda_tegra_first_init()
281 bus->dma_stop_delay = 100; in hda_tegra_first_init()
282 card->sync_irq = bus->irq; in hda_tegra_first_init()
293 if (of_device_is_compatible(np, "nvidia,tegra194-hda")) { in hda_tegra_first_init()
296 dev_info(card->dev, "Override SDO lines to %u\n", in hda_tegra_first_init()
299 val = readl(hda->regs + FPCI_DBG_CFG_2) & ~FPCI_GCAP_NSDO_MASK; in hda_tegra_first_init()
301 writel(val, hda->regs + FPCI_DBG_CFG_2); in hda_tegra_first_init()
305 dev_dbg(card->dev, "chipset global capabilities = 0x%x\n", gcap); in hda_tegra_first_init()
307 chip->align_buffer_size = 1; in hda_tegra_first_init()
312 chip->capture_streams = (gcap >> 8) & 0x0f; in hda_tegra_first_init()
313 chip->playback_streams = (gcap >> 12) & 0x0f; in hda_tegra_first_init()
314 if (!chip->playback_streams && !chip->capture_streams) { in hda_tegra_first_init()
316 chip->playback_streams = NUM_PLAYBACK_SD; in hda_tegra_first_init()
317 chip->capture_streams = NUM_CAPTURE_SD; in hda_tegra_first_init()
319 chip->capture_index_offset = 0; in hda_tegra_first_init()
320 chip->playback_index_offset = chip->capture_streams; in hda_tegra_first_init()
321 chip->num_streams = chip->playback_streams + chip->capture_streams; in hda_tegra_first_init()
326 dev_err(card->dev, "failed to initialize streams: %d\n", err); in hda_tegra_first_init()
332 dev_err(card->dev, "failed to allocate stream pages: %d\n", in hda_tegra_first_init()
341 * Playback (for 44.1K/48K, 2-channel, 16-bps) fails with in hda_tegra_first_init()
354 if (of_device_is_compatible(np, "nvidia,tegra30-hda")) in hda_tegra_first_init()
355 chip->bus.core.sdo_limit = 16; in hda_tegra_first_init()
358 if (!bus->codec_mask) { in hda_tegra_first_init()
359 dev_err(card->dev, "no codecs found!\n"); in hda_tegra_first_init()
360 return -ENODEV; in hda_tegra_first_init()
364 strncpy(card->driver, drv_name, sizeof(card->driver)); in hda_tegra_first_init()
369 if (strlen(sname) > sizeof(card->shortname)) in hda_tegra_first_init()
370 dev_info(card->dev, "truncating shortname for card\n"); in hda_tegra_first_init()
371 strncpy(card->shortname, sname, sizeof(card->shortname)); in hda_tegra_first_init()
374 snprintf(card->longname, sizeof(card->longname), in hda_tegra_first_init()
376 card->shortname, bus->addr, bus->irq); in hda_tegra_first_init()
389 struct hda_tegra *hda) in hda_tegra_create() argument
398 chip = &hda->chip; in hda_tegra_create()
400 mutex_init(&chip->open_mutex); in hda_tegra_create()
401 chip->card = card; in hda_tegra_create()
402 chip->ops = &hda_tegra_ops; in hda_tegra_create()
403 chip->driver_caps = driver_caps; in hda_tegra_create()
404 chip->driver_type = driver_caps & 0xff; in hda_tegra_create()
405 chip->dev_index = 0; in hda_tegra_create()
406 INIT_LIST_HEAD(&chip->pcm_list); in hda_tegra_create()
408 chip->codec_probe_mask = -1; in hda_tegra_create()
410 chip->single_cmd = false; in hda_tegra_create()
411 chip->snoop = true; in hda_tegra_create()
413 INIT_WORK(&hda->probe_work, hda_tegra_probe_work); in hda_tegra_create()
419 chip->bus.core.sync_write = 0; in hda_tegra_create()
420 chip->bus.core.needs_damn_long_delay = 1; in hda_tegra_create()
421 chip->bus.core.aligned_mmio = 1; in hda_tegra_create()
425 dev_err(card->dev, "Error creating device\n"); in hda_tegra_create()
433 { .compatible = "nvidia,tegra30-hda" },
434 { .compatible = "nvidia,tegra194-hda" },
446 struct hda_tegra *hda; in hda_tegra_probe() local
449 hda = devm_kzalloc(&pdev->dev, sizeof(*hda), GFP_KERNEL); in hda_tegra_probe()
450 if (!hda) in hda_tegra_probe()
451 return -ENOMEM; in hda_tegra_probe()
452 hda->dev = &pdev->dev; in hda_tegra_probe()
453 chip = &hda->chip; in hda_tegra_probe()
455 err = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, in hda_tegra_probe()
458 dev_err(&pdev->dev, "Error creating card!\n"); in hda_tegra_probe()
462 hda->reset = devm_reset_control_array_get_exclusive(&pdev->dev); in hda_tegra_probe()
463 if (IS_ERR(hda->reset)) { in hda_tegra_probe()
464 err = PTR_ERR(hda->reset); in hda_tegra_probe()
468 hda->clocks[hda->nclocks++].id = "hda"; in hda_tegra_probe()
469 hda->clocks[hda->nclocks++].id = "hda2hdmi"; in hda_tegra_probe()
470 hda->clocks[hda->nclocks++].id = "hda2codec_2x"; in hda_tegra_probe()
472 err = devm_clk_bulk_get(&pdev->dev, hda->nclocks, hda->clocks); in hda_tegra_probe()
476 err = hda_tegra_create(card, driver_flags, hda); in hda_tegra_probe()
479 card->private_data = chip; in hda_tegra_probe()
481 dev_set_drvdata(&pdev->dev, card); in hda_tegra_probe()
483 pm_runtime_enable(hda->dev); in hda_tegra_probe()
485 pm_runtime_forbid(hda->dev); in hda_tegra_probe()
487 schedule_work(&hda->probe_work); in hda_tegra_probe()
498 struct hda_tegra *hda = container_of(work, struct hda_tegra, probe_work); in hda_tegra_probe_work() local
499 struct azx *chip = &hda->chip; in hda_tegra_probe_work()
500 struct platform_device *pdev = to_platform_device(hda->dev); in hda_tegra_probe_work()
503 pm_runtime_get_sync(hda->dev); in hda_tegra_probe_work()
517 err = snd_card_register(chip->card); in hda_tegra_probe_work()
521 chip->running = 1; in hda_tegra_probe_work()
522 snd_hda_set_power_save(&chip->bus, power_save * 1000); in hda_tegra_probe_work()
525 pm_runtime_put(hda->dev); in hda_tegra_probe_work()
533 ret = snd_card_free(dev_get_drvdata(&pdev->dev)); in hda_tegra_remove()
534 pm_runtime_disable(&pdev->dev); in hda_tegra_remove()
541 struct snd_card *card = dev_get_drvdata(&pdev->dev); in hda_tegra_shutdown()
546 chip = card->private_data; in hda_tegra_shutdown()
547 if (chip && chip->running) in hda_tegra_shutdown()
553 .name = "tegra-hda",
563 MODULE_DESCRIPTION("Tegra HDA bus driver");