aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>2009-04-07 13:34:16 -0700
committerJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>2009-04-07 13:34:16 -0700
commit38f4b8c0da01ae7cd9b93386842ce272d6fde9ab (patch)
tree3c8c52201aac038094bfea7efdd0984a8f62045e /sound
parenta811454027352c762e0d5bba1b1d8f7d26bf96ae (diff)
parent8e2c4f2844c0e8dcdfe312e5f2204854ca8532c6 (diff)
Merge commit 'origin/master' into for-linus/xen/master
* commit 'origin/master': (4825 commits) Fix build errors due to CONFIG_BRANCH_TRACER=y parport: Use the PCI IRQ if offered tty: jsm cleanups Adjust path to gpio headers KGDB_SERIAL_CONSOLE check for module Change KCONFIG name tty: Blackin CTS/RTS Change hardware flow control from poll to interrupt driven Add support for the MAX3100 SPI UART. lanana: assign a device name and numbering for MAX3100 serqt: initial clean up pass for tty side tty: Use the generic RS485 ioctl on CRIS tty: Correct inline types for tty_driver_kref_get() splice: fix deadlock in splicing to file nilfs2: support nanosecond timestamp nilfs2: introduce secondary super block nilfs2: simplify handling of active state of segments nilfs2: mark minor flag for checkpoint created by internal operation nilfs2: clean up sketch file nilfs2: super block operations fix endian bug ... Conflicts: arch/x86/include/asm/thread_info.h arch/x86/lguest/boot.c drivers/xen/manage.c
Diffstat (limited to 'sound')
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c15
-rw-r--r--sound/atmel/abdac.c4
-rw-r--r--sound/atmel/ac97c.c128
-rw-r--r--sound/atmel/ac97c.h14
-rw-r--r--sound/core/info.c31
-rw-r--r--sound/core/oss/mixer_oss.c8
-rw-r--r--sound/i2c/other/tea575x-tuner.c302
-rw-r--r--sound/isa/opl3sa2.c1
-rw-r--r--sound/oss/pss.c2
-rw-r--r--sound/pci/Kconfig2
-rw-r--r--sound/pci/ad1889.c4
-rw-r--r--sound/pci/ali5451/ali5451.c4
-rw-r--r--sound/pci/als300.c4
-rw-r--r--sound/pci/als4000.c4
-rw-r--r--sound/pci/au88x0/au88x0.c4
-rw-r--r--sound/pci/aw2/aw2-alsa.c4
-rw-r--r--sound/pci/azt3328.c4
-rw-r--r--sound/pci/ca0106/ca0106_main.c4
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c4
-rw-r--r--sound/pci/emu10k1/emu10k1x.c4
-rw-r--r--sound/pci/es1938.c4
-rw-r--r--sound/pci/es1968.c4
-rw-r--r--sound/pci/hda/patch_analog.c2
-rw-r--r--sound/pci/hda/patch_realtek.c5
-rw-r--r--sound/pci/hda/patch_sigmatel.c20
-rw-r--r--sound/pci/ice1712/ice1712.c4
-rw-r--r--sound/pci/maestro3.c4
-rw-r--r--sound/pci/mixart/mixart.c2
-rw-r--r--sound/pci/pcxhr/pcxhr.c2
-rw-r--r--sound/pci/sis7019.c2
-rw-r--r--sound/pci/sonicvibes.c4
-rw-r--r--sound/pci/trident/trident_main.c4
-rw-r--r--sound/ppc/powermac.c2
-rw-r--r--sound/sh/aica.c2
-rw-r--r--sound/soc/blackfin/Kconfig2
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c4
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c4
-rw-r--r--sound/soc/codecs/ak4535.c3
-rw-r--r--sound/soc/codecs/twl4030.c61
-rw-r--r--sound/soc/codecs/twl4030.h1
-rw-r--r--sound/soc/codecs/wm9705.c37
-rw-r--r--sound/soc/fsl/fsl_dma.c29
-rw-r--r--sound/soc/fsl/fsl_ssi.c99
-rw-r--r--sound/soc/omap/omap-mcbsp.c11
-rw-r--r--sound/soc/omap/omap-pcm.c2
-rw-r--r--sound/soc/pxa/Kconfig10
-rw-r--r--sound/soc/pxa/Makefile2
-rw-r--r--sound/soc/pxa/magician.c560
-rw-r--r--sound/soc/pxa/pxa-ssp.c12
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c4
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.c2
-rw-r--r--sound/soc/soc-core.c20
-rw-r--r--sound/usb/usbaudio.c255
53 files changed, 1320 insertions, 406 deletions
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index 7793d2a511c..0afd1a8226f 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -238,6 +238,8 @@ static inline void pxa_ac97_cold_pxa3xx(void)
bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
{
+ unsigned long gsr;
+
#ifdef CONFIG_PXA25x
if (cpu_is_pxa25x())
pxa_ac97_warm_pxa25x();
@@ -254,10 +256,10 @@ bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
else
#endif
BUG();
-
- if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
+ gsr = GSR | gsr_bits;
+ if (!(gsr & (GSR_PCR | GSR_SCR))) {
printk(KERN_INFO "%s: warm reset timeout (GSR=%#lx)\n",
- __func__, gsr_bits);
+ __func__, gsr);
return false;
}
@@ -268,6 +270,8 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
{
+ unsigned long gsr;
+
#ifdef CONFIG_PXA25x
if (cpu_is_pxa25x())
pxa_ac97_cold_pxa25x();
@@ -285,9 +289,10 @@ bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
#endif
BUG();
- if (!((GSR | gsr_bits) & (GSR_PCR | GSR_SCR))) {
+ gsr = GSR | gsr_bits;
+ if (!(gsr & (GSR_PCR | GSR_SCR))) {
printk(KERN_INFO "%s: cold reset timeout (GSR=%#lx)\n",
- __func__, gsr_bits);
+ __func__, gsr);
return false;
}
diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c
index 28b3c7f7cfe..f2f41c85422 100644
--- a/sound/atmel/abdac.c
+++ b/sound/atmel/abdac.c
@@ -165,7 +165,7 @@ static struct snd_pcm_hardware atmel_abdac_hw = {
.buffer_bytes_max = 64 * 4096,
.period_bytes_min = 4096,
.period_bytes_max = 4096,
- .periods_min = 4,
+ .periods_min = 6,
.periods_max = 64,
};
@@ -502,7 +502,7 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, card);
dev_info(&pdev->dev, "Atmel ABDAC at 0x%p using %s\n",
- dac->regs, dac->dma.chan->dev->device.bus_id);
+ dac->regs, dev_name(&dac->dma.chan->dev->device));
return retval;
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
index dd72e00e5ae..0c0f8771656 100644
--- a/sound/atmel/ac97c.c
+++ b/sound/atmel/ac97c.c
@@ -1,5 +1,5 @@
/*
- * Driver for the Atmel AC97C controller
+ * Driver for Atmel AC97C
*
* Copyright (C) 2005-2009 Atmel Corporation
*
@@ -10,6 +10,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/bitmap.h>
+#include <linux/device.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/init.h>
@@ -65,6 +66,7 @@ struct atmel_ac97c {
/* Serialize access to opened variable */
spinlock_t lock;
void __iomem *regs;
+ int irq;
int opened;
int reset_pin;
};
@@ -150,10 +152,10 @@ static struct snd_pcm_hardware atmel_ac97c_hw = {
.rate_max = 48000,
.channels_min = 1,
.channels_max = 2,
- .buffer_bytes_max = 64 * 4096,
+ .buffer_bytes_max = 2 * 2 * 64 * 2048,
.period_bytes_min = 4096,
.period_bytes_max = 4096,
- .periods_min = 4,
+ .periods_min = 6,
.periods_max = 64,
};
@@ -297,9 +299,11 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
{
struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long word = 0;
+ unsigned long word = ac97c_readl(chip, OCA);
int retval;
+ word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
+
/* assign channels to AC97C channel A */
switch (runtime->channels) {
case 1:
@@ -312,7 +316,6 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
default:
/* TODO: support more than two channels */
return -EINVAL;
- break;
}
ac97c_writel(chip, OCA, word);
@@ -324,13 +327,25 @@ static int atmel_ac97c_playback_prepare(struct snd_pcm_substream *substream)
word |= AC97C_CMR_CEM_LITTLE;
break;
case SNDRV_PCM_FORMAT_S16_BE: /* fall through */
- default:
word &= ~(AC97C_CMR_CEM_LITTLE);
break;
+ default:
+ word = ac97c_readl(chip, OCA);
+ word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
+ ac97c_writel(chip, OCA, word);
+ return -EINVAL;
}
+ /* Enable underrun interrupt on channel A */
+ word |= AC97C_CSR_UNRUN;
+
ac97c_writel(chip, CAMR, word);
+ /* Enable channel A event interrupt */
+ word = ac97c_readl(chip, IMR);
+ word |= AC97C_SR_CAEVT;
+ ac97c_writel(chip, IER, word);
+
/* set variable rate if needed */
if (runtime->rate != 48000) {
word = ac97c_readl(chip, MR);
@@ -359,9 +374,11 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
{
struct atmel_ac97c *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- unsigned long word = 0;
+ unsigned long word = ac97c_readl(chip, ICA);
int retval;
+ word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
+
/* assign channels to AC97C channel A */
switch (runtime->channels) {
case 1:
@@ -374,7 +391,6 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
default:
/* TODO: support more than two channels */
return -EINVAL;
- break;
}
ac97c_writel(chip, ICA, word);
@@ -386,13 +402,25 @@ static int atmel_ac97c_capture_prepare(struct snd_pcm_substream *substream)
word |= AC97C_CMR_CEM_LITTLE;
break;
case SNDRV_PCM_FORMAT_S16_BE: /* fall through */
- default:
word &= ~(AC97C_CMR_CEM_LITTLE);
break;
+ default:
+ word = ac97c_readl(chip, ICA);
+ word &= ~(AC97C_CH_MASK(PCM_LEFT) | AC97C_CH_MASK(PCM_RIGHT));
+ ac97c_writel(chip, ICA, word);
+ return -EINVAL;
}
+ /* Enable overrun interrupt on channel A */
+ word |= AC97C_CSR_OVRUN;
+
ac97c_writel(chip, CAMR, word);
+ /* Enable channel A event interrupt */
+ word = ac97c_readl(chip, IMR);
+ word |= AC97C_SR_CAEVT;
+ ac97c_writel(chip, IER, word);
+
/* set variable rate if needed */
if (runtime->rate != 48000) {
word = ac97c_readl(chip, MR);
@@ -543,6 +571,43 @@ static struct snd_pcm_ops atmel_ac97_capture_ops = {
.pointer = atmel_ac97c_capture_pointer,
};
+static irqreturn_t atmel_ac97c_interrupt(int irq, void *dev)
+{
+ struct atmel_ac97c *chip = (struct atmel_ac97c *)dev;
+ irqreturn_t retval = IRQ_NONE;
+ u32 sr = ac97c_readl(chip, SR);
+ u32 casr = ac97c_readl(chip, CASR);
+ u32 cosr = ac97c_readl(chip, COSR);
+
+ if (sr & AC97C_SR_CAEVT) {
+ dev_info(&chip->pdev->dev, "channel A event%s%s%s%s%s%s\n",
+ casr & AC97C_CSR_OVRUN ? " OVRUN" : "",
+ casr & AC97C_CSR_RXRDY ? " RXRDY" : "",
+ casr & AC97C_CSR_UNRUN ? " UNRUN" : "",
+ casr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "",
+ casr & AC97C_CSR_TXRDY ? " TXRDY" : "",
+ !casr ? " NONE" : "");
+ retval = IRQ_HANDLED;
+ }
+
+ if (sr & AC97C_SR_COEVT) {
+ dev_info(&chip->pdev->dev, "codec channel event%s%s%s%s%s\n",
+ cosr & AC97C_CSR_OVRUN ? " OVRUN" : "",
+ cosr & AC97C_CSR_RXRDY ? " RXRDY" : "",
+ cosr & AC97C_CSR_TXEMPTY ? " TXEMPTY" : "",
+ cosr & AC97C_CSR_TXRDY ? " TXRDY" : "",
+ !cosr ? " NONE" : "");
+ retval = IRQ_HANDLED;
+ }
+
+ if (retval == IRQ_NONE) {
+ dev_err(&chip->pdev->dev, "spurious interrupt sr 0x%08x "
+ "casr 0x%08x cosr 0x%08x\n", sr, casr, cosr);
+ }
+
+ return retval;
+}
+
static int __devinit atmel_ac97c_pcm_new(struct atmel_ac97c *chip)
{
struct snd_pcm *pcm;
@@ -665,17 +730,17 @@ static bool filter(struct dma_chan *chan, void *slave)
static void atmel_ac97c_reset(struct atmel_ac97c *chip)
{
- ac97c_writel(chip, MR, AC97C_MR_WRST);
+ ac97c_writel(chip, MR, 0);
+ ac97c_writel(chip, MR, AC97C_MR_ENA);
+ ac97c_writel(chip, CAMR, 0);
+ ac97c_writel(chip, COMR, 0);
if (gpio_is_valid(chip->reset_pin)) {
gpio_set_value(chip->reset_pin, 0);
/* AC97 v2.2 specifications says minimum 1 us. */
- udelay(10);
+ udelay(2);
gpio_set_value(chip->reset_pin, 1);
}
-
- udelay(1);
- ac97c_writel(chip, MR, AC97C_MR_ENA);
}
static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
@@ -690,6 +755,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
.read = atmel_ac97c_read,
};
int retval;
+ int irq;
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!regs) {
@@ -703,6 +769,12 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
return -ENXIO;
}
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_dbg(&pdev->dev, "could not get irq\n");
+ return -ENXIO;
+ }
+
pclk = clk_get(&pdev->dev, "pclk");
if (IS_ERR(pclk)) {
dev_dbg(&pdev->dev, "no peripheral clock\n");
@@ -719,6 +791,13 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
chip = get_chip(card);
+ retval = request_irq(irq, atmel_ac97c_interrupt, 0, "AC97C", chip);
+ if (retval) {
+ dev_dbg(&pdev->dev, "unable to request irq %d\n", irq);
+ goto err_request_irq;
+ }
+ chip->irq = irq;
+
spin_lock_init(&chip->lock);
strcpy(card->driver, "Atmel AC97C");
@@ -747,14 +826,18 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
snd_card_set_dev(card, &pdev->dev);
+ atmel_ac97c_reset(chip);
+
+ /* Enable overrun interrupt from codec channel */
+ ac97c_writel(chip, COMR, AC97C_CSR_OVRUN);
+ ac97c_writel(chip, IER, ac97c_readl(chip, IMR) | AC97C_SR_COEVT);
+
retval = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus);
if (retval) {
dev_dbg(&pdev->dev, "could not register on ac97 bus\n");
goto err_ac97_bus;
}
- atmel_ac97c_reset(chip);
-
retval = atmel_ac97c_mixer_new(chip);
if (retval) {
dev_dbg(&pdev->dev, "could not register ac97 mixer\n");
@@ -773,7 +856,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
chip->dma.rx_chan = dma_request_channel(mask, filter, dws);
dev_info(&chip->pdev->dev, "using %s for DMA RX\n",
- chip->dma.rx_chan->dev->device.bus_id);
+ dev_name(&chip->dma.rx_chan->dev->device));
set_bit(DMA_RX_CHAN_PRESENT, &chip->flags);
}
@@ -789,7 +872,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
chip->dma.tx_chan = dma_request_channel(mask, filter, dws);
dev_info(&chip->pdev->dev, "using %s for DMA TX\n",
- chip->dma.tx_chan->dev->device.bus_id);
+ dev_name(&chip->dma.tx_chan->dev->device));
set_bit(DMA_TX_CHAN_PRESENT, &chip->flags);
}
@@ -809,7 +892,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev)
retval = snd_card_register(card);
if (retval) {
dev_dbg(&pdev->dev, "could not register sound card\n");
- goto err_ac97_bus;
+ goto err_dma;
}
platform_set_drvdata(pdev, card);
@@ -836,6 +919,8 @@ err_ac97_bus:
iounmap(chip->regs);
err_ioremap:
+ free_irq(irq, chip);
+err_request_irq:
snd_card_free(card);
err_snd_card_new:
clk_disable(pclk);
@@ -884,9 +969,14 @@ static int __devexit atmel_ac97c_remove(struct platform_device *pdev)
if (gpio_is_valid(chip->reset_pin))
gpio_free(chip->reset_pin);
+ ac97c_writel(chip, CAMR, 0);
+ ac97c_writel(chip, COMR, 0);
+ ac97c_writel(chip, MR, 0);
+
clk_disable(chip->pclk);
clk_put(chip->pclk);
iounmap(chip->regs);
+ free_irq(chip->irq, chip);
if (test_bit(DMA_RX_CHAN_PRESENT, &chip->flags))
dma_release_channel(chip->dma.rx_chan);
diff --git a/sound/atmel/ac97c.h b/sound/atmel/ac97c.h
index c17bd582598..ecbba5021c8 100644
--- a/sound/atmel/ac97c.h
+++ b/sound/atmel/ac97c.h
@@ -1,5 +1,5 @@
/*
- * Register definitions for the Atmel AC97C controller
+ * Register definitions for Atmel AC97C
*
* Copyright (C) 2005-2009 Atmel Corporation
*
@@ -17,10 +17,6 @@
#define AC97C_CATHR 0x24
#define AC97C_CASR 0x28
#define AC97C_CAMR 0x2c
-#define AC97C_CBRHR 0x30
-#define AC97C_CBTHR 0x34
-#define AC97C_CBSR 0x38
-#define AC97C_CBMR 0x3c
#define AC97C_CORHR 0x40
#define AC97C_COTHR 0x44
#define AC97C_COSR 0x48
@@ -46,8 +42,10 @@
#define AC97C_MR_VRA (1 << 2)
#define AC97C_CSR_TXRDY (1 << 0)
+#define AC97C_CSR_TXEMPTY (1 << 1)
#define AC97C_CSR_UNRUN (1 << 2)
#define AC97C_CSR_RXRDY (1 << 4)
+#define AC97C_CSR_OVRUN (1 << 5)
#define AC97C_CSR_ENDTX (1 << 10)
#define AC97C_CSR_ENDRX (1 << 14)
@@ -61,11 +59,15 @@
#define AC97C_CMR_DMAEN (1 << 22)
#define AC97C_SR_CAEVT (1 << 3)
+#define AC97C_SR_COEVT (1 << 2)
+#define AC97C_SR_WKUP (1 << 1)
+#define AC97C_SR_SOF (1 << 0)
+#define AC97C_CH_MASK(slot) \
+ (0x7 << (3 * (AC97_SLOT_##slot - 3)))
#define AC97C_CH_ASSIGN(slot, channel) \
(AC97C_CHANNEL_##channel << (3 * (AC97_SLOT_##slot - 3)))
#define AC97C_CHANNEL_NONE 0x0
#define AC97C_CHANNEL_A 0x1
-#define AC97C_CHANNEL_B 0x2
#endif /* __SOUND_ATMEL_AC97C_H */
diff --git a/sound/core/info.c b/sound/core/info.c
index 70fa87189f3..35df614f6c5 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -154,11 +154,6 @@ EXPORT_SYMBOL(snd_seq_root);
struct snd_info_entry *snd_oss_root;
#endif
-static inline void snd_info_entry_prepare(struct proc_dir_entry *de)
-{
- de->owner = THIS_MODULE;
-}
-
static void snd_remove_proc_entry(struct proc_dir_entry *parent,
struct proc_dir_entry *de)
{
@@ -522,32 +517,11 @@ static const struct file_operations snd_info_entry_operations =
.release = snd_info_entry_release,
};
-/**
- * snd_create_proc_entry - create a procfs entry
- * @name: the name of the proc file
- * @mode: the file permission bits, S_Ixxx
- * @parent: the parent proc-directory entry
- *
- * Creates a new proc file entry with the given name and permission
- * on the given directory.
- *
- * Returns the pointer of new instance or NULL on failure.
- */
-static struct proc_dir_entry *snd_create_proc_entry(const char *name, mode_t mode,
- struct proc_dir_entry *parent)
-{
- struct proc_dir_entry *p;
- p = create_proc_entry(name, mode, parent);
- if (p)
- snd_info_entry_prepare(p);
- return p;
-}
-
int __init snd_info_init(void)
{
struct proc_dir_entry *p;
- p = snd_create_proc_entry("asound", S_IFDIR | S_IRUGO | S_IXUGO, NULL);
+ p = create_proc_entry("asound", S_IFDIR | S_IRUGO | S_IXUGO, NULL);
if (p == NULL)
return -ENOMEM;
snd_proc_root = p;
@@ -974,12 +948,11 @@ int snd_info_register(struct snd_info_entry * entry)
return -ENXIO;
root = entry->parent == NULL ? snd_proc_root : entry->parent->p;
mutex_lock(&info_mutex);
- p = snd_create_proc_entry(entry->name, entry->mode, root);
+ p = create_proc_entry(entry->name, entry->mode, root);
if (!p) {
mutex_unlock(&info_mutex);
return -ENOMEM;
}
- p->owner = entry->module;
if (!S_ISDIR(entry->mode))
p->proc_fops = &snd_info_entry_operations;
p->size = entry->size;
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index e570649184e..5dcd8a52697 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -703,19 +703,27 @@ static int snd_mixer_oss_put_volume1(struct snd_mixer_oss_file *fmixer,
if (left || right) {
if (slot->present & SNDRV_MIXER_OSS_PRESENT_PSWITCH)
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PSWITCH], left, right, 0);
+ if (slot->present & SNDRV_MIXER_OSS_PRESENT_CSWITCH)
+ snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], left, right, 0);
if (slot->present & SNDRV_MIXER_OSS_PRESENT_GSWITCH)
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GSWITCH], left, right, 0);
if (slot->present & SNDRV_MIXER_OSS_PRESENT_PROUTE)
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PROUTE], left, right, 1);
+ if (slot->present & SNDRV_MIXER_OSS_PRESENT_CROUTE)
+ snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], left, right, 1);
if (slot->present & SNDRV_MIXER_OSS_PRESENT_GROUTE)
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1);
} else {
if (slot->present & SNDRV_MIXER_OSS_PRESENT_PSWITCH) {
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PSWITCH], left, right, 0);
+ } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_CSWITCH) {
+ snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CSWITCH], left, right, 0);
} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GSWITCH) {
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GSWITCH], left, right, 0);
} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_PROUTE) {
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PROUTE], left, right, 1);
+ } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_CROUTE) {
+ snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CROUTE], left, right, 1);
} else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GROUTE) {
snd_mixer_oss_put_volume1_sw(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GROUTE], left, right, 1);
}
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index 9d98a6658ac..d31c373e076 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -24,6 +24,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/init.h>
+#include <linux/version.h>
#include <sound/core.h>
#include <sound/tea575x-tuner.h>
@@ -31,6 +32,13 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips");
MODULE_LICENSE("GPL");
+static int radio_nr = -1;
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+#define FREQ_LO (87 * 16000)
+#define FREQ_HI (108 * 16000)
+
/*
* definitions
*/
@@ -53,6 +61,17 @@ MODULE_LICENSE("GPL");
#define TEA575X_BIT_DUMMY (1<<15) /* buffer */
#define TEA575X_BIT_FREQ_MASK 0x7fff
+static struct v4l2_queryctrl radio_qctrl[] = {
+ {
+ .id = V4L2_CID_AUDIO_MUTE,
+ .name = "Mute",
+ .minimum = 0,
+ .maximum = 1,
+ .default_value = 1,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ }
+};
+
/*
* lowlevel part
*/
@@ -84,94 +103,146 @@ static void snd_tea575x_set_freq(struct snd_tea575x *tea)
* Linux Video interface
*/
-static long snd_tea575x_ioctl(struct file *file,
- unsigned int cmd, unsigned long data)
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *v)
{
struct snd_tea575x *tea = video_drvdata(file);
- void __user *arg = (void __user *)data;
-
- switch(cmd) {
- case VIDIOCGCAP:
- {
- struct video_capability v;
- v.type = VID_TYPE_TUNER;
- v.channels = 1;
- v.audios = 1;
- /* No we don't do pictures */
- v.maxwidth = 0;
- v.maxheight = 0;
- v.minwidth = 0;
- v.minheight = 0;
- strcpy(v.name, tea->tea5759 ? "TEA5759" : "TEA5757");
- if (copy_to_user(arg,&v,sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if (copy_from_user(&v, arg,sizeof(v))!=0)
- return -EFAULT;
- if (v.tuner) /* Only 1 tuner */
- return -EINVAL;
- v.rangelow = (87*16000);
- v.rangehigh = (108*16000);
- v.flags = VIDEO_TUNER_LOW;
- v.mode = VIDEO_MODE_AUTO;
- strcpy(v.name, "FM");
- v.signal = 0xFFFF;
- if (copy_to_user(arg, &v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&v, arg, sizeof(v)))
- return -EFAULT;
- if(v.tuner!=0)
- return -EINVAL;
- /* Only 1 tuner so no setting needed ! */
+
+ strcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757");
+ strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver));
+ strlcpy(v->card, "Maestro Radio", sizeof(v->card));
+ sprintf(v->bus_info, "PCI");
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ if (v->index > 0)
+ return -EINVAL;
+
+ strcpy(v->name, "FM");
+ v->type = V4L2_TUNER_RADIO;
+ v->rangelow = FREQ_LO;
+ v->rangehigh = FREQ_HI;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+ v->signal = 0xffff;
+ retu