From f6f11018dc7ea62482f36846e9f6eb0f27df7c3c Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 11 Aug 2008 17:04:32 +1000 Subject: powerpc/drivers: Use linux/of_device.h instead of asm/of_device.h Signed-off-by: Stephen Rothwell Acked-by: Takashi Iwai Signed-off-by: Paul Mackerras --- sound/aoa/soundbus/soundbus.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/aoa/soundbus/soundbus.h b/sound/aoa/soundbus/soundbus.h index 622cd37a011..a0f223c13f6 100644 --- a/sound/aoa/soundbus/soundbus.h +++ b/sound/aoa/soundbus/soundbus.h @@ -8,7 +8,7 @@ #ifndef __SOUNDBUS_H #define __SOUNDBUS_H -#include +#include #include #include -- cgit v1.2.3 From 7a715f46012f3552294154978aed59cba9804928 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 27 Aug 2008 18:37:58 -0700 Subject: sparc: Make SBUS DMA interfaces take struct device. This is the first step in converting all the SBUS drivers over to generic dma_*(). Signed-off-by: David S. Miller --- sound/core/memalloc.c | 6 ++++-- sound/sparc/dbri.c | 15 +++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'sound') diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index f5d6d8d1297..cc803972c0f 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -192,7 +192,8 @@ static void *snd_malloc_sbus_pages(struct device *dev, size_t size, snd_assert(size > 0, return NULL); snd_assert(dma_addr != NULL, return NULL); pg = get_order(size); - res = sbus_alloc_consistent(sdev, PAGE_SIZE * (1 << pg), dma_addr); + res = sbus_alloc_consistent(&sdev->ofdev.dev, PAGE_SIZE * (1 << pg), + dma_addr); if (res != NULL) inc_snd_pages(pg); return res; @@ -208,7 +209,8 @@ static void snd_free_sbus_pages(struct device *dev, size_t size, return; pg = get_order(size); dec_snd_pages(pg); - sbus_free_consistent(sdev, PAGE_SIZE * (1 << pg), ptr, dma_addr); + sbus_free_consistent(&sdev->ofdev.dev, PAGE_SIZE * (1 << pg), + ptr, dma_addr); } #endif /* CONFIG_SBUS */ diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index ee2e1b4f355..a6b32ec34bd 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -2097,7 +2097,8 @@ static int snd_dbri_hw_params(struct snd_pcm_substream *substream, else direction = SBUS_DMA_FROMDEVICE; - info->dvma_buffer = sbus_map_single(dbri->sdev, + info->dvma_buffer = + sbus_map_single(&dbri->sdev->ofdev.dev, runtime->dma_area, params_buffer_bytes(hw_params), direction); @@ -2125,7 +2126,7 @@ static int snd_dbri_hw_free(struct snd_pcm_substream *substream) else direction = SBUS_DMA_FROMDEVICE; - sbus_unmap_single(dbri->sdev, info->dvma_buffer, + sbus_unmap_single(&dbri->sdev->ofdev.dev, info->dvma_buffer, substream->runtime->buffer_size, direction); info->dvma_buffer = 0; } @@ -2524,7 +2525,8 @@ static int __devinit snd_dbri_create(struct snd_card *card, dbri->sdev = sdev; dbri->irq = irq; - dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma), + dbri->dma = sbus_alloc_consistent(&sdev->ofdev.dev, + sizeof(struct dbri_dma), &dbri->dma_dvma); memset((void *)dbri->dma, 0, sizeof(struct dbri_dma)); @@ -2537,7 +2539,7 @@ static int __devinit snd_dbri_create(struct snd_card *card, dbri->regs_size, "DBRI Registers"); if (!dbri->regs) { printk(KERN_ERR "DBRI: could not allocate registers\n"); - sbus_free_consistent(sdev, sizeof(struct dbri_dma), + sbus_free_consistent(&sdev->ofdev.dev, sizeof(struct dbri_dma), (void *)dbri->dma, dbri->dma_dvma); return -EIO; } @@ -2547,7 +2549,7 @@ static int __devinit snd_dbri_create(struct snd_card *card, if (err) { printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq); sbus_iounmap(dbri->regs, dbri->regs_size); - sbus_free_consistent(sdev, sizeof(struct dbri_dma), + sbus_free_consistent(&sdev->ofdev.dev, sizeof(struct dbri_dma), (void *)dbri->dma, dbri->dma_dvma); return err; } @@ -2575,7 +2577,8 @@ static void snd_dbri_free(struct snd_dbri *dbri) sbus_iounmap(dbri->regs, dbri->regs_size); if (dbri->dma) - sbus_free_consistent(dbri->sdev, sizeof(struct dbri_dma), + sbus_free_consistent(&dbri->sdev->ofdev.dev, + sizeof(struct dbri_dma), (void *)dbri->dma, dbri->dma_dvma); } -- cgit v1.2.3 From 738f2b7b813913e651f39387d007dd961755dee2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 27 Aug 2008 18:09:11 -0700 Subject: sparc: Convert all SBUS drivers to dma_*() interfaces. And all the SBUS dma interfaces are deleted. A private implementation remains inside of the 32-bit sparc port which exists only for the sake of the implementation of dma_*(). Signed-off-by: David S. Miller --- sound/core/memalloc.c | 8 ++++---- sound/sparc/dbri.c | 41 +++++++++++++++++++++-------------------- 2 files changed, 25 insertions(+), 24 deletions(-) (limited to 'sound') diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index cc803972c0f..ccaaac45faf 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -192,8 +192,8 @@ static void *snd_malloc_sbus_pages(struct device *dev, size_t size, snd_assert(size > 0, return NULL); snd_assert(dma_addr != NULL, return NULL); pg = get_order(size); - res = sbus_alloc_consistent(&sdev->ofdev.dev, PAGE_SIZE * (1 << pg), - dma_addr); + res = dma_alloc_coherent(&sdev->ofdev.dev, PAGE_SIZE * (1 << pg), + dma_addr, GFP_ATOMIC); if (res != NULL) inc_snd_pages(pg); return res; @@ -209,8 +209,8 @@ static void snd_free_sbus_pages(struct device *dev, size_t size, return; pg = get_order(size); dec_snd_pages(pg); - sbus_free_consistent(&sdev->ofdev.dev, PAGE_SIZE * (1 << pg), - ptr, dma_addr); + dma_free_coherent(&sdev->ofdev.dev, PAGE_SIZE * (1 << pg), + ptr, dma_addr); } #endif /* CONFIG_SBUS */ diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index a6b32ec34bd..5242ecbb91d 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include @@ -2093,15 +2094,15 @@ static int snd_dbri_hw_params(struct snd_pcm_substream *substream, */ if (info->dvma_buffer == 0) { if (DBRI_STREAMNO(substream) == DBRI_PLAY) - direction = SBUS_DMA_TODEVICE; + direction = DMA_TO_DEVICE; else - direction = SBUS_DMA_FROMDEVICE; + direction = DMA_FROM_DEVICE; info->dvma_buffer = - sbus_map_single(&dbri->sdev->ofdev.dev, - runtime->dma_area, - params_buffer_bytes(hw_params), - direction); + dma_map_single(&dbri->sdev->ofdev.dev, + runtime->dma_area, + params_buffer_bytes(hw_params), + direction); } direction = params_buffer_bytes(hw_params); @@ -2122,12 +2123,12 @@ static int snd_dbri_hw_free(struct snd_pcm_substream *substream) */ if (info->dvma_buffer) { if (DBRI_STREAMNO(substream) == DBRI_PLAY) - direction = SBUS_DMA_TODEVICE; + direction = DMA_TO_DEVICE; else - direction = SBUS_DMA_FROMDEVICE; + direction = DMA_FROM_DEVICE; - sbus_unmap_single(&dbri->sdev->ofdev.dev, info->dvma_buffer, - substream->runtime->buffer_size, direction); + dma_unmap_single(&dbri->sdev->ofdev.dev, info->dvma_buffer, + substream->runtime->buffer_size, direction); info->dvma_buffer = 0; } if (info->pipe != -1) { @@ -2525,9 +2526,9 @@ static int __devinit snd_dbri_create(struct snd_card *card, dbri->sdev = sdev; dbri->irq = irq; - dbri->dma = sbus_alloc_consistent(&sdev->ofdev.dev, - sizeof(struct dbri_dma), - &dbri->dma_dvma); + dbri->dma = dma_alloc_coherent(&sdev->ofdev.dev, + sizeof(struct dbri_dma), + &dbri->dma_dvma, GFP_ATOMIC); memset((void *)dbri->dma, 0, sizeof(struct dbri_dma)); dprintk(D_GEN, "DMA Cmd Block 0x%p (0x%08x)\n", @@ -2539,8 +2540,8 @@ static int __devinit snd_dbri_create(struct snd_card *card, dbri->regs_size, "DBRI Registers"); if (!dbri->regs) { printk(KERN_ERR "DBRI: could not allocate registers\n"); - sbus_free_consistent(&sdev->ofdev.dev, sizeof(struct dbri_dma), - (void *)dbri->dma, dbri->dma_dvma); + dma_free_coherent(&sdev->ofdev.dev, sizeof(struct dbri_dma), + (void *)dbri->dma, dbri->dma_dvma); return -EIO; } @@ -2549,8 +2550,8 @@ static int __devinit snd_dbri_create(struct snd_card *card, if (err) { printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq); sbus_iounmap(dbri->regs, dbri->regs_size); - sbus_free_consistent(&sdev->ofdev.dev, sizeof(struct dbri_dma), - (void *)dbri->dma, dbri->dma_dvma); + dma_free_coherent(&sdev->ofdev.dev, sizeof(struct dbri_dma), + (void *)dbri->dma, dbri->dma_dvma); return err; } @@ -2577,9 +2578,9 @@ static void snd_dbri_free(struct snd_dbri *dbri) sbus_iounmap(dbri->regs, dbri->regs_size); if (dbri->dma) - sbus_free_consistent(&dbri->sdev->ofdev.dev, - sizeof(struct dbri_dma), - (void *)dbri->dma, dbri->dma_dvma); + dma_free_coherent(&dbri->sdev->ofdev.dev, + sizeof(struct dbri_dma), + (void *)dbri->dma, dbri->dma_dvma); } static int __devinit dbri_probe(struct of_device *of_dev, -- cgit v1.2.3 From dc8aa2e9d6c965c11ddd05fca721b2218585b9f0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 27 Aug 2008 00:29:27 -0700 Subject: amd7930: Convert to pure OF driver. Signed-off-by: David S. Miller --- sound/sparc/amd7930.c | 83 +++++++++++++-------------------------------------- 1 file changed, 20 insertions(+), 63 deletions(-) (limited to 'sound') diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index 0c63e0585b1..0f82c3f6cfd 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c @@ -1,6 +1,6 @@ /* * Driver for AMD7930 sound chips found on Sparcs. - * Copyright (C) 2002 David S. Miller + * Copyright (C) 2002, 2008 David S. Miller * * Based entirely upon drivers/sbus/audio/amd7930.c which is: * Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu) @@ -35,6 +35,8 @@ #include #include #include +#include +#include #include #include @@ -44,7 +46,6 @@ #include #include -#include #include static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ @@ -335,8 +336,8 @@ struct snd_amd7930 { int pgain; int mgain; + struct of_device *op; unsigned int irq; - unsigned int regs_size; struct snd_amd7930 *next; }; @@ -920,13 +921,16 @@ static int __devinit snd_amd7930_mixer(struct snd_amd7930 *amd) static int snd_amd7930_free(struct snd_amd7930 *amd) { + struct of_device *op = amd->op; + amd7930_idle(amd); if (amd->irq) free_irq(amd->irq, amd); if (amd->regs) - sbus_iounmap(amd->regs, amd->regs_size); + of_iounmap(&op->resource[0], amd->regs, + resource_size(&op->resource[0])); kfree(amd); @@ -945,13 +949,12 @@ static struct snd_device_ops snd_amd7930_dev_ops = { }; static int __devinit snd_amd7930_create(struct snd_card *card, - struct resource *rp, - unsigned int reg_size, + struct of_device *op, int irq, int dev, struct snd_amd7930 **ramd) { - unsigned long flags; struct snd_amd7930 *amd; + unsigned long flags; int err; *ramd = NULL; @@ -961,9 +964,10 @@ static int __devinit snd_amd7930_create(struct snd_card *card, spin_lock_init(&amd->lock); amd->card = card; - amd->regs_size = reg_size; + amd->op = op; - amd->regs = sbus_ioremap(rp, 0, amd->regs_size, "amd7930"); + amd->regs = of_ioremap(&op->resource[0], 0, + resource_size(&op->resource[0]), "amd7930"); if (!amd->regs) { snd_printk("amd7930-%d: Unable to map chip registers.\n", dev); return -EIO; @@ -1012,12 +1016,15 @@ static int __devinit snd_amd7930_create(struct snd_card *card, return 0; } -static int __devinit amd7930_attach_common(struct resource *rp, int irq) +static int __devinit amd7930_sbus_probe(struct of_device *op, const struct of_device_id *match) { + struct resource *rp = &op->resource[0]; static int dev_num; struct snd_card *card; struct snd_amd7930 *amd; - int err; + int err, irq; + + irq = op->irqs[0]; if (dev_num >= SNDRV_CARDS) return -ENODEV; @@ -1038,8 +1045,7 @@ static int __devinit amd7930_attach_common(struct resource *rp, int irq) (unsigned long long)rp->start, irq); - if ((err = snd_amd7930_create(card, rp, - (rp->end - rp->start) + 1, + if ((err = snd_amd7930_create(card, op, irq, dev_num, &amd)) < 0) goto out_err; @@ -1064,42 +1070,6 @@ out_err: return err; } -static int __devinit amd7930_obio_attach(struct device_node *dp) -{ - const struct linux_prom_registers *regs; - const struct linux_prom_irqs *irqp; - struct resource res, *rp; - int len; - - irqp = of_get_property(dp, "intr", &len); - if (!irqp) { - snd_printk("%s: Firmware node lacks IRQ property.\n", - dp->full_name); - return -ENODEV; - } - - regs = of_get_property(dp, "reg", &len); - if (!regs) { - snd_printk("%s: Firmware node lacks register property.\n", - dp->full_name); - return -ENODEV; - } - - rp = &res; - rp->start = regs->phys_addr; - rp->end = rp->start + regs->reg_size - 1; - rp->flags = IORESOURCE_IO | (regs->which_io & 0xff); - - return amd7930_attach_common(rp, irqp->pri); -} - -static int __devinit amd7930_sbus_probe(struct of_device *dev, const struct of_device_id *match) -{ - struct sbus_dev *sdev = to_sbus_device(&dev->dev); - - return amd7930_attach_common(&sdev->resource[0], sdev->irqs[0]); -} - static struct of_device_id amd7930_match[] = { { .name = "audio", @@ -1115,20 +1085,7 @@ static struct of_platform_driver amd7930_sbus_driver = { static int __init amd7930_init(void) { - struct device_node *dp; - - /* Try to find the sun4c "audio" node first. */ - dp = of_find_node_by_path("/"); - dp = dp->child; - while (dp) { - if (!strcmp(dp->name, "audio")) - amd7930_obio_attach(dp); - - dp = dp->sibling; - } - - /* Probe each SBUS for amd7930 chips. */ - return of_register_driver(&amd7930_sbus_driver, &sbus_bus_type); + return of_register_driver(&amd7930_sbus_driver, &of_bus_type); } static void __exit amd7930_exit(void) -- cgit v1.2.3 From 2bd320f89d417c370f4cf45470d102332c25ea24 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 27 Aug 2008 00:30:59 -0700 Subject: dbri: Convert to pure OF driver. Signed-off-by: David S. Miller --- sound/sparc/dbri.c | 59 +++++++++++++++++++++++++----------------------------- 1 file changed, 27 insertions(+), 32 deletions(-) (limited to 'sound') diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 5242ecbb91d..446f985b76f 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -67,7 +67,7 @@ #include #include -#include +#include #include MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets"); @@ -298,7 +298,7 @@ struct dbri_streaminfo { /* This structure holds the information for both chips (DBRI & CS4215) */ struct snd_dbri { int regs_size, irq; /* Needed for unload */ - struct sbus_dev *sdev; /* SBUS device info */ + struct of_device *op; /* OF device info */ spinlock_t lock; struct dbri_dma *dma; /* Pointer to our DMA block */ @@ -2099,7 +2099,7 @@ static int snd_dbri_hw_params(struct snd_pcm_substream *substream, direction = DMA_FROM_DEVICE; info->dvma_buffer = - dma_map_single(&dbri->sdev->ofdev.dev, + dma_map_single(&dbri->op->dev, runtime->dma_area, params_buffer_bytes(hw_params), direction); @@ -2127,7 +2127,7 @@ static int snd_dbri_hw_free(struct snd_pcm_substream *substream) else direction = DMA_FROM_DEVICE; - dma_unmap_single(&dbri->sdev->ofdev.dev, info->dvma_buffer, + dma_unmap_single(&dbri->op->dev, info->dvma_buffer, substream->runtime->buffer_size, direction); info->dvma_buffer = 0; } @@ -2516,17 +2516,17 @@ static void __devinit snd_dbri_proc(struct snd_card *card) static void snd_dbri_free(struct snd_dbri *dbri); static int __devinit snd_dbri_create(struct snd_card *card, - struct sbus_dev *sdev, - int irq, int dev) + struct of_device *op, + int irq, int dev) { struct snd_dbri *dbri = card->private_data; int err; spin_lock_init(&dbri->lock); - dbri->sdev = sdev; + dbri->op = op; dbri->irq = irq; - dbri->dma = dma_alloc_coherent(&sdev->ofdev.dev, + dbri->dma = dma_alloc_coherent(&op->dev, sizeof(struct dbri_dma), &dbri->dma_dvma, GFP_ATOMIC); memset((void *)dbri->dma, 0, sizeof(struct dbri_dma)); @@ -2535,12 +2535,12 @@ static int __devinit snd_dbri_create(struct snd_card *card, dbri->dma, dbri->dma_dvma); /* Map the registers into memory. */ - dbri->regs_size = sdev->reg_addrs[0].reg_size; - dbri->regs = sbus_ioremap(&sdev->resource[0], 0, - dbri->regs_size, "DBRI Registers"); + dbri->regs_size = resource_size(&op->resource[0]); + dbri->regs = of_ioremap(&op->resource[0], 0, + dbri->regs_size, "DBRI Registers"); if (!dbri->regs) { printk(KERN_ERR "DBRI: could not allocate registers\n"); - dma_free_coherent(&sdev->ofdev.dev, sizeof(struct dbri_dma), + dma_free_coherent(&op->dev, sizeof(struct dbri_dma), (void *)dbri->dma, dbri->dma_dvma); return -EIO; } @@ -2549,8 +2549,8 @@ static int __devinit snd_dbri_create(struct snd_card *card, "DBRI audio", dbri); if (err) { printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq); - sbus_iounmap(dbri->regs, dbri->regs_size); - dma_free_coherent(&sdev->ofdev.dev, sizeof(struct dbri_dma), + of_iounmap(&op->resource[0], dbri->regs, dbri->regs_size); + dma_free_coherent(&op->dev, sizeof(struct dbri_dma), (void *)dbri->dma, dbri->dma_dvma); return err; } @@ -2575,28 +2575,23 @@ static void snd_dbri_free(struct snd_dbri *dbri) free_irq(dbri->irq, dbri); if (dbri->regs) - sbus_iounmap(dbri->regs, dbri->regs_size); + of_iounmap(&dbri->op->resource[0], dbri->regs, dbri->regs_size); if (dbri->dma) - dma_free_coherent(&dbri->sdev->ofdev.dev, + dma_free_coherent(&dbri->op->dev, sizeof(struct dbri_dma), (void *)dbri->dma, dbri->dma_dvma); } -static int __devinit dbri_probe(struct of_device *of_dev, - const struct of_device_id *match) +static int __devinit dbri_probe(struct of_device *op, const struct of_device_id *match) { - struct sbus_dev *sdev = to_sbus_device(&of_dev->dev); struct snd_dbri *dbri; - int irq; struct resource *rp; struct snd_card *card; static int dev = 0; + int irq; int err; - dprintk(D_GEN, "DBRI: Found %s in SBUS slot %d\n", - sdev->prom_name, sdev->slot); - if (dev >= SNDRV_CARDS) return -ENODEV; if (!enable[dev]) { @@ -2604,7 +2599,7 @@ static int __devinit dbri_probe(struct of_device *of_dev, return -ENOENT; } - irq = sdev->irqs[0]; + irq = op->irqs[0]; if (irq <= 0) { printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev); return -ENODEV; @@ -2617,12 +2612,12 @@ static int __devinit dbri_probe(struct of_device *of_dev, strcpy(card->driver, "DBRI"); strcpy(card->shortname, "Sun DBRI"); - rp = &sdev->resource[0]; + rp = &op->resource[0]; sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d", card->shortname, rp->flags & 0xffL, (unsigned long long)rp->start, irq); - err = snd_dbri_create(card, sdev, irq, dev); + err = snd_dbri_create(card, op, irq, dev); if (err < 0) { snd_card_free(card); return err; @@ -2639,7 +2634,7 @@ static int __devinit dbri_probe(struct of_device *of_dev, /* /proc file handling */ snd_dbri_proc(card); - dev_set_drvdata(&of_dev->dev, card); + dev_set_drvdata(&op->dev, card); err = snd_card_register(card); if (err < 0) @@ -2647,7 +2642,7 @@ static int __devinit dbri_probe(struct of_device *of_dev, printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n", dev, dbri->regs, - dbri->irq, sdev->prom_name[9], dbri->mm.version); + dbri->irq, op->node->name[9], dbri->mm.version); dev++; return 0; @@ -2658,14 +2653,14 @@ _err: return err; } -static int __devexit dbri_remove(struct of_device *dev) +static int __devexit dbri_remove(struct of_device *op) { - struct snd_card *card = dev_get_drvdata(&dev->dev); + struct snd_card *card = dev_get_drvdata(&op->dev); snd_dbri_free(card->private_data); snd_card_free(card); - dev_set_drvdata(&dev->dev, NULL); + dev_set_drvdata(&op->dev, NULL); return 0; } @@ -2692,7 +2687,7 @@ static struct of_platform_driver dbri_sbus_driver = { /* Probe for the dbri chip and then attach the driver. */ static int __init dbri_init(void) { - return of_register_driver(&dbri_sbus_driver, &sbus_bus_type); + return of_register_driver(&dbri_sbus_driver, &of_bus_type); } static void __exit dbri_exit(void) -- cgit v1.2.3 From 12b1c03df10da61e222b86f0e1ece9cdb2a909d6 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 27 Aug 2008 00:31:36 -0700 Subject: cs4231: Use SNDRV_DMA_TYPE_DEV instead of SNDRV_DMA_TYPE_SBUS. SBUS layer now uses dma_*() interfaces, no need for special DMA code any longer. Signed-off-by: David S. Miller --- sound/sparc/cs4231.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 1c4797be72e..e2be131723e 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -1784,9 +1784,9 @@ static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont) static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm) { - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS, - snd_dma_sbus_data(chip->dev_u.sdev), - 64 * 1024, 128 * 1024); + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, + &chip->dev_u.sdev->ofdev.dev, + 64 * 1024, 128 * 1024); } /* -- cgit v1.2.3 From 759ee81be6d87c150ea2b300c221b4fec8b5f646 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 27 Aug 2008 00:33:26 -0700 Subject: alsa: Remove special SBUS dma support code. No longer used. Signed-off-by: David S. Miller --- sound/core/memalloc.c | 50 +------------------------------------------------- 1 file changed, 1 insertion(+), 49 deletions(-) (limited to 'sound') diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index ccaaac45faf..3733351a27f 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -33,9 +33,6 @@ #include #include #include -#ifdef CONFIG_SBUS -#include -#endif MODULE_AUTHOR("Takashi Iwai , Jaroslav Kysela "); @@ -180,41 +177,6 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr, } #endif /* CONFIG_HAS_DMA */ -#ifdef CONFIG_SBUS - -static void *snd_malloc_sbus_pages(struct device *dev, size_t size, - dma_addr_t *dma_addr) -{ - struct sbus_dev *sdev = (struct sbus_dev *)dev; - int pg; - void *res; - - snd_assert(size > 0, return NULL); - snd_assert(dma_addr != NULL, return NULL); - pg = get_order(size); - res = dma_alloc_coherent(&sdev->ofdev.dev, PAGE_SIZE * (1 << pg), - dma_addr, GFP_ATOMIC); - if (res != NULL) - inc_snd_pages(pg); - return res; -} - -static void snd_free_sbus_pages(struct device *dev, size_t size, - void *ptr, dma_addr_t dma_addr) -{ - struct sbus_dev *sdev = (struct sbus_dev *)dev; - int pg; - - if (ptr == NULL) - return; - pg = get_order(size); - dec_snd_pages(pg); - dma_free_coherent(&sdev->ofdev.dev, PAGE_SIZE * (1 << pg), - ptr, dma_addr); -} - -#endif /* CONFIG_SBUS */ - /* * * ALSA generic memory management @@ -249,11 +211,6 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size, dmab->area = snd_malloc_pages(size, (unsigned long)device); dmab->addr = 0; break; -#ifdef CONFIG_SBUS - case SNDRV_DMA_TYPE_SBUS: - dmab->area = snd_malloc_sbus_pages(device, size, &dmab->addr); - break; -#endif #ifdef CONFIG_HAS_DMA case SNDRV_DMA_TYPE_DEV: dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr); @@ -322,11 +279,6 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab) case SNDRV_DMA_TYPE_CONTINUOUS: snd_free_pages(dmab->area, dmab->bytes); break; -#ifdef CONFIG_SBUS - case SNDRV_DMA_TYPE_SBUS: - snd_free_sbus_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr); - break; -#endif #ifdef CONFIG_HAS_DMA case SNDRV_DMA_TYPE_DEV: snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr); @@ -433,7 +385,7 @@ static int snd_mem_proc_read(struct seq_file *seq, void *offset) long pages = snd_allocated_pages >> (PAGE_SHIFT-12); struct snd_mem_list *mem; int devno; - static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" }; + static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG" }; mutex_lock(&list_mutex); seq_printf(seq, "pages : %li bytes (%li pages per %likB)\n", -- cgit v1.2.3 From ae251031ad22a659b8261440b049d5981e57880c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 27 Aug 2008 18:24:01 -0700 Subject: cs4231: Convert SBUS side to OF driver. Signed-off-by: David S. Miller --- sound/sparc/cs4231.c | 78 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 28 deletions(-) (limited to 'sound') diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index e2be131723e..271b0420f8b 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -1,6 +1,6 @@ /* * Driver for CS4231 sound chips found on Sparcs. - * Copyright (C) 2002 David S. Miller + * Copyright (C) 2002, 2008 David S. Miller * * Based entirely upon drivers/sbus/audio/cs4231.c which is: * Copyright (C) 1996, 1997, 1998 Derrick J Brashear (shadow@andrew.cmu.edu) @@ -17,7 +17,8 @@ #include #include #include - +#include +#include #include #include @@ -29,7 +30,6 @@ #ifdef CONFIG_SBUS #define SBUS_SUPPORT -#include #endif #if defined(CONFIG_PCI) && defined(CONFIG_SPARC64) @@ -116,7 +116,7 @@ struct snd_cs4231 { union { #ifdef SBUS_SUPPORT - struct sbus_dev *sdev; + struct of_device *op; #endif #ifdef EBUS_SUPPORT struct pci_dev *pdev; @@ -1785,7 +1785,7 @@ static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont) static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm) { snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - &chip->dev_u.sdev->ofdev.dev, + &chip->dev_u.op->dev, 64 * 1024, 128 * 1024); } @@ -1795,11 +1795,13 @@ static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm) static int snd_cs4231_sbus_free(struct snd_cs4231 *chip) { + struct of_device *op = chip->dev_u.op; + if (chip->irq[0]) free_irq(chip->irq[0], chip); if (chip->port) - sbus_iounmap(chip->port, chip->regs_size); + of_iounmap(&op->resource[0], chip->port, chip->regs_size); return 0; } @@ -1816,7 +1818,7 @@ static struct snd_device_ops snd_cs4231_sbus_dev_ops = { }; static int __init snd_cs4231_sbus_create(struct snd_card *card, - struct sbus_dev *sdev, + struct of_device *op, int dev) { struct snd_cs4231 *chip = card->private_data; @@ -1827,13 +1829,13 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, spin_lock_init(&chip->p_dma.sbus_info.lock); mutex_init(&chip->mce_mutex); mutex_init(&chip->open_mutex); - chip->dev_u.sdev = sdev; - chip->regs_size = sdev->reg_addrs[0].reg_size; + chip->dev_u.op = op; + chip->regs_size = resource_size(&op->resource[0]); memcpy(&chip->image, &snd_cs4231_original_image, sizeof(snd_cs4231_original_image)); - chip->port = sbus_ioremap(&sdev->resource[0], 0, - chip->regs_size, "cs4231"); + chip->port = of_ioremap(&op->resource[0], 0, + chip->regs_size, "cs4231"); if (!chip->port) { snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev); return -EIO; @@ -1856,14 +1858,14 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, chip->c_dma.address = sbus_dma_addr; chip->c_dma.preallocate = sbus_dma_preallocate; - if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt, + if (request_irq(op->irqs[0], snd_cs4231_sbus_interrupt, IRQF_SHARED, "cs4231", chip)) { snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %d\n", - dev, sdev->irqs[0]); + dev, op->irqs[0]); snd_cs4231_sbus_free(chip); return -EBUSY; } - chip->irq[0] = sdev->irqs[0]; + chip->irq[0] = op->irqs[0]; if (snd_cs4231_probe(chip) < 0) { snd_cs4231_sbus_free(chip); @@ -1880,12 +1882,16 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, return 0; } -static int __init cs4231_sbus_attach(struct sbus_dev *sdev) +static int __devinit cs4231_probe(struct of_device *op, const struct of_device_id *match) { - struct resource *rp = &sdev->resource[0]; + struct resource *rp = &op->resource[0]; struct snd_card *card; int err; + if (strcmp(op->node->parent->name, "sbus") && + strcmp(op->node->parent->name, "sbi")) + return -ENODEV; + err = cs4231_attach_begin(&card); if (err) return err; @@ -1894,9 +1900,9 @@ static int __init cs4231_sbus_attach(struct sbus_dev *sdev) card->shortname, rp->flags & 0xffL, (unsigned long long)rp->start, - sdev->irqs[0]); + op->irqs[0]); - err = snd_cs4231_sbus_create(card, sdev, dev); + err = snd_cs4231_sbus_create(card, op, dev); if (err < 0) { snd_card_free(card); return err; @@ -2101,12 +2107,25 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) } #endif -static int __init cs4231_init(void) -{ #ifdef SBUS_SUPPORT - struct sbus_bus *sbus; - struct sbus_dev *sdev; +static struct of_device_id cs4231_match[] = { + { + .name = "SUNW,CS4231", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, cs4231_match); + +static struct of_platform_driver cs4231_driver = { + .name = "audio", + .match_table = cs4231_match, + .probe = cs4231_probe, +}; #endif + +static int __init cs4231_init(void) +{ #ifdef EBUS_SUPPORT struct linux_ebus *ebus; struct linux_ebus_device *edev; @@ -2116,11 +2135,10 @@ static int __init cs4231_init(void) found = 0; #ifdef SBUS_SUPPORT - for_all_sbusdev(sdev, sbus) { - if (!strcmp(sdev->prom_name, "SUNW,CS4231")) { - if (cs4231_sbus_attach(sdev) == 0) - found++; - } + { + int err = of_register_driver(&cs4231_driver, &of_bus_type); + if (err) + return err; } #endif #ifdef EBUS_SUPPORT @@ -2147,13 +2165,17 @@ static int __init cs4231_init(void) #endif - return (found > 0) ? 0 : -EIO; + return 0; } static void __exit cs4231_exit(void) { struct snd_cs4231 *p = cs4231_list; +#ifdef SBUS_SUPPORT + of_unregister_driver(&cs4231_driver); +#endif + while (p != NULL) { struct snd_cs4231 *next = p->next; -- cgit v1.2.3 From aae7fb87ec4d2df6cb551670b1765cf4e5795a3b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 29 Aug 2008 23:10:21 -0700 Subject: sparc: Move EBUS DMA interfaces into seperate header file. These have no dependencies on the EBUS probing layer, the clients setup the registers and all of those details. The EBUS DMA layer just programs and manages the DMA controller found in EBUS. Signed-off-by: David S. Miller --- sound/sparc/cs4231.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 271b0420f8b..e6dba4f7169 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -36,6 +36,7 @@ #define EBUS_SUPPORT #include #include +#include #endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ -- cgit v1.2.3 From afc88ad6b38797aeec4d635140099ace077df587 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 30 Aug 2008 00:13:55 -0700 Subject: cs4231: Convert to EBUS side to pure OF driver. Signed-off-by: David S. Miller --- sound/sparc/cs4231.c | 172 ++++++++++++++++----------------------------------- 1 file changed, 54 insertions(+), 118 deletions(-) (limited to 'sound') diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index e6dba4f7169..cdbfae96bd8 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -35,7 +35,6 @@ #if defined(CONFIG_PCI) && defined(CONFIG_SPARC64) #define EBUS_SUPPORT #include -#include #include #endif @@ -71,8 +70,6 @@ struct cs4231_dma_control { int (*request)(struct cs4231_dma_control *dma_cont, dma_addr_t bus_addr, size_t len); unsigned int (*address)(struct cs4231_dma_control *dma_cont); - void (*preallocate)(struct snd_cs4231 *chip, - struct snd_pcm *pcm); #ifdef EBUS_SUPPORT struct ebus_dma_info ebus_info; #endif @@ -115,21 +112,12 @@ struct snd_cs4231 { struct mutex mce_mutex; /* mutex for mce register */ struct mutex open_mutex; /* mutex for ALSA open/close */ - union { -#ifdef SBUS_SUPPORT - struct of_device *op; -#endif -#ifdef EBUS_SUPPORT - struct pci_dev *pdev; -#endif - } dev_u; + struct of_device *op; unsigned int irq[2]; unsigned int regs_size; struct snd_cs4231 *next; }; -static struct snd_cs4231 *cs4231_list; - /* Eventually we can use sound/isa/cs423x/cs4231_lib.c directly, but for * now.... -DaveM */ @@ -268,27 +256,19 @@ static unsigned char snd_cs4231_original_image[32] = static u8 __cs4231_readb(struct snd_cs4231 *cp, void __iomem *reg_addr) { -#ifdef EBUS_SUPPORT if (cp->flags & CS4231_FLAG_EBUS) return readb(reg_addr); else -#endif -#ifdef SBUS_SUPPORT return sbus_readb(reg_addr); -#endif } static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val, void __iomem *reg_addr) { -#ifdef EBUS_SUPPORT if (cp->flags & CS4231_FLAG_EBUS) return writeb(val, reg_addr); else -#endif -#ifdef SBUS_SUPPORT return sbus_writeb(val, reg_addr); -#endif } /* @@ -1259,7 +1239,9 @@ static int __init snd_cs4231_pcm(struct snd_card *card) pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; strcpy(pcm->name, "CS4231"); - chip->p_dma.preallocate(chip, pcm); + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, + &chip->op->dev, + 64 * 1024, 128 * 1024); chip->pcm = pcm; @@ -1627,8 +1609,7 @@ static int __init cs4231_attach_finish(struct snd_card *card) if (err < 0) goto out_err; - chip->next = cs4231_list; - cs4231_list = chip; + dev_set_drvdata(&chip->op->dev, chip); dev++; return 0; @@ -1783,20 +1764,13 @@ static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont) return sbus_readl(base->regs + base->dir + APCVA); } -static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm) -{ - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - &chip->dev_u.op->dev, - 64 * 1024, 128 * 1024); -} - /* * Init and exit routines */ static int snd_cs4231_sbus_free(struct snd_cs4231 *chip) { - struct of_device *op = chip->dev_u.op; + struct of_device *op = chip->op; if (chip->irq[0]) free_irq(chip->irq[0], chip); @@ -1830,7 +1804,7 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, spin_lock_init(&chip->p_dma.sbus_info.lock); mutex_init(&chip->mce_mutex); mutex_init(&chip->open_mutex); - chip->dev_u.op = op; + chip->op = op; chip->regs_size = resource_size(&op->resource[0]); memcpy(&chip->image, &snd_cs4231_original_image, sizeof(snd_cs4231_original_image)); @@ -1851,13 +1825,11 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, chip->p_dma.enable = sbus_dma_enable; chip->p_dma.request = sbus_dma_request; chip->p_dma.address = sbus_dma_addr; - chip->p_dma.preallocate = sbus_dma_preallocate; chip->c_dma.prepare = sbus_dma_prepare; chip->c_dma.enable = sbus_dma_enable; chip->c_dma.request = sbus_dma_request; chip->c_dma.address = sbus_dma_addr; - chip->c_dma.preallocate = sbus_dma_preallocate; if (request_irq(op->irqs[0], snd_cs4231_sbus_interrupt, IRQF_SHARED, "cs4231", chip)) { @@ -1883,16 +1855,12 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card, return 0; } -static int __devinit cs4231_probe(struct of_device *op, const struct of_device_id *match) +static int __devinit cs4231_sbus_probe(struct of_device *op, const struct of_device_id *match) { struct resource *rp = &op->resource[0]; struct snd_card *card; int err; - if (strcmp(op->node->parent->name, "sbus") && - strcmp(op->node->parent->name, "sbi")) - return -ENODEV; - err = cs4231_attach_begin(&card); if (err) return err; @@ -1956,30 +1924,25 @@ static unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont) return ebus_dma_addr(&dma_cont->ebus_info); } -static void _ebus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm) -{ - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(chip->dev_u.pdev), - 64*1024, 128*1024); -} - /* * Init and exit routines */ static int snd_cs4231_ebus_free(struct snd_cs4231 *chip) { + struct of_device *op = chip->op; + if (chip->c_dma.ebus_info.regs) { ebus_dma_unregister(&chip->c_dma.ebus_info); - iounmap(chip->c_dma.ebus_info.regs); + of_iounmap(&op->resource[2], chip->c_dma.ebus_info.regs, 0x10); } if (chip->p_dma.ebus_info.regs) { ebus_dma_unregister(&chip->p_dma.ebus_info); - iounmap(chip->p_dma.ebus_info.regs); + of_iounmap(&op->resource[1], chip->p_dma.ebus_info.regs, 0x10); } if (chip->port) - iounmap(chip->port); + of_iounmap(&op->resource[0], chip->port, 0x10); return 0; } @@ -1996,7 +1959,7 @@ static struct snd_device_ops snd_cs4231_ebus_dev_ops = { }; static int __init snd_cs4231_ebus_create(struct snd_card *card, - struct linux_ebus_device *edev, + struct of_device *op, int dev) { struct snd_cs4231 *chip = card->private_data; @@ -2008,35 +1971,35 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card, mutex_init(&chip->mce_mutex); mutex_init(&chip->open_mutex); chip->flags |= CS4231_FLAG_EBUS; - chip->dev_u.pdev = edev->bus->self; + chip->op = op; memcpy(&chip->image, &snd_cs4231_original_image, sizeof(snd_cs4231_original_image)); strcpy(chip->c_dma.ebus_info.name, "cs4231(capture)"); chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback; chip->c_dma.ebus_info.client_cookie = chip; - chip->c_dma.ebus_info.irq = edev->irqs[0]; + chip->c_dma.ebus_info.irq = op->irqs[0]; strcpy(chip->p_dma.ebus_info.name, "cs4231(play)"); chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback; chip->p_dma.ebus_info.client_cookie = chip; - chip->p_dma.ebus_info.irq = edev->irqs[1]; + chip->p_dma.ebus_info.irq = op->irqs[1]; chip->p_dma.prepare = _ebus_dma_prepare; chip->p_dma.enable = _ebus_dma_enable; chip->p_dma.request = _ebus_dma_request; chip->p_dma.address = _ebus_dma_addr; - chip->p_dma.preallocate = _ebus_dma_preallocate; chip->c_dma.prepare = _ebus_dma_prepare; chip->c_dma.enable = _ebus_dma_enable; chip->c_dma.request = _ebus_dma_request; chip->c_dma.address = _ebus_dma_addr; - chip->c_dma.preallocate = _ebus_dma_preallocate; - chip->port = ioremap(edev->resource[0].start, 0x10); - chip->p_dma.ebus_info.regs = ioremap(edev->resource[1].start, 0x10); - chip->c_dma.ebus_info.regs = ioremap(edev->resource[2].start, 0x10); + chip->port = of_ioremap(&op->resource[0], 0, 0x10, "cs4231"); + chip->p_dma.ebus_info.regs = + of_ioremap(&op->resource[1], 0, 0x10, "cs4231_pdma"); + chip->c_dma.ebus_info.regs = + of_ioremap(&op->resource[2], 0, 0x10, "cs4231_cdma"); if (!chip->port || !chip->p_dma.ebus_info.regs || !chip->c_dma.ebus_info.regs) { snd_cs4231_ebus_free(chip); @@ -2084,7 +2047,7 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card, return 0; } -static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) +static int __devinit cs4231_ebus_probe(struct of_device *op, const struct of_device_id *match) { struct snd_card *card; int err; @@ -2095,10 +2058,10 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) sprintf(card->longname, "%s at 0x%lx, irq %d", card->shortname, - edev->resource[0].start, - edev->irqs[0]); + op->resource[0].start, + op->irqs[0]); - err = snd_cs4231_ebus_create(card, edev, dev); + err = snd_cs4231_ebus_create(card, op, dev); if (err < 0) { snd_card_free(card); return err; @@ -2108,11 +2071,37 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) } #endif +static int __devinit cs4231_probe(struct of_device *op, const struct of_device_id *match) +{ +#ifdef EBUS_SUPPORT + if (!strcmp(op->node->parent->name, "ebus")) + return cs4231_ebus_probe(op, match); +#endif #ifdef SBUS_SUPPORT + if (!strcmp(op->node->parent->name, "sbus") || + !strcmp(op->node->parent->name, "sbi")) + return cs4231_sbus_probe(op, match); +#endif + return -ENODEV; +} + +static int __devexit cs4231_remove(struct of_device *op) +{ + struct snd_cs4231 *chip = dev_get_drvdata(&op->dev); + + snd_card_free(chip->card); + + return 0; +} + static struct of_device_id cs4231_match[] = { { .name = "SUNW,CS4231", }, + { + .name = "audio", + .compatible = "SUNW,CS4231", + }, {}, }; @@ -2122,70 +2111,17 @@ static struct of_platform_driver cs4231_driver = { .name = "audio", .match_table = cs4231_match, .probe = cs4231_probe, + .remove = __devexit_p(cs4231_remove), }; -#endif static int __init cs4231_init(void) { -#ifdef EBUS_SUPPORT - struct linux_ebus *ebus; - struct linux_ebus_device *edev; -#endif - int found; - - found = 0; - -#ifdef SBUS_SUPPORT - { - int err = of_register_driver(&cs4231_driver, &of_bus_type); - if (err) - return err; - } -#endif -#ifdef EBUS_SUPPORT - for_each_ebus(ebus) { - for_each_ebusdev(edev, ebus) { - int match = 0; - - if (!strcmp(edev->prom_node->name, "SUNW,CS4231")) { - match = 1; - } else if (!strcmp(edev->prom_node->name, "audio")) { - const char *compat; - - compat = of_get_property(edev->prom_node, - "compatible", NULL); - if (compat && !strcmp(compat, "SUNW,CS4231")) - match = 1; - } - - if (match && - cs4231_ebus_attach(edev) == 0) - found++; - } - } -#endif - - - return 0; + return of_register_driver(&cs4231_driver, &of_bus_type); } static void __exit cs4231_exit(void) { - struct snd_cs4231 *p = cs4231_list; - -#ifdef SBUS_SUPPORT of_unregister_driver(&cs4231_driver); -#endif - - while (p != NULL) { - struct snd_cs4231 *next = p->next; - - snd_card_free(p->card); - - p = next; - } - - cs4231_list = NULL; } module_init(cs4231_init); -- cgit v1.2.3 From fd098316ef533e8441576f020ead4beab93154ce Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 31 Aug 2008 01:23:17 -0700 Subject: sparc: Annotate of_device_id arrays with const or __initdata. As suggested by Stephen Rothwell. Signed-off-by: David S. Miller --- sound/sparc/amd7930.c | 2 +- sound/sparc/cs4231.c | 2 +- sound/sparc/dbri.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index 0f82c3f6cfd..5af5503edad 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c @@ -1070,7 +1070,7 @@ out_err: return err; } -static struct of_device_id amd7930_match[] = { +static const struct of_device_id amd7930_match[] = { { .name = "audio", }, diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index cdbfae96bd8..727438d276e 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -2094,7 +2094,7 @@ static int __devexit cs4231_remove(struct of_device *op) return 0; } -static struct of_device_id cs4231_match[] = { +static const struct of_device_id cs4231_match[] = { { .name = "SUNW,CS4231", }, diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 446f985b76f..2edb0ad3de7 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -2665,7 +2665,7 @@ static int __devexit dbri_remove(struct of_device *op) return 0; } -static struct of_device_id dbri_match[] = { +static const struct of_device_id dbri_match[] = { { .name = "SUNW,DBRIe", }, -- cgit v1.2.3 From 5c73a7d0411999e3cb3c6d64225450813738ae25 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 1 Sep 2008 15:25:20 -0700 Subject: hrtimer: convert sound/ to the new hrtimer apis In order to be able to do range hrtimers we need to use accessor functions to the "expire" member of the hrtimer struct. This patch converts sound/ to these accessors. Signed-off-by: Arjan van de Ven --- sound/drivers/pcsp/pcsp_lib.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c index e341f3f83b6..1f42e406311 100644 --- a/sound/drivers/pcsp/pcsp_lib.c +++ b/sound/drivers/pcsp/pcsp_lib.c @@ -34,7 +34,7 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) chip->thalf = 0; if (!atomic_read(&chip->timer_active)) return HRTIMER_NORESTART; - hrtimer_forward(&chip->timer, chip->timer.expires, + hrtimer_forward(&chip->timer, hrtimer_get_expires(&chip->timer), ktime_set(0, chip->ns_rem)); return HRTIMER_RESTART; } @@ -118,7 +118,8 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) chip->ns_rem = PCSP_PERIOD_NS(); ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem); chip->ns_rem -= ns; - hrtimer_forward(&chip->timer, chip->timer.expires, ktime_set(0, ns)); + hrtimer_forward(&chip->timer, hrtimer_get_expires(&chip->timer), + ktime_set(0, ns)); return HRTIMER_RESTART; exit_nr_unlock2: -- cgit v1.2.3 From 6168cda927ecdf3347537e0d01618ca2a2272007 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Fri, 5 Sep 2008 18:15:22 +0800 Subject: [ARM] pxa/corgi: use generic GPIO API for SCOOP GPIOs Original patch from Dmitry Baryshkov's inital scoop gpio conversion work at http://git.infradead.org/users/dbaryshkov/zaurus-2.6.git. Signed-off-by: Dmitry Baryshkov Signed-off-by: Eric Miao Signed-off-by: Russell King --- sound/soc/pxa/corgi.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) (limited to 'sound') diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 0a53f72077f..fa69faa886e 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -18,13 +18,13 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include @@ -54,8 +54,8 @@ static void corgi_ext_control(struct snd_soc_codec *codec) switch (corgi_jack_func) { case CORGI_HP: /* set = unmute headphone */ - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); + gpio_set_value(CORGI_GPIO_MUTE_L, 1); + gpio_set_value(CORGI_GPIO_MUTE_R, 1); snd_soc_dapm_disable_pin(codec, "Mic Jack"); snd_soc_dapm_disable_pin(codec, "Line Jack"); snd_soc_dapm_enable_pin(codec, "Headphone Jack"); @@ -63,24 +63,24 @@ static void corgi_ext_control(struct snd_soc_codec *codec) break; case CORGI_MIC: /* reset = mute headphone */ - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); + gpio_set_value(CORGI_GPIO_MUTE_L, 0); + gpio_set_value(CORGI_GPIO_MUTE_R, 0); snd_soc_dapm_enable_pin(codec, "Mic Jack"); snd_soc_dapm_disable_pin(codec, "Line Jack"); snd_soc_dapm_disable_pin(codec, "Headphone Jack"); snd_soc_dapm_disable_pin(codec, "Headset Jack"); break; case CORGI_LINE: - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); + gpio_set_value(CORGI_GPIO_MUTE_L, 0); + gpio_set_value(CORGI_GPIO_MUTE_R, 0); snd_soc_dapm_disable_pin(codec, "Mic Jack"); snd_soc_dapm_enable_pin(codec, "Line Jack"); snd_soc_dapm_disable_pin(codec, "Headphone Jack"); snd_soc_dapm_disable_pin(codec, "Headset Jack"); break; case CORGI_HEADSET: - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); + gpio_set_value(CORGI_GPIO_MUTE_L, 0); + gpio_set_value(CORGI_GPIO_MUTE_R, 1); snd_soc_dapm_enable_pin(codec, "Mic Jack"); snd_soc_dapm_disable_pin(codec, "Line Jack"); snd_soc_dapm_disable_pin(codec, "Headphone Jack"); @@ -114,8 +114,8 @@ static int corgi_shutdown(struct snd_pcm_substream *substream) struct snd_soc_codec *codec = rtd->socdev->codec; /* set = unmute headphone */ - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); + gpio_set_value(CORGI_GPIO_MUTE_L, 1); + gpio_set_value(CORGI_GPIO_MUTE_R, 1); return 0; } @@ -218,22 +218,14 @@ static int corgi_set_spk(struct snd_kcontrol *kcontrol, static int corgi_amp_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - if (SND_SOC_DAPM_EVENT_ON(event)) - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON); - else - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON); - + gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event)); return 0; } static int corgi_mic_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - if (SND_SOC_DAPM_EVENT_ON(event)) - set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS); - else - reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS); - + gpio_set_value(CORGI_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event)); return 0; } -- cgit v1.2.3 From fff147208b48680cb7b627a144113a6585828a0e Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Fri, 5 Sep 2008 22:15:23 +0800 Subject: [ARM] pxa/spitz: use generic GPIO API for SCOOP1/SCOOP2 GPIOs Original patch from Dmitry Baryshkov's inital scoop gpio conversion work at http://git.infradead.org/users/dbaryshkov/zaurus-2.6.git. Signed-off-by: Dmitry Baryshkov Signed-off-by: Eric Miao Signed-off-by: Russell King --- sound/soc/pxa/spitz.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) (limited to 'sound') diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 37cb768fc93..acfa712844e 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -19,13 +19,13 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include @@ -63,8 +63,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec) snd_soc_dapm_disable_pin(codec, "Mic Jack"); snd_soc_dapm_disable_pin(codec, "Line Jack"); snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); + gpio_set_value(SPITZ_GPIO_MUTE_L, 1); + gpio_set_value(SPITZ_GPIO_MUTE_R, 1); break; case SPITZ_MIC: /* enable mic jack and bias, mute hp */ @@ -72,8 +72,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec) snd_soc_dapm_disable_pin(codec, "Headset Jack"); snd_soc_dapm_disable_pin(codec, "Line Jack"); snd_soc_dapm_enable_pin(codec, "Mic Jack"); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); + gpio_set_value(SPITZ_GPIO_MUTE_L, 0); + gpio_set_value(SPITZ_GPIO_MUTE_R, 0); break; case SPITZ_LINE: /* enable line jack, disable mic bias and mute hp */ @@ -81,8 +81,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec) snd_soc_dapm_disable_pin(codec, "Headset Jack"); snd_soc_dapm_disable_pin(codec, "Mic Jack"); snd_soc_dapm_enable_pin(codec, "Line Jack"); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); + gpio_set_value(SPITZ_GPIO_MUTE_L, 0); + gpio_set_value(SPITZ_GPIO_MUTE_R, 0); break; case SPITZ_HEADSET: /* enable and unmute headset jack enable mic bias, mute L hp */ @@ -90,8 +90,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec) snd_soc_dapm_enable_pin(codec, "Mic Jack"); snd_soc_dapm_disable_pin(codec, "Line Jack"); snd_soc_dapm_enable_pin(codec, "Headset Jack"); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); + gpio_set_value(SPITZ_GPIO_MUTE_L, 0); + gpio_set_value(SPITZ_GPIO_MUTE_R, 1); break; case SPITZ_HP_OFF: @@ -100,8 +100,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec) snd_soc_dapm_disable_pin(codec, "Headset Jack"); snd_soc_dapm_disable_pin(codec, "Mic Jack"); snd_soc_dapm_disable_pin(codec, "Line Jack"); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); + gpio_set_value(SPITZ_GPIO_MUTE_L, 0); + gpio_set_value(SPITZ_GPIO_MUTE_R, 0); break; } snd_soc_dapm_sync(codec); @@ -215,14 +215,9 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol, static int spitz_mic_bias(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - if (machine_is_borzoi() || machine_is_spitz()) { - if (SND_SOC_DAPM_EVENT_ON(event)) - set_scoop_gpio(&spitzscoop2_device.dev, - SPITZ_SCP2_MIC_BIAS); - else - reset_scoop_gpio(&spitzscoop2_device.dev, - SPITZ_SCP2_MIC_BIAS); - } + if (machine_is_borzoi() || machine_is_spitz()) + gpio_set_value(SPITZ_GPIO_MIC_BIAS, + SND_SOC_DAPM_EVENT_ON(event)); if (machine_is_akita()) { if (SND_SOC_DAPM_EVENT_ON(event)) -- cgit v1.2.3 From f72de6638b8e55283739de174b57c0ae4203c446 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Sat, 6 Sep 2008 08:46:23 +0800 Subject: [ARM] pxa/akita: use pca953x instead of akita-ioexp Use generic pca953x which provides gpiolib interface instead of akita-specific akita-ioexp with non-standard interface to pins. Signed-off-by: Dmitry Baryshkov Cc: Richard Purdie Cc: Mark Brown Signed-off-by: Eric Miao Signed-off-by: Russell King --- sound/soc/pxa/spitz.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'sound') diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index acfa712844e..b89a3edd218 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "../codecs/wm8750.h" #include "pxa2xx-pcm.h" @@ -219,14 +218,10 @@ static int spitz_mic_bias(struct snd_soc_dapm_widget *w, gpio_set_value(SPITZ_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event)); - if (machine_is_akita()) { - if (SND_SOC_DAPM_EVENT_ON(event)) - akita_set_ioexp(&akitaioexp_device.dev, - AKITA_IOEXP_MIC_BIAS); - else - akita_reset_ioexp(&akitaioexp_device.dev, - AKITA_IOEXP_MIC_BIAS); - } + if (machine_is_akita()) + gpio_set_value(AKITA_GPIO_MIC_BIAS, + SND_SOC_DAPM_EVENT_ON(event)); + return 0; } -- cgit v1.2.3 From a3927471c65b5ca94da853a1a46ec5db4609c502 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 25 Sep 2008 13:30:07 +0100 Subject: [ARM] pxa: avoid needless pxa_gpio_mode() during resume The pin configurations are restored early on during resume. There's no need for drivers to re-affirm the gpio modes. Signed-off-by: Russell King --- sound/soc/pxa/pxa2xx-ac97.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'sound') diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index d94a495bd6b..7d7ce164836 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -293,14 +293,6 @@ static int pxa2xx_ac97_suspend(struct platform_device *pdev, static int pxa2xx_ac97_resume(struct platform_device *pdev, struct snd_soc_dai *dai) { - pxa_gpio_mode(GPIO31_SYNC_AC97_MD); - pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); - pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); - pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD); -#ifdef CONFIG_PXA27x - /* Use GPIO 113 as AC97 Reset on Bulverde */ - pxa_gpio_mode(113 | GPIO_ALT_FN_2_OUT); -#endif clk_enable(ac97_clk); return 0; } -- cgit v1.2.3 From 87f3dd77974cba1ba0798abd741ede50f56b3eb3 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 8 Sep 2008 15:26:43 +0800 Subject: [ARM] pxa: simplify DMA register definitions 1. DRCMRxx is no longer recommended, use DRCMR(xx) instead, and pass DRCMR index by "struct resource" if possible 2. DCSRxx, DDADRxx, DSADRxx, DTADRxx, DCMDxx is never used, use DCSR(), DDADR(), DSADR(), DTADR(), DCMD() instead Signed-off-by: Eric Miao Acked-by: Nicolas Pitre Signed-off-by: Russell King --- sound/arm/pxa2xx-ac97.c | 4 ++-- sound/soc/pxa/pxa2xx-ac97.c | 10 +++++----- sound/soc/pxa/pxa2xx-i2s.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'sound') diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 199cca3366d..714b3baa4be 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c @@ -215,7 +215,7 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = { static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = { .name = "AC97 PCM out", .dev_addr = __PREG(PCDR), - .drcmr = &DRCMRTXPCDR, + .drcmr = &DRCMR(12), .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_BURST32 | DCMD_WIDTH4, }; @@ -223,7 +223,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = { static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_in = { .name = "AC97 PCM in", .dev_addr = __PREG(PCDR), - .drcmr = &DRCMRRXPCDR, + .drcmr = &DRCMR(11), .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | DCMD_BURST32 | DCMD_WIDTH4, }; diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 7d7ce164836..ac8f227bab0 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -244,7 +244,7 @@ struct snd_ac97_bus_ops soc_ac97_ops = { static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = { .name = "AC97 PCM Stereo out", .dev_addr = __PREG(PCDR), - .drcmr = &DRCMRTXPCDR, + .drcmr = &DRCMR(12), .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_BURST32 | DCMD_WIDTH4, }; @@ -252,7 +252,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = { static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = { .name = "AC97 PCM Stereo in", .dev_addr = __PREG(PCDR), - .drcmr = &DRCMRRXPCDR, + .drcmr = &DRCMR(11), .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | DCMD_BURST32 | DCMD_WIDTH4, }; @@ -260,7 +260,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = { static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = { .name = "AC97 Aux PCM (Slot 5) Mono out", .dev_addr = __PREG(MODR), - .drcmr = &DRCMRTXMODR, + .drcmr = &DRCMR(10), .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_BURST16 | DCMD_WIDTH2, }; @@ -268,7 +268,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = { static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = { .name = "AC97 Aux PCM (Slot 5) Mono in", .dev_addr = __PREG(MODR), - .drcmr = &DRCMRRXMODR, + .drcmr = &DRCMR(9), .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | DCMD_BURST16 | DCMD_WIDTH2, }; @@ -276,7 +276,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = { static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = { .name = "AC97 Mic PCM (Slot 6) Mono in", .dev_addr = __PREG(MCDR), - .drcmr = &DRCMRRXMCDR, + .drcmr = &DRCMR(8), .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | DCMD_BURST16 | DCMD_WIDTH2, }; diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index c796b188277..2dbe612fddd 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -44,7 +44,7 @@ static struct clk *clk_i2s; static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = { .name = "I2S PCM Stereo out", .dev_addr = __PREG(SADR), - .drcmr = &DRCMRTXSADR, + .drcmr = &DRCMR(3), .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_BURST32 | DCMD_WIDTH4, }; @@ -52,7 +52,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = { static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = { .name = "I2S PCM Stereo in", .dev_addr = __PREG(SADR), - .drcmr = &DRCMRRXSADR, + .drcmr = &DRCMR(2), .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | DCMD_BURST32 | DCMD_WIDTH4, }; -- cgit v1.2.3 From 52358ba3a89012c54712c24074ceb4b1c669af52 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Mon, 8 Sep 2008 15:37:50 +0800 Subject: [ARM] pxa: move I2S register and bit definitions into pxa2xx-i2s.c Signed-off-by: Eric Miao Acked-by: Mark Brown Signed-off-by: Russell King --- sound/soc/pxa/pxa2xx-i2s.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'sound') diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 2dbe612fddd..ad4c31ddb3d 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -30,6 +30,46 @@ #include "pxa2xx-pcm.h" #include "pxa2xx-i2s.h" +/* + * I2S Controller Register and Bit Definitions + */ +#define SACR0 __REG(0x40400000) /* Global Control Register */ +#define SACR1 __REG(0x40400004) /* Serial Audio I 2 S/MSB-Justified Control Register */ +#define SASR0 __REG(0x4040000C) /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */ +#define SAIMR __REG(0x40400014) /* Serial Audio Interrupt Mask Register */ +#define SAICR __REG(0x40400018) /* Serial Audio Interrupt Clear Register */ +#define SADIV __REG(0x40400060) /* Audio Clock Divider Register. */ +#define SADR __REG(0x40400080) /* Serial Audio Data Register (TX and RX FIFO access Register). */ + +#define SACR0_RFTH(x) ((x) << 12) /* Rx FIFO Interrupt or DMA Trigger Threshold */ +#define SACR0_TFTH(x) ((x) << 8) /* Tx FIFO Interrupt or DMA Trigger Threshold */ +#define SACR0_STRF (1 << 5) /* FIFO Select for EFWR Special Function */ +#define SACR0_EFWR (1 << 4) /* Enable EFWR Function */ +#define SACR0_RST (1 << 3) /* FIFO, i2s Register Reset */ +#define SACR0_BCKD (1 << 2) /* Bit Clock Direction */ +#define SACR0_ENB (1 << 0) /* Enable I2S Link */ +#define SACR1_ENLBF (1 << 5) /* Enable Loopback */ +#define SACR1_DRPL (1 << 4) /* Disable Replaying Function */ +#define SACR1_DREC (1 << 3) /* Disable Recording Function */ +#define SACR1_AMSL (1 << 0) /* Specify Alternate Mode */ + +#define SASR0_I2SOFF (1 << 7) /* Controller Status */ +#define SASR0_ROR (1 << 6) /* Rx FIFO Overrun */ +#define SASR0_TUR (1 << 5) /* Tx FIFO Underrun */ +#define SASR0_RFS (1 << 4) /* Rx FIFO Service Request */ +#define SASR0_TFS (1 << 3) /* Tx FIFO Service Request */ +#define SASR0_BSY (1 << 2) /* I2S Busy */ +#define SASR0_RNE (1 << 1) /* Rx FIFO Not Empty */ +#define SASR0_TNF (1 << 0) /* Tx FIFO Not Empty */ + +#define SAICR_ROR (1 << 6) /* Clear Rx FIFO Overrun Interrupt */ +#define SAICR_TUR (1 << 5) /* Clear Tx FIFO Underrun Interrupt */ + +#define SAIMR_ROR (1 << 6) /* Enable Rx FIFO Overrun Condition Interrupt */ +#define SAIMR_TUR (1 << 5) /* Enable Tx FIFO Underrun Condition Interrupt */ +#define SAIMR_RFS (1 << 4) /* Enable Rx FIFO Service Interrupt */ +#define SAIMR_TFS (1 << 3) /* Enable Tx FIFO Service Interrupt */ + struct pxa_i2s_port { u32 sadiv; u32 sacr0; -- cgit v1.2.3 From 2f3d00250ae5b1d2727e2723da805290ec408503 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 23 Aug 2008 04:52:00 -0300 Subject: V4L/DVB (8777): tea575x-tuner: replace video_exclusive_open/release Move the video_exclusive_open/release functionality into the driver itself. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- sound/i2c/other/tea575x-tuner.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index 83e90057270..621d7fe3074 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c @@ -175,6 +175,23 @@ static void snd_tea575x_release(struct video_device *vfd) { } +static int snd_tea575x_exclusive_open(struct inode *inode, struct file *file) +{ + struct video_device *dev = video_devdata(file); + struct snd_tea575x *tea = video_get_drvdata(dev); + + return test_and_set_bit(0, &tea->in_use) ? -EBUSY : 0; +} + +static int snd_tea575x_exclusive_release(struct inode *inode, struct file *file) +{ + struct video_device *dev = video_devdata(file); + struct snd_tea575x *tea = video_get_drvdata(dev); + + clear_bit(0, &tea->in_use); + return 0; +} + /* * initialize all the tea575x chips */ @@ -193,9 +210,10 @@ void snd_tea575x_init(struct snd_tea575x *tea) tea->vd.release = snd_tea575x_release; video_set_drvdata(&tea->vd, tea); tea->vd.fops = &tea->fops; + tea->in_use = 0; tea->fops.owner = tea->card->module; - tea->fops.open = video_exclusive_open; - tea->fops.release = video_exclusive_release; + tea->fops.open = snd_tea575x_exclusive_open; + tea->fops.release = snd_tea575x_exclusive_release; tea->fops.ioctl = snd_tea575x_ioctl; if (video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->dev_nr - 1) < 0) { snd_printk(KERN_ERR "unable to register tea575x tuner\n"); -- cgit v1.2.3 From c170ecf434bceb0e188b14a6deb3bfa3ec9ef699 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 23 Aug 2008 08:32:09 -0300 Subject: V4L/DVB (8788): v4l: replace video_get_drvdata(video_devdata(filp)) with video_drvdata(filp) Use the new video_drvdata(filp) function where it is safe to do so. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- sound/i2c/other/tea575x-tuner.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index 621d7fe3074..c13a178383b 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c @@ -87,8 +87,7 @@ static void snd_tea575x_set_freq(struct snd_tea575x *tea) static int snd_tea575x_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long data) { - struct video_device *dev = video_devdata(file); - struct snd_tea575x *tea = video_get_drvdata(dev); + struct snd_tea575x *tea = video_drvdata(file); void __user *arg = (void __user *)data; switch(cmd) { @@ -177,16 +176,14 @@ static void snd_tea575x_release(struct video_device *vfd) static int snd_tea575x_exclusive_open(struct inode *inode, struct file *file) { - struct video_device *dev = video_devdata(file); - struct snd_tea575x *tea = video_get_drvdata(dev); + struct snd_tea575x *tea = video_drvdata(file); return test_and_set_bit(0, &tea->in_use) ? -EBUSY : 0; } static int snd_tea575x_exclusive_release(struct inode *inode, struct file *file) { - struct video_device *dev = video_devdata(file); - struct snd_tea575x *tea = video_get_drvdata(dev); + struct snd_tea575x *tea = video_drvdata(file); clear_bit(0, &tea->in_use); return 0; -- cgit v1.2.3 From ec4e86ba0662ed85f3b3a38fb220dc51d951da84 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Oct 2008 08:02:41 +0200 Subject: ALSA: hda - Fix PCM type of Nvidia HDMI devices Added the missing PCM type for Nvidia HDMI devices so that they point the right device number. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_nvhdmi.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index 1a65775d28e..2eed2c8b98d 100644 --- a/sound/pci/hda/patch_nvhdmi.c +++ b/sound/pci/hda/patch_nvhdmi.c @@ -116,6 +116,7 @@ static int nvhdmi_build_pcms(struct hda_codec *codec) codec->pcm_info = info; info->name = "NVIDIA HDMI"; + info->pcm_type = HDA_PCM_TYPE_HDMI; info->stream[SNDRV_PCM_STREAM_PLAYBACK] = nvhdmi_pcm_digital_playback; return 0; -- cgit v1.2.3 From cdbdd1676a5379f1d5cbd4d476f5e349f445befe Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 16 Oct 2008 11:00:06 +0100 Subject: ALSA: ASoC: Convert playpaq_wm8510 to bulk route registration API Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai --- sound/soc/at32/playpaq_wm8510.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'sound') diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/at32/playpaq_wm8510.c index 98a2d5826a8..b1966e4dfcd 100644 --- a/sound/soc/at32/playpaq_wm8510.c +++ b/sound/soc/at32/playpaq_wm8510.c @@ -304,7 +304,7 @@ static const struct snd_soc_dapm_widget playpaq_dapm_widgets[] = { -static const char *intercon[][3] = { +static const struct snd_soc_dapm_route intercon[] = { /* speaker connected to SPKOUT */ {"Ext Spk", NULL, "SPKOUTP"}, {"Ext Spk", NULL, "SPKOUTN"}, @@ -312,9 +312,6 @@ static const char *intercon[][3] = { {"Mic Bias", NULL, "Int Mic"}, {"MICN", NULL, "Mic Bias"}, {"MICP", NULL, "Mic Bias"}, - - /* Terminator */ - {NULL, NULL, NULL}, }; @@ -334,11 +331,8 @@ static int playpaq_wm8510_init(struct snd_soc_codec *codec) /* * Setup audio path interconnects */ - for (i = 0; intercon[i][0] != NULL; i++) { - snd_soc_dapm_connect_input(codec, - intercon[i][0], - intercon[i][1], intercon[i][2]); - } + snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + /* always connected pins */ -- cgit v1.2.3 From abe9ab8f62203ced11119fb96acc3b8dd107ebc4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 21 Jul 2008 20:03:34 -0700 Subject: device create: sound: convert device_create_drvdata to device_create Now that device_create() has been audited, rename things back to the original call to be sane. Cc: Jaroslav Kysela Signed-off-by: Greg Kroah-Hartman --- sound/core/init.c | 6 +++--- sound/core/sound.c | 5 ++--- sound/oss/soundcard.c | 15 +++++++-------- sound/sound_core.c | 5 ++--- 4 files changed, 14 insertions(+), 17 deletions(-) (limited to 'sound') diff --git a/sound/core/init.c b/sound/core/init.c index 8af467df924..ef2352c2e45 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -549,9 +549,9 @@ int snd_card_register(struct snd_card *card) return -EINVAL; #ifndef CONFIG_SYSFS_DEPRECATED if (!card->card_dev) { - card->card_dev = device_create_drvdata(sound_class, card->dev, - MKDEV(0, 0), NULL, - "card%i", card->number); + card->card_dev = device_create(sound_class, card->dev, + MKDEV(0, 0), NULL, + "card%i", card->number); if (IS_ERR(card->card_dev)) card->card_dev = NULL; } diff --git a/sound/core/sound.c b/sound/core/sound.c index c0685e2f0af..44a69bb8d4f 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -274,9 +274,8 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev, return minor; } snd_minors[minor] = preg; - preg->dev = device_create_drvdata(sound_class, device, - MKDEV(major, minor), - private_data, "%s", name); + preg->dev = device_create(sound_class, device, MKDEV(major, minor), + private_data, "%s", name); if (IS_ERR(preg->dev)) { snd_minors[minor] = NULL; mutex_unlock(&sound_mutex); diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c index 7d89c081a08..61aaedae6b7 100644 --- a/sound/oss/soundcard.c +++ b/sound/oss/soundcard.c @@ -560,19 +560,18 @@ static int __init oss_init(void) sound_dmap_flag = (dmabuf > 0 ? 1 : 0); for (i = 0; i < ARRAY_SIZE(dev_list); i++) { - device_create_drvdata(sound_class, NULL, - MKDEV(SOUND_MAJOR, dev_list[i].minor), - NULL, "%s", dev_list[i].name); + device_create(sound_class, NULL, + MKDEV(SOUND_MAJOR, dev_list[i].minor), NULL, + "%s", dev_list[i].name); if (!dev_list[i].num) continue; for (j = 1; j < *dev_list[i].num; j++) - device_create_drvdata(sound_class, NULL, - MKDEV(SOUND_MAJOR, - dev_list[i].minor + (j*0x10)), - NULL, - "%s%d", dev_list[i].name, j); + device_create(sound_class, NULL, + MKDEV(SOUND_MAJOR, + dev_list[i].minor + (j*0x10)), + NULL, "%s%d", dev_list[i].name, j); } if (sound_nblocks >= 1024) diff --git a/sound/sound_core.c b/sound/sound_core.c index 4ae07e236b3..faef87a9bc3 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c @@ -220,9 +220,8 @@ static int sound_insert_unit(struct sound_unit **list, const struct file_operati else sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP); - device_create_drvdata(sound_class, dev, - MKDEV(SOUND_MAJOR, s->unit_minor), - NULL, s->name+6); + device_create(sound_class, dev, MKDEV(SOUND_MAJOR, s->unit_minor), + NULL, s->name+6); return r; fail: -- cgit v1.2.3 From 7c2dfee84863628f9af109131edd4344ce567d16 Mon Sep 17 00:00:00 2001 From: Zhaolei Date: Fri, 17 Oct 2008 21:04:55 +0800 Subject: ALSA: Fix debugfs_create_dir's error checking method for sound/soc/ debugfs_create_dir() returns NULL if an error occurs, returns -ENODEV when debugfs is not enabled in the kernel. Signed-off-by: Zhao Lei Acked-by: Mark Brown Signed-off-by: Takashi Iwai --- sound/soc/soc-dapm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index efbd0b37810..7351db9606e 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -831,7 +831,7 @@ int snd_soc_dapm_sys_add(struct device *dev) return ret; asoc_debugfs = debugfs_create_dir("asoc", NULL); - if (!IS_ERR(asoc_debugfs)) + if (!IS_ERR(asoc_debugfs) && asoc_debugfs) debugfs_create_u32("dapm_pop_time", 0744, asoc_debugfs, &pop_time); else -- cgit v1.2.3 From 7639a4541f7e7abb1295ff8ab39cc2f5842239ae Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 20 Oct 2008 13:02:48 +0900 Subject: sh: Migrate common board headers to mach-common/. Signed-off-by: Paul Mundt --- sound/oss/sh_dac_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c index b493660deb3..e5d42399491 100644 --- a/sound/oss/sh_dac_audio.c +++ b/sound/oss/sh_dac_audio.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #define MODNAME "sh_dac_audio" -- cgit v1.2.3 From 1ee2a322b058f6399dc900603f9ebb392037ff77 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 20 Oct 2008 08:06:39 +0200 Subject: ALSA: ps3: Add support for SPDIF/HDMI passthru Add support for SPDIF/HDMI pass-through support of PS3 audio driver. Signed-off-by: Masakazu Mokuno Signed-off-by: Takashi Iwai --- sound/ppc/snd_ps3.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++---- sound/ppc/snd_ps3.h | 1 + 2 files changed, 91 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index 20d0e328288..8f9e3859c37 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c @@ -666,6 +666,7 @@ static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card) card->avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; card->avs.avs_audio_format = PS3AV_CMD_AUDIO_FORMAT_PCM; card->avs.avs_audio_source = PS3AV_CMD_AUDIO_SOURCE_SERIAL; + memcpy(card->avs.avs_cs_info, ps3av_mode_cs_info, 8); ret = snd_ps3_change_avsetting(card); @@ -685,6 +686,7 @@ static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream) { struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); struct snd_ps3_avsetting_info avs; + int ret; avs = card->avs; @@ -729,19 +731,92 @@ static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream) return 1; } - if ((card->avs.avs_audio_width != avs.avs_audio_width) || - (card->avs.avs_audio_rate != avs.avs_audio_rate)) { - card->avs = avs; - snd_ps3_change_avsetting(card); + memcpy(avs.avs_cs_info, ps3av_mode_cs_info, 8); + if (memcmp(&card->avs, &avs, sizeof(avs))) { pr_debug("%s: after freq=%d width=%d\n", __func__, card->avs.avs_audio_rate, card->avs.avs_audio_width); - return 0; + card->avs = avs; + snd_ps3_change_avsetting(card); + ret = 0; } else + ret = 1; + + /* check CS non-audio bit and mute accordingly */ + if (avs.avs_cs_info[0] & 0x02) + ps3av_audio_mute_analog(1); /* mute if non-audio */ + else + ps3av_audio_mute_analog(0); + + return ret; +} + +/* + * SPDIF status bits controls + */ +static int snd_ps3_spdif_mask_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; + uinfo->count = 1; + return 0; +} + +/* FIXME: ps3av_set_audio_mode() assumes only consumer mode */ +static int snd_ps3_spdif_cmask_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memset(ucontrol->value.iec958.status, 0xff, 8); + return 0; +} + +static int snd_ps3_spdif_pmask_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return 0; +} + +static int snd_ps3_spdif_default_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memcpy(ucontrol->value.iec958.status, ps3av_mode_cs_info, 8); + return 0; +} + +static int snd_ps3_spdif_default_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + if (memcmp(ps3av_mode_cs_info, ucontrol->value.iec958.status, 8)) { + memcpy(ps3av_mode_cs_info, ucontrol->value.iec958.status, 8); return 1; + } + return 0; } +static struct snd_kcontrol_new spdif_ctls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), + .info = snd_ps3_spdif_mask_info, + .get = snd_ps3_spdif_cmask_get, + }, + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), + .info = snd_ps3_spdif_mask_info, + .get = snd_ps3_spdif_pmask_get, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), + .info = snd_ps3_spdif_mask_info, + .get = snd_ps3_spdif_default_get, + .put = snd_ps3_spdif_default_put, + }, +}; static int snd_ps3_map_mmio(void) @@ -842,7 +917,7 @@ static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start) static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev) { - int ret; + int i, ret; u64 lpar_addr, lpar_size; BUG_ON(!firmware_has_feature(FW_FEATURE_PS3_LV1)); @@ -903,6 +978,15 @@ static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev) strcpy(the_card.card->driver, "PS3"); strcpy(the_card.card->shortname, "PS3"); strcpy(the_card.card->longname, "PS3 sound"); + + /* create control elements */ + for (i = 0; i < ARRAY_SIZE(spdif_ctls); i++) { + ret = snd_ctl_add(the_card.card, + snd_ctl_new1(&spdif_ctls[i], &the_card)); + if (ret < 0) + goto clean_card; + } + /* create PCM devices instance */ /* NOTE:this driver works assuming pcm:substream = 1:1 */ ret = snd_pcm_new(the_card.card, diff --git a/sound/ppc/snd_ps3.h b/sound/ppc/snd_ps3.h index 4b7e6fbbe50..326fb29e82d 100644 --- a/sound/ppc/snd_ps3.h +++ b/sound/ppc/snd_ps3.h @@ -51,6 +51,7 @@ struct snd_ps3_avsetting_info { uint32_t avs_audio_width; uint32_t avs_audio_format; /* fixed */ uint32_t avs_audio_source; /* fixed */ + unsigned char avs_cs_info[8]; }; /* * PS3 audio 'card' instance -- cgit v1.2.3 From ba9d0fd0f0af3eb7ec463847b409dd88f8e5c031 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 20 Oct 2008 15:29:59 +0300 Subject: ALSA: ASoC: OMAP: Fix DSP DAI format in McBSP DAI driver Fix word clock length which must equal to one bit clock cycle in DSP mode. Surprisingly McBSP is able synchronize into wrong length when it's slave but e.g. TLV320AIC33 codec in slave configuration is outputting some amount of noise if word clock length is longer than one bit clock cycle. Fix also bit clock and frame sync polarities in DSP mode since they are opposite from I2S. Signed-off-by: Jarkko Nikula Cc: Arun KS Signed-off-by: Takashi Iwai --- sound/soc/omap/omap-mcbsp.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 0a063a98a66..853b33ae343 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -43,6 +43,7 @@ struct omap_mcbsp_data { unsigned int bus_id; struct omap_mcbsp_reg_cfg regs; + unsigned int fmt; /* * Flags indicating is the bus already activated and configured by * another substream @@ -200,6 +201,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; + int wlen; unsigned long port; if (cpu_class_is_omap1()) { @@ -244,19 +246,29 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: /* Set word lengths */ + wlen = 16; regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_16); regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_16); regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_16); regs->xcr1 |= XWDLEN1(OMAP_MCBSP_WORD_16); - /* Set FS period and length in terms of bit clock periods */ - regs->srgr2 |= FPER(16 * 2 - 1); - regs->srgr1 |= FWID(16 - 1); break; default: /* Unsupported PCM format */ return -EINVAL; } + /* Set FS period and length in terms of bit clock periods */ + switch (mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + regs->srgr2 |= FPER(wlen * 2 - 1); + regs->srgr1 |= FWID(wlen - 1); + break; + case SND_SOC_DAIFMT_DSP_A: + regs->srgr2 |= FPER(wlen * 2 - 1); + regs->srgr1 |= FWID(0); + break; + } + omap_mcbsp_config(bus_id, &mcbsp_data->regs); mcbsp_data->configured = 1; @@ -272,10 +284,12 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, { struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; + unsigned int temp_fmt = fmt; if (mcbsp_data->configured) return 0; + mcbsp_data->fmt = fmt; memset(regs, 0, sizeof(*regs)); /* Generic McBSP register settings */ regs->spcr2 |= XINTM(3) | FREE; @@ -293,6 +307,8 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, /* 0-bit data delay */ regs->rcr2 |= RDATDLY(0); regs->xcr2 |= XDATDLY(0); + /* Invert bit clock and FS polarity configuration for DSP_A */ + temp_fmt ^= SND_SOC_DAIFMT_IB_IF; break; default: /* Unsupported data format */ @@ -316,7 +332,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, } /* Set bit clock (CLKX/CLKR) and FS polarities */ - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + switch (temp_fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: /* * Normal BCLK + FS. -- cgit v1.2.3 From 2f5ad54ea6e2e38156bfb889964deee991f3087a Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sun, 28 Sep 2008 16:20:09 -0700 Subject: pci: use pci_ioremap_bar() in sound/ Use the newly introduced pci_ioremap_bar() function in sound/. pci_ioremap_bar() just takes a pci device and a bar number, with the goal of making it really hard to get wrong, while also having a central place to stick sanity checks. Signed-off-by: Arjan van de Ven Signed-off-by: Takashi Iwai --- sound/pci/ad1889.c | 2 +- sound/pci/atiixp.c | 2 +- sound/pci/atiixp_modem.c | 2 +- sound/pci/au88x0/au88x0.c | 3 +-- sound/pci/bt87x.c | 3 +-- sound/pci/cs4281.c | 4 ++-- sound/pci/cs5530.c | 2 +- sound/pci/hda/hda_intel.c | 2 +- sound/pci/mixart/mixart.c | 3 +-- 9 files changed, 10 insertions(+), 13 deletions(-) (limited to 'sound') diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c index 92f3a976ef2..a7f38e63303 100644 --- a/sound/pci/ad1889.c +++ b/sound/pci/ad1889.c @@ -932,7 +932,7 @@ snd_ad1889_create(struct snd_card *card, goto free_and_ret; chip->bar = pci_resource_start(pci, 0); - chip->iobase = ioremap_nocache(chip->bar, pci_resource_len(pci, 0)); + chip->iobase = pci_ioremap_bar(pci, 0); if (chip->iobase == NULL) { printk(KERN_ERR PFX "unable to reserve region.\n"); err = -EBUSY; diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 085a52b8c80..226fe8237d3 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -1609,7 +1609,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card, return err; } chip->addr = pci_resource_start(pci, 0); - chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci, 0)); + chip->remap_addr = pci_ioremap_bar(pci, 0); if (chip->remap_addr == NULL) { snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); snd_atiixp_free(chip); diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index 2f106306c7f..0e6e5cc1c50 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c @@ -1252,7 +1252,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card, return err; } chip->addr = pci_resource_start(pci, 0); - chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci, 0)); + chip->remap_addr = pci_ioremap_bar(pci, 0); if (chip->remap_addr == NULL) { snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); snd_atiixp_free(chip); diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c index 68368e49007..a36d4d1fd41 100644 --- a/sound/pci/au88x0/au88x0.c +++ b/sound/pci/au88x0/au88x0.c @@ -180,8 +180,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip) if ((err = pci_request_regions(pci, CARD_NAME_SHORT)) != 0) goto regions_out; - chip->mmio = ioremap_nocache(pci_resource_start(pci, 0), - pci_resource_len(pci, 0)); + chip->mmio = pci_ioremap_bar(pci, 0); if (!chip->mmio) { printk(KERN_ERR "MMIO area remap failed.\n"); err = -ENOMEM; diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 3aa8d973540..1aa1c040254 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -749,8 +749,7 @@ static int __devinit snd_bt87x_create(struct snd_card *card, pci_disable_device(pci); return err; } - chip->mmio = ioremap_nocache(pci_resource_start(pci, 0), - pci_resource_len(pci, 0)); + chip->mmio = pci_ioremap_bar(pci, 0); if (!chip->mmio) { snd_printk(KERN_ERR "cannot remap io memory\n"); err = -ENOMEM; diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index ef9308f7c45..192e7842e18 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -1382,8 +1382,8 @@ static int __devinit snd_cs4281_create(struct snd_card *card, chip->ba0_addr = pci_resource_start(pci, 0); chip->ba1_addr = pci_resource_start(pci, 1); - chip->ba0 = ioremap_nocache(chip->ba0_addr, pci_resource_len(pci, 0)); - chip->ba1 = ioremap_nocache(chip->ba1_addr, pci_resource_len(pci, 1)); + chip->ba0 = pci_ioremap_bar(pci, 0); + chip->ba1 = pci_ioremap_bar(pci, 1); if (!chip->ba0 || !chip->ba1) { snd_cs4281_free(chip); return -ENOMEM; diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c index 7ff8b68e997..4d9378d8120 100644 --- a/sound/pci/cs5530.c +++ b/sound/pci/cs5530.c @@ -132,7 +132,7 @@ static int __devinit snd_cs5530_create(struct snd_card *card, } chip->pci_base = pci_resource_start(pci, 0); - mem = ioremap_nocache(chip->pci_base, pci_resource_len(pci, 0)); + mem = pci_ioremap_bar(pci, 0); if (mem == NULL) { kfree(chip); pci_disable_device(pci); diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 9f316c1b279..f080f8ce0ec 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2158,7 +2158,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, } chip->addr = pci_resource_start(pci, 0); - chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci,0)); + chip->remap_addr = pci_ioremap_bar(pci, 0); if (chip->remap_addr == NULL) { snd_printk(KERN_ERR SFX "ioremap error\n"); err = -ENXIO; diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 2d0dce649a6..ae7601f353a 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -1314,8 +1314,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci, } for (i = 0; i < 2; i++) { mgr->mem[i].phys = pci_resource_start(pci, i); - mgr->mem[i].virt = ioremap_nocache(mgr->mem[i].phys, - pci_resource_len(pci, i)); + mgr->mem[i].virt = pci_ioremap_bar(pci, i); if (!mgr->mem[i].virt) { printk(KERN_ERR "unable to remap resource 0x%lx\n", mgr->mem[i].phys); -- cgit v1.2.3 From aeb5d727062a0238a2f96c9c380fbd2be4640c6f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 2 Sep 2008 15:28:45 -0400 Subject: [PATCH] introduce fmode_t, do annotations Signed-off-by: Al Viro --- sound/core/oss/pcm_oss.c | 2 +- sound/oss/au1550_ac97.c | 2 +- sound/oss/dmasound/dmasound.h | 4 ++-- sound/oss/dmasound/dmasound_atari.c | 4 ++-- sound/oss/dmasound/dmasound_core.c | 10 +++++----- sound/oss/msnd.h | 2 +- sound/oss/sound_config.h | 20 ++++++-------------- sound/oss/swarm_cs4297a.c | 2 +- sound/oss/vwsnd.c | 2 +- 9 files changed, 20 insertions(+), 28 deletions(-) (limited to 'sound') diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 1af62b8b86c..e17836680f4 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -2283,7 +2283,7 @@ static int snd_pcm_oss_open_file(struct file *file, int idx, err; struct snd_pcm_oss_file *pcm_oss_file; struct snd_pcm_substream *substream; - unsigned int f_mode = file->f_mode; + fmode_t f_mode = file->f_mode; if (rpcm_oss_file) *rpcm_oss_file = NULL; diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c index 23018a7c063..81e1f443d09 100644 --- a/sound/oss/au1550_ac97.c +++ b/sound/oss/au1550_ac97.c @@ -93,7 +93,7 @@ static struct au1550_state { spinlock_t lock; struct mutex open_mutex; struct mutex sem; - mode_t open_mode; + fmode_t open_mode; wait_queue_head_t open_wait; struct dmabuf { diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h index d978b009656..1cb13fe56ec 100644 --- a/sound/oss/dmasound/dmasound.h +++ b/sound/oss/dmasound/dmasound.h @@ -129,7 +129,7 @@ typedef struct { int (*mixer_ioctl)(u_int, u_long); /* optional */ int (*write_sq_setup)(void); /* optional */ int (*read_sq_setup)(void); /* optional */ - int (*sq_open)(mode_t); /* optional */ + int (*sq_open)(fmode_t); /* optional */ int (*state_info)(char *, size_t); /* optional */ void (*abort_read)(void); /* optional */ int min_dsp_speed; @@ -235,7 +235,7 @@ struct sound_queue { */ int active; wait_queue_head_t action_queue, open_queue, sync_queue; - int open_mode; + fmode_t open_mode; int busy, syncing, xruns, died; }; diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c index 285239d64b8..4d45bd63718 100644 --- a/sound/oss/dmasound/dmasound_atari.c +++ b/sound/oss/dmasound/dmasound_atari.c @@ -143,7 +143,7 @@ static int AtaMixerIoctl(u_int cmd, u_long arg); static int TTMixerIoctl(u_int cmd, u_long arg); static int FalconMixerIoctl(u_int cmd, u_long arg); static int AtaWriteSqSetup(void); -static int AtaSqOpen(mode_t mode); +static int AtaSqOpen(fmode_t mode); static int TTStateInfo(char *buffer, size_t space); static int FalconStateInfo(char *buffer, size_t space); @@ -1461,7 +1461,7 @@ static int AtaWriteSqSetup(void) return 0 ; } -static int AtaSqOpen(mode_t mode) +static int AtaSqOpen(fmode_t mode) { write_sq_ignore_int = 1; return 0 ; diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index 95fc5c68175..b8239f3168f 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -212,7 +212,7 @@ static int irq_installed; #endif /* MODULE */ /* control over who can modify resources shared between play/record */ -static mode_t shared_resource_owner; +static fmode_t shared_resource_owner; static int shared_resources_initialised; /* @@ -668,7 +668,7 @@ static inline void sq_init_waitqueue(struct sound_queue *sq) #if 0 /* blocking open() */ static inline void sq_wake_up(struct sound_queue *sq, struct file *file, - mode_t mode) + fmode_t mode) { if (file->f_mode & mode) { sq->busy = 0; /* CHECK: IS THIS OK??? */ @@ -677,7 +677,7 @@ static inline void sq_wake_up(struct sound_queue *sq, struct file *file, } #endif -static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode, +static int sq_open2(struct sound_queue *sq, struct file *file, fmode_t mode, int numbufs, int bufsize) { int rc = 0; @@ -891,10 +891,10 @@ static int sq_release(struct inode *inode, struct file *file) is the owner - if we have problems. */ -static int shared_resources_are_mine(mode_t md) +static int shared_resources_are_mine(fmode_t md) { if (shared_resource_owner) - return (shared_resource_owner & md ) ; + return (shared_resource_owner & md) != 0; else { shared_resource_owner = md ; return 1 ; diff --git a/sound/oss/msnd.h b/sound/oss/msnd.h index 61b3955481c..c8be47ec2b7 100644 --- a/sound/oss/msnd.h +++ b/sound/oss/msnd.h @@ -211,7 +211,7 @@ typedef struct multisound_dev { /* State variables */ enum { msndClassic, msndPinnacle } type; - mode_t mode; + fmode_t mode; unsigned long flags; #define F_RESETTING 0 #define F_HAVEDIGITAL 1 diff --git a/sound/oss/sound_config.h b/sound/oss/sound_config.h index 1a00a321061..55271fbe7f4 100644 --- a/sound/oss/sound_config.h +++ b/sound/oss/sound_config.h @@ -110,24 +110,16 @@ struct channel_info { #define OPEN_WRITE PCM_ENABLE_OUTPUT #define OPEN_READWRITE (OPEN_READ|OPEN_WRITE) -#if OPEN_READ == FMODE_READ && OPEN_WRITE == FMODE_WRITE - -static inline int translate_mode(struct file *file) -{ - return file->f_mode; -} - -#else - static inline int translate_mode(struct file *file) { - return ((file->f_mode & FMODE_READ) ? OPEN_READ : 0) | - ((file->f_mode & FMODE_WRITE) ? OPEN_WRITE : 0); + if (OPEN_READ == (__force int)FMODE_READ && + OPEN_WRITE == (__force int)FMODE_WRITE) + return (__force int)(file->f_mode & (FMODE_READ | FMODE_WRITE)); + else + return ((file->f_mode & FMODE_READ) ? OPEN_READ : 0) | + ((file->f_mode & FMODE_WRITE) ? OPEN_WRITE : 0); } -#endif - - #include "sound_calls.h" #include "dev_table.h" diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c index 044453a4ee5..41562ecde5b 100644 --- a/sound/oss/swarm_cs4297a.c +++ b/sound/oss/swarm_cs4297a.c @@ -295,7 +295,7 @@ struct cs4297a_state { struct mutex open_mutex; struct mutex open_sem_adc; struct mutex open_sem_dac; - mode_t open_mode; + fmode_t open_mode; wait_queue_head_t open_wait; wait_queue_head_t open_wait_adc; wait_queue_head_t open_wait_dac; diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c index dcbb3f739e6..78b8acc7c3b 100644 --- a/sound/oss/vwsnd.c +++ b/sound/oss/vwsnd.c @@ -1509,7 +1509,7 @@ typedef struct vwsnd_dev { struct mutex open_mutex; struct mutex io_mutex; struct mutex mix_mutex; - mode_t open_mode; + fmode_t open_mode; wait_queue_head_t open_wait; lithium_t lith; -- cgit v1.2.3 From 863b45180ef541a1990e4986d30fb7a93022a733 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 21 Oct 2008 17:01:47 +0200 Subject: ALSA: hda - Fix conflicting volume controls on ALC260 ALC260 auto-parsing mode may create multiple controls for the same volume widget (0x08 and 0x09) depending on the pin. For example, Front and Headphone volumes may control the same volume, just the latter one wins. This patch adds a proper check of the existing of the volume control and avoid the doulbed creation of the same volume controls. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e72707cb60a..ef4955c73c8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4996,7 +4996,7 @@ static struct hda_verb alc260_test_init_verbs[] = { */ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, - const char *pfx) + const char *pfx, int *vol_bits) { hda_nid_t nid_vol; unsigned long vol_val, sw_val; @@ -5018,10 +5018,14 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, } else return 0; /* N/A */ - snprintf(name, sizeof(name), "%s Playback Volume", pfx); - err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); - if (err < 0) - return err; + if (!(*vol_bits & (1 << nid_vol))) { + /* first control for the volume widget */ + snprintf(name, sizeof(name), "%s Playback Volume", pfx); + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); + if (err < 0) + return err; + *vol_bits |= (1 << nid_vol); + } snprintf(name, sizeof(name), "%s Playback Switch", pfx); err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); if (err < 0) @@ -5035,6 +5039,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, { hda_nid_t nid; int err; + int vols = 0; spec->multiout.num_dacs = 1; spec->multiout.dac_nids = spec->private_dac_nids; @@ -5042,21 +5047,22 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, nid = cfg->line_out_pins[0]; if (nid) { - err = alc260_add_playback_controls(spec, nid, "Front"); + err = alc260_add_playback_controls(spec, nid, "Front", &vols); if (err < 0) return err; } nid = cfg->speaker_pins[0]; if (nid) { - err = alc260_add_playback_controls(spec, nid, "Speaker"); + err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); if (err < 0) return err; } nid = cfg->hp_pins[0]; if (nid) { - err = alc260_add_playback_controls(spec, nid, "Headphone"); + err = alc260_add_playback_controls(spec, nid, "Headphone", + &vols); if (err < 0) return err; } -- cgit v1.2.3 From da74ae3e32374755e0fbdfed4074cf839a82f615 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Tue, 21 Oct 2008 20:28:04 -0700 Subject: ALSA: hda - correct bracketing in spdif test in patch_sigmatel.c Noticed by sparse: sound/pci/hda/patch_sigmatel.c:1285:43: warning: dubious: !x & y Signed-off-by: Harvey Harrison Acked-by: Matthew Ranostay Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index a2ac7205d45..788fdc6f326 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1282,7 +1282,7 @@ static int stac92xx_build_controls(struct hda_codec *codec) return err; spec->multiout.share_spdif = 1; } - if (spec->dig_in_nid && (!spec->gpio_dir & 0x01)) { + if (spec->dig_in_nid && !(spec->gpio_dir & 0x01)) { err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); if (err < 0) return err; -- cgit v1.2.3 From da6320becf31c40b60d4b1dc6b339c9a766b671c Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Wed, 22 Oct 2008 15:00:29 +0300 Subject: ALSA: ASoC: OMAP: Continue fixing DSP DAI format in McBSP DAI driver Fix "ASoC: OMAP: Fix DSP DAI format in McBSP DAI driver" was not correct due misunderstanding of DSP_A format and similar error in TLV320AIC33 codec which was used to test the original fix. This patch corrects now DSP_A format in OMAP McBSP DAI driver and is verified with TLV320AIC23 codec that's implementing DSP_A correctly. Signed-off-by: Jarkko Nikula Cc: Arun KS Signed-off-by: Takashi Iwai --- sound/soc/omap/omap-mcbsp.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'sound') diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 853b33ae343..8485a8a9d0f 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -265,7 +265,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, break; case SND_SOC_DAIFMT_DSP_A: regs->srgr2 |= FPER(wlen * 2 - 1); - regs->srgr1 |= FWID(0); + regs->srgr1 |= FWID(wlen * 2 - 2); break; } @@ -284,7 +284,6 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, { struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; - unsigned int temp_fmt = fmt; if (mcbsp_data->configured) return 0; @@ -307,8 +306,6 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, /* 0-bit data delay */ regs->rcr2 |= RDATDLY(0); regs->xcr2 |= XDATDLY(0); - /* Invert bit clock and FS polarity configuration for DSP_A */ - temp_fmt ^= SND_SOC_DAIFMT_IB_IF; break; default: /* Unsupported data format */ @@ -332,7 +329,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, } /* Set bit clock (CLKX/CLKR) and FS polarities */ - switch (temp_fmt & SND_SOC_DAIFMT_INV_MASK) { + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: /* * Normal BCLK + FS. -- cgit v1.2.3 From 4b7d283150b35db6e5e10f72606f603ff424c92a Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Thu, 23 Oct 2008 14:27:03 +0300 Subject: ALSA: ASoC: tlv320aic3x: Fix DSP DAI format and signal polarities matching - Codec doesn't support to configure bit clock and frame sync polarities - Codec doesn't support DSP_A format but DSP_B with inverted bit clock polarity - Match also other formats with their signal polarities Signed-off-by: Jarkko Nikula Acked-by: Mark Brown Signed-off-by: Takashi Iwai --- sound/soc/codecs/tlv320aic3x.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 05336ed7e49..cff276ee261 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -863,17 +863,21 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai, return -EINVAL; } - /* interface format */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: + /* + * match both interface format and signal polarities since they + * are fixed + */ + switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK | + SND_SOC_DAIFMT_INV_MASK)) { + case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF): break; - case SND_SOC_DAIFMT_DSP_A: + case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF): iface_breg |= (0x01 << 6); break; - case SND_SOC_DAIFMT_RIGHT_J: + case (SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_NB_NF): iface_breg |= (0x02 << 6); break; - case SND_SOC_DAIFMT_LEFT_J: + case (SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF): iface_breg |= (0x03 << 6); break; default: -- cgit v1.2.3 From e044c39ae258678d6ebb09fccb2a0fdf7ec51847 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 27 Oct 2008 16:56:24 +0100 Subject: ALSA: hda - Restore default pin configs for realtek codecs Some machines have broken BIOS resume that doesn't restore the default pin configuration properly, which results in a wrong detection of HP pin. This causes a silent speaker output due to missing HP detection. Related bug: Novell bug#406101 https://bugzilla.novell.com/show_bug.cgi?id=406101 This patch fixes the issue by saving/restoring the default pin configs by the driver itself. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 77 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index ef4955c73c8..4eceab9bd10 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -307,6 +307,13 @@ struct alc_spec { /* for PLL fix */ hda_nid_t pll_nid; unsigned int pll_coef_idx, pll_coef_bit; + +#ifdef SND_HDA_NEEDS_RESUME +#define ALC_MAX_PINS 16 + unsigned int num_pins; + hda_nid_t pin_nids[ALC_MAX_PINS]; + unsigned int pin_cfgs[ALC_MAX_PINS]; +#endif }; /* @@ -2778,6 +2785,64 @@ static void alc_free(struct hda_codec *codec) codec->spec = NULL; /* to be sure */ } +#ifdef SND_HDA_NEEDS_RESUME +static void store_pin_configs(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + hda_nid_t nid, end_nid; + + end_nid = codec->start_nid + codec->num_nodes; + for (nid = codec->start_nid; nid < end_nid; nid++) { + unsigned int wid_caps = get_wcaps(codec, nid); + unsigned int wid_type = + (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + if (wid_type != AC_WID_PIN) + continue; + if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids)) + break; + spec->pin_nids[spec->num_pins] = nid; + spec->pin_cfgs[spec->num_pins] = + snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, 0); + spec->num_pins++; + } +} + +static void resume_pin_configs(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int i; + + for (i = 0; i < spec->num_pins; i++) { + hda_nid_t pin_nid = spec->pin_nids[i]; + unsigned int pin_config = spec->pin_cfgs[i]; + snd_hda_codec_write(codec, pin_nid, 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, + pin_config & 0x000000ff); + snd_hda_codec_write(codec, pin_nid, 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, + (pin_config & 0x0000ff00) >> 8); + snd_hda_codec_write(codec, pin_nid, 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, + (pin_config & 0x00ff0000) >> 16); + snd_hda_codec_write(codec, pin_nid, 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, + pin_config >> 24); + } +} + +static int alc_resume(struct hda_codec *codec) +{ + resume_pin_configs(codec); + codec->patch_ops.init(codec); + snd_hda_codec_resume_amp(codec); + snd_hda_codec_resume_cache(codec); + return 0; +} +#else +#define store_pin_configs(codec) +#endif + /* */ static struct hda_codec_ops alc_patch_ops = { @@ -2786,6 +2851,9 @@ static struct hda_codec_ops alc_patch_ops = { .init = alc_init, .free = alc_free, .unsol_event = alc_unsol_event, +#ifdef SND_HDA_NEEDS_RESUME + .resume = alc_resume, +#endif #ifdef CONFIG_SND_HDA_POWER_SAVE .check_power_status = alc_check_power_status, #endif @@ -3832,6 +3900,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec) spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux; + store_pin_configs(codec); return 1; } @@ -5250,6 +5319,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec) } spec->num_mixers++; + store_pin_configs(codec); return 1; } @@ -10313,6 +10383,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; + store_pin_configs(codec); return 1; } @@ -11447,6 +11518,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; + store_pin_configs(codec); return 1; } @@ -12230,6 +12302,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) spec->mixers[spec->num_mixers] = alc269_capture_mixer; spec->num_mixers++; + store_pin_configs(codec); return 1; } @@ -13316,6 +13389,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec) spec->mixers[spec->num_mixers] = alc861_capture_mixer; spec->num_mixers++; + store_pin_configs(codec); return 1; } @@ -14427,6 +14501,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; + store_pin_configs(codec); return 1; } @@ -16258,6 +16333,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec) spec->mixers[spec->num_mixers] = alc662_capture_mixer; spec->num_mixers++; + + store_pin_configs(codec); return 1; } -- cgit v1.2.3 From c3e5203bed1999df716e3c7119f6749523eb952f Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Mon, 27 Oct 2008 17:09:25 +0800 Subject: ALSA: ASoC: Blackfin: update SPORT0 port selector (v2) - Setting the TFS pin selector for SPORT 0 based on whether the selected port id F or G. If the port is F then no conflict should exist for the TFS. When Port G is selected and EMAC then there is a conflict between the PHY interrupt line and TFS. Current settings prevent the conflict by ignoring the TFS pin when Port G is selected. This allows both ssm2602 using Port G and EMAC concurrently. - some code cleanup Signed-off-by: Cliff Cai Signed-off-by: Bryan Wu Acked-by: Mark Brown Signed-off-by: Takashi Iwai --- sound/soc/blackfin/bf5xx-i2s.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'sound') diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c index 827587f0818..e020c160ee4 100644 --- a/sound/soc/blackfin/bf5xx-i2s.c +++ b/sound/soc/blackfin/bf5xx-i2s.c @@ -70,12 +70,24 @@ static struct sport_param sport_params[2] = { } }; -static u16 sport_req[][7] = { - { P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, - P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0}, - { P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, - P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0}, -}; +/* + * Setting the TFS pin selector for SPORT 0 based on whether the selected + * port id F or G. If the port is F then no conflict should exist for the + * TFS. When Port G is selected and EMAC then there is a conflict between + * the PHY interrupt line and TFS. Current settings prevent the conflict + * by ignoring the TFS pin when Port G is selected. This allows both + * ssm2602 using Port G and EMAC concurrently. + */ +#ifdef CONFIG_BF527_SPORT0_PORTF +#define LOCAL_SPORT0_TFS (P_SPORT0_TFS) +#else +#define LOCAL_SPORT0_TFS (0) +#endif + +static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS, + P_SPORT0_DRPRI, P_SPORT0_RSCLK, LOCAL_SPORT0_TFS, 0}, + {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, P_SPORT1_DRPRI, + P_SPORT1_RSCLK, P_SPORT1_TFS, 0} }; static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) @@ -98,23 +110,21 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, ret = -EINVAL; break; default: + printk(KERN_ERR "%s: Unknown DAI format type\n", __func__); ret = -EINVAL; break; } switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - ret = -EINVAL; - break; - case SND_SOC_DAIFMT_CBM_CFS: - ret = -EINVAL; - break; case SND_SOC_DAIFMT_CBM_CFM: break; + case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBM_CFS: case SND_SOC_DAIFMT_CBS_CFM: ret = -EINVAL; break; default: + printk(KERN_ERR "%s: Unknown DAI master type\n", __func__); ret = -EINVAL; break; } -- cgit v1.2.3 From 5695ff44160e62d9193c0201706853bcfe2a077f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 28 Oct 2008 15:39:26 +0100 Subject: ALSA: hda - Add another HP model for AD1884A Added a quirk entry for another HP mobile device with AD1884A codec. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_analog.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 2b00c4afdf9..d3fd432cb3e 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -3860,6 +3860,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = { static struct snd_pci_quirk ad1884a_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), + SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD), {} }; -- cgit v1.2.3 From 8199de3b29d7f22f3163fcf03f7a61644c93c2ea Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 28 Oct 2008 14:50:13 +0000 Subject: ALSA: hda: Add HDA vendor ID for Wolfson Microelectronics Add Wolfson Microelectronics to the HDA vendor ID table. Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 6447754ae56..ba1ab737b55 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -64,6 +64,7 @@ static struct hda_vendor_id hda_vendor_ids[] = { { 0x14f1, "Conexant" }, { 0x17e8, "Chrontel" }, { 0x1854, "LG" }, + { 0x1aec, "Wolfson Microelectronics" }, { 0x434d, "C-Media" }, { 0x8384, "SigmaTel" }, {} /* terminator */ -- cgit v1.2.3 From c1e99bd9d6a0c82f4fa9078ed1f570e57b2f3944 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 29 Oct 2008 08:03:42 +0100 Subject: ALSA: hda - Fix SPDIF mute on IDT/STAC codecs The SPDIF mute switch code seems broken. It doesn't set unmute bits properly. Also it contains the duplicated lines (merge error?) to be cleaned up. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 788fdc6f326..df9b0bc7f87 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -566,10 +566,8 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol, nid = codec->slave_dig_outs[smux_idx - 1]; if (spec->cur_smux[smux_idx] == smux->num_items - 1) val = AMP_OUT_MUTE; - if (smux_idx == 0) - nid = spec->multiout.dig_out_nid; else - nid = codec->slave_dig_outs[smux_idx - 1]; + val = AMP_OUT_UNMUTE; /* un/mute SPDIF out */ snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, val); -- cgit v1.2.3 From 0cbf00980f0fc4cc064a15ab3dfce19b5fae9130 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 29 Oct 2008 16:18:25 +0100 Subject: ALSA: hda - Add reboot notifier The current snd-hda-intel driver seems blocking the power-off on some devices like eeepc. Although this is likely a BIOS problem, we can add a workaround by disabling IRQ lines before power-off operation. This patch adds the reboot notifier to achieve it. The detailed problem description is found in bug#11889: http://bugme.linux-foundation.org/show_bug.cgi?id=11889 Tested-by: Luiz Fernando N. Capitulino Cc: stable@kernel.org Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 9f316c1b279..c04ac38e2b2 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include "hda_codec.h" @@ -397,6 +398,9 @@ struct azx { /* for pending irqs */ struct work_struct irq_pending_work; + + /* reboot notifier (for mysterious hangup problem at power-down) */ + struct notifier_block reboot_notifier; }; /* driver types */ @@ -1978,6 +1982,28 @@ static int azx_resume(struct pci_dev *pci) #endif /* CONFIG_PM */ +/* + * reboot notifier for hang-up problem at power-down + */ +static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf) +{ + struct azx *chip = container_of(nb, struct azx, reboot_notifier); + azx_stop_chip(chip); + return NOTIFY_OK; +} + +static void azx_notifier_register(struct azx *chip) +{ + chip->reboot_notifier.notifier_call = azx_halt; + register_reboot_notifier(&chip->reboot_notifier); +} + +static void azx_notifier_unregister(struct azx *chip) +{ + if (chip->reboot_notifier.notifier_call) + unregister_reboot_notifier(&chip->reboot_notifier); +} + /* * destructor */ @@ -1985,6 +2011,8 @@ static int azx_free(struct azx *chip) { int i; + azx_notifier_unregister(chip); + if (chip->initialized) { azx_clear_irq_pending(chip); for (i = 0; i < chip->num_streams; i++) @@ -2348,6 +2376,7 @@ static int __devinit azx_probe(struct pci_dev *pci, pci_set_drvdata(pci, card); chip->running = 1; power_down_all_codecs(chip); + azx_notifier_register(chip); dev++; return err; -- cgit v1.2.3 From be376649344ba2c3d00021f8bbf64392aa01ad55 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 29 Oct 2008 15:34:39 -0700 Subject: dbri: check dma_alloc_coherent errors Needs to check for dma_alloc_coherent() allocation failure. Signed-off-by: FUJITA Tomonori Signed-off-by: David S. Miller --- sound/sparc/dbri.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound') diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index c257ad8bdfb..23ed6f04a71 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c @@ -2534,6 +2534,8 @@ static int __devinit snd_dbri_create(struct snd_card *card, dbri->dma = dma_alloc_coherent(&op->dev, sizeof(struct dbri_dma), &dbri->dma_dvma, GFP_ATOMIC); + if (!dbri->dma) + return -ENOMEM; memset((void *)dbri->dma, 0, sizeof(struct dbri_dma)); dprintk(D_GEN, "DMA Cmd Block 0x%p (0x%08x)\n", -- cgit v1.2.3 From 762b8df748d83c14070afbf0c6f8c0f4a91a13bf Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 30 Oct 2008 12:37:08 +0000 Subject: ALSA: ASoC: Fix mono controls after conversion to support full int masks When ASoC was converted to support full int width masks SOC_SINGLE_VALUE() omitted the assignment of rshift, causing the control operatins to report some mono controls as stereo. This happened to work some of the time due to a confusion between shift and min in snd_soc_info_volsw(). Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai --- sound/soc/soc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 462e635dfc7..a3adbf06b1e 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1462,7 +1462,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; int max = mc->max; - unsigned int shift = mc->min; + unsigned int shift = mc->shift; unsigned int rshift = mc->rshift; if (max == 1) -- cgit v1.2.3 From f06c8fd73e3658a659d5e5b56c44bd80fe244268 Mon Sep 17 00:00:00 2001 From: Jon Smirl Date: Thu, 30 Oct 2008 12:37:09 +0000 Subject: ALSA: ASoC: Fix some minor errors in mpc5200 psc i2s driver Fix missing unsigned for irqsave flags in psc i2s driver Make attribute visiblity static Collect all sysfs errors before checking status [Word wrapped DEVICE_ATTR() lines for 80 columns -- broonie] Signed-off-by: Jon Smirl Acked-by: Grant Likely Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai --- sound/soc/fsl/mpc5200_psc_i2s.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c index 86923299bc1..94a02eaa482 100644 --- a/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/sound/soc/fsl/mpc5200_psc_i2s.c @@ -277,7 +277,7 @@ static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd) struct mpc52xx_psc __iomem *regs = psc_i2s->psc_regs; u16 imr; u8 psc_cmd; - long flags; + unsigned long flags; if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) s = &psc_i2s->capture; @@ -699,9 +699,11 @@ static ssize_t psc_i2s_stat_store(struct device *dev, return count; } -DEVICE_ATTR(status, 0644, psc_i2s_status_show, NULL); -DEVICE_ATTR(playback_underrun, 0644, psc_i2s_stat_show, psc_i2s_stat_store); -DEVICE_ATTR(capture_overrun, 0644, psc_i2s_stat_show, psc_i2s_stat_store); +static DEVICE_ATTR(status, 0644, psc_i2s_status_show, NULL); +static DEVICE_ATTR(playback_underrun, 0644, psc_i2s_stat_show, + psc_i2s_stat_store); +static DEVICE_ATTR(capture_overrun, 0644, psc_i2s_stat_show, + psc_i2s_stat_store); /* --------------------------------------------------------------------- * OF platform bus binding code: @@ -819,8 +821,8 @@ static int __devinit psc_i2s_of_probe(struct of_device *op, /* Register the SYSFS files */ rc = device_create_file(psc_i2s->dev, &dev_attr_status); - rc = device_create_file(psc_i2s->dev, &dev_attr_capture_overrun); - rc = device_create_file(psc_i2s->dev, &dev_attr_playback_underrun); + rc |= device_create_file(psc_i2s->dev, &dev_attr_capture_overrun); + rc |= device_create_file(psc_i2s->dev, &dev_attr_playback_underrun); if (rc) dev_info(psc_i2s->dev, "error creating sysfs files\n"); -- cgit v1.2.3 From 13d622b33dfbd99205a7add5751ba47445e480a6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 30 Oct 2008 12:37:10 +0000 Subject: ALSA: ASoC: Fix WM9713 ALC Decay Time name The control had an extra space at the end of the name. Signed-off-by: Mark Brown Signed-off-by: Takashi Iwai --- sound/soc/codecs/wm9713.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index aba402b3c99..945b32ed988 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -140,7 +140,7 @@ SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0), SOC_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0), SOC_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0), -SOC_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV, 4, 15, 0), +SOC_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0), SOC_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0), SOC_ENUM("ALC Function", wm9713_enum[6]), SOC_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0), -- cgit v1.2.3 From 4605b718e8b8f0dd3d811ddf90f630fd0835b7bf Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 31 Oct 2008 14:18:24 +0100 Subject: ALSA: hda - Disable broken mic auto-muting in Realtek codes The recent addition of automatic mic-muting is broken in some cases. The code assumes that the pin nids <= 0x18, but the digital pins can be less than 0x18. Also, it assumes the front-mic being the internal mic, but it depends on the hardware implementation actually. Instead of complex case-fixes, better to disable the code as now. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4eceab9bd10..a80d57cbc35 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -829,6 +829,7 @@ static void alc_sku_automute(struct hda_codec *codec) spec->jack_present ? 0 : PIN_OUT); } +#if 0 /* it's broken in some acses -- temporarily disabled */ static void alc_mic_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -849,6 +850,9 @@ static void alc_mic_automute(struct hda_codec *codec) snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic, HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); } +#else +#define alc_mic_automute(codec) /* NOP */ +#endif /* disabled */ /* unsolicited event for HP jack sensing */ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) @@ -1058,12 +1062,14 @@ do_sku: AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT); +#if 0 /* it's broken in some acses -- temporarily disabled */ if (spec->autocfg.input_pins[AUTO_PIN_MIC] && spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]) snd_hda_codec_write(codec, spec->autocfg.input_pins[AUTO_PIN_MIC], 0, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT); +#endif /* disabled */ spec->unsol_event = alc_sku_unsol_event; } -- cgit v1.2.3 From ee956e090e114ede6542c76a7465ed6ce118ad52 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 31 Oct 2008 17:16:31 +0100 Subject: ALSA: hda - Add digital-mic for ALC269 auto-probe mode The digital mic wasn't detected properly for ALC269 auto-probing mode because of its widget number. Fixed now. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a80d57cbc35..d327a371595 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -12244,8 +12244,26 @@ static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec, return 0; } -#define alc269_auto_create_analog_input_ctls \ - alc880_auto_create_analog_input_ctls +static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) +{ + int err; + + err = alc880_auto_create_analog_input_ctls(spec, cfg); + if (err < 0) + return err; + /* digital-mic input pin is excluded in alc880_auto_create..() + * because it's under 0x18 + */ + if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 || + cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { + struct hda_input_mux *imux = &spec->private_imux; + imux->items[imux->num_items].label = "Int Mic"; + imux->items[imux->num_items].index = 0x05; + imux->num_items++; + } + return 0; +} #ifdef CONFIG_SND_HDA_POWER_SAVE #define alc269_loopbacks alc880_loopbacks -- cgit v1.2.3 From 233e70f4228e78eb2f80dc6650f65d3ae3dbf17c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 31 Oct 2008 23:28:30 +0000 Subject: saner FASYNC handling on file close As it is, all instances of ->release() for files that have ->fasync() need to remember to evict file from fasync lists; forgetting that creates a hole and we actually have a bunch that *does* forget. So let's keep our lives simple - let __fput() check FASYNC in file->f_flags and call ->fasync() there if it's been set. And lose that crap in ->release() instances - leaving it there is still valid, but we don't have to bother anymore. Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- sound/core/control.c | 1 - sound/core/init.c | 5 ++++- sound/core/pcm_native.c | 1 - sound/core/timer.c | 1 - 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/core/control.c b/sound/core/control.c index b0bf4269104..636b3b52ef8 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -113,7 +113,6 @@ static int snd_ctl_release(struct inode *inode, struct file *file) unsigned int idx; ctl = file->private_data; - fasync_helper(-1, file, 0, &ctl->fasync); file->private_data = NULL; card = ctl->card; write_lock_irqsave(&card->ctl_files_rwlock, flags); diff --git a/sound/core/init.c b/sound/core/init.c index ef2352c2e45..b47ff8b44be 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -264,8 +264,11 @@ static int snd_disconnect_release(struct inode *inode, struct file *file) } spin_unlock(&shutdown_lock); - if (likely(df)) + if (likely(df)) { + if ((file->f_flags & FASYNC) && df->disconnected_f_op->fasync) + df->disconnected_f_op->fasync(-1, file, 0); return df->disconnected_f_op->release(inode, file); + } panic("%s(%p, %p) failed!", __func__, inode, file); } diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index aef18682c03..a789efc9df3 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -2169,7 +2169,6 @@ static int snd_pcm_release(struct inode *inode, struct file *file) if (snd_BUG_ON(!substream)) return -ENXIO; pcm = substream->pcm; - fasync_helper(-1, file, 0, &substream->runtime->fasync); mutex_lock(&pcm->open_mutex); snd_pcm_release_substream(substream); kfree(pcm_file); diff --git a/sound/core/timer.c b/sound/core/timer.c index e582face89d..c584408c9f1 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -1263,7 +1263,6 @@ static int snd_timer_user_release(struct inode *inode, struct file *file) if (file->private_data) { tu = file->private_data; file->private_data = NULL; - fasync_helper(-1, file, 0, &tu->fasync); if (tu->timeri) snd_timer_close(tu->timeri); kfree(tu->queue); -- cgit v1.2.3 From 4b30fbde910dd40b831528e916cb8a91823f618f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 1 Nov 2008 18:19:49 +0000 Subject: oss: fix O_NONBLOCK in dmasound_core We broke O_NONBLOCK handling in OSS dmasound_core in 2.3.11-pre3 - the original code copied f_flags to open_mode and then checked for O_NONBLOCK in there, but that got changed to copying f_mode and O_NONBLOCK has not reached that field in any kernel version. Since we do not care for any other bits, the fix is obvious... Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- sound/oss/dmasound/dmasound.h | 2 +- sound/oss/dmasound/dmasound_core.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h index 1cb13fe56ec..1308d8d3418 100644 --- a/sound/oss/dmasound/dmasound.h +++ b/sound/oss/dmasound/dmasound.h @@ -235,7 +235,7 @@ struct sound_queue { */ int active; wait_queue_head_t action_queue, open_queue, sync_queue; - fmode_t open_mode; + int non_blocking; int busy, syncing, xruns, died; }; diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index b8239f3168f..793b7f47843 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -603,7 +603,7 @@ static ssize_t sq_write(struct file *file, const char __user *src, size_t uLeft, while (uLeft) { while (write_sq.count >= write_sq.max_active) { sq_play(); - if (write_sq.open_mode & O_NONBLOCK) + if (write_sq.non_blocking) return uWritten > 0 ? uWritten : -EAGAIN; SLEEP(write_sq.action_queue); if (signal_pending(current)) @@ -718,7 +718,7 @@ static int sq_open2(struct sound_queue *sq, struct file *file, fmode_t mode, return rc; } - sq->open_mode = file->f_mode; + sq->non_blocking = file->f_flags & O_NONBLOCK; } return rc; } -- cgit v1.2.3 From 69e50282b726bab75c8050c4836dc89b7eb7bf1a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 3 Nov 2008 10:07:43 +0100 Subject: ALSA: hda - Add a quirk for another Acer Aspire (1025:0090) Added a quirk for another Acer Aspier laptop (1025:0090) with ALC883 codec. Reported in Novell bnc#426935: https://bugzilla.novell.com/show_bug.cgi?id=426935 Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d327a371595..a4666c96a44 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8414,6 +8414,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), + SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), -- cgit v1.2.3 From 6b3ab21ef1ac15db4b053ce0ba8eae0ef9361c8a Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Mon, 3 Nov 2008 08:12:43 -0500 Subject: ALSA: hda: make a STAC_DELL_EQ option Add support for explicitly enabling the EQ distortion hack for systems without software biquad support. Signed-off-by: Matthew Ranostay Cc: stable@kernel.org Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index df9b0bc7f87..e6085915d86 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -69,6 +69,7 @@ enum { enum { STAC_92HD73XX_REF, STAC_DELL_M6, + STAC_DELL_EQ, STAC_92HD73XX_MODELS }; @@ -773,9 +774,7 @@ static struct hda_verb dell_eq_core_init[] = { }; static struct hda_verb dell_m6_core_init[] = { - /* set master volume to max value without distortion - * and direct control */ - { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, + { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, /* setup audio connections */ { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, @@ -1600,11 +1599,13 @@ static unsigned int dell_m6_pin_configs[13] = { static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, [STAC_DELL_M6] = dell_m6_pin_configs, + [STAC_DELL_EQ] = dell_m6_pin_configs, }; static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { [STAC_92HD73XX_REF] = "ref", [STAC_DELL_M6] = "dell-m6", + [STAC_DELL_EQ] = "dell-eq", }; static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { @@ -4131,12 +4132,17 @@ again: sizeof(stac92hd73xx_dmux)); switch (spec->board_config) { - case STAC_DELL_M6: + case STAC_DELL_EQ: spec->init = dell_eq_core_init; + /* fallthru */ + case STAC_DELL_M6: spec->num_smuxes = 0; spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER]; spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP]; spec->num_amps = 1; + + if (!spec->init) + spec->init = dell_m6_core_init; switch (codec->subsystem_id) { case 0x1028025e: /* Analog Mics */ case 0x1028025f: @@ -4146,8 +4152,6 @@ again: break; case 0x10280271: /* Digital Mics */ case 0x10280272: - spec->init = dell_m6_core_init; - /* fall-through */ case 0x10280254: case 0x10280255: stac92xx_set_config_reg(codec, 0x13, 0x90A60160); -- cgit v1.2.3 From c4dc5071859bf666a5a9d6565f16c51a261a88b7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 4 Nov 2008 13:30:57 +0100 Subject: ALSA: hda - Limit the number of GPIOs show in proc Limit the number of GPIOs shown in proc. Otherwise it gets too long unnecessarily, and hard to analyze. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_proc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 743d77922bc..c39af986bff 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -483,6 +483,8 @@ static void print_gpio(struct snd_info_buffer *buffer, (gpio & AC_GPIO_UNSOLICITED) ? 1 : 0, (gpio & AC_GPIO_WAKE) ? 1 : 0); max = gpio & AC_GPIO_IO_COUNT; + if (!max || max > 8) + return; enable = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_GPIO_MASK, 0); direction = snd_hda_codec_read(codec, nid, 0, -- cgit v1.2.3 From 959973b92d3ba235edfa5dcb5df1be1e5d1deba2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 5 Nov 2008 11:30:56 +0100 Subject: ALSA: hda - Add a quirk for MEDION MD96630 Use model=lenovo-ms7195-dig for MEDION MD96630 laptop (17c0:4085) with ALC888 codec. Reference: Novell bnc#412548 https://bugzilla.novell.com/show_bug.cgi?id=412528 Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a4666c96a44..a378c014512 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -8469,6 +8469,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), + SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), -- cgit v1.2.3 From 65b92e5cbc8acd14ea83190b4d016f765dce6075 Mon Sep 17 00:00:00 2001 From: Michel Marti Date: Sat, 8 Nov 2008 11:33:32 +0100 Subject: ALSA: hda - Add another HP model (6730s) for AD1884A Added model=laptop for another HP machine (103c:3614) with AD1884A codec. Signed-off-by: Michel Marti Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_analog.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index d3fd432cb3e..400df85a445 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -3861,6 +3861,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = { static struct snd_pci_quirk ad1884a_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), + SND_PCI_QUIRK(0x103c, 0x3614, "HP 6730s", AD1884A_LAPTOP), SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD), {} }; -- cgit v1.2.3 From 00c9ddd1d4cc73aa0077f379279d716cb0ab0ba5 Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Sun, 9 Nov 2008 12:50:52 +0100 Subject: ALSA: HDSP: check for io box before uploading firmware currently the hdsp driver tries to upload the firmware, even if the io box is not connected. this patch adds a check for the io box before trying to upload the firmware. thus instead of messages complaining about the fifo status and firmware loading failure, the driver gives a message that no multiface or digiface is connected. [A minor coding-style fix by tiwai] Signed-off-by: Tim Blechmann Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdsp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index d723543bead..d680114b3e4 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -5045,6 +5045,10 @@ static int __devinit snd_hdsp_create(struct snd_card *card, /* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */ ssleep(2); + err = hdsp_check_for_iobox(hdsp); + if (err < 0) + return err; + if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { #ifdef HDSP_FW_LOADER if ((err = hdsp_request_fw_loader(hdsp)) < 0) @@ -5057,7 +5061,7 @@ static int __devinit snd_hdsp_create(struct snd_card *card, /* init is complete, we return */ return 0; #endif - /* no iobox connected, we defer initialization */ + /* we defer initialization */ snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n"); if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) return err; -- cgit v1.2.3 From 3ae7e2e22900b90bbe1d19454405950893c110be Mon Sep 17 00:00:00 2001 From: Tim Blechmann Date: Sat, 8 Nov 2008 14:42:18 +0100 Subject: ALSA: hdsp: check for iobox and upload firmware during ioctl currently, the error message when trying to run hdspmixer or hdspconf if the breakout box is not connected is somehow misleading, since it asks the user to upload the firmware. this patch adds a test, whether the breakout box is connected and tries to upload the firmware in the case, that it is not present, e.g. because of power failures of the breakout box. [Minor coding-style fixes by tiwai] Signed-off-by: Tim Blechmann Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdsp.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'sound') diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index d680114b3e4..736246f98ac 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -4548,11 +4548,20 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne { struct hdsp *hdsp = (struct hdsp *)hw->private_data; void __user *argp = (void __user *)arg; + int err; switch (cmd) { case SNDRV_HDSP_IOCTL_GET_PEAK_RMS: { struct hdsp_peak_rms __user *peak_rms = (struct hdsp_peak_rms __user *)arg; + err = hdsp_check_for_iobox(hdsp); + if (err < 0) + return err; + + err = hdsp_check_for_firmware(hdsp, 1); + if (err < 0) + return err; + if (!(hdsp->state & HDSP_FirmwareLoaded)) { snd_printk(KERN_ERR "Hammerfall-DSP: firmware needs to be uploaded to the card.\n"); return -EINVAL; @@ -4572,10 +4581,14 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne unsigned long flags; int i; - if (!(hdsp->state & HDSP_FirmwareLoaded)) { - snd_printk(KERN_ERR "Hammerfall-DSP: Firmware needs to be uploaded to the card.\n"); - return -EINVAL; - } + err = hdsp_check_for_iobox(hdsp); + if (err < 0) + return err; + + err = hdsp_check_for_firmware(hdsp, 1); + if (err < 0) + return err; + spin_lock_irqsave(&hdsp->lock, flags); info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp); info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp); -- cgit v1.2.3 From 0f101fa6bccdc797ddcee40fd4c55e879155a40f Mon Sep 17 00:00:00 2001 From: Ville Syrjala Date: Sun, 9 Nov 2008 20:32:40 +0200 Subject: ALSA: gusextreme: Fix build errors gusextreme depends on opl3 support. Add the approriate select to Kconfig. Also remove the unnecessary hwdep select. Relevant build errors: ERROR: "snd_opl3_hwdep_new" [sound/isa/gus/snd-gusextreme.ko] undefined! ERROR: "snd_opl3_create" [sound/isa/gus/snd-gusextreme.ko] undefined! Signed-off-by: Ville Syrjala Signed-off-by: Takashi Iwai --- sound/isa/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 660beb41f76..ce0aa044e27 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig @@ -211,7 +211,7 @@ config SND_GUSCLASSIC config SND_GUSEXTREME tristate "Gravis UltraSound Extreme" - select SND_HWDEP + select SND_OPL3_LIB select SND_MPU401_UART select SND_PCM help -- cgit v1.2.3 From 254248313aed7e6ff295ca21a82ca989b1f69c16 Mon Sep 17 00:00:00 2001 From: Travis Place Date: Mon, 10 Nov 2008 17:56:23 +0100 Subject: ALSA: hda - Make the HP EliteBook 8530p use AD1884A model laptop Added a QUIRK to patch_analog.c for the HP Elitebook 8530p (IDs 0x103c:0x30e7) to use AD1884A model 'laptop' by default. Playback and Capture confirmed working. Signed-off-by: Travis Place Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_analog.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 400df85a445..686c77491de 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -3861,6 +3861,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = { static struct snd_pci_quirk ad1884a_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), + SND_PCI_QUIRK(0x103c, 0x30e7, "HP EliteBook 8530p", AD1884A_LAPTOP), SND_PCI_QUIRK(0x103c, 0x3614, "HP 6730s", AD1884A_LAPTOP), SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD), {} -- cgit v1.2.3 From 355a0ec471377a8a907b79c8fba3f0f09b44656e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 11 Nov 2008 16:46:19 +0100 Subject: ALSA: hda - Add missing analog-mux mixer creation for STAC9200 The creation of analog-mux mixer element is missing in patch_stac9200() due to the dynamic allocation patch. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index e6085915d86..1627756e5c7 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3530,6 +3530,12 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) if ((err = stac9200_auto_create_lfe_ctls(codec, &spec->autocfg)) < 0) return err; + if (spec->num_muxes > 0) { + err = stac92xx_auto_create_mux_input_ctls(codec); + if (err < 0) + return err; + } + if (spec->autocfg.dig_out_pin) spec->multiout.dig_out_nid = 0x05; if (spec->autocfg.dig_in_pin) -- cgit v1.2.3 From 4f1e6bc3646ab50b8181555ab7e6eeab68b8632a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 11 Nov 2008 16:47:24 +0100 Subject: ALSA: hda - Fix input pin initialization for STAC/IDT codecs The input pins are sometimes not initialized properly because of the optimization check of the current pinctl code. Force to initialize the mic input pins so that they can be set up properly even if they were in a weird state. But keep other input pins if already set up as input, since this could be an extra mic pin. Reference: Novell bnc#443738 https://bugzilla.novell.com/show_bug.cgi?id=443738 Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 1627756e5c7..a51160106df 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3653,14 +3653,18 @@ static int stac92xx_init(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = cfg->input_pins[i]; if (nid) { - unsigned int pinctl = snd_hda_codec_read(codec, nid, - 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); - /* if PINCTL already set then skip */ - if (pinctl & AC_PINCAP_IN) - continue; - pinctl = AC_PINCTL_IN_EN; - if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) - pinctl |= stac92xx_get_vref(codec, nid); + unsigned int pinctl; + if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) { + /* for mic pins, force to initialize */ + pinctl = stac92xx_get_vref(codec, nid); + } else { + pinctl = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); + /* if PINCTL already set then skip */ + if (pinctl & AC_PINCTL_IN_EN) + continue; + } + pinctl |= AC_PINCTL_IN_EN; stac92xx_auto_set_pinctl(codec, nid, pinctl); } } -- cgit v1.2.3 From d7a8943635485597ae7c6d554a8ccf3ce5a42d2d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 12 Nov 2008 09:48:04 +0100 Subject: ALSA: hda - Fix IDT/STAC multiple HP detection Due to the recent change for multiple HP as line-out switch, only one of the multiple headphons (usually a wrong one) is toggled and the other pins are still disabled. This causes the silent output problem on some Dell laptops. Also, the hp_switch check is screwed up when a line-in or a mic-in jack exists. This is added as an additional output, but hp_switch check doesn't take it into account. This patch fixes these issues: simplify hp_switch check by using the NID instead of bool, and clean up / fix the toggle of HP pins in unsol event handler code. Reference: Novell bnc#443267 https://bugzilla.novell.com/show_bug.cgi?id=443267 Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 59 ++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 14 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index a51160106df..4300a679cd8 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -212,7 +212,7 @@ struct sigmatel_spec { /* i/o switches */ unsigned int io_switch[2]; unsigned int clfe_swap; - unsigned int hp_switch; + unsigned int hp_switch; /* NID of HP as line-out */ unsigned int aloopback; struct hda_pcm pcm_rec[2]; /* PCM information */ @@ -2443,7 +2443,7 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol, struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; - ucontrol->value.integer.value[0] = spec->hp_switch; + ucontrol->value.integer.value[0] = !!spec->hp_switch; return 0; } @@ -2452,8 +2452,9 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; - - spec->hp_switch = ucontrol->value.integer.value[0]; + int nid = kcontrol->private_value; + + spec->hp_switch = ucontrol->value.integer.value[0] ? nid : 0; /* check to be sure that the ports are upto date with * switch changes @@ -2862,7 +2863,8 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, if (cfg->hp_outs > 1) { err = stac92xx_add_control(spec, STAC_CTL_WIDGET_HP_SWITCH, - "Headphone as Line Out Switch", 0); + "Headphone as Line Out Switch", + cfg->hp_pins[cfg->hp_outs - 1]); if (err < 0) return err; } @@ -3786,11 +3788,30 @@ static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid) return 0; } +/* return non-zero if the hp-pin of the given array index isn't + * a jack-detection target + */ +static int no_hp_sensing(struct sigmatel_spec *spec, int i) +{ + struct auto_pin_cfg *cfg = &spec->autocfg; + + /* ignore sensing of shared line and mic jacks */ + if (spec->line_switch && + cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE]) + return 1; + if (spec->mic_switch && + cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC]) + return 1; + /* ignore if the pin is set as line-out */ + if (cfg->hp_pins[i] == spec->hp_switch) + return 1; + return 0; +} + static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) { struct sigmatel_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; - int nid = cfg->hp_pins[cfg->hp_outs - 1]; int i, presence; presence = 0; @@ -3801,15 +3822,16 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) for (i = 0; i < cfg->hp_outs; i++) { if (presence) break; - if (spec->hp_switch && cfg->hp_pins[i] == nid) - break; + if (no_hp_sensing(spec, i)) + continue; presence = get_hp_pin_presence(codec, cfg->hp_pins[i]); } if (presence) { - /* disable lineouts, enable hp */ + /* disable lineouts */ if (spec->hp_switch) - stac92xx_reset_pinctl(codec, nid, AC_PINCTL_OUT_EN); + stac92xx_reset_pinctl(codec, spec->hp_switch, + AC_PINCTL_OUT_EN); for (i = 0; i < cfg->line_outs; i++) stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], AC_PINCTL_OUT_EN); @@ -3821,9 +3843,10 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) spec->gpio_dir, spec->gpio_data & ~spec->eapd_mask); } else { - /* enable lineouts, disable hp */ + /* enable lineouts */ if (spec->hp_switch) - stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); + stac92xx_set_pinctl(codec, spec->hp_switch, + AC_PINCTL_OUT_EN); for (i = 0; i < cfg->line_outs; i++) stac92xx_set_pinctl(codec, cfg->line_out_pins[i], AC_PINCTL_OUT_EN); @@ -3835,8 +3858,16 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) spec->gpio_dir, spec->gpio_data | spec->eapd_mask); } - if (!spec->hp_switch && cfg->hp_outs > 1 && presence) - stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); + /* toggle hp outs */ + for (i = 0; i < cfg->hp_outs; i++) { + unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; + if (no_hp_sensing(spec, i)) + continue; + if (presence) + stac92xx_set_pinctl(codec, cfg->hp_pins[i], val); + else + stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val); + } } static void stac92xx_pin_sense(struct hda_codec *codec, int idx) -- cgit v1.2.3 From 4d4e9bb339cfcde7811af10859ba1ce2fe3d46b4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 12 Nov 2008 16:45:04 +0100 Subject: ALSA: hda - Add digital beep playback switch for STAC/IDT codecs The digital beep widget may have no mute control, and always enabling the beep is ofen pretty annoying, especially on laptops. This patch adds a mixer control "PC Beep Playback Switch" when there is no mixer amp mute is found, and controls it on software. Reference: Novell bnc#444572 https://bugzilla.novell.com/show_bug.cgi?id=444572 Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_beep.c | 4 +++ sound/pci/hda/hda_beep.h | 1 + sound/pci/hda/patch_sigmatel.c | 69 ++++++++++++++++++++++++++++++++++++++---- 3 files changed, 68 insertions(+), 6 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 9b77b3e0fa9..b1796ae1e8f 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c @@ -37,6 +37,9 @@ static void snd_hda_generate_beep(struct work_struct *work) container_of(work, struct hda_beep, beep_work); struct hda_codec *codec = beep->codec; + if (!beep->enabled) + return; + /* generate tone */ snd_hda_codec_write_cache(codec, beep->nid, 0, AC_VERB_SET_BEEP_CONTROL, beep->tone); @@ -115,6 +118,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) beep->nid = nid; beep->dev = input_dev; beep->codec = codec; + beep->enabled = 1; codec->beep = beep; INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h index de4036e6e71..b9679f081ca 100644 --- a/sound/pci/hda/hda_beep.h +++ b/sound/pci/hda/hda_beep.h @@ -31,6 +31,7 @@ struct hda_beep { char phys[32]; int tone; int nid; + int enabled; struct work_struct beep_work; /* scheduled task for beep event */ }; diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 4300a679cd8..1633ef2c654 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2587,8 +2587,10 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { }; /* add dynamic controls */ -static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type, - int idx, const char *name, unsigned long val) +static int stac92xx_add_control_temp(struct sigmatel_spec *spec, + struct snd_kcontrol_new *ktemp, + int idx, const char *name, + unsigned long val) { struct snd_kcontrol_new *knew; @@ -2607,20 +2609,29 @@ static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type, } knew = &spec->kctl_alloc[spec->num_kctl_used]; - *knew = stac92xx_control_templates[type]; + *knew = *ktemp; knew->index = idx; knew->name = kstrdup(name, GFP_KERNEL); - if (! knew->name) + if (!knew->name) return -ENOMEM; knew->private_value = val; spec->num_kctl_used++; return 0; } +static inline int stac92xx_add_control_idx(struct sigmatel_spec *spec, + int type, int idx, const char *name, + unsigned long val) +{ + return stac92xx_add_control_temp(spec, + &stac92xx_control_templates[type], + idx, name, val); +} + /* add dynamic controls */ -static int stac92xx_add_control(struct sigmatel_spec *spec, int type, - const char *name, unsigned long val) +static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type, + const char *name, unsigned long val) { return stac92xx_add_control_idx(spec, type, 0, name, val); } @@ -3062,6 +3073,43 @@ static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec, return 0; } +#ifdef CONFIG_SND_HDA_INPUT_BEEP +#define stac92xx_dig_beep_switch_info snd_ctl_boolean_mono_info + +static int stac92xx_dig_beep_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + ucontrol->value.integer.value[0] = codec->beep->enabled; + return 0; +} + +static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + int enabled = !!ucontrol->value.integer.value[0]; + if (codec->beep->enabled != enabled) { + codec->beep->enabled = enabled; + return 1; + } + return 0; +} + +static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .info = stac92xx_dig_beep_switch_info, + .get = stac92xx_dig_beep_switch_get, + .put = stac92xx_dig_beep_switch_put, +}; + +static int stac92xx_beep_switch_ctl(struct hda_codec *codec) +{ + return stac92xx_add_control_temp(codec->spec, &stac92xx_dig_beep_ctrl, + 0, "PC Beep Playback Switch", 0); +} +#endif + static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; @@ -3368,6 +3416,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out #ifdef CONFIG_SND_HDA_INPUT_BEEP if (spec->digbeep_nid > 0) { hda_nid_t nid = spec->digbeep_nid; + unsigned int caps; err = stac92xx_auto_create_beep_ctls(codec, nid); if (err < 0) @@ -3375,6 +3424,14 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out err = snd_hda_attach_beep_device(codec, nid); if (err < 0) return err; + /* if no beep switch is available, make its own one */ + caps = query_amp_caps(codec, nid, HDA_OUTPUT); + if (codec->beep && + !((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT)) { + err = stac92xx_beep_switch_ctl(codec); + if (err < 0) + return err; + } } #endif -- cgit v1.2.3 From 6a12afb5640217454cad21e8cf9a74b038fa3717 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 13 Nov 2008 13:08:56 +0100 Subject: ALSA: hda - Missing NULL check in hda_beep.c Added a NULL check of input_allocate_device() in hda_beep.c. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_beep.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index b1796ae1e8f..3ecd7e797de 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c @@ -88,6 +88,10 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) snprintf(beep->phys, sizeof(beep->phys), "card%d/codec#%d/beep0", codec->bus->card->number, codec->addr); input_dev = input_allocate_device(); + if (!input_dev) { + kfree(beep); + return -ENOMEM; + } /* setup digital beep device */ input_dev->name = "HDA Digital PCBeep"; -- cgit v1.2.3 From c39555d6edd0142972f577405d5259879ecc1635 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Fri, 14 Nov 2008 17:46:22 -0500 Subject: ALSA: hda: STAC_VREF_EVENT value change Changed value for STAC_VREF_EVENT from 0x40 to 0x00 because the unsol response value is only 6-bits width and the former value was 1<<6 which is an overrun. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 1633ef2c654..f205570def1 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -36,9 +36,11 @@ #include "hda_beep.h" #define NUM_CONTROL_ALLOC 32 + +#define STAC_VREF_EVENT 0x00 +#define STAC_INSERT_EVENT 0x10 #define STAC_PWR_EVENT 0x20 #define STAC_HP_EVENT 0x30 -#define STAC_VREF_EVENT 0x40 enum { STAC_REF, -- cgit v1.2.3 From d6f35e3f0da14a5eb02114708d88ae2f59dc8283 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 14 Nov 2008 19:08:18 +0100 Subject: ALSA: sound/pci/pcxhr/pcxhr.c: introduce missing kfree and pci_disable_device Error handling code following a kzalloc should free the allocated data. The error handling code is adjusted to call pci_disable_device(pci); as well, as done later in the function The semantic match that finds the problem is as follows: (http://www.emn.fr/x-info/coccinelle/) // @r exists@ local idexpression x; statement S; expression E; identifier f,l; position p1,p2; expression *ptr != NULL; @@ ( if ((x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...)) == NULL) S | x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); ... if (x == NULL) S ) <... when != x when != if (...) { <+...x...+> } x->f = E ...> ( return \(0\|<+...x...+>\|ptr\); | return@p2 ...; ) @script:python@ p1 << r.p1; p2 << r.p2; @@ print "* file: %s kmalloc %s return %s" % (p1[0].file,p1[0].line,p2[0].line) // Signed-off-by: Julia Lawall Signed-off-by: Takashi Iwai --- sound/pci/pcxhr/pcxhr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sound') diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 0e06c6c9fcc..73de6e989b3 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -1229,8 +1229,11 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id return -ENOMEM; } - if (snd_BUG_ON(pci_id->driver_data >= PCI_ID_LAST)) + if (snd_BUG_ON(pci_id->driver_data >= PCI_ID_LAST)) { + kfree(mgr); + pci_disable_device(pci); return -ENODEV; + } card_name = pcxhr_board_params[pci_id->driver_data].board_name; mgr->playback_chips = pcxhr_board_params[pci_id->driver_data].playback_chips; mgr->capture_chips = pcxhr_board_params[pci_id->driver_data].capture_chips; -- cgit v1.2.3 From 8e5f262bfcd90c041160a491a238661ebbb584a4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sat, 15 Nov 2008 19:28:54 +0100 Subject: ALSA: hda - Check model type instead of SSID in patch_92hd71bxx() Check board preset model instead of codec->subsystem_id in patch_92hd71bxx() so that other hardwares configured via the model option work like the given model. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index f205570def1..0df6f979f2a 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4488,8 +4488,8 @@ again: codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; break; case 0x111d7608: /* 5 Port with Analog Mixer */ - switch (codec->subsystem_id) { - case 0x103c361a: + switch (spec->board_config) { + case STAC_HP_M4: /* Enable VREF power saving on GPIO1 detect */ snd_hda_codec_write(codec, codec->afg, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); -- cgit v1.2.3 From 41c3b648bd4cdc34fd1918e288f8afe78903432e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 18 Nov 2008 10:45:15 +0100 Subject: ALSA: hda - Fix GPIO initialization in patch_stac92hd71bxx() Fixed the GPIO mask and co initialization in patch_stac92hd71bxx() so that the gpio_maks for HP_M4 model is set properly. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 0df6f979f2a..b254e90b47c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4478,6 +4478,13 @@ again: stac92xx_set_config_regs(codec); } + if (spec->board_config > STAC_92HD71BXX_REF) { + /* GPIO0 = EAPD */ + spec->gpio_mask = 0x01; + spec->gpio_dir = 0x01; + spec->gpio_data = 0x01; + } + switch (codec->vendor_id) { case 0x111d76b6: /* 4 Port without Analog Mixer */ case 0x111d76b7: @@ -4537,13 +4544,6 @@ again: spec->aloopback_mask = 0x50; spec->aloopback_shift = 0; - if (spec->board_config > STAC_92HD71BXX_REF) { - /* GPIO0 = EAPD */ - spec->gpio_mask = 0x01; - spec->gpio_dir = 0x01; - spec->gpio_data = 0x01; - } - spec->powerdown_adcs = 1; spec->digbeep_nid = 0x26; spec->mux_nids = stac92hd71bxx_mux_nids; -- cgit v1.2.3 From 80bf272468a8b63f5550304363e55c1ba06c13db Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 18 Nov 2008 10:48:41 +0100 Subject: ALSA: hda - Add quirks for HP Pavilion DV models Added the quirk entries for HP Pavilion DV5 and DV7 with model=hp-m4. Reference: Novell bnc#445321, bnc#445161 https://bugzilla.novell.com/show_bug.cgi?id=445321 https://bugzilla.novell.com/show_bug.cgi?id=445161 Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index b254e90b47c..25d4bf8e422 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1688,6 +1688,10 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_92HD71BXX_REF), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2, + "HP dv5", STAC_HP_M4), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, + "HP dv7", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, "unknown HP", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, -- cgit v1.2.3 From c5d08bb567874e410210cf7d21a25f28fcceb0a7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 18 Nov 2008 10:55:36 +0100 Subject: ALSA: hda - Fix resume of GPIO unsol event for STAC/IDT Use cached write for setting the GPIO unsolicited event mask to be restored properly at resume. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 25d4bf8e422..9563b5bbb27 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -4502,7 +4502,7 @@ again: switch (spec->board_config) { case STAC_HP_M4: /* Enable VREF power saving on GPIO1 detect */ - snd_hda_codec_write(codec, codec->afg, 0, + snd_hda_codec_write_cache(codec, codec->afg, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); snd_hda_codec_write_cache(codec, codec->afg, 0, AC_VERB_SET_UNSOLICITED_ENABLE, @@ -4895,7 +4895,7 @@ static int patch_stac9205(struct hda_codec *codec) stac92xx_set_config_reg(codec, 0x20, 0x1c410030); /* Enable unsol response for GPIO4/Dock HP connection */ - snd_hda_codec_write(codec, codec->afg, 0, + snd_hda_codec_write_cache(codec, codec->afg, 0, AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10); snd_hda_codec_write_cache(codec, codec->afg, 0, AC_VERB_SET_UNSOLICITED_ENABLE, -- cgit v1.2.3 From eea0579fc85e64e9f05361d5aacf496fe7a151aa Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 26 Nov 2008 14:13:03 +0100 Subject: ALSA: pcsp - Fix starting the stream with HRTIMER_CB_IRQSAFE_UNLOCK With the callback mode HRTIMER_CB_IRQSAFE_UNLOCK, the start of the stream with zero delay doesn't work. Since IRQSAFE mode is removed, we have to change the pcsp start-up code. This patch splits the callback function to two parts, the triggering of the port and the calculation of the expire time, and the update of the ALSA PCM core. The first part is called both from the trigger-start and the hrtimer callback while the latter is handled only in the hrtimer callback. Signed-off-by: Takashi Iwai --- sound/drivers/pcsp/pcsp.h | 2 + sound/drivers/pcsp/pcsp_lib.c | 87 ++++++++++++++++++++++++++++--------------- 2 files changed, 58 insertions(+), 31 deletions(-) (limited to 'sound') diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h index 70533a333b5..cdef2664218 100644 --- a/sound/drivers/pcsp/pcsp.h +++ b/sound/drivers/pcsp/pcsp.h @@ -62,6 +62,8 @@ struct snd_pcsp { unsigned short port, irq, dma; spinlock_t substream_lock; struct snd_pcm_substream *playback_substream; + unsigned int fmt_size; + unsigned int is_signed; size_t playback_ptr; size_t period_ptr; atomic_t timer_active; diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c index f8d8470861d..84cc2658c05 100644 --- a/sound/drivers/pcsp/pcsp_lib.c +++ b/sound/drivers/pcsp/pcsp_lib.c @@ -36,12 +36,13 @@ static void pcsp_call_pcm_elapsed(unsigned long priv) static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0); -enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) +/* write the port and returns the next expire time in ns; + * called at the trigger-start and in hrtimer callback + */ +static unsigned long pcsp_timer_update(struct hrtimer *handle) { unsigned char timer_cnt, val; - int fmt_size, periods_elapsed; u64 ns; - size_t period_bytes, buffer_bytes; struct snd_pcm_substream *substream; struct snd_pcm_runtime *runtime; struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); @@ -51,28 +52,25 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) outb(chip->val61, 0x61); chip->thalf = 0; if (!atomic_read(&chip->timer_active)) - goto stop; - hrtimer_forward(&chip->timer, hrtimer_get_expires(&chip->timer), - ktime_set(0, chip->ns_rem)); - return HRTIMER_RESTART; + return 0; + return chip->ns_rem; } if (!atomic_read(&chip->timer_active)) - goto stop; + return 0; substream = chip->playback_substream; if (!substream) - goto stop; + return 0; runtime = substream->runtime; - fmt_size = snd_pcm_format_physical_width(runtime->format) >> 3; /* assume it is mono! */ - val = runtime->dma_area[chip->playback_ptr + fmt_size - 1]; - if (snd_pcm_format_signed(runtime->format)) + val = runtime->dma_area[chip->playback_ptr + chip->fmt_size - 1]; + if (chip->is_signed) val ^= 0x80; timer_cnt = val * CUR_DIV() / 256; if (timer_cnt && chip->enable) { - spin_lock(&i8253_lock); + spin_lock_irqsave(&i8253_lock, flags); if (!nforce_wa) { outb_p(chip->val61, 0x61); outb_p(timer_cnt, 0x42); @@ -81,14 +79,39 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) outb(chip->val61 ^ 2, 0x61); chip->thalf = 1; } - spin_unlock(&i8253_lock); + spin_unlock_irqrestore(&i8253_lock, flags); } + chip->ns_rem = PCSP_PERIOD_NS(); + ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem); + chip->ns_rem -= ns; + return ns; +} + +enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) +{ + struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); + struct snd_pcm_substream *substream; + int periods_elapsed, pointer_update; + size_t period_bytes, buffer_bytes; + unsigned long ns; + unsigned long flags; + + pointer_update = !chip->thalf; + ns = pcsp_timer_update(handle); + if (!ns) + return HRTIMER_NORESTART; + + /* update the playback position */ + substream = chip->playback_substream; + if (!substream) + return HRTIMER_NORESTART; + period_bytes = snd_pcm_lib_period_bytes(substream); buffer_bytes = snd_pcm_lib_buffer_bytes(substream); spin_lock_irqsave(&chip->substream_lock, flags); - chip->playback_ptr += PCSP_INDEX_INC() * fmt_size; + chip->playback_ptr += PCSP_INDEX_INC() * chip->fmt_size; periods_elapsed = chip->playback_ptr - chip->period_ptr; if (periods_elapsed < 0) { #if PCSP_DEBUG @@ -106,32 +129,27 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) if (periods_elapsed) { chip->period_ptr += periods_elapsed * period_bytes; chip->period_ptr %= buffer_bytes; - tasklet_schedule(&pcsp_pcm_tasklet); } spin_unlock_irqrestore(&chip->substream_lock, flags); - if (!atomic_read(&chip->timer_active)) - goto stop; + if (periods_elapsed) + tasklet_schedule(&pcsp_pcm_tasklet); - chip->ns_rem = PCSP_PERIOD_NS(); - ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem); - chip->ns_rem -= ns; - hrtimer_forward(&chip->timer, hrtimer_get_expires(&chip->timer), - ktime_set(0, ns)); - return HRTIMER_RESTART; + hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns)); - stop: - return HRTIMER_NORESTART; + return HRTIMER_RESTART; } -static void pcsp_start_playing(struct snd_pcsp *chip) +static int pcsp_start_playing(struct snd_pcsp *chip) { + unsigned long ns; + #if PCSP_DEBUG printk(KERN_INFO "PCSP: start_playing called\n"); #endif if (atomic_read(&chip->timer_active)) { printk(KERN_ERR "PCSP: Timer already active\n"); - return; + return -EIO; } spin_lock(&i8253_lock); @@ -141,7 +159,12 @@ static void pcsp_start_playing(struct snd_pcsp *chip) atomic_set(&chip->timer_active, 1); chip->thalf = 0; - hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL); + ns = pcsp_timer_update(&pcsp_chip.timer); + if (!ns) + return -EIO; + + hrtimer_start(&pcsp_chip.timer, ktime_set(0, ns), HRTIMER_MODE_REL); + return 0; } static void pcsp_stop_playing(struct snd_pcsp *chip) @@ -221,6 +244,9 @@ static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream) pcsp_sync_stop(chip); chip->playback_ptr = 0; chip->period_ptr = 0; + chip->fmt_size = + snd_pcm_format_physical_width(substream->runtime->format) >> 3; + chip->is_signed = snd_pcm_format_signed(substream->runtime->format); return 0; } @@ -233,8 +259,7 @@ static int snd_pcsp_trigger(struct snd_pcm_substream *substream, int cmd) switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: - pcsp_start_playing(chip); - break; + return pcsp_start_playing(chip); case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: pcsp_stop_playing(chip); -- cgit v1.2.3