aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorDylan Reid <dgreid@chromium.org>2014-05-19 22:18:27 -0400
committerTakashi Iwai <tiwai@suse.de>2014-05-20 03:38:38 -0400
commit3c320f3f5649667874d754e59bdd84dab185fe04 (patch)
tree30eddddabb1fbbc34c464dee7e454886780dcb4f /sound/pci
parent9674678633377ac5065dc587a536abfe6ff98ca9 (diff)
ALSA: hda - Add driver for Tegra SoC HDA
This adds a driver for the HDA block in Tegra SoCs. The HDA bus is used to communicate with the HDMI codec on Tegra124. Most of the code is re-used from the Intel/PCI HDA driver. It brings over only two of the module params, power_save and probe_mask. Signed-off-by: Dylan Reid <dgreid@chromium.org> Reviewed-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/Kconfig15
-rw-r--r--sound/pci/hda/Makefile2
-rw-r--r--sound/pci/hda/hda_tegra.c584
3 files changed, 601 insertions, 0 deletions
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index ac17c3fc9388..ebf4c2fb99df 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -20,6 +20,21 @@ config SND_HDA_INTEL
20 To compile this driver as a module, choose M here: the module 20 To compile this driver as a module, choose M here: the module
21 will be called snd-hda-intel. 21 will be called snd-hda-intel.
22 22
23config SND_HDA_TEGRA
24 tristate "NVIDIA Tegra HD Audio"
25 depends on ARCH_TEGRA
26 select SND_HDA
27 help
28 Say Y here to support the HDA controller present in NVIDIA
29 Tegra SoCs
30
31 This options enables support for the HD Audio controller
32 present in some NVIDIA Tegra SoCs, used to communicate audio
33 to the HDMI output.
34
35 To compile this driver as a module, choose M here: the module
36 will be called snd-hda-tegra.
37
23if SND_HDA 38if SND_HDA
24 39
25config SND_HDA_DSP_LOADER 40config SND_HDA_DSP_LOADER
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index d0d0c19ddfc2..194f30935e77 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -1,5 +1,6 @@
1snd-hda-intel-objs := hda_intel.o 1snd-hda-intel-objs := hda_intel.o
2snd-hda-controller-objs := hda_controller.o 2snd-hda-controller-objs := hda_controller.o
3snd-hda-tegra-objs := hda_tegra.o
3# for haswell power well 4# for haswell power well
4snd-hda-intel-$(CONFIG_SND_HDA_I915) += hda_i915.o 5snd-hda-intel-$(CONFIG_SND_HDA_I915) += hda_i915.o
5 6
@@ -47,3 +48,4 @@ obj-$(CONFIG_SND_HDA_CODEC_HDMI) += snd-hda-codec-hdmi.o
47# otherwise the codec patches won't be hooked before the PCI probe 48# otherwise the codec patches won't be hooked before the PCI probe
48# when built in kernel 49# when built in kernel
49obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o 50obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
51obj-$(CONFIG_SND_HDA_TEGRA) += snd-hda-tegra.o
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
new file mode 100644
index 000000000000..e472bc882fc1
--- /dev/null
+++ b/sound/pci/hda/hda_tegra.c
@@ -0,0 +1,584 @@
1/*
2 *
3 * Implementation of primary ALSA driver code base for NVIDIA Tegra HDA.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19#include <linux/clk.h>
20#include <linux/clocksource.h>
21#include <linux/completion.h>
22#include <linux/delay.h>
23#include <linux/dma-mapping.h>
24#include <linux/init.h>
25#include <linux/interrupt.h>
26#include <linux/io.h>
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/moduleparam.h>
30#include <linux/mutex.h>
31#include <linux/of_device.h>
32#include <linux/reboot.h>
33#include <linux/slab.h>
34#include <linux/time.h>
35
36#include <sound/core.h>
37#include <sound/initval.h>
38
39#include "hda_codec.h"
40#include "hda_controller.h"
41#include "hda_priv.h"
42
43/* Defines for Nvidia Tegra HDA support */
44#define HDA_BAR0 0x8000
45
46#define HDA_CFG_CMD 0x1004
47#define HDA_CFG_BAR0 0x1010
48
49#define HDA_ENABLE_IO_SPACE (1 << 0)
50#define HDA_ENABLE_MEM_SPACE (1 << 1)
51#define HDA_ENABLE_BUS_MASTER (1 << 2)
52#define HDA_ENABLE_SERR (1 << 8)
53#define HDA_DISABLE_INTR (1 << 10)
54#define HDA_BAR0_INIT_PROGRAM 0xFFFFFFFF
55#define HDA_BAR0_FINAL_PROGRAM (1 << 14)
56
57/* IPFS */
58#define HDA_IPFS_CONFIG 0x180
59#define HDA_IPFS_EN_FPCI 0x1
60
61#define HDA_IPFS_FPCI_BAR0 0x80
62#define HDA_FPCI_BAR0_START 0x40
63
64#define HDA_IPFS_INTR_MASK 0x188
65#define HDA_IPFS_EN_INTR (1 << 16)
66
67/* max number of SDs */
68#define NUM_CAPTURE_SD 1
69#define NUM_PLAYBACK_SD 1
70
71struct hda_tegra {
72 struct azx chip;
73 struct device *dev;
74 struct clk *hda_clk;
75 struct clk *hda2codec_2x_clk;
76 struct clk *hda2hdmi_clk;
77 void __iomem *regs;
78};
79
80static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
81module_param(power_save, bint, 0644);
82MODULE_PARM_DESC(power_save,
83 "Automatic power-saving timeout (in seconds, 0 = disable).");
84
85/*
86 * DMA page allocation ops.
87 */
88static int dma_alloc_pages(struct azx *chip, int type, size_t size,
89 struct snd_dma_buffer *buf)
90{
91 return snd_dma_alloc_pages(type, chip->card->dev, size, buf);
92}
93
94static void dma_free_pages(struct azx *chip, struct snd_dma_buffer *buf)
95{
96 snd_dma_free_pages(buf);
97}
98
99static int substream_alloc_pages(struct azx *chip,
100 struct snd_pcm_substream *substream,
101 size_t size)
102{
103 struct azx_dev *azx_dev = get_azx_dev(substream);
104
105 azx_dev->bufsize = 0;
106 azx_dev->period_bytes = 0;
107 azx_dev->format_val = 0;
108 return snd_pcm_lib_malloc_pages(substream, size);
109}
110
111static int substream_free_pages(struct azx *chip,
112 struct snd_pcm_substream *substream)
113{
114 return snd_pcm_lib_free_pages(substream);
115}
116
117/*
118 * Register access ops. Tegra HDA register access is DWORD only.
119 */
120static void hda_tegra_writel(u32 value, u32 *addr)
121{
122 writel(value, addr);
123}
124
125static u32 hda_tegra_readl(u32 *addr)
126{
127 return readl(addr);
128}
129
130static void hda_tegra_writew(u16 value, u16 *addr)
131{
132 unsigned int shift = ((unsigned long)(addr) & 0x3) << 3;
133 void *dword_addr = (void *)((unsigned long)(addr) & ~0x3);
134 u32 v;
135
136 v = readl(dword_addr);
137 v &= ~(0xffff << shift);
138 v |= value << shift;
139 writel(v, dword_addr);
140}
141
142static u16 hda_tegra_readw(u16 *addr)
143{
144 unsigned int shift = ((unsigned long)(addr) & 0x3) << 3;
145 void *dword_addr = (void *)((unsigned long)(addr) & ~0x3);
146 u32 v;
147
148 v = readl(dword_addr);
149 return (v >> shift) & 0xffff;
150}
151
152static void hda_tegra_writeb(u8 value, u8 *addr)
153{
154 unsigned int shift = ((unsigned long)(addr) & 0x3) << 3;
155 void *dword_addr = (void *)((unsigned long)(addr) & ~0x3);
156 u32 v;
157
158 v = readl(dword_addr);
159 v &= ~(0xff << shift);
160 v |= value << shift;
161 writel(v, dword_addr);
162}
163
164static u8 hda_tegra_readb(u8 *addr)
165{
166 unsigned int shift = ((unsigned long)(addr) & 0x3) << 3;
167 void *dword_addr = (void *)((unsigned long)(addr) & ~0x3);
168 u32 v;
169
170 v = readl(dword_addr);
171 return (v >> shift) & 0xff;
172}
173
174static const struct hda_controller_ops hda_tegra_ops = {
175 .reg_writel = hda_tegra_writel,
176 .reg_readl = hda_tegra_readl,
177 .reg_writew = hda_tegra_writew,
178 .reg_readw = hda_tegra_readw,
179 .reg_writeb = hda_tegra_writeb,
180 .reg_readb = hda_tegra_readb,
181 .dma_alloc_pages = dma_alloc_pages,
182 .dma_free_pages = dma_free_pages,
183 .substream_alloc_pages = substream_alloc_pages,
184 .substream_free_pages = substream_free_pages,
185};
186
187static void hda_tegra_init(struct hda_tegra *hda)
188{
189 u32 v;
190
191 /* Enable PCI access */
192 v = readl(hda->regs + HDA_IPFS_CONFIG);
193 v |= HDA_IPFS_EN_FPCI;
194 writel(v, hda->regs + HDA_IPFS_CONFIG);
195
196 /* Enable MEM/IO space and bus master */
197 v = readl(hda->regs + HDA_CFG_CMD);
198 v &= ~HDA_DISABLE_INTR;
199 v |= HDA_ENABLE_MEM_SPACE | HDA_ENABLE_IO_SPACE |
200 HDA_ENABLE_BUS_MASTER | HDA_ENABLE_SERR;
201 writel(v, hda->regs + HDA_CFG_CMD);
202
203 writel(HDA_BAR0_INIT_PROGRAM, hda->regs + HDA_CFG_BAR0);
204 writel(HDA_BAR0_FINAL_PROGRAM, hda->regs + HDA_CFG_BAR0);
205 writel(HDA_FPCI_BAR0_START, hda->regs + HDA_IPFS_FPCI_BAR0);
206
207 v = readl(hda->regs + HDA_IPFS_INTR_MASK);
208 v |= HDA_IPFS_EN_INTR;
209 writel(v, hda->regs + HDA_IPFS_INTR_MASK);
210}
211
212static int hda_tegra_enable_clocks(struct hda_tegra *data)
213{
214 int rc;
215
216 rc = clk_prepare_enable(data->hda_clk);
217 if (rc)
218 return rc;
219 rc = clk_prepare_enable(data->hda2codec_2x_clk);
220 if (rc)
221 goto disable_hda;
222 rc = clk_prepare_enable(data->hda2hdmi_clk);
223 if (rc)
224 goto disable_codec_2x;
225
226 return 0;
227
228disable_codec_2x:
229 clk_disable_unprepare(data->hda2codec_2x_clk);
230disable_hda:
231 clk_disable_unprepare(data->hda_clk);
232 return rc;
233}
234
235static void hda_tegra_disable_clocks(struct hda_tegra *data)
236{
237 clk_disable_unprepare(data->hda2hdmi_clk);
238 clk_disable_unprepare(data->hda2codec_2x_clk);
239 clk_disable_unprepare(data->hda_clk);
240}
241
242#ifdef CONFIG_PM_SLEEP
243/*
244 * power management
245 */
246static int hda_tegra_suspend(struct device *dev)
247{
248 struct snd_card *card = dev_get_drvdata(dev);
249 struct azx *chip = card->private_data;
250 struct azx_pcm *p;
251 struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip);
252
253 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
254 list_for_each_entry(p, &chip->pcm_list, list)
255 snd_pcm_suspend_all(p->pcm);
256 if (chip->initialized)
257 snd_hda_suspend(chip->bus);
258
259 azx_stop_chip(chip);
260 azx_enter_link_reset(chip);
261 hda_tegra_disable_clocks(hda);
262
263 return 0;
264}
265
266static int hda_tegra_resume(struct device *dev)
267{
268 struct snd_card *card = dev_get_drvdata(dev);
269 struct azx *chip = card->private_data;
270 struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip);
271 int status;
272
273 hda_tegra_enable_clocks(hda);
274
275 /* Read STATESTS before controller reset */
276 status = azx_readw(chip, STATESTS);
277
278 hda_tegra_init(hda);
279
280 azx_init_chip(chip, 1);
281
282 snd_hda_resume(chip->bus);
283 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
284
285 return 0;
286}
287#endif /* CONFIG_PM_SLEEP */
288
289static const struct dev_pm_ops hda_tegra_pm = {
290 SET_SYSTEM_SLEEP_PM_OPS(hda_tegra_suspend, hda_tegra_resume)
291};
292
293/*
294 * reboot notifier for hang-up problem at power-down
295 */
296static int hda_tegra_halt(struct notifier_block *nb, unsigned long event,
297 void *buf)
298{
299 struct azx *chip = container_of(nb, struct azx, reboot_notifier);
300 snd_hda_bus_reboot_notify(chip->bus);
301 azx_stop_chip(chip);
302 return NOTIFY_OK;
303}
304
305static void hda_tegra_notifier_register(struct azx *chip)
306{
307 chip->reboot_notifier.notifier_call = hda_tegra_halt;
308 register_reboot_notifier(&chip->reboot_notifier);
309}
310
311static void hda_tegra_notifier_unregister(struct azx *chip)
312{
313 if (chip->reboot_notifier.notifier_call)
314 unregister_reboot_notifier(&chip->reboot_notifier);
315}
316
317/*
318 * destructor
319 */
320static int hda_tegra_dev_free(struct snd_device *device)
321{
322 int i;
323 struct azx *chip = device->device_data;
324
325 hda_tegra_notifier_unregister(chip);
326
327 if (chip->initialized) {
328 for (i = 0; i < chip->num_streams; i++)
329 azx_stream_stop(chip, &chip->azx_dev[i]);
330 azx_stop_chip(chip);
331 }
332
333 azx_free_stream_pages(chip);
334
335 return 0;
336}
337
338static int hda_tegra_init_chip(struct azx *chip, struct platform_device *pdev)
339{
340 struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip);
341 struct device *dev = hda->dev;
342 struct resource *res;
343 int err;
344
345 hda->hda_clk = devm_clk_get(dev, "hda");
346 if (IS_ERR(hda->hda_clk))
347 return PTR_ERR(hda->hda_clk);
348 hda->hda2codec_2x_clk = devm_clk_get(dev, "hda2codec_2x");
349 if (IS_ERR(hda->hda2codec_2x_clk))
350 return PTR_ERR(hda->hda2codec_2x_clk);
351 hda->hda2hdmi_clk = devm_clk_get(dev, "hda2hdmi");
352 if (IS_ERR(hda->hda2hdmi_clk))
353 return PTR_ERR(hda->hda2hdmi_clk);
354
355 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
356 hda->regs = devm_ioremap_resource(dev, res);
357 if (IS_ERR(chip->remap_addr))
358 return PTR_ERR(chip->remap_addr);
359
360 chip->remap_addr = hda->regs + HDA_BAR0;
361 chip->addr = res->start + HDA_BAR0;
362
363 err = hda_tegra_enable_clocks(hda);
364 if (err)
365 return err;
366
367 hda_tegra_init(hda);
368
369 return 0;
370}
371
372/*
373 * The codecs were powered up in snd_hda_codec_new().
374 * Now all initialization done, so turn them down if possible
375 */
376static void power_down_all_codecs(struct azx *chip)
377{
378 struct hda_codec *codec;
379 list_for_each_entry(codec, &chip->bus->codec_list, list)
380 snd_hda_power_down(codec);
381}
382
383static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev)
384{
385 struct snd_card *card = chip->card;
386 int err;
387 unsigned short gcap;
388 int irq_id = platform_get_irq(pdev, 0);
389
390 err = hda_tegra_init_chip(chip, pdev);
391 if (err)
392 return err;
393
394 err = devm_request_irq(chip->card->dev, irq_id, azx_interrupt,
395 IRQF_SHARED, KBUILD_MODNAME, chip);
396 if (err) {
397 dev_err(chip->card->dev,
398 "unable to request IRQ %d, disabling device\n",
399 irq_id);
400 return err;
401 }
402 chip->irq = irq_id;
403
404 synchronize_irq(chip->irq);
405
406 gcap = azx_readw(chip, GCAP);
407 dev_dbg(card->dev, "chipset global capabilities = 0x%x\n", gcap);
408
409 /* read number of streams from GCAP register instead of using
410 * hardcoded value
411 */
412 chip->capture_streams = (gcap >> 8) & 0x0f;
413 chip->playback_streams = (gcap >> 12) & 0x0f;
414 if (!chip->playback_streams && !chip->capture_streams) {
415 /* gcap didn't give any info, switching to old method */
416 chip->playback_streams = NUM_PLAYBACK_SD;
417 chip->capture_streams = NUM_CAPTURE_SD;
418 }
419 chip->capture_index_offset = 0;
420 chip->playback_index_offset = chip->capture_streams;
421 chip->num_streams = chip->playback_streams + chip->capture_streams;
422 chip->azx_dev = devm_kcalloc(card->dev, chip->num_streams,
423 sizeof(*chip->azx_dev), GFP_KERNEL);
424 if (!chip->azx_dev)
425 return -ENOMEM;
426
427 err = azx_alloc_stream_pages(chip);
428 if (err < 0)
429 return err;
430
431 /* initialize streams */
432 azx_init_stream(chip);
433
434 /* initialize chip */
435 azx_init_chip(chip, 1);
436
437 /* codec detection */
438 if (!chip->codec_mask) {
439 dev_err(card->dev, "no codecs found!\n");
440 return -ENODEV;
441 }
442
443 strcpy(card->driver, "tegra-hda");
444 strcpy(card->shortname, "tegra-hda");
445 snprintf(card->longname, sizeof(card->longname),
446 "%s at 0x%lx irq %i",
447 card->shortname, chip->addr, chip->irq);
448
449 return 0;
450}
451
452/*
453 * constructor
454 */
455static int hda_tegra_create(struct snd_card *card,
456 unsigned int driver_caps,
457 const struct hda_controller_ops *hda_ops,
458 struct hda_tegra *hda)
459{
460 static struct snd_device_ops ops = {
461 .dev_free = hda_tegra_dev_free,
462 };
463 struct azx *chip;
464 int err;
465
466 chip = &hda->chip;
467
468 spin_lock_init(&chip->reg_lock);
469 mutex_init(&chip->open_mutex);
470 chip->card = card;
471 chip->ops = hda_ops;
472 chip->irq = -1;
473 chip->driver_caps = driver_caps;
474 chip->driver_type = driver_caps & 0xff;
475 chip->dev_index = 0;
476 INIT_LIST_HEAD(&chip->pcm_list);
477 INIT_LIST_HEAD(&chip->list);
478
479 chip->position_fix[0] = POS_FIX_AUTO;
480 chip->position_fix[1] = POS_FIX_AUTO;
481 chip->codec_probe_mask = -1;
482
483 chip->single_cmd = false;
484 chip->snoop = true;
485
486 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
487 if (err < 0) {
488 dev_err(card->dev, "Error creating device\n");
489 return err;
490 }
491
492 return 0;
493}
494
495static const struct of_device_id hda_tegra_match[] = {
496 { .compatible = "nvidia,tegra30-hda" },
497 {},
498};
499MODULE_DEVICE_TABLE(of, tegra_platform_hda_match);
500
501static int hda_tegra_probe(struct platform_device *pdev)
502{
503 struct snd_card *card;
504 struct azx *chip;
505 struct hda_tegra *hda;
506 int err;
507 const unsigned int driver_flags = AZX_DCAPS_RIRB_DELAY;
508
509 hda = devm_kzalloc(&pdev->dev, sizeof(*hda), GFP_KERNEL);
510 if (!hda)
511 return -ENOMEM;
512 hda->dev = &pdev->dev;
513 chip = &hda->chip;
514
515 err = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
516 THIS_MODULE, 0, &card);
517 if (err < 0) {
518 dev_err(&pdev->dev, "Error creating card!\n");
519 return err;
520 }
521
522 err = hda_tegra_create(card, driver_flags, &hda_tegra_ops, hda);
523 if (err < 0)
524 goto out_free;
525 card->private_data = chip;
526
527 dev_set_drvdata(&pdev->dev, card);
528
529 err = hda_tegra_first_init(chip, pdev);
530 if (err < 0)
531 goto out_free;
532
533 /* create codec instances */
534 err = azx_codec_create(chip, NULL, 0, &power_save);
535 if (err < 0)
536 goto out_free;
537
538 err = azx_codec_configure(chip);
539 if (err < 0)
540 goto out_free;
541
542 /* create PCM streams */
543 err = snd_hda_build_pcms(chip->bus);
544 if (err < 0)
545 goto out_free;
546
547 /* create mixer controls */
548 err = azx_mixer_create(chip);
549 if (err < 0)
550 goto out_free;
551
552 err = snd_card_register(chip->card);
553 if (err < 0)
554 goto out_free;
555
556 chip->running = 1;
557 power_down_all_codecs(chip);
558 hda_tegra_notifier_register(chip);
559
560 return 0;
561
562out_free:
563 snd_card_free(card);
564 return err;
565}
566
567static int hda_tegra_remove(struct platform_device *pdev)
568{
569 return snd_card_free(dev_get_drvdata(&pdev->dev));
570}
571
572static struct platform_driver tegra_platform_hda = {
573 .driver = {
574 .name = "tegra-hda",
575 .pm = &hda_tegra_pm,
576 .of_match_table = hda_tegra_match,
577 },
578 .probe = hda_tegra_probe,
579 .remove = hda_tegra_remove,
580};
581module_platform_driver(tegra_platform_hda);
582
583MODULE_DESCRIPTION("Tegra HDA bus driver");
584MODULE_LICENSE("GPL v2");