提交 ea49b166 编写于 作者: L Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (41 commits)
  ALSA: hda - Identify more variants for ALC269
  ALSA: hda - Fix wrong ALC269 variant check
  ALSA: hda - Enable jack sense for Thinkpad Edge 11
  ALSA: Revert "ALSA: hda - Fix switching between dmic and mic using the same mux on IDT/STAC"
  ALSA: hda - Fixed ALC887-VD initial error
  ALSA: atmel - Fix the return value in error path
  ALSA: hda: Use hp-laptop quirk to enable headphones automute for Asus A52J
  ALSA: snd-atmel-abdac: test wrong variable
  ALSA: azt3328: period bug fix (for PA), add missing ACK on stop timer
  ALSA: hda: Add Samsung R720 SSID for subwoofer pin fixup
  ALSA: sound/pci/asihpi/hpioctl.c: Remove unnecessary casts of pci_get_drvdata
  ALSA: sound/core/pcm_lib.c: Remove unnecessary semicolons
  ALSA: sound/ppc: Use printf extension %pR for struct resource
  ALSA: ac97: Apply quirk for Dell Latitude D610 binding Master and Headphone controls
  ASoC: uda134x - set reg_cache_default to uda134x_reg
  ASoC: Add support for MAX98089 CODEC
  ASoC: davinci: fixes for multi-component
  ASoC: Fix register cache setup WM8994 for multi-component
  ASoC: Fix dapm_seq_compare() for multi-component
  ASoC: RX1950: Fix hw_params function
  ...
...@@ -359,8 +359,8 @@ static struct clk_lookup dm355_clks[] = { ...@@ -359,8 +359,8 @@ static struct clk_lookup dm355_clks[] = {
CLK(NULL, "uart1", &uart1_clk), CLK(NULL, "uart1", &uart1_clk),
CLK(NULL, "uart2", &uart2_clk), CLK(NULL, "uart2", &uart2_clk),
CLK("i2c_davinci.1", NULL, &i2c_clk), CLK("i2c_davinci.1", NULL, &i2c_clk),
CLK("davinci-asp.0", NULL, &asp0_clk), CLK("davinci-mcbsp.0", NULL, &asp0_clk),
CLK("davinci-asp.1", NULL, &asp1_clk), CLK("davinci-mcbsp.1", NULL, &asp1_clk),
CLK("davinci_mmc.0", NULL, &mmcsd0_clk), CLK("davinci_mmc.0", NULL, &mmcsd0_clk),
CLK("davinci_mmc.1", NULL, &mmcsd1_clk), CLK("davinci_mmc.1", NULL, &mmcsd1_clk),
CLK("spi_davinci.0", NULL, &spi0_clk), CLK("spi_davinci.0", NULL, &spi0_clk),
...@@ -664,7 +664,7 @@ static struct resource dm355_asp1_resources[] = { ...@@ -664,7 +664,7 @@ static struct resource dm355_asp1_resources[] = {
}; };
static struct platform_device dm355_asp1_device = { static struct platform_device dm355_asp1_device = {
.name = "davinci-asp", .name = "davinci-mcbsp",
.id = 1, .id = 1,
.num_resources = ARRAY_SIZE(dm355_asp1_resources), .num_resources = ARRAY_SIZE(dm355_asp1_resources),
.resource = dm355_asp1_resources, .resource = dm355_asp1_resources,
......
...@@ -459,7 +459,7 @@ static struct clk_lookup dm365_clks[] = { ...@@ -459,7 +459,7 @@ static struct clk_lookup dm365_clks[] = {
CLK(NULL, "usb", &usb_clk), CLK(NULL, "usb", &usb_clk),
CLK("davinci_emac.1", NULL, &emac_clk), CLK("davinci_emac.1", NULL, &emac_clk),
CLK("davinci_voicecodec", NULL, &voicecodec_clk), CLK("davinci_voicecodec", NULL, &voicecodec_clk),
CLK("davinci-asp.0", NULL, &asp0_clk), CLK("davinci-mcbsp", NULL, &asp0_clk),
CLK(NULL, "rto", &rto_clk), CLK(NULL, "rto", &rto_clk),
CLK(NULL, "mjcp", &mjcp_clk), CLK(NULL, "mjcp", &mjcp_clk),
CLK(NULL, NULL, NULL), CLK(NULL, NULL, NULL),
...@@ -922,8 +922,8 @@ static struct resource dm365_asp_resources[] = { ...@@ -922,8 +922,8 @@ static struct resource dm365_asp_resources[] = {
}; };
static struct platform_device dm365_asp_device = { static struct platform_device dm365_asp_device = {
.name = "davinci-asp", .name = "davinci-mcbsp",
.id = 0, .id = -1,
.num_resources = ARRAY_SIZE(dm365_asp_resources), .num_resources = ARRAY_SIZE(dm365_asp_resources),
.resource = dm365_asp_resources, .resource = dm365_asp_resources,
}; };
......
...@@ -302,7 +302,7 @@ static struct clk_lookup dm644x_clks[] = { ...@@ -302,7 +302,7 @@ static struct clk_lookup dm644x_clks[] = {
CLK("davinci_emac.1", NULL, &emac_clk), CLK("davinci_emac.1", NULL, &emac_clk),
CLK("i2c_davinci.1", NULL, &i2c_clk), CLK("i2c_davinci.1", NULL, &i2c_clk),
CLK("palm_bk3710", NULL, &ide_clk), CLK("palm_bk3710", NULL, &ide_clk),
CLK("davinci-asp", NULL, &asp_clk), CLK("davinci-mcbsp", NULL, &asp_clk),
CLK("davinci_mmc.0", NULL, &mmcsd_clk), CLK("davinci_mmc.0", NULL, &mmcsd_clk),
CLK(NULL, "spi", &spi_clk), CLK(NULL, "spi", &spi_clk),
CLK(NULL, "gpio", &gpio_clk), CLK(NULL, "gpio", &gpio_clk),
...@@ -580,7 +580,7 @@ static struct resource dm644x_asp_resources[] = { ...@@ -580,7 +580,7 @@ static struct resource dm644x_asp_resources[] = {
}; };
static struct platform_device dm644x_asp_device = { static struct platform_device dm644x_asp_device = {
.name = "davinci-asp", .name = "davinci-mcbsp",
.id = -1, .id = -1,
.num_resources = ARRAY_SIZE(dm644x_asp_resources), .num_resources = ARRAY_SIZE(dm644x_asp_resources),
.resource = dm644x_asp_resources, .resource = dm644x_asp_resources,
......
...@@ -522,9 +522,6 @@ ...@@ -522,9 +522,6 @@
#define WM8350_MCLK_SEL_PLL_32K 3 #define WM8350_MCLK_SEL_PLL_32K 3
#define WM8350_MCLK_SEL_MCLK 5 #define WM8350_MCLK_SEL_MCLK 5
#define WM8350_MCLK_DIR_OUT 0
#define WM8350_MCLK_DIR_IN 1
/* clock divider id's */ /* clock divider id's */
#define WM8350_ADC_CLKDIV 0 #define WM8350_ADC_CLKDIV 0
#define WM8350_DAC_CLKDIV 1 #define WM8350_DAC_CLKDIV 1
......
...@@ -420,9 +420,9 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev) ...@@ -420,9 +420,9 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev)
return PTR_ERR(pclk); return PTR_ERR(pclk);
} }
sample_clk = clk_get(&pdev->dev, "sample_clk"); sample_clk = clk_get(&pdev->dev, "sample_clk");
if (IS_ERR(pclk)) { if (IS_ERR(sample_clk)) {
dev_dbg(&pdev->dev, "no sample clock\n"); dev_dbg(&pdev->dev, "no sample clock\n");
retval = PTR_ERR(pclk); retval = PTR_ERR(sample_clk);
goto out_put_pclk; goto out_put_pclk;
} }
clk_enable(pclk); clk_enable(pclk);
......
...@@ -223,7 +223,7 @@ static void xrun_log(struct snd_pcm_substream *substream, ...@@ -223,7 +223,7 @@ static void xrun_log(struct snd_pcm_substream *substream,
entry->jiffies = jiffies; entry->jiffies = jiffies;
entry->pos = pos; entry->pos = pos;
entry->period_size = runtime->period_size; entry->period_size = runtime->period_size;
entry->buffer_size = runtime->buffer_size;; entry->buffer_size = runtime->buffer_size;
entry->old_hw_ptr = runtime->status->hw_ptr; entry->old_hw_ptr = runtime->status->hw_ptr;
entry->hw_ptr_base = runtime->hw_ptr_base; entry->hw_ptr_base = runtime->hw_ptr_base;
log->idx = (log->idx + 1) % XRUN_LOG_CNT; log->idx = (log->idx + 1) % XRUN_LOG_CNT;
......
...@@ -71,7 +71,7 @@ int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver, ...@@ -71,7 +71,7 @@ int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver,
if (sound_nblocks >= MAX_MEM_BLOCKS) if (sound_nblocks >= MAX_MEM_BLOCKS)
sound_nblocks = MAX_MEM_BLOCKS - 1; sound_nblocks = MAX_MEM_BLOCKS - 1;
op = (struct audio_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct audio_operations))); op = (struct audio_operations *) (sound_mem_blocks[sound_nblocks] = vzalloc(sizeof(struct audio_operations)));
sound_nblocks++; sound_nblocks++;
if (sound_nblocks >= MAX_MEM_BLOCKS) if (sound_nblocks >= MAX_MEM_BLOCKS)
sound_nblocks = MAX_MEM_BLOCKS - 1; sound_nblocks = MAX_MEM_BLOCKS - 1;
...@@ -81,7 +81,6 @@ int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver, ...@@ -81,7 +81,6 @@ int sound_install_audiodrv(int vers, char *name, struct audio_driver *driver,
sound_unload_audiodev(num); sound_unload_audiodev(num);
return -(ENOMEM); return -(ENOMEM);
} }
memset((char *) op, 0, sizeof(struct audio_operations));
init_waitqueue_head(&op->in_sleeper); init_waitqueue_head(&op->in_sleeper);
init_waitqueue_head(&op->out_sleeper); init_waitqueue_head(&op->out_sleeper);
init_waitqueue_head(&op->poll_sleeper); init_waitqueue_head(&op->poll_sleeper);
...@@ -128,7 +127,7 @@ int sound_install_mixer(int vers, char *name, struct mixer_operations *driver, ...@@ -128,7 +127,7 @@ int sound_install_mixer(int vers, char *name, struct mixer_operations *driver,
/* FIXME: This leaks a mixer_operations struct every time its called /* FIXME: This leaks a mixer_operations struct every time its called
until you unload sound! */ until you unload sound! */
op = (struct mixer_operations *) (sound_mem_blocks[sound_nblocks] = vmalloc(sizeof(struct mixer_operations))); op = (struct mixer_operations *) (sound_mem_blocks[sound_nblocks] = vzalloc(sizeof(struct mixer_operations)));
sound_nblocks++; sound_nblocks++;
if (sound_nblocks >= MAX_MEM_BLOCKS) if (sound_nblocks >= MAX_MEM_BLOCKS)
sound_nblocks = MAX_MEM_BLOCKS - 1; sound_nblocks = MAX_MEM_BLOCKS - 1;
...@@ -137,7 +136,6 @@ int sound_install_mixer(int vers, char *name, struct mixer_operations *driver, ...@@ -137,7 +136,6 @@ int sound_install_mixer(int vers, char *name, struct mixer_operations *driver,
printk(KERN_ERR "Sound: Can't allocate mixer driver for (%s)\n", name); printk(KERN_ERR "Sound: Can't allocate mixer driver for (%s)\n", name);
return -ENOMEM; return -ENOMEM;
} }
memset((char *) op, 0, sizeof(struct mixer_operations));
memcpy((char *) op, (char *) driver, driver_size); memcpy((char *) op, (char *) driver, driver_size);
strlcpy(op->name, name, sizeof(op->name)); strlcpy(op->name, name, sizeof(op->name));
......
...@@ -178,7 +178,7 @@ int MIDIbuf_open(int dev, struct file *file) ...@@ -178,7 +178,7 @@ int MIDIbuf_open(int dev, struct file *file)
return err; return err;
parms[dev].prech_timeout = MAX_SCHEDULE_TIMEOUT; parms[dev].prech_timeout = MAX_SCHEDULE_TIMEOUT;
midi_in_buf[dev] = (struct midi_buf *) vmalloc(sizeof(struct midi_buf)); midi_in_buf[dev] = vmalloc(sizeof(struct midi_buf));
if (midi_in_buf[dev] == NULL) if (midi_in_buf[dev] == NULL)
{ {
...@@ -188,7 +188,7 @@ int MIDIbuf_open(int dev, struct file *file) ...@@ -188,7 +188,7 @@ int MIDIbuf_open(int dev, struct file *file)
} }
midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0; midi_in_buf[dev]->len = midi_in_buf[dev]->head = midi_in_buf[dev]->tail = 0;
midi_out_buf[dev] = (struct midi_buf *) vmalloc(sizeof(struct midi_buf)); midi_out_buf[dev] = vmalloc(sizeof(struct midi_buf));
if (midi_out_buf[dev] == NULL) if (midi_out_buf[dev] == NULL)
{ {
......
...@@ -859,7 +859,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, ...@@ -859,7 +859,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg,
return 0; return 0;
case SNDCTL_COPR_LOAD: case SNDCTL_COPR_LOAD:
buf = (copr_buffer *) vmalloc(sizeof(copr_buffer)); buf = vmalloc(sizeof(copr_buffer));
if (buf == NULL) if (buf == NULL)
return -ENOSPC; return -ENOSPC;
if (copy_from_user(buf, arg, sizeof(copr_buffer))) { if (copy_from_user(buf, arg, sizeof(copr_buffer))) {
...@@ -871,7 +871,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, ...@@ -871,7 +871,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg,
return err; return err;
case SNDCTL_COPR_SENDMSG: case SNDCTL_COPR_SENDMSG:
mbuf = (copr_msg *)vmalloc(sizeof(copr_msg)); mbuf = vmalloc(sizeof(copr_msg));
if (mbuf == NULL) if (mbuf == NULL)
return -ENOSPC; return -ENOSPC;
if (copy_from_user(mbuf, arg, sizeof(copr_msg))) { if (copy_from_user(mbuf, arg, sizeof(copr_msg))) {
...@@ -895,7 +895,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg, ...@@ -895,7 +895,7 @@ static int pss_coproc_ioctl(void *dev_info, unsigned int cmd, void __user *arg,
case SNDCTL_COPR_RCVMSG: case SNDCTL_COPR_RCVMSG:
err = 0; err = 0;
mbuf = (copr_msg *)vmalloc(sizeof(copr_msg)); mbuf = vmalloc(sizeof(copr_msg));
if (mbuf == NULL) if (mbuf == NULL)
return -ENOSPC; return -ENOSPC;
data = (unsigned short *)mbuf->data; data = (unsigned short *)mbuf->data;
......
...@@ -1646,13 +1646,13 @@ void sequencer_init(void) ...@@ -1646,13 +1646,13 @@ void sequencer_init(void)
{ {
if (sequencer_ok) if (sequencer_ok)
return; return;
queue = (unsigned char *)vmalloc(SEQ_MAX_QUEUE * EV_SZ); queue = vmalloc(SEQ_MAX_QUEUE * EV_SZ);
if (queue == NULL) if (queue == NULL)
{ {
printk(KERN_ERR "sequencer: Can't allocate memory for sequencer output queue\n"); printk(KERN_ERR "sequencer: Can't allocate memory for sequencer output queue\n");
return; return;
} }
iqueue = (unsigned char *)vmalloc(SEQ_MAX_QUEUE * IEV_SZ); iqueue = vmalloc(SEQ_MAX_QUEUE * IEV_SZ);
if (iqueue == NULL) if (iqueue == NULL)
{ {
printk(KERN_ERR "sequencer: Can't allocate memory for sequencer input queue\n"); printk(KERN_ERR "sequencer: Can't allocate memory for sequencer input queue\n");
......
...@@ -435,7 +435,7 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev) ...@@ -435,7 +435,7 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev)
struct hpi_message hm; struct hpi_message hm;
struct hpi_response hr; struct hpi_response hr;
struct hpi_adapter *pa; struct hpi_adapter *pa;
pa = (struct hpi_adapter *)pci_get_drvdata(pci_dev); pa = pci_get_drvdata(pci_dev);
hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM,
HPI_SUBSYS_DELETE_ADAPTER); HPI_SUBSYS_DELETE_ADAPTER);
......
...@@ -1129,10 +1129,11 @@ snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip, ...@@ -1129,10 +1129,11 @@ snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip,
count_areas = size/2; count_areas = size/2;
addr_area2 = addr+count_areas; addr_area2 = addr+count_areas;
count_areas--; /* max. index */
snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n", snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n",
addr, count_areas, addr_area2, count_areas); addr, count_areas, addr_area2, count_areas);
count_areas--; /* max. index */
/* build combined I/O buffer length word */ /* build combined I/O buffer length word */
lengths = (count_areas << 16) | (count_areas); lengths = (count_areas << 16) | (count_areas);
spin_lock_irqsave(&chip->reg_lock, flags); spin_lock_irqsave(&chip->reg_lock, flags);
...@@ -1740,11 +1741,15 @@ static const struct snd_pcm_hardware snd_azf3328_hardware = ...@@ -1740,11 +1741,15 @@ static const struct snd_pcm_hardware snd_azf3328_hardware =
.rate_max = AZF_FREQ_66200, .rate_max = AZF_FREQ_66200,
.channels_min = 1, .channels_min = 1,
.channels_max = 2, .channels_max = 2,
.buffer_bytes_max = 65536, .buffer_bytes_max = (64*1024),
.period_bytes_min = 64, .period_bytes_min = 1024,
.period_bytes_max = 65536, .period_bytes_max = (32*1024),
.periods_min = 1, /* We simply have two DMA areas (instead of a list of descriptors
.periods_max = 1024, such as other cards); I believe that this is a fixed hardware
attribute and there isn't much driver magic to be done to expand it.
Thus indicate that we have at least and at most 2 periods. */
.periods_min = 2,
.periods_max = 2,
/* FIXME: maybe that card actually has a FIFO? /* FIXME: maybe that card actually has a FIFO?
* Hmm, it seems newer revisions do have one, but we still don't know * Hmm, it seems newer revisions do have one, but we still don't know
* its size... */ * its size... */
...@@ -1980,8 +1985,13 @@ snd_azf3328_timer_stop(struct snd_timer *timer) ...@@ -1980,8 +1985,13 @@ snd_azf3328_timer_stop(struct snd_timer *timer)
chip = snd_timer_chip(timer); chip = snd_timer_chip(timer);
spin_lock_irqsave(&chip->reg_lock, flags); spin_lock_irqsave(&chip->reg_lock, flags);
/* disable timer countdown and interrupt */ /* disable timer countdown and interrupt */
/* FIXME: should we write TIMER_IRQ_ACK here? */ /* Hmm, should we write TIMER_IRQ_ACK here?
snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0); YES indeed, otherwise a rogue timer operation - which prompts
ALSA(?) to call repeated stop() in vain, but NOT start() -
will never end (value 0x03 is kept shown in control byte).
Simply manually poking 0x04 _once_ immediately successfully stops
the hardware/ALSA interrupt activity. */
snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x04);
spin_unlock_irqrestore(&chip->reg_lock, flags); spin_unlock_irqrestore(&chip->reg_lock, flags);
snd_azf3328_dbgcallleave(); snd_azf3328_dbgcallleave();
return 0; return 0;
......
...@@ -129,8 +129,6 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream) ...@@ -129,8 +129,6 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream)
apcm->substream = substream; apcm->substream = substream;
apcm->interrupt = ct_atc_pcm_interrupt; apcm->interrupt = ct_atc_pcm_interrupt;
runtime->private_data = apcm;
runtime->private_free = ct_atc_pcm_free_substream;
if (IEC958 == substream->pcm->device) { if (IEC958 == substream->pcm->device) {
runtime->hw = ct_spdif_passthru_playback_hw; runtime->hw = ct_spdif_passthru_playback_hw;
atc->spdif_out_passthru(atc, 1); atc->spdif_out_passthru(atc, 1);
...@@ -155,8 +153,12 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream) ...@@ -155,8 +153,12 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream)
} }
apcm->timer = ct_timer_instance_new(atc->timer, apcm); apcm->timer = ct_timer_instance_new(atc->timer, apcm);
if (!apcm->timer) if (!apcm->timer) {
kfree(apcm);
return -ENOMEM; return -ENOMEM;
}
runtime->private_data = apcm;
runtime->private_free = ct_atc_pcm_free_substream;
return 0; return 0;
} }
...@@ -278,8 +280,6 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream) ...@@ -278,8 +280,6 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
apcm->started = 0; apcm->started = 0;
apcm->substream = substream; apcm->substream = substream;
apcm->interrupt = ct_atc_pcm_interrupt; apcm->interrupt = ct_atc_pcm_interrupt;
runtime->private_data = apcm;
runtime->private_free = ct_atc_pcm_free_substream;
runtime->hw = ct_pcm_capture_hw; runtime->hw = ct_pcm_capture_hw;
runtime->hw.rate_max = atc->rsr * atc->msr; runtime->hw.rate_max = atc->rsr * atc->msr;
...@@ -298,8 +298,12 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream) ...@@ -298,8 +298,12 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
} }
apcm->timer = ct_timer_instance_new(atc->timer, apcm); apcm->timer = ct_timer_instance_new(atc->timer, apcm);
if (!apcm->timer) if (!apcm->timer) {
kfree(apcm);
return -ENOMEM; return -ENOMEM;
}
runtime->private_data = apcm;
runtime->private_free = ct_atc_pcm_free_substream;
return 0; return 0;
} }
......
...@@ -3100,6 +3100,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { ...@@ -3100,6 +3100,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_HP_LAPTOP),
SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5),
...@@ -3110,6 +3111,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { ...@@ -3110,6 +3111,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x390a, "Lenovo S10-3t", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x390a, "Lenovo S10-3t", CXT5066_IDEAPAD),
......
...@@ -14623,7 +14623,10 @@ static int alc275_setup_dual_adc(struct hda_codec *codec) ...@@ -14623,7 +14623,10 @@ static int alc275_setup_dual_adc(struct hda_codec *codec)
/* different alc269-variants */ /* different alc269-variants */
enum { enum {
ALC269_TYPE_NORMAL, ALC269_TYPE_NORMAL,
ALC269_TYPE_ALC258,
ALC269_TYPE_ALC259, ALC269_TYPE_ALC259,
ALC269_TYPE_ALC269VB,
ALC269_TYPE_ALC270,
ALC269_TYPE_ALC271X, ALC269_TYPE_ALC271X,
}; };
...@@ -15023,7 +15026,7 @@ static int alc269_fill_coef(struct hda_codec *codec) ...@@ -15023,7 +15026,7 @@ static int alc269_fill_coef(struct hda_codec *codec)
static int patch_alc269(struct hda_codec *codec) static int patch_alc269(struct hda_codec *codec)
{ {
struct alc_spec *spec; struct alc_spec *spec;
int board_config; int board_config, coef;
int err; int err;
spec = kzalloc(sizeof(*spec), GFP_KERNEL); spec = kzalloc(sizeof(*spec), GFP_KERNEL);
...@@ -15034,14 +15037,23 @@ static int patch_alc269(struct hda_codec *codec) ...@@ -15034,14 +15037,23 @@ static int patch_alc269(struct hda_codec *codec)
alc_auto_parse_customize_define(codec); alc_auto_parse_customize_define(codec);
if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){ coef = alc_read_coef_idx(codec, 0);
if ((coef & 0x00f0) == 0x0010) {
if (codec->bus->pci->subsystem_vendor == 0x1025 && if (codec->bus->pci->subsystem_vendor == 0x1025 &&
spec->cdefine.platform_type == 1) { spec->cdefine.platform_type == 1) {
alc_codec_rename(codec, "ALC271X"); alc_codec_rename(codec, "ALC271X");
spec->codec_variant = ALC269_TYPE_ALC271X; spec->codec_variant = ALC269_TYPE_ALC271X;
} else { } else if ((coef & 0xf000) == 0x1000) {
spec->codec_variant = ALC269_TYPE_ALC270;
} else if ((coef & 0xf000) == 0x2000) {
alc_codec_rename(codec, "ALC259"); alc_codec_rename(codec, "ALC259");
spec->codec_variant = ALC269_TYPE_ALC259; spec->codec_variant = ALC269_TYPE_ALC259;
} else if ((coef & 0xf000) == 0x3000) {
alc_codec_rename(codec, "ALC258");
spec->codec_variant = ALC269_TYPE_ALC258;
} else {
alc_codec_rename(codec, "ALC269VB");
spec->codec_variant = ALC269_TYPE_ALC269VB;
} }
} else } else
alc_fix_pll_init(codec, 0x20, 0x04, 15); alc_fix_pll_init(codec, 0x20, 0x04, 15);
...@@ -15104,7 +15116,7 @@ static int patch_alc269(struct hda_codec *codec) ...@@ -15104,7 +15116,7 @@ static int patch_alc269(struct hda_codec *codec)
spec->stream_digital_capture = &alc269_pcm_digital_capture; spec->stream_digital_capture = &alc269_pcm_digital_capture;
if (!spec->adc_nids) { /* wasn't filled automatically? use default */ if (!spec->adc_nids) { /* wasn't filled automatically? use default */
if (spec->codec_variant != ALC269_TYPE_NORMAL) { if (spec->codec_variant == ALC269_TYPE_NORMAL) {
spec->adc_nids = alc269_adc_nids; spec->adc_nids = alc269_adc_nids;
spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
spec->capsrc_nids = alc269_capsrc_nids; spec->capsrc_nids = alc269_capsrc_nids;
...@@ -19298,6 +19310,7 @@ static const struct alc_fixup alc662_fixups[] = { ...@@ -19298,6 +19310,7 @@ static const struct alc_fixup alc662_fixups[] = {
static struct snd_pci_quirk alc662_fixup_tbl[] = { static struct snd_pci_quirk alc662_fixup_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
{} {}
...@@ -19419,7 +19432,10 @@ static int patch_alc888(struct hda_codec *codec) ...@@ -19419,7 +19432,10 @@ static int patch_alc888(struct hda_codec *codec)
{ {
if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){ if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
kfree(codec->chip_name); kfree(codec->chip_name);
codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL); if (codec->vendor_id == 0x10ec0887)
codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
else
codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
if (!codec->chip_name) { if (!codec->chip_name) {
alc_free(codec); alc_free(codec);
return -ENOMEM; return -ENOMEM;
...@@ -19909,7 +19925,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { ...@@ -19909,7 +19925,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
.patch = patch_alc882 }, .patch = patch_alc882 },
{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
{ .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
{ .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
.patch = patch_alc882 }, .patch = patch_alc882 },
{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
......
...@@ -389,6 +389,11 @@ static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { ...@@ -389,6 +389,11 @@ static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = {
0x11, 0x20, 0 0x11, 0x20, 0
}; };
#define STAC92HD87B_NUM_DMICS 1
static hda_nid_t stac92hd87b_dmic_nids[STAC92HD87B_NUM_DMICS + 1] = {
0x11, 0
};
#define STAC92HD83XXX_NUM_CAPS 2 #define STAC92HD83XXX_NUM_CAPS 2
static unsigned long stac92hd83xxx_capvols[] = { static unsigned long stac92hd83xxx_capvols[] = {
HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
...@@ -3486,10 +3491,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, ...@@ -3486,10 +3491,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
return err; return err;
} }
if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) { if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
snd_hda_add_imux_item(imux, label, index, NULL); snd_hda_add_imux_item(imux, label, index, NULL);
spec->num_analog_muxes++;
}
} }
return 0; return 0;
...@@ -5452,12 +5455,17 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) ...@@ -5452,12 +5455,17 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
stac92hd83xxx_brd_tbl[spec->board_config]); stac92hd83xxx_brd_tbl[spec->board_config]);
switch (codec->vendor_id) { switch (codec->vendor_id) {
case 0x111d76d1:
case 0x111d76d9:
spec->dmic_nids = stac92hd87b_dmic_nids;
spec->num_dmics = stac92xx_connected_ports(codec,
stac92hd87b_dmic_nids,
STAC92HD87B_NUM_DMICS);
/* Fall through */
case 0x111d7666: case 0x111d7666:
case 0x111d7667: case 0x111d7667:
case 0x111d7668: case 0x111d7668:
case 0x111d7669: case 0x111d7669:
case 0x111d76d1:
case 0x111d76d9:
spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids); spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
spec->pin_nids = stac92hd88xxx_pin_nids; spec->pin_nids = stac92hd88xxx_pin_nids;
spec->mono_nid = 0; spec->mono_nid = 0;
......
...@@ -1864,6 +1864,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { ...@@ -1864,6 +1864,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
.name = "Dell Inspiron 8600", /* STAC9750/51 */ .name = "Dell Inspiron 8600", /* STAC9750/51 */
.type = AC97_TUNE_HP_ONLY .type = AC97_TUNE_HP_ONLY
}, },
{
.subvendor = 0x1028,
.subdevice = 0x0182,
.name = "Dell Latitude D610", /* STAC9750/51 */
.type = AC97_TUNE_HP_ONLY
},
{ {
.subvendor = 0x1028, .subvendor = 0x1028,
.subdevice = 0x0186, .subdevice = 0x0186,
......
...@@ -25,11 +25,21 @@ ...@@ -25,11 +25,21 @@
#include <sound/hwdep.h> #include <sound/hwdep.h>
#ifndef readl_be
#define readl_be(x) be32_to_cpu(__raw_readl(x)) #define readl_be(x) be32_to_cpu(__raw_readl(x))
#endif
#ifndef writel_be
#define writel_be(data,addr) __raw_writel(cpu_to_be32(data),addr) #define writel_be(data,addr) __raw_writel(cpu_to_be32(data),addr)
#endif
#ifndef readl_le
#define readl_le(x) le32_to_cpu(__raw_readl(x)) #define readl_le(x) le32_to_cpu(__raw_readl(x))
#endif
#ifndef writel_le
#define writel_le(data,addr) __raw_writel(cpu_to_le32(data),addr) #define writel_le(data,addr) __raw_writel(cpu_to_le32(data),addr)
#endif
#define MIXART_MEM(mgr,x) ((mgr)->mem[0].virt + (x)) #define MIXART_MEM(mgr,x) ((mgr)->mem[0].virt + (x))
#define MIXART_REG(mgr,x) ((mgr)->mem[1].virt + (x)) #define MIXART_REG(mgr,x) ((mgr)->mem[1].virt + (x))
......
...@@ -1228,10 +1228,8 @@ int __devinit snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return) ...@@ -1228,10 +1228,8 @@ int __devinit snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
chip->rsrc[i].start + 1, chip->rsrc[i].start + 1,
rnames[i]) == NULL) { rnames[i]) == NULL) {
printk(KERN_ERR "snd: can't request rsrc " printk(KERN_ERR "snd: can't request rsrc "
" %d (%s: 0x%016llx:%016llx)\n", " %d (%s: %pR)\n",
i, rnames[i], i, rnames[i], &chip->rsrc[i]);
(unsigned long long)chip->rsrc[i].start,
(unsigned long long)chip->rsrc[i].end);
err = -ENODEV; err = -ENODEV;
goto __error; goto __error;
} }
...@@ -1256,10 +1254,8 @@ int __devinit snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return) ...@@ -1256,10 +1254,8 @@ int __devinit snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return)
chip->rsrc[i].start + 1, chip->rsrc[i].start + 1,
rnames[i]) == NULL) { rnames[i]) == NULL) {
printk(KERN_ERR "snd: can't request rsrc " printk(KERN_ERR "snd: can't request rsrc "
" %d (%s: 0x%016llx:%016llx)\n", " %d (%s: %pR)\n",
i, rnames[i], i, rnames[i], &chip->rsrc[i]);
(unsigned long long)chip->rsrc[i].start,
(unsigned long long)chip->rsrc[i].end);
err = -ENODEV; err = -ENODEV;
goto __error; goto __error;
} }
......
...@@ -16,7 +16,8 @@ config SND_ATMEL_SOC_SSC ...@@ -16,7 +16,8 @@ config SND_ATMEL_SOC_SSC
config SND_AT91_SOC_SAM9G20_WM8731 config SND_AT91_SOC_SAM9G20_WM8731
tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board" tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC && \
AT91_PROGRAMMABLE_CLOCKS
select SND_ATMEL_SOC_SSC select SND_ATMEL_SOC_SSC
select SND_SOC_WM8731 select SND_SOC_WM8731
help help
...@@ -25,7 +26,7 @@ config SND_AT91_SOC_SAM9G20_WM8731 ...@@ -25,7 +26,7 @@ config SND_AT91_SOC_SAM9G20_WM8731
config SND_AT32_SOC_PLAYPAQ config SND_AT32_SOC_PLAYPAQ
tristate "SoC Audio support for PlayPaq with WM8510" tristate "SoC Audio support for PlayPaq with WM8510"
depends on SND_ATMEL_SOC && BOARD_PLAYPAQ depends on SND_ATMEL_SOC && BOARD_PLAYPAQ && AT91_PROGRAMMABLE_CLOCKS
select SND_ATMEL_SOC_SSC select SND_ATMEL_SOC_SSC
select SND_SOC_WM8510 select SND_SOC_WM8510
help help
......
...@@ -28,6 +28,11 @@ ...@@ -28,6 +28,11 @@
#include <sound/max98088.h> #include <sound/max98088.h>
#include "max98088.h" #include "max98088.h"
enum max98088_type {
MAX98088,
MAX98089,
};
struct max98088_cdata { struct max98088_cdata {
unsigned int rate; unsigned int rate;
unsigned int fmt; unsigned int fmt;
...@@ -36,6 +41,7 @@ struct max98088_cdata { ...@@ -36,6 +41,7 @@ struct max98088_cdata {
struct max98088_priv { struct max98088_priv {
u8 reg_cache[M98088_REG_CNT]; u8 reg_cache[M98088_REG_CNT];
enum max98088_type devtype;
void *control_data; void *control_data;
struct max98088_pdata *pdata; struct max98088_pdata *pdata;
unsigned int sysclk; unsigned int sysclk;
...@@ -2040,6 +2046,8 @@ static int max98088_i2c_probe(struct i2c_client *i2c, ...@@ -2040,6 +2046,8 @@ static int max98088_i2c_probe(struct i2c_client *i2c,
if (max98088 == NULL) if (max98088 == NULL)
return -ENOMEM; return -ENOMEM;
max98088->devtype = id->driver_data;
i2c_set_clientdata(i2c, max98088); i2c_set_clientdata(i2c, max98088);
max98088->control_data = i2c; max98088->control_data = i2c;
max98088->pdata = i2c->dev.platform_data; max98088->pdata = i2c->dev.platform_data;
...@@ -2059,7 +2067,8 @@ static int __devexit max98088_i2c_remove(struct i2c_client *client) ...@@ -2059,7 +2067,8 @@ static int __devexit max98088_i2c_remove(struct i2c_client *client)
} }
static const struct i2c_device_id max98088_i2c_id[] = { static const struct i2c_device_id max98088_i2c_id[] = {
{ "max98088", 0 }, { "max98088", MAX98088 },
{ "max98089", MAX98089 },
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, max98088_i2c_id); MODULE_DEVICE_TABLE(i2c, max98088_i2c_id);
......
...@@ -597,6 +597,7 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = { ...@@ -597,6 +597,7 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = {
.resume = uda134x_soc_resume, .resume = uda134x_soc_resume,
.reg_cache_size = sizeof(uda134x_reg), .reg_cache_size = sizeof(uda134x_reg),
.reg_word_size = sizeof(u8), .reg_word_size = sizeof(u8),
.reg_cache_default = uda134x_reg,
.reg_cache_step = 1, .reg_cache_step = 1,
.read = uda134x_read_reg_cache, .read = uda134x_read_reg_cache,
.write = uda134x_write, .write = uda134x_write,
......
...@@ -831,7 +831,7 @@ static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai, ...@@ -831,7 +831,7 @@ static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
} }
/* MCLK direction */ /* MCLK direction */
if (dir == WM8350_MCLK_DIR_OUT) if (dir == SND_SOC_CLOCK_OUT)
wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2, wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2,
WM8350_MCLK_DIR); WM8350_MCLK_DIR);
else else
...@@ -1586,6 +1586,13 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) ...@@ -1586,6 +1586,13 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME, wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
WM8350_OUT2_VU | WM8350_OUT2R_MUTE); WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
/* Make sure AIF tristating is disabled by default */
wm8350_clear_bits(wm8350, WM8350_AI_FORMATING, WM8350_AIF_TRI);
/* Make sure we've got a sane companding setup too */
wm8350_clear_bits(wm8350, WM8350_ADC_DAC_COMP,
WM8350_DAC_COMP | WM8350_LOOPBACK);
/* Make sure jack detect is disabled to start off with */ /* Make sure jack detect is disabled to start off with */
wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
WM8350_JDL_ENA | WM8350_JDR_ENA); WM8350_JDL_ENA | WM8350_JDR_ENA);
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
/* codec private data */ /* codec private data */
struct wm8776_priv { struct wm8776_priv {
enum snd_soc_control_type control_type; enum snd_soc_control_type control_type;
u16 reg_cache[WM8776_CACHEREGNUM];
int sysclk[2]; int sysclk[2];
}; };
......
...@@ -3500,8 +3500,11 @@ static ssize_t wm8962_beep_set(struct device *dev, ...@@ -3500,8 +3500,11 @@ static ssize_t wm8962_beep_set(struct device *dev,
{ {
struct wm8962_priv *wm8962 = dev_get_drvdata(dev); struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
long int time; long int time;
int ret;
strict_strtol(buf, 10, &time); ret = strict_strtol(buf, 10, &time);
if (ret != 0)
return ret;
input_event(wm8962->beep, EV_SND, SND_TONE, time); input_event(wm8962->beep, EV_SND, SND_TONE, time);
......
...@@ -3903,6 +3903,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) ...@@ -3903,6 +3903,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
return -ENOMEM; return -ENOMEM;
snd_soc_codec_set_drvdata(codec, wm8994); snd_soc_codec_set_drvdata(codec, wm8994);
codec->reg_cache = &wm8994->reg_cache;
wm8994->pdata = dev_get_platdata(codec->dev->parent); wm8994->pdata = dev_get_platdata(codec->dev->parent);
wm8994->codec = codec; wm8994->codec = codec;
......
...@@ -157,12 +157,23 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) ...@@ -157,12 +157,23 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
} }
/* davinci-evm digital audio interface glue - connects codec <--> CPU */ /* davinci-evm digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link evm_dai = { static struct snd_soc_dai_link dm6446_evm_dai = {
.name = "TLV320AIC3X", .name = "TLV320AIC3X",
.stream_name = "AIC3X", .stream_name = "AIC3X",
.cpu_dai_name = "davinci-mcasp.0", .cpu_dai_name = "davinci-mcbsp",
.codec_dai_name = "tlv320aic3x-hifi", .codec_dai_name = "tlv320aic3x-hifi",
.codec_name = "tlv320aic3x-codec.0-001a", .codec_name = "tlv320aic3x-codec.1-001b",
.platform_name = "davinci-pcm-audio",
.init = evm_aic3x_init,
.ops = &evm_ops,
};
static struct snd_soc_dai_link dm355_evm_dai = {
.name = "TLV320AIC3X",
.stream_name = "AIC3X",
.cpu_dai_name = "davinci-mcbsp.1",
.codec_dai_name = "tlv320aic3x-hifi",
.codec_name = "tlv320aic3x-codec.1-001b",
.platform_name = "davinci-pcm-audio", .platform_name = "davinci-pcm-audio",
.init = evm_aic3x_init, .init = evm_aic3x_init,
.ops = &evm_ops, .ops = &evm_ops,
...@@ -172,10 +183,10 @@ static struct snd_soc_dai_link dm365_evm_dai = { ...@@ -172,10 +183,10 @@ static struct snd_soc_dai_link dm365_evm_dai = {
#ifdef CONFIG_SND_DM365_AIC3X_CODEC #ifdef CONFIG_SND_DM365_AIC3X_CODEC
.name = "TLV320AIC3X", .name = "TLV320AIC3X",
.stream_name = "AIC3X", .stream_name = "AIC3X",
.cpu_dai_name = "davinci-i2s", .cpu_dai_name = "davinci-mcbsp",
.codec_dai_name = "tlv320aic3x-hifi", .codec_dai_name = "tlv320aic3x-hifi",
.init = evm_aic3x_init, .init = evm_aic3x_init,
.codec_name = "tlv320aic3x-codec.0-001a", .codec_name = "tlv320aic3x-codec.1-0018",
.ops = &evm_ops, .ops = &evm_ops,
#elif defined(CONFIG_SND_DM365_VOICE_CODEC) #elif defined(CONFIG_SND_DM365_VOICE_CODEC)
.name = "Voice Codec - CQ93VC", .name = "Voice Codec - CQ93VC",
...@@ -219,10 +230,17 @@ static struct snd_soc_dai_link da8xx_evm_dai = { ...@@ -219,10 +230,17 @@ static struct snd_soc_dai_link da8xx_evm_dai = {
.ops = &evm_ops, .ops = &evm_ops,
}; };
/* davinci dm6446, dm355 evm audio machine driver */ /* davinci dm6446 evm audio machine driver */
static struct snd_soc_card snd_soc_card_evm = { static struct snd_soc_card dm6446_snd_soc_card_evm = {
.name = "DaVinci EVM", .name = "DaVinci DM6446 EVM",
.dai_link = &evm_dai, .dai_link = &dm6446_evm_dai,
.num_links = 1,
};
/* davinci dm355 evm audio machine driver */
static struct snd_soc_card dm355_snd_soc_card_evm = {
.name = "DaVinci DM355 EVM",
.dai_link = &dm355_evm_dai,
.num_links = 1, .num_links = 1,
}; };
...@@ -261,10 +279,10 @@ static int __init evm_init(void) ...@@ -261,10 +279,10 @@ static int __init evm_init(void)
int ret; int ret;
if (machine_is_davinci_evm()) { if (machine_is_davinci_evm()) {
evm_snd_dev_data = &snd_soc_card_evm; evm_snd_dev_data = &dm6446_snd_soc_card_evm;
index = 0; index = 0;
} else if (machine_is_davinci_dm355_evm()) { } else if (machine_is_davinci_dm355_evm()) {
evm_snd_dev_data = &snd_soc_card_evm; evm_snd_dev_data = &dm355_snd_soc_card_evm;
index = 1; index = 1;
} else if (machine_is_davinci_dm365_evm()) { } else if (machine_is_davinci_dm365_evm()) {
evm_snd_dev_data = &dm365_snd_soc_card_evm; evm_snd_dev_data = &dm365_snd_soc_card_evm;
......
...@@ -426,9 +426,6 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -426,9 +426,6 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
snd_pcm_format_t fmt; snd_pcm_format_t fmt;
unsigned element_cnt = 1; unsigned element_cnt = 1;
dai->capture_dma_data = dev->dma_params;
dai->playback_dma_data = dev->dma_params;
/* general line settings */ /* general line settings */
spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
...@@ -601,6 +598,15 @@ static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -601,6 +598,15 @@ static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
return ret; return ret;
} }
static int davinci_i2s_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(dai);
snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
return 0;
}
static void davinci_i2s_shutdown(struct snd_pcm_substream *substream, static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
...@@ -612,6 +618,7 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream, ...@@ -612,6 +618,7 @@ static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 #define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
static struct snd_soc_dai_ops davinci_i2s_dai_ops = { static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
.startup = davinci_i2s_startup,
.shutdown = davinci_i2s_shutdown, .shutdown = davinci_i2s_shutdown,
.prepare = davinci_i2s_prepare, .prepare = davinci_i2s_prepare,
.trigger = davinci_i2s_trigger, .trigger = davinci_i2s_trigger,
...@@ -749,7 +756,7 @@ static struct platform_driver davinci_mcbsp_driver = { ...@@ -749,7 +756,7 @@ static struct platform_driver davinci_mcbsp_driver = {
.probe = davinci_i2s_probe, .probe = davinci_i2s_probe,
.remove = davinci_i2s_remove, .remove = davinci_i2s_remove,
.driver = { .driver = {
.name = "davinci-i2s", .name = "davinci-mcbsp",
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
}; };
......
...@@ -715,9 +715,6 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, ...@@ -715,9 +715,6 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
int word_length; int word_length;
u8 fifo_level; u8 fifo_level;
cpu_dai->capture_dma_data = dev->dma_params;
cpu_dai->playback_dma_data = dev->dma_params;
davinci_hw_common_param(dev, substream->stream); davinci_hw_common_param(dev, substream->stream);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
fifo_level = dev->txnumevt; fifo_level = dev->txnumevt;
...@@ -799,7 +796,17 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, ...@@ -799,7 +796,17 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
return ret; return ret;
} }
static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct davinci_audio_dev *dev = snd_soc_dai_get_drvdata(dai);
snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
return 0;
}
static struct snd_soc_dai_ops davinci_mcasp_dai_ops = { static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
.startup = davinci_mcasp_startup,
.trigger = davinci_mcasp_trigger, .trigger = davinci_mcasp_trigger,
.hw_params = davinci_mcasp_hw_params, .hw_params = davinci_mcasp_hw_params,
.set_fmt = davinci_mcasp_set_dai_fmt, .set_fmt = davinci_mcasp_set_dai_fmt,
......
...@@ -84,7 +84,7 @@ static struct snd_soc_ops sffsdr_ops = { ...@@ -84,7 +84,7 @@ static struct snd_soc_ops sffsdr_ops = {
static struct snd_soc_dai_link sffsdr_dai = { static struct snd_soc_dai_link sffsdr_dai = {
.name = "PCM3008", /* Codec name */ .name = "PCM3008", /* Codec name */
.stream_name = "PCM3008 HiFi", .stream_name = "PCM3008 HiFi",
.cpu_dai_name = "davinci-asp.0", .cpu_dai_name = "davinci-mcbsp",
.codec_dai_name = "pcm3008-hifi", .codec_dai_name = "pcm3008-hifi",
.codec_name = "pcm3008-codec", .codec_name = "pcm3008-codec",
.platform_name = "davinci-pcm-audio", .platform_name = "davinci-pcm-audio",
......
...@@ -97,9 +97,6 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream, ...@@ -97,9 +97,6 @@ static int davinci_vcif_hw_params(struct snd_pcm_substream *substream,
&davinci_vcif_dev->dma_params[substream->stream]; &davinci_vcif_dev->dma_params[substream->stream];
u32 w; u32 w;
dai->capture_dma_data = davinci_vcif_dev->dma_params;
dai->playback_dma_data = davinci_vcif_dev->dma_params;
/* Restart the codec before setup */ /* Restart the codec before setup */
davinci_vcif_stop(substream); davinci_vcif_stop(substream);
davinci_vcif_start(substream); davinci_vcif_start(substream);
...@@ -174,9 +171,19 @@ static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -174,9 +171,19 @@ static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd,
return ret; return ret;
} }
static int davinci_vcif_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct davinci_vcif_dev *dev = snd_soc_dai_get_drvdata(dai);
snd_soc_dai_set_dma_data(dai, substream, dev->dma_params);
return 0;
}
#define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000 #define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000
static struct snd_soc_dai_ops davinci_vcif_dai_ops = { static struct snd_soc_dai_ops davinci_vcif_dai_ops = {
.startup = davinci_vcif_startup,
.trigger = davinci_vcif_trigger, .trigger = davinci_vcif_trigger,
.hw_params = davinci_vcif_hw_params, .hw_params = davinci_vcif_hw_params,
}; };
......
...@@ -160,7 +160,7 @@ static int __devinit psc_i2s_of_probe(struct platform_device *op, ...@@ -160,7 +160,7 @@ static int __devinit psc_i2s_of_probe(struct platform_device *op,
rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai)); rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai));
if (rc != 0) { if (rc != 0) {
pr_err("Failed to register DAI\n"); pr_err("Failed to register DAI\n");
return 0; return rc;
} }
psc_dma = dev_get_drvdata(&op->dev); psc_dma = dev_get_drvdata(&op->dev);
......
...@@ -34,8 +34,8 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream, ...@@ -34,8 +34,8 @@ static int eukrea_tlv320_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params) struct snd_pcm_hw_params *params)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret; int ret;
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
...@@ -79,10 +79,10 @@ static struct snd_soc_ops eukrea_tlv320_snd_ops = { ...@@ -79,10 +79,10 @@ static struct snd_soc_ops eukrea_tlv320_snd_ops = {
static struct snd_soc_dai_link eukrea_tlv320_dai = { static struct snd_soc_dai_link eukrea_tlv320_dai = {
.name = "tlv320aic23", .name = "tlv320aic23",
.stream_name = "TLV320AIC23", .stream_name = "TLV320AIC23",
.codec_dai = "tlv320aic23-hifi", .codec_dai_name = "tlv320aic23-hifi",
.platform_name = "imx-pcm-audio.0", .platform_name = "imx-pcm-audio.0",
.codec_name = "tlv320aic23-codec.0-001a", .codec_name = "tlv320aic23-codec.0-001a",
.cpu_dai = "imx-ssi.0", .cpu_dai_name = "imx-ssi.0",
.ops = &eukrea_tlv320_snd_ops, .ops = &eukrea_tlv320_snd_ops,
}; };
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/dmaengine.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/initval.h> #include <sound/initval.h>
...@@ -27,165 +28,146 @@ ...@@ -27,165 +28,146 @@
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <mach/dma-mx1-mx2.h> #include <mach/dma.h>
#include "imx-ssi.h" #include "imx-ssi.h"
struct imx_pcm_runtime_data { struct imx_pcm_runtime_data {
int sg_count; int period_bytes;
struct scatterlist *sg_list;
int period;
int periods; int periods;
unsigned long dma_addr;
int dma; int dma;
struct snd_pcm_substream *substream;
unsigned long offset; unsigned long offset;
unsigned long size; unsigned long size;
unsigned long period_cnt;
void *buf; void *buf;
int period_time; int period_time;
struct dma_async_tx_descriptor *desc;
struct dma_chan *dma_chan;
struct imx_dma_data dma_data;
}; };
/* Called by the DMA framework when a period has elapsed */ static void audio_dma_irq(void *data)
static void imx_ssi_dma_progression(int channel, void *data,
struct scatterlist *sg)
{ {
struct snd_pcm_substream *substream = data; struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data; struct imx_pcm_runtime_data *iprtd = runtime->private_data;
if (!sg) iprtd->offset += iprtd->period_bytes;
return; iprtd->offset %= iprtd->period_bytes * iprtd->periods;
runtime = iprtd->substream->runtime;
iprtd->offset = sg->dma_address - runtime->dma_addr; snd_pcm_period_elapsed(substream);
snd_pcm_period_elapsed(iprtd->substream);
} }
static void imx_ssi_dma_callback(int channel, void *data) static bool filter(struct dma_chan *chan, void *param)
{ {
pr_err("%s shouldn't be called\n", __func__); struct imx_pcm_runtime_data *iprtd = param;
}
static void snd_imx_dma_err_callback(int channel, void *data, int err) if (!imx_dma_is_general_purpose(chan))
{ return false;
struct snd_pcm_substream *substream = data;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct imx_pcm_dma_params *dma_params =
snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data;
int ret;
pr_err("DMA timeout on channel %d -%s%s%s%s\n", chan->private = &iprtd->dma_data;
channel,
err & IMX_DMA_ERR_BURST ? " burst" : "",
err & IMX_DMA_ERR_REQUEST ? " request" : "",
err & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
err & IMX_DMA_ERR_BUFFER ? " buffer" : "");
imx_dma_disable(iprtd->dma); return true;
ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
DMA_MODE_WRITE : DMA_MODE_READ);
if (!ret)
imx_dma_enable(iprtd->dma);
} }
static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct imx_pcm_dma_params *dma_params; struct imx_pcm_dma_params *dma_params;
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data; struct imx_pcm_runtime_data *iprtd = runtime->private_data;
struct dma_slave_config slave_config;
dma_cap_mask_t mask;
enum dma_slave_buswidth buswidth;
int ret; int ret;
dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); iprtd->dma_data.peripheral_type = IMX_DMATYPE_SSI;
if (iprtd->dma < 0) { iprtd->dma_data.priority = DMA_PRIO_HIGH;
pr_err("Failed to claim the audio DMA\n"); iprtd->dma_data.dma_request = dma_params->dma;
return -ENODEV;
}
ret = imx_dma_setup_handlers(iprtd->dma, /* Try to grab a DMA channel */
imx_ssi_dma_callback, dma_cap_zero(mask);
snd_imx_dma_err_callback, substream); dma_cap_set(DMA_SLAVE, mask);
if (ret) iprtd->dma_chan = dma_request_channel(mask, filter, iprtd);
goto out; if (!iprtd->dma_chan)
return -EINVAL;
ret = imx_dma_setup_progression_handler(iprtd->dma, switch (params_format(params)) {
imx_ssi_dma_progression); case SNDRV_PCM_FORMAT_S16_LE:
if (ret) { buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
pr_err("Failed to setup the DMA handler\n"); break;
goto out; case SNDRV_PCM_FORMAT_S20_3LE:
case SNDRV_PCM_FORMAT_S24_LE:
buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
break;
default:
return 0;
} }
ret = imx_dma_config_channel(iprtd->dma, if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO, slave_config.direction = DMA_TO_DEVICE;
IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR, slave_config.dst_addr = dma_params->dma_addr;
dma_params->dma, 1); slave_config.dst_addr_width = buswidth;
if (ret < 0) { slave_config.dst_maxburst = dma_params->burstsize;
pr_err("Cannot configure DMA channel: %d\n", ret); } else {
goto out; slave_config.direction = DMA_FROM_DEVICE;
slave_config.src_addr = dma_params->dma_addr;
slave_config.src_addr_width = buswidth;
slave_config.src_maxburst = dma_params->burstsize;
} }
imx_dma_config_burstlen(iprtd->dma, dma_params->burstsize * 2); ret = dmaengine_slave_config(iprtd->dma_chan, &slave_config);
if (ret)
return ret;
return 0; return 0;
out:
imx_dma_free(iprtd->dma);
return ret;
} }
static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params) struct snd_pcm_hw_params *params)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data; struct imx_pcm_runtime_data *iprtd = runtime->private_data;
int i;
unsigned long dma_addr; unsigned long dma_addr;
struct dma_chan *chan;
struct imx_pcm_dma_params *dma_params;
int ret;
imx_ssi_dma_alloc(substream); dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
ret = imx_ssi_dma_alloc(substream, params);
if (ret)
return ret;
chan = iprtd->dma_chan;
iprtd->size = params_buffer_bytes(params); iprtd->size = params_buffer_bytes(params);
iprtd->periods = params_periods(params); iprtd->periods = params_periods(params);
iprtd->period = params_period_bytes(params); iprtd->period_bytes = params_period_bytes(params);
iprtd->offset = 0; iprtd->offset = 0;
iprtd->period_time = HZ / (params_rate(params) / iprtd->period_time = HZ / (params_rate(params) /
params_period_size(params)); params_period_size(params));
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
if (iprtd->sg_count != iprtd->periods) {
kfree(iprtd->sg_list);
iprtd->sg_list = kcalloc(iprtd->periods + 1,
sizeof(struct scatterlist), GFP_KERNEL);
if (!iprtd->sg_list)
return -ENOMEM;
iprtd->sg_count = iprtd->periods + 1;
}
sg_init_table(iprtd->sg_list, iprtd->sg_count);
dma_addr = runtime->dma_addr; dma_addr = runtime->dma_addr;
for (i = 0; i < iprtd->periods; i++) { iprtd->buf = (unsigned int *)substream->dma_buffer.area;
iprtd->sg_list[i].page_link = 0;
iprtd->sg_list[i].offset = 0; iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr,
iprtd->sg_list[i].dma_address = dma_addr; iprtd->period_bytes * iprtd->periods,
iprtd->sg_list[i].length = iprtd->period; iprtd->period_bytes,
dma_addr += iprtd->period; substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
DMA_TO_DEVICE : DMA_FROM_DEVICE);
if (!iprtd->desc) {
dev_err(&chan->dev->device, "cannot prepare slave dma\n");
return -EINVAL;
} }
/* close the loop */ iprtd->desc->callback = audio_dma_irq;
iprtd->sg_list[iprtd->sg_count - 1].offset = 0; iprtd->desc->callback_param = substream;
iprtd->sg_list[iprtd->sg_count - 1].length = 0;
iprtd->sg_list[iprtd->sg_count - 1].page_link =
((unsigned long) iprtd->sg_list | 0x01) & ~0x02;
return 0; return 0;
} }
...@@ -194,41 +176,21 @@ static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream) ...@@ -194,41 +176,21 @@ static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data; struct imx_pcm_runtime_data *iprtd = runtime->private_data;
if (iprtd->dma >= 0) { if (iprtd->dma_chan) {
imx_dma_free(iprtd->dma); dma_release_channel(iprtd->dma_chan);
iprtd->dma = -EINVAL; iprtd->dma_chan = NULL;
} }
kfree(iprtd->sg_list);
iprtd->sg_list = NULL;
return 0; return 0;
} }
static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream) static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
{ {
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct imx_pcm_dma_params *dma_params; struct imx_pcm_dma_params *dma_params;
struct imx_pcm_runtime_data *iprtd = runtime->private_data;
int err;
dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
iprtd->substream = substream;
iprtd->buf = (unsigned int *)substream->dma_buffer.area;
iprtd->period_cnt = 0;
pr_debug("%s: buf: %p period: %d periods: %d\n",
__func__, iprtd->buf, iprtd->period, iprtd->periods);
err = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
DMA_MODE_WRITE : DMA_MODE_READ);
if (err)
return err;
return 0; return 0;
} }
...@@ -241,14 +203,14 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) ...@@ -241,14 +203,14 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
imx_dma_enable(iprtd->dma); dmaengine_submit(iprtd->desc);
break; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
imx_dma_disable(iprtd->dma); dmaengine_terminate_all(iprtd->dma_chan);
break; break;
default: default:
...@@ -263,6 +225,9 @@ static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream ...@@ -263,6 +225,9 @@ static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data; struct imx_pcm_runtime_data *iprtd = runtime->private_data;
pr_debug("%s: %ld %ld\n", __func__, iprtd->offset,
bytes_to_frames(substream->runtime, iprtd->offset));
return bytes_to_frames(substream->runtime, iprtd->offset); return bytes_to_frames(substream->runtime, iprtd->offset);
} }
...@@ -279,7 +244,7 @@ static struct snd_pcm_hardware snd_imx_hardware = { ...@@ -279,7 +244,7 @@ static struct snd_pcm_hardware snd_imx_hardware = {
.channels_max = 2, .channels_max = 2,
.buffer_bytes_max = IMX_SSI_DMABUF_SIZE, .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
.period_bytes_min = 128, .period_bytes_min = 128,
.period_bytes_max = 16 * 1024, .period_bytes_max = 65535, /* Limited by SDMA engine */
.periods_min = 2, .periods_min = 2,
.periods_max = 255, .periods_max = 255,
.fifo_size = 0, .fifo_size = 0,
...@@ -304,11 +269,23 @@ static int snd_imx_open(struct snd_pcm_substream *substream) ...@@ -304,11 +269,23 @@ static int snd_imx_open(struct snd_pcm_substream *substream)
} }
snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware); snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
return 0;
}
static int snd_imx_close(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data;
kfree(iprtd);
return 0; return 0;
} }
static struct snd_pcm_ops imx_pcm_ops = { static struct snd_pcm_ops imx_pcm_ops = {
.open = snd_imx_open, .open = snd_imx_open,
.close = snd_imx_close,
.ioctl = snd_pcm_lib_ioctl, .ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_imx_pcm_hw_params, .hw_params = snd_imx_pcm_hw_params,
.hw_free = snd_imx_pcm_hw_free, .hw_free = snd_imx_pcm_hw_free,
...@@ -340,7 +317,6 @@ static struct platform_driver imx_pcm_driver = { ...@@ -340,7 +317,6 @@ static struct platform_driver imx_pcm_driver = {
.name = "imx-pcm-audio", .name = "imx-pcm-audio",
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = imx_soc_platform_probe, .probe = imx_soc_platform_probe,
.remove = __devexit_p(imx_soc_platform_remove), .remove = __devexit_p(imx_soc_platform_remove),
}; };
...@@ -356,4 +332,3 @@ static void __exit snd_imx_pcm_exit(void) ...@@ -356,4 +332,3 @@ static void __exit snd_imx_pcm_exit(void)
platform_driver_unregister(&imx_pcm_driver); platform_driver_unregister(&imx_pcm_driver);
} }
module_exit(snd_imx_pcm_exit); module_exit(snd_imx_pcm_exit);
...@@ -439,7 +439,22 @@ void imx_pcm_free(struct snd_pcm *pcm) ...@@ -439,7 +439,22 @@ void imx_pcm_free(struct snd_pcm *pcm)
} }
EXPORT_SYMBOL_GPL(imx_pcm_free); EXPORT_SYMBOL_GPL(imx_pcm_free);
static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
{
struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
uint32_t val;
snd_soc_dai_set_drvdata(dai, ssi);
val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
writel(val, ssi->base + SSI_SFCSR);
return 0;
}
static struct snd_soc_dai_driver imx_ssi_dai = { static struct snd_soc_dai_driver imx_ssi_dai = {
.probe = imx_ssi_dai_probe,
.playback = { .playback = {
.channels_min = 2, .channels_min = 2,
.channels_max = 2, .channels_max = 2,
...@@ -455,20 +470,6 @@ static struct snd_soc_dai_driver imx_ssi_dai = { ...@@ -455,20 +470,6 @@ static struct snd_soc_dai_driver imx_ssi_dai = {
.ops = &imx_ssi_pcm_dai_ops, .ops = &imx_ssi_pcm_dai_ops,
}; };
static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
{
struct imx_ssi *ssi = dev_get_drvdata(dai->dev);
uint32_t val;
snd_soc_dai_set_drvdata(dai, ssi);
val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
writel(val, ssi->base + SSI_SFCSR);
return 0;
}
static struct snd_soc_dai_driver imx_ac97_dai = { static struct snd_soc_dai_driver imx_ac97_dai = {
.probe = imx_ssi_dai_probe, .probe = imx_ssi_dai_probe,
.ac97_control = 1, .ac97_control = 1,
...@@ -677,7 +678,17 @@ static int imx_ssi_probe(struct platform_device *pdev) ...@@ -677,7 +678,17 @@ static int imx_ssi_probe(struct platform_device *pdev)
goto failed_register; goto failed_register;
} }
ssi->soc_platform_pdev = platform_device_alloc("imx-fiq-pcm-audio", pdev->id); ssi->soc_platform_pdev_fiq = platform_device_alloc("imx-fiq-pcm-audio", pdev->id);
if (!ssi->soc_platform_pdev_fiq)
goto failed_pdev_fiq_alloc;
platform_set_drvdata(ssi->soc_platform_pdev_fiq, ssi);
ret = platform_device_add(ssi->soc_platform_pdev_fiq);
if (ret) {
dev_err(&pdev->dev, "failed to add platform device\n");
goto failed_pdev_fiq_add;
}
ssi->soc_platform_pdev = platform_device_alloc("imx-pcm-audio", pdev->id);
if (!ssi->soc_platform_pdev) if (!ssi->soc_platform_pdev)
goto failed_pdev_alloc; goto failed_pdev_alloc;
platform_set_drvdata(ssi->soc_platform_pdev, ssi); platform_set_drvdata(ssi->soc_platform_pdev, ssi);
...@@ -692,6 +703,9 @@ static int imx_ssi_probe(struct platform_device *pdev) ...@@ -692,6 +703,9 @@ static int imx_ssi_probe(struct platform_device *pdev)
failed_pdev_add: failed_pdev_add:
platform_device_put(ssi->soc_platform_pdev); platform_device_put(ssi->soc_platform_pdev);
failed_pdev_alloc: failed_pdev_alloc:
failed_pdev_fiq_add:
platform_device_put(ssi->soc_platform_pdev_fiq);
failed_pdev_fiq_alloc:
snd_soc_unregister_dai(&pdev->dev); snd_soc_unregister_dai(&pdev->dev);
failed_register: failed_register:
failed_ac97: failed_ac97:
......
...@@ -185,6 +185,9 @@ ...@@ -185,6 +185,9 @@
#define DRV_NAME "imx-ssi" #define DRV_NAME "imx-ssi"
#include <linux/dmaengine.h>
#include <mach/dma.h>
struct imx_pcm_dma_params { struct imx_pcm_dma_params {
int dma; int dma;
unsigned long dma_addr; unsigned long dma_addr;
...@@ -212,6 +215,7 @@ struct imx_ssi { ...@@ -212,6 +215,7 @@ struct imx_ssi {
int enabled; int enabled;
struct platform_device *soc_platform_pdev; struct platform_device *soc_platform_pdev;
struct platform_device *soc_platform_pdev_fiq;
}; };
struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev, struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
......
...@@ -20,9 +20,6 @@ ...@@ -20,9 +20,6 @@
#include <sound/soc-dapm.h> #include <sound/soc-dapm.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include "../codecs/wm9712.h"
#include "imx-ssi.h"
static struct snd_soc_card imx_phycore; static struct snd_soc_card imx_phycore;
static struct snd_soc_ops imx_phycore_hifi_ops = { static struct snd_soc_ops imx_phycore_hifi_ops = {
...@@ -41,7 +38,7 @@ static struct snd_soc_dai_link imx_phycore_dai_ac97[] = { ...@@ -41,7 +38,7 @@ static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
}; };
static struct snd_soc_card imx_phycore = { static struct snd_soc_card imx_phycore = {
.name = "PhyCORE-audio", .name = "PhyCORE-ac97-audio",
.dai_link = imx_phycore_dai_ac97, .dai_link = imx_phycore_dai_ac97,
.num_links = ARRAY_SIZE(imx_phycore_dai_ac97), .num_links = ARRAY_SIZE(imx_phycore_dai_ac97),
}; };
......
...@@ -644,15 +644,23 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, ...@@ -644,15 +644,23 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
case OMAP_MCBSP_CLKR_SRC_CLKR: case OMAP_MCBSP_CLKR_SRC_CLKR:
if (cpu_class_is_omap1())
break;
omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKR); omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKR);
break; break;
case OMAP_MCBSP_CLKR_SRC_CLKX: case OMAP_MCBSP_CLKR_SRC_CLKX:
if (cpu_class_is_omap1())
break;
omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKX); omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKX);
break; break;
case OMAP_MCBSP_FSR_SRC_FSR: case OMAP_MCBSP_FSR_SRC_FSR:
if (cpu_class_is_omap1())
break;
omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSR); omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSR);
break; break;
case OMAP_MCBSP_FSR_SRC_FSX: case OMAP_MCBSP_FSR_SRC_FSX:
if (cpu_class_is_omap1())
break;
omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSX); omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSX);
break; break;
default: default:
......
...@@ -100,8 +100,13 @@ static int corgi_startup(struct snd_pcm_substream *substream) ...@@ -100,8 +100,13 @@ static int corgi_startup(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec; struct snd_soc_codec *codec = rtd->codec;
mutex_lock(&codec->mutex);
/* check the jack status at stream startup */ /* check the jack status at stream startup */
corgi_ext_control(codec); corgi_ext_control(codec);
mutex_unlock(&codec->mutex);
return 0; return 0;
} }
......
...@@ -72,9 +72,13 @@ static int magician_startup(struct snd_pcm_substream *substream) ...@@ -72,9 +72,13 @@ static int magician_startup(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec; struct snd_soc_codec *codec = rtd->codec;
mutex_lock(&codec->mutex);
/* check the jack status at stream startup */ /* check the jack status at stream startup */
magician_ext_control(codec); magician_ext_control(codec);
mutex_unlock(&codec->mutex);
return 0; return 0;
} }
......
...@@ -77,8 +77,13 @@ static int poodle_startup(struct snd_pcm_substream *substream) ...@@ -77,8 +77,13 @@ static int poodle_startup(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec; struct snd_soc_codec *codec = rtd->codec;
mutex_lock(&codec->mutex);
/* check the jack status at stream startup */ /* check the jack status at stream startup */
poodle_ext_control(codec); poodle_ext_control(codec);
mutex_unlock(&codec->mutex);
return 0; return 0;
} }
......
...@@ -108,8 +108,13 @@ static int spitz_startup(struct snd_pcm_substream *substream) ...@@ -108,8 +108,13 @@ static int spitz_startup(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec; struct snd_soc_codec *codec = rtd->codec;
mutex_lock(&codec->mutex);
/* check the jack status at stream startup */ /* check the jack status at stream startup */
spitz_ext_control(codec); spitz_ext_control(codec);
mutex_unlock(&codec->mutex);
return 0; return 0;
} }
......
...@@ -81,8 +81,13 @@ static int tosa_startup(struct snd_pcm_substream *substream) ...@@ -81,8 +81,13 @@ static int tosa_startup(struct snd_pcm_substream *substream)
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_codec *codec = rtd->codec; struct snd_soc_codec *codec = rtd->codec;
mutex_lock(&codec->mutex);
/* check the jack status at stream startup */ /* check the jack status at stream startup */
tosa_ext_control(codec); tosa_ext_control(codec);
mutex_unlock(&codec->mutex);
return 0; return 0;
} }
......
...@@ -2,6 +2,7 @@ config SND_S3C24XX_SOC ...@@ -2,6 +2,7 @@ config SND_S3C24XX_SOC
tristate "SoC Audio for the Samsung S3CXXXX chips" tristate "SoC Audio for the Samsung S3CXXXX chips"
depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210
select S3C64XX_DMA if ARCH_S3C64XX select S3C64XX_DMA if ARCH_S3C64XX
select S3C2410_DMA if ARCH_S3C2410
help help
Say Y or M if you want to add support for codecs attached to Say Y or M if you want to add support for codecs attached to
the S3C24XX AC97 or I2S interfaces. You will also need to the S3C24XX AC97 or I2S interfaces. You will also need to
......
...@@ -50,7 +50,6 @@ static unsigned int rates[] = { ...@@ -50,7 +50,6 @@ static unsigned int rates[] = {
16000, 16000,
44100, 44100,
48000, 48000,
88200,
}; };
static struct snd_pcm_hw_constraint_list hw_rates = { static struct snd_pcm_hw_constraint_list hw_rates = {
...@@ -130,7 +129,6 @@ static const struct snd_soc_dapm_route audio_map[] = { ...@@ -130,7 +129,6 @@ static const struct snd_soc_dapm_route audio_map[] = {
}; };
static struct platform_device *s3c24xx_snd_device; static struct platform_device *s3c24xx_snd_device;
static struct clk *xtal;
static int rx1950_startup(struct snd_pcm_substream *substream) static int rx1950_startup(struct snd_pcm_substream *substream)
{ {
...@@ -179,10 +177,8 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream, ...@@ -179,10 +177,8 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
case 44100: case 44100:
case 88200: case 88200:
clk_source = S3C24XX_CLKSRC_MPLL; clk_source = S3C24XX_CLKSRC_MPLL;
fs_mode = S3C2410_IISMOD_256FS; fs_mode = S3C2410_IISMOD_384FS;
div = clk_get_rate(xtal) / (256 * rate); div = 1;
if (clk_get_rate(xtal) % (256 * rate) > (128 * rate))
div++;
break; break;
default: default:
printk(KERN_ERR "%s: rate %d is not supported\n", printk(KERN_ERR "%s: rate %d is not supported\n",
...@@ -210,7 +206,7 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream, ...@@ -210,7 +206,7 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
/* set MCLK division for sample rate */ /* set MCLK division for sample rate */
ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
S3C2410_IISMOD_384FS); fs_mode);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -295,17 +291,8 @@ static int __init rx1950_init(void) ...@@ -295,17 +291,8 @@ static int __init rx1950_init(void)
goto err_plat_add; goto err_plat_add;
} }
xtal = clk_get(&s3c24xx_snd_device->dev, "xtal");
if (IS_ERR(xtal)) {
ret = PTR_ERR(xtal);
platform_device_unregister(s3c24xx_snd_device);
goto err_clk;
}
return 0; return 0;
err_clk:
err_plat_add: err_plat_add:
err_plat_alloc: err_plat_alloc:
err_gpio_conf: err_gpio_conf:
...@@ -320,7 +307,6 @@ static void __exit rx1950_exit(void) ...@@ -320,7 +307,6 @@ static void __exit rx1950_exit(void)
platform_device_unregister(s3c24xx_snd_device); platform_device_unregister(s3c24xx_snd_device);
snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
hp_jack_gpios); hp_jack_gpios);
clk_put(xtal);
gpio_free(S3C2410_GPA(1)); gpio_free(S3C2410_GPA(1));
} }
......
...@@ -3043,8 +3043,10 @@ int snd_soc_register_dais(struct device *dev, ...@@ -3043,8 +3043,10 @@ int snd_soc_register_dais(struct device *dev,
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); dai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL);
if (dai == NULL) if (dai == NULL) {
return -ENOMEM; ret = -ENOMEM;
goto err;
}
/* create DAI component name */ /* create DAI component name */
dai->name = fmt_multiple_name(dev, &dai_drv[i]); dai->name = fmt_multiple_name(dev, &dai_drv[i]);
...@@ -3263,9 +3265,6 @@ int snd_soc_register_codec(struct device *dev, ...@@ -3263,9 +3265,6 @@ int snd_soc_register_codec(struct device *dev,
return 0; return 0;
error: error:
for (i--; i >= 0; i--)
snd_soc_unregister_dai(dev);
if (codec->reg_cache) if (codec->reg_cache)
kfree(codec->reg_cache); kfree(codec->reg_cache);
kfree(codec->name); kfree(codec->name);
......
...@@ -683,12 +683,12 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a, ...@@ -683,12 +683,12 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
struct snd_soc_dapm_widget *b, struct snd_soc_dapm_widget *b,
int sort[]) int sort[])
{ {
if (a->codec != b->codec)
return (unsigned long)a - (unsigned long)b;
if (sort[a->id] != sort[b->id]) if (sort[a->id] != sort[b->id])
return sort[a->id] - sort[b->id]; return sort[a->id] - sort[b->id];
if (a->reg != b->reg) if (a->reg != b->reg)
return a->reg - b->reg; return a->reg - b->reg;
if (a->codec != b->codec)
return (unsigned long)a->codec - (unsigned long)b->codec;
return 0; return 0;
} }
......
...@@ -155,7 +155,7 @@ static int snd_at73c213_set_bitrate(struct snd_at73c213 *chip) ...@@ -155,7 +155,7 @@ static int snd_at73c213_set_bitrate(struct snd_at73c213 *chip)
if (max_tries < 1) if (max_tries < 1)
max_tries = 1; max_tries = 1;
/* ssc_div must be a power of 2. */ /* ssc_div must be even. */
ssc_div = (ssc_div + 1) & ~1UL; ssc_div = (ssc_div + 1) & ~1UL;
if ((ssc_rate / (ssc_div * 2 * 16)) < BITRATE_MIN) { if ((ssc_rate / (ssc_div * 2 * 16)) < BITRATE_MIN) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册