Merge branch 'for-linus' into for-next

Back-merge from for-linus just to make the further development easier.
This commit is contained in:
Takashi Iwai 2016-09-11 09:33:12 +02:00
commit 3d2f4d0c0d
576 changed files with 7217 additions and 3231 deletions

View file

@ -1633,11 +1633,13 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
return -EBUSY;
}
list_add_tail(&rmidi->list, &snd_rawmidi_devices);
mutex_unlock(&register_mutex);
err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI,
rmidi->card, rmidi->device,
&snd_rawmidi_f_ops, rmidi, &rmidi->dev);
if (err < 0) {
rmidi_err(rmidi, "unable to register\n");
mutex_lock(&register_mutex);
list_del(&rmidi->list);
mutex_unlock(&register_mutex);
return err;
@ -1645,6 +1647,7 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
if (rmidi->ops && rmidi->ops->dev_register &&
(err = rmidi->ops->dev_register(rmidi)) < 0) {
snd_unregister_device(&rmidi->dev);
mutex_lock(&register_mutex);
list_del(&rmidi->list);
mutex_unlock(&register_mutex);
return err;
@ -1677,7 +1680,6 @@ static int snd_rawmidi_dev_register(struct snd_device *device)
}
}
#endif /* CONFIG_SND_OSSEMUL */
mutex_unlock(&register_mutex);
sprintf(name, "midi%d", rmidi->device);
entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root);
if (entry) {

View file

@ -35,6 +35,9 @@
#include <sound/initval.h>
#include <linux/kmod.h>
/* internal flags */
#define SNDRV_TIMER_IFLG_PAUSED 0x00010000
#if IS_ENABLED(CONFIG_SND_HRTIMER)
#define DEFAULT_TIMER_LIMIT 4
#else
@ -294,8 +297,21 @@ int snd_timer_open(struct snd_timer_instance **ti,
get_device(&timer->card->card_dev);
timeri->slave_class = tid->dev_sclass;
timeri->slave_id = slave_id;
if (list_empty(&timer->open_list_head) && timer->hw.open)
timer->hw.open(timer);
if (list_empty(&timer->open_list_head) && timer->hw.open) {
int err = timer->hw.open(timer);
if (err) {
kfree(timeri->owner);
kfree(timeri);
if (timer->card)
put_device(&timer->card->card_dev);
module_put(timer->module);
mutex_unlock(&register_mutex);
return err;
}
}
list_add_tail(&timeri->open_list, &timer->open_list_head);
snd_timer_check_master(timeri);
mutex_unlock(&register_mutex);
@ -526,6 +542,10 @@ static int snd_timer_stop1(struct snd_timer_instance *timeri, bool stop)
}
}
timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START);
if (stop)
timeri->flags &= ~SNDRV_TIMER_IFLG_PAUSED;
else
timeri->flags |= SNDRV_TIMER_IFLG_PAUSED;
snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP :
SNDRV_TIMER_EVENT_CONTINUE);
unlock:
@ -587,6 +607,10 @@ int snd_timer_stop(struct snd_timer_instance *timeri)
*/
int snd_timer_continue(struct snd_timer_instance *timeri)
{
/* timer can continue only after pause */
if (!(timeri->flags & SNDRV_TIMER_IFLG_PAUSED))
return -EINVAL;
if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE)
return snd_timer_start_slave(timeri, false);
else
@ -813,6 +837,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid,
timer->tmr_subdevice = tid->subdevice;
if (id)
strlcpy(timer->id, id, sizeof(timer->id));
timer->sticks = 1;
INIT_LIST_HEAD(&timer->device_list);
INIT_LIST_HEAD(&timer->open_list_head);
INIT_LIST_HEAD(&timer->active_list_head);
@ -1817,6 +1842,9 @@ static int snd_timer_user_continue(struct file *file)
tu = file->private_data;
if (!tu->timeri)
return -EBADFD;
/* start timer instead of continue if it's not used before */
if (!(tu->timeri->flags & SNDRV_TIMER_IFLG_PAUSED))
return snd_timer_user_start(file);
tu->timeri->lost = 0;
return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0;
}
@ -1958,6 +1986,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
tu->qused--;
spin_unlock_irq(&tu->qlock);
mutex_lock(&tu->ioctl_lock);
if (tu->tread) {
if (copy_to_user(buffer, &tu->tqueue[qhead],
sizeof(struct snd_timer_tread)))
@ -1967,6 +1996,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
sizeof(struct snd_timer_read)))
err = -EFAULT;
}
mutex_unlock(&tu->ioctl_lock);
spin_lock_irq(&tu->qlock);
if (err < 0)

View file

@ -108,7 +108,6 @@ struct snd_efw {
u8 *resp_buf;
u8 *pull_ptr;
u8 *push_ptr;
unsigned int resp_queues;
};
int snd_efw_transaction_cmd(struct fw_unit *unit,

View file

@ -25,6 +25,7 @@ hwdep_read_resp_buf(struct snd_efw *efw, char __user *buf, long remained,
{
unsigned int length, till_end, type;
struct snd_efw_transaction *t;
u8 *pull_ptr;
long count = 0;
if (remained < sizeof(type) + sizeof(struct snd_efw_transaction))
@ -38,8 +39,17 @@ hwdep_read_resp_buf(struct snd_efw *efw, char __user *buf, long remained,
buf += sizeof(type);
/* write into buffer as many responses as possible */
while (efw->resp_queues > 0) {
t = (struct snd_efw_transaction *)(efw->pull_ptr);
spin_lock_irq(&efw->lock);
/*
* When another task reaches here during this task's access to user
* space, it picks up current position in buffer and can read the same
* series of responses.
*/
pull_ptr = efw->pull_ptr;
while (efw->push_ptr != pull_ptr) {
t = (struct snd_efw_transaction *)(pull_ptr);
length = be32_to_cpu(t->length) * sizeof(__be32);
/* confirm enough space for this response */
@ -49,26 +59,39 @@ hwdep_read_resp_buf(struct snd_efw *efw, char __user *buf, long remained,
/* copy from ring buffer to user buffer */
while (length > 0) {
till_end = snd_efw_resp_buf_size -
(unsigned int)(efw->pull_ptr - efw->resp_buf);
(unsigned int)(pull_ptr - efw->resp_buf);
till_end = min_t(unsigned int, length, till_end);
if (copy_to_user(buf, efw->pull_ptr, till_end))
spin_unlock_irq(&efw->lock);
if (copy_to_user(buf, pull_ptr, till_end))
return -EFAULT;
efw->pull_ptr += till_end;
if (efw->pull_ptr >= efw->resp_buf +
snd_efw_resp_buf_size)
efw->pull_ptr -= snd_efw_resp_buf_size;
spin_lock_irq(&efw->lock);
pull_ptr += till_end;
if (pull_ptr >= efw->resp_buf + snd_efw_resp_buf_size)
pull_ptr -= snd_efw_resp_buf_size;
length -= till_end;
buf += till_end;
count += till_end;
remained -= till_end;
}
efw->resp_queues--;
}
/*
* All of tasks can read from the buffer nearly simultaneously, but the
* last position for each task is different depending on the length of
* given buffer. Here, for simplicity, a position of buffer is set by
* the latest task. It's better for a listening application to allow one
* thread to read from the buffer. Unless, each task can read different
* sequence of responses depending on variation of buffer length.
*/
efw->pull_ptr = pull_ptr;
spin_unlock_irq(&efw->lock);
return count;
}
@ -76,14 +99,17 @@ static long
hwdep_read_locked(struct snd_efw *efw, char __user *buf, long count,
loff_t *offset)
{
union snd_firewire_event event;
union snd_firewire_event event = {
.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS,
};
memset(&event, 0, sizeof(event));
spin_lock_irq(&efw->lock);
event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
event.lock_status.status = (efw->dev_lock_count > 0);
efw->dev_lock_changed = false;
spin_unlock_irq(&efw->lock);
count = min_t(long, count, sizeof(event.lock_status));
if (copy_to_user(buf, &event, count))
@ -98,10 +124,15 @@ hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
{
struct snd_efw *efw = hwdep->private_data;
DEFINE_WAIT(wait);
bool dev_lock_changed;
bool queued;
spin_lock_irq(&efw->lock);
while ((!efw->dev_lock_changed) && (efw->resp_queues == 0)) {
dev_lock_changed = efw->dev_lock_changed;
queued = efw->push_ptr != efw->pull_ptr;
while (!dev_lock_changed && !queued) {
prepare_to_wait(&efw->hwdep_wait, &wait, TASK_INTERRUPTIBLE);
spin_unlock_irq(&efw->lock);
schedule();
@ -109,15 +140,17 @@ hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
if (signal_pending(current))
return -ERESTARTSYS;
spin_lock_irq(&efw->lock);
dev_lock_changed = efw->dev_lock_changed;
queued = efw->push_ptr != efw->pull_ptr;
}
if (efw->dev_lock_changed)
count = hwdep_read_locked(efw, buf, count, offset);
else if (efw->resp_queues > 0)
count = hwdep_read_resp_buf(efw, buf, count, offset);
spin_unlock_irq(&efw->lock);
if (dev_lock_changed)
count = hwdep_read_locked(efw, buf, count, offset);
else if (queued)
count = hwdep_read_resp_buf(efw, buf, count, offset);
return count;
}
@ -160,7 +193,7 @@ hwdep_poll(struct snd_hwdep *hwdep, struct file *file, poll_table *wait)
poll_wait(file, &efw->hwdep_wait, wait);
spin_lock_irq(&efw->lock);
if (efw->dev_lock_changed || (efw->resp_queues > 0))
if (efw->dev_lock_changed || efw->pull_ptr != efw->push_ptr)
events = POLLIN | POLLRDNORM;
else
events = 0;

View file

@ -188,8 +188,8 @@ proc_read_queues_state(struct snd_info_entry *entry,
else
consumed = (unsigned int)(efw->push_ptr - efw->pull_ptr);
snd_iprintf(buffer, "%d %d/%d\n",
efw->resp_queues, consumed, snd_efw_resp_buf_size);
snd_iprintf(buffer, "%d/%d\n",
consumed, snd_efw_resp_buf_size);
}
static void

View file

@ -121,11 +121,11 @@ copy_resp_to_buf(struct snd_efw *efw, void *data, size_t length, int *rcode)
size_t capacity, till_end;
struct snd_efw_transaction *t;
spin_lock_irq(&efw->lock);
t = (struct snd_efw_transaction *)data;
length = min_t(size_t, be32_to_cpu(t->length) * sizeof(u32), length);
spin_lock_irq(&efw->lock);
if (efw->push_ptr < efw->pull_ptr)
capacity = (unsigned int)(efw->pull_ptr - efw->push_ptr);
else
@ -155,7 +155,6 @@ copy_resp_to_buf(struct snd_efw *efw, void *data, size_t length, int *rcode)
}
/* for hwdep */
efw->resp_queues++;
wake_up(&efw->hwdep_wait);
*rcode = RCODE_COMPLETE;

View file

@ -16,31 +16,14 @@
#include "tascam.h"
static long hwdep_read_locked(struct snd_tscm *tscm, char __user *buf,
long count)
{
union snd_firewire_event event;
memset(&event, 0, sizeof(event));
event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS;
event.lock_status.status = (tscm->dev_lock_count > 0);
tscm->dev_lock_changed = false;
count = min_t(long, count, sizeof(event.lock_status));
if (copy_to_user(buf, &event, count))
return -EFAULT;
return count;
}
static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
loff_t *offset)
{
struct snd_tscm *tscm = hwdep->private_data;
DEFINE_WAIT(wait);
union snd_firewire_event event;
union snd_firewire_event event = {
.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS,
};
spin_lock_irq(&tscm->lock);
@ -54,10 +37,16 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count,
spin_lock_irq(&tscm->lock);
}
memset(&event, 0, sizeof(event));
count = hwdep_read_locked(tscm, buf, count);
event.lock_status.status = (tscm->dev_lock_count > 0);
tscm->dev_lock_changed = false;
spin_unlock_irq(&tscm->lock);
count = min_t(long, count, sizeof(event.lock_status));
if (copy_to_user(buf, &event, count))
return -EFAULT;
return count;
}

View file

@ -907,20 +907,23 @@ static int azx_resume(struct device *dev)
struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip;
struct hda_intel *hda;
struct hdac_bus *bus;
if (!card)
return 0;
chip = card->private_data;
hda = container_of(chip, struct hda_intel, chip);
bus = azx_bus(chip);
if (chip->disabled || hda->init_failed || !chip->running)
return 0;
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
&& hda->need_i915_power) {
snd_hdac_display_power(azx_bus(chip), true);
snd_hdac_i915_set_bclk(azx_bus(chip));
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
snd_hdac_display_power(bus, true);
if (hda->need_i915_power)
snd_hdac_i915_set_bclk(bus);
}
if (chip->msi)
if (pci_enable_msi(pci) < 0)
chip->msi = 0;
@ -930,6 +933,11 @@ static int azx_resume(struct device *dev)
hda_intel_init_chip(chip, true);
/* power down again for link-controlled chips */
if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL) &&
!hda->need_i915_power)
snd_hdac_display_power(bus, false);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
trace_azx_resume(chip);
@ -1009,6 +1017,7 @@ static int azx_runtime_resume(struct device *dev)
chip = card->private_data;
hda = container_of(chip, struct hda_intel, chip);
bus = azx_bus(chip);
if (chip->disabled || hda->init_failed)
return 0;
@ -1016,15 +1025,9 @@ static int azx_runtime_resume(struct device *dev)
return 0;
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
bus = azx_bus(chip);
if (hda->need_i915_power) {
snd_hdac_display_power(bus, true);
snd_hdac_display_power(bus, true);
if (hda->need_i915_power)
snd_hdac_i915_set_bclk(bus);
} else {
/* toggle codec wakeup bit for STATESTS read */
snd_hdac_set_codec_wakeup(bus, true);
snd_hdac_set_codec_wakeup(bus, false);
}
}
/* Read STATESTS before controller reset */
@ -1044,6 +1047,11 @@ static int azx_runtime_resume(struct device *dev)
azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
~STATESTS_INT_MASK);
/* power down again for link-controlled chips */
if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL) &&
!hda->need_i915_power)
snd_hdac_display_power(bus, false);
trace_azx_runtime_resume(chip);
return 0;
}

View file

@ -4828,7 +4828,7 @@ enum {
ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC292_FIXUP_TPT440_DOCK,
ALC292_FIXUP_TPT440,
ALC283_FIXUP_BXBT2807_MIC,
ALC283_FIXUP_HEADSET_MIC,
ALC255_FIXUP_DELL_WMI_MIC_MUTE_LED,
ALC282_FIXUP_ASPIRE_V5_PINS,
ALC280_FIXUP_HP_GPIO4,
@ -4855,6 +4855,7 @@ enum {
ALC221_FIXUP_HP_FRONT_MIC,
ALC292_FIXUP_TPT460,
ALC298_FIXUP_SPK_VOLUME,
ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER,
};
static const struct hda_fixup alc269_fixups[] = {
@ -5323,7 +5324,7 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC292_FIXUP_TPT440_DOCK,
},
[ALC283_FIXUP_BXBT2807_MIC] = {
[ALC283_FIXUP_HEADSET_MIC] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
{ 0x19, 0x04a110f0 },
@ -5518,6 +5519,15 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
},
[ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
{ 0x1b, 0x90170151 },
{ }
},
.chained = true,
.chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
},
};
static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@ -5562,6 +5572,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER),
SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME),
@ -5653,7 +5664,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x10cf, 0x1757, "Lifebook E752", ALC269_FIXUP_LIFEBOOK_HP_PIN),
SND_PCI_QUIRK(0x10cf, 0x1845, "Lifebook U904", ALC269_FIXUP_LIFEBOOK_EXTMIC),
SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC),
SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_BXBT2807_MIC),
SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC),
SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
@ -5796,6 +5808,13 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
{0x14, 0x90170110}, \
{0x15, 0x0221401f}
#define ALC295_STANDARD_PINS \
{0x12, 0xb7a60130}, \
{0x14, 0x90170110}, \
{0x17, 0x21014020}, \
{0x18, 0x21a19030}, \
{0x21, 0x04211020}
#define ALC298_STANDARD_PINS \
{0x12, 0x90a60130}, \
{0x21, 0x03211020}
@ -5896,6 +5915,14 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
{0x12, 0x90a60170},
{0x14, 0x90170120},
{0x21, 0x02211030}),
SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell Inspiron 5468", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
{0x12, 0x90a60180},
{0x14, 0x90170120},
{0x21, 0x02211030}),
SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
{0x12, 0xb7a60130},
{0x14, 0x90170110},
{0x21, 0x02211020}),
SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC256_STANDARD_PINS),
SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
@ -6007,6 +6034,8 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC292_STANDARD_PINS,
{0x13, 0x90a60140}),
SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC295_STANDARD_PINS),
SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
ALC298_STANDARD_PINS,
{0x17, 0x90170110}),

View file

@ -299,8 +299,9 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream,
clk_enable(ssc_p->ssc->clk);
ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk);
/* Reset the SSC to keep it at a clean status */
ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
/* Reset the SSC unless initialized to keep it in a clean state */
if (!ssc_p->initialized)
ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
dir = 0;

View file

@ -1247,8 +1247,8 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
return -EINVAL;
}
/* By default only 32 BCLK per WCLK is supported */
dai_clk_mode |= DA7213_DAI_BCLKS_PER_WCLK_32;
/* By default only 64 BCLK per WCLK is supported */
dai_clk_mode |= DA7213_DAI_BCLKS_PER_WCLK_64;
snd_soc_write(codec, DA7213_DAI_CLK_MODE, dai_clk_mode);
snd_soc_update_bits(codec, DA7213_DAI_CTRL, DA7213_DAI_FORMAT_MASK,

View file

@ -412,6 +412,7 @@ static int max98371_i2c_remove(struct i2c_client *client)
static const struct i2c_device_id max98371_i2c_id[] = {
{ "max98371", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, max98371_i2c_id);

View file

@ -212,31 +212,6 @@ static const unsigned short logtable[256] = {
0xfa2f, 0xfaea, 0xfba5, 0xfc60, 0xfd1a, 0xfdd4, 0xfe8e, 0xff47
};
static struct snd_soc_dai *nau8825_get_codec_dai(struct nau8825 *nau8825)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(nau8825->dapm);
struct snd_soc_component *component = &codec->component;
struct snd_soc_dai *codec_dai, *_dai;
list_for_each_entry_safe(codec_dai, _dai, &component->dai_list, list) {
if (!strncmp(codec_dai->name, NUVOTON_CODEC_DAI,
strlen(NUVOTON_CODEC_DAI)))
return codec_dai;
}
return NULL;
}
static bool nau8825_dai_is_active(struct nau8825 *nau8825)
{
struct snd_soc_dai *codec_dai = nau8825_get_codec_dai(nau8825);
if (codec_dai) {
if (codec_dai->playback_active || codec_dai->capture_active)
return true;
}
return false;
}
/**
* nau8825_sema_acquire - acquire the semaphore of nau88l25
* @nau8825: component to register the codec private data with
@ -250,19 +225,26 @@ static bool nau8825_dai_is_active(struct nau8825 *nau8825)
* Acquires the semaphore without jiffies. If no more tasks are allowed
* to acquire the semaphore, calling this function will put the task to
* sleep until the semaphore is released.
* It returns if the semaphore was acquired.
* If the semaphore is not released within the specified number of jiffies,
* this function returns -ETIME.
* If the sleep is interrupted by a signal, this function will return -EINTR.
* It returns 0 if the semaphore was acquired successfully.
*/
static void nau8825_sema_acquire(struct nau8825 *nau8825, long timeout)
static int nau8825_sema_acquire(struct nau8825 *nau8825, long timeout)
{
int ret;
if (timeout)
if (timeout) {
ret = down_timeout(&nau8825->xtalk_sem, timeout);
else
if (ret < 0)
dev_warn(nau8825->dev, "Acquire semaphone timeout\n");
} else {
ret = down_interruptible(&nau8825->xtalk_sem);
if (ret < 0)
dev_warn(nau8825->dev, "Acquire semaphone fail\n");
}
if (ret < 0)
dev_warn(nau8825->dev, "Acquire semaphone fail\n");
return ret;
}
/**
@ -1205,6 +1187,8 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
unsigned int val_len = 0;
nau8825_sema_acquire(nau8825, 2 * HZ);
switch (params_width(params)) {
case 16:
val_len |= NAU8825_I2S_DL_16;
@ -1225,6 +1209,9 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1,
NAU8825_I2S_DL_MASK, val_len);
/* Release the semaphone. */
nau8825_sema_release(nau8825);
return 0;
}
@ -1234,6 +1221,8 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
unsigned int ctrl1_val = 0, ctrl2_val = 0;
nau8825_sema_acquire(nau8825, 2 * HZ);
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM:
ctrl2_val |= NAU8825_I2S_MS_MASTER;
@ -1282,6 +1271,9 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2,
NAU8825_I2S_MS_MASK, ctrl2_val);
/* Release the semaphone. */
nau8825_sema_release(nau8825);
return 0;
}
@ -1611,8 +1603,11 @@ static irqreturn_t nau8825_interrupt(int irq, void *data)
* cess and restore changes if process
* is ongoing when ejection.
*/
int ret;
nau8825->xtalk_protect = true;
nau8825_sema_acquire(nau8825, 0);
ret = nau8825_sema_acquire(nau8825, 0);
if (ret < 0)
nau8825->xtalk_protect = false;
}
/* Startup cross talk detection process */
nau8825->xtalk_state = NAU8825_XTALK_PREPARE;
@ -2238,23 +2233,14 @@ static int __maybe_unused nau8825_suspend(struct snd_soc_codec *codec)
static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec)
{
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
int ret;
regcache_cache_only(nau8825->regmap, false);
regcache_sync(nau8825->regmap);
if (nau8825_is_jack_inserted(nau8825->regmap)) {
/* If the jack is inserted, we need to check whether the play-
* back is active before suspend. If active, the driver has to
* raise the protection for cross talk function to avoid the
* playback recovers before cross talk process finish. Other-
* wise, the playback will be interfered by cross talk func-
* tion. It is better to apply hardware related parameters
* before starting playback or record.
*/
if (nau8825_dai_is_active(nau8825)) {
nau8825->xtalk_protect = true;
nau8825_sema_acquire(nau8825, 0);
}
}
nau8825->xtalk_protect = true;
ret = nau8825_sema_acquire(nau8825, 0);
if (ret < 0)
nau8825->xtalk_protect = false;
enable_irq(nau8825->irq);
return 0;

View file

@ -581,7 +581,7 @@ static int wm2000_anc_transition(struct wm2000_priv *wm2000,
if (anc_transitions[i].dest == ANC_OFF)
clk_disable_unprepare(wm2000->mclk);
return ret;
return 0;
}
static int wm2000_anc_set_mode(struct wm2000_priv *wm2000)

View file

@ -1,5 +1,5 @@
obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) := simple-card-utils.o
snd-soc-simple-card-utils-objs := simple-card-utils.o
snd-soc-simple-card-objs := simple-card.o
obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o
obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) += snd-soc-simple-card-utils.o
obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o

View file

@ -7,6 +7,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/of.h>
#include <sound/simple_card_utils.h>
@ -95,3 +96,8 @@ int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
return 0;
}
EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name);
/* Module information */
MODULE_AUTHOR("Kuninori Morimoto <[email protected]>");
MODULE_DESCRIPTION("ALSA SoC Simple Card Utils");
MODULE_LICENSE("GPL v2");

View file

@ -123,6 +123,11 @@ int snd_skl_get_module_info(struct skl_sst *ctx, u8 *uuid,
uuid_mod = (uuid_le *)uuid;
if (list_empty(&ctx->uuid_list)) {
dev_err(ctx->dev, "Module list is empty\n");
return -EINVAL;
}
list_for_each_entry(module, &ctx->uuid_list, list) {
if (uuid_le_cmp(*uuid_mod, module->uuid) == 0) {
dfw_config->module_id = module->id;

View file

@ -672,8 +672,10 @@ static int skl_probe(struct pci_dev *pci,
skl->nhlt = skl_nhlt_init(bus->dev);
if (skl->nhlt == NULL)
if (skl->nhlt == NULL) {
err = -ENODEV;
goto out_free;
}
skl_nhlt_update_topology_bin(skl);

View file

@ -38,10 +38,10 @@
struct abe_twl6040 {
int jack_detection; /* board can detect jack events */
int mclk_freq; /* MCLK frequency speed for twl6040 */
struct platform_device *dmic_codec_dev;
};
struct platform_device *dmic_codec_dev;
static int omap_abe_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@ -258,8 +258,6 @@ static int omap_abe_probe(struct platform_device *pdev)
if (priv == NULL)
return -ENOMEM;
priv->dmic_codec_dev = ERR_PTR(-EINVAL);
if (snd_soc_of_parse_card_name(card, "ti,model")) {
dev_err(&pdev->dev, "Card name is not provided\n");
return -ENODEV;
@ -284,13 +282,6 @@ static int omap_abe_probe(struct platform_device *pdev)
num_links = 2;
abe_twl6040_dai_links[1].cpu_of_node = dai_node;
abe_twl6040_dai_links[1].platform_of_node = dai_node;
priv->dmic_codec_dev = platform_device_register_simple(
"dmic-codec", -1, NULL, 0);
if (IS_ERR(priv->dmic_codec_dev)) {
dev_err(&pdev->dev, "Can't instantiate dmic-codec\n");
return PTR_ERR(priv->dmic_codec_dev);
}
} else {
num_links = 1;
}
@ -299,16 +290,14 @@ static int omap_abe_probe(struct platform_device *pdev)
of_property_read_u32(node, "ti,mclk-freq", &priv->mclk_freq);
if (!priv->mclk_freq) {
dev_err(&pdev->dev, "MCLK frequency not provided\n");
ret = -EINVAL;
goto err_unregister;
return -EINVAL;
}
card->fully_routed = 1;
if (!priv->mclk_freq) {
dev_err(&pdev->dev, "MCLK frequency missing\n");
ret = -ENODEV;
goto err_unregister;
return -ENODEV;
}
card->dai_link = abe_twl6040_dai_links;
@ -317,17 +306,9 @@ static int omap_abe_probe(struct platform_device *pdev)
snd_soc_card_set_drvdata(card, priv);
ret = snd_soc_register_card(card);
if (ret) {
if (ret)
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret);
goto err_unregister;
}
return 0;
err_unregister:
if (!IS_ERR(priv->dmic_codec_dev))
platform_device_unregister(priv->dmic_codec_dev);
return ret;
}
@ -335,13 +316,9 @@ err_unregister:
static int omap_abe_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card);
snd_soc_unregister_card(card);
if (!IS_ERR(priv->dmic_codec_dev))
platform_device_unregister(priv->dmic_codec_dev);
return 0;
}
@ -361,7 +338,33 @@ static struct platform_driver omap_abe_driver = {
.remove = omap_abe_remove,
};
module_platform_driver(omap_abe_driver);
static int __init omap_abe_init(void)
{
int ret;
dmic_codec_dev = platform_device_register_simple("dmic-codec", -1, NULL,
0);
if (IS_ERR(dmic_codec_dev)) {
pr_err("%s: dmic-codec device registration failed\n", __func__);
return PTR_ERR(dmic_codec_dev);
}
ret = platform_driver_register(&omap_abe_driver);
if (ret) {
pr_err("%s: platform driver registration failed\n", __func__);
platform_device_unregister(dmic_codec_dev);
}
return ret;
}
module_init(omap_abe_init);
static void __exit omap_abe_exit(void)
{
platform_driver_unregister(&omap_abe_driver);
platform_device_unregister(dmic_codec_dev);
}
module_exit(omap_abe_exit);
MODULE_AUTHOR("Misael Lopez Cruz <[email protected]>");
MODULE_DESCRIPTION("ALSA SoC for OMAP boards with ABE and twl6040 codec");

View file

@ -31,7 +31,6 @@
#include <linux/err.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/of_device.h>
@ -55,7 +54,6 @@ struct omap_mcpdm {
unsigned long phys_base;
void __iomem *io_base;
int irq;
struct clk *pdmclk;
struct mutex mutex;
@ -390,15 +388,14 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
int ret;
clk_prepare_enable(mcpdm->pdmclk);
pm_runtime_enable(mcpdm->dev);
/* Disable lines while request is ongoing */
pm_runtime_get_sync(mcpdm->dev);
omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00);
ret = devm_request_irq(mcpdm->dev, mcpdm->irq, omap_mcpdm_irq_handler,
0, "McPDM", (void *)mcpdm);
ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, 0, "McPDM",
(void *)mcpdm);
pm_runtime_put_sync(mcpdm->dev);
@ -423,9 +420,9 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)
{
struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
free_irq(mcpdm->irq, (void *)mcpdm);
pm_runtime_disable(mcpdm->dev);
clk_disable_unprepare(mcpdm->pdmclk);
return 0;
}
@ -445,8 +442,6 @@ static int omap_mcpdm_suspend(struct snd_soc_dai *dai)
mcpdm->pm_active_count++;
}
clk_disable_unprepare(mcpdm->pdmclk);
return 0;
}
@ -454,8 +449,6 @@ static int omap_mcpdm_resume(struct snd_soc_dai *dai)
{
struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
clk_prepare_enable(mcpdm->pdmclk);
if (mcpdm->pm_active_count) {
while (mcpdm->pm_active_count--)
pm_runtime_get_sync(mcpdm->dev);
@ -549,15 +542,6 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
mcpdm->dev = &pdev->dev;
mcpdm->pdmclk = devm_clk_get(&pdev->dev, "pdmclk");
if (IS_ERR(mcpdm->pdmclk)) {
if (PTR_ERR(mcpdm->pdmclk) == -EPROBE_DEFER)
return -EPROBE_DEFER;
dev_warn(&pdev->dev, "Error getting pdmclk (%ld)!\n",
PTR_ERR(mcpdm->pdmclk));
mcpdm->pdmclk = NULL;
}
ret = devm_snd_soc_register_component(&pdev->dev,
&omap_mcpdm_component,
&omap_mcpdm_dai, 1);

View file

@ -58,10 +58,12 @@ static struct platform_device *s3c24xx_uda134x_snd_device;
static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
{
int ret = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
#ifdef ENFORCE_RATES
struct snd_pcm_runtime *runtime = substream->runtime;
#endif
int ret = 0;
mutex_lock(&clk_lock);
pr_debug("%s %d\n", __func__, clk_users);
@ -71,8 +73,7 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
printk(KERN_ERR "%s cannot get xtal\n", __func__);
ret = PTR_ERR(xtal);
} else {
pclk = clk_get(&s3c24xx_uda134x_snd_device->dev,
"pclk");
pclk = clk_get(cpu_dai->dev, "iis");
if (IS_ERR(pclk)) {
printk(KERN_ERR "%s cannot get pclk\n",
__func__);

View file

@ -226,8 +226,12 @@ static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io,
ifscr = 0;
fsrate = 0;
if (fin != fout) {
u64 n;
ifscr = 1;
fsrate = 0x0400000 / fout * fin;
n = (u64)0x0400000 * fin;
do_div(n, fout);
fsrate = n;
}
/*

View file

@ -121,7 +121,7 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
dpcm_be_disconnect(fe, stream);
fe->dpcm[stream].runtime = NULL;
goto fe_err;
goto path_err;
}
dpcm_clear_pending_state(fe, stream);
@ -136,6 +136,8 @@ static int soc_compr_open_fe(struct snd_compr_stream *cstream)
return 0;
path_err:
dpcm_path_put(&list);
fe_err:
if (fe->dai_link->compr_ops && fe->dai_link->compr_ops->shutdown)
fe->dai_link->compr_ops->shutdown(cstream);

View file

@ -1056,7 +1056,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
if (!rtd->platform) {
dev_err(card->dev, "ASoC: platform %s not registered\n",
dai_link->platform_name);
return -EPROBE_DEFER;
goto _err_defer;
}
soc_add_pcm_runtime(card, rtd);
@ -2083,14 +2083,13 @@ static int soc_cleanup_card_resources(struct snd_soc_card *card)
/* remove auxiliary devices */
soc_remove_aux_devices(card);
snd_soc_dapm_free(&card->dapm);
soc_cleanup_card_debugfs(card);
/* remove the card */
if (card->remove)
card->remove(card);
snd_soc_dapm_free(&card->dapm);
snd_card_free(card->snd_card);
return 0;

View file

@ -3493,6 +3493,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
const struct snd_soc_pcm_stream *config = w->params + w->params_select;
struct snd_pcm_substream substream;
struct snd_pcm_hw_params *params = NULL;
struct snd_pcm_runtime *runtime = NULL;
u64 fmt;
int ret;
@ -3541,6 +3542,14 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
memset(&substream, 0, sizeof(substream));
/* Allocate a dummy snd_pcm_runtime for startup() and other ops() */
runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
if (!runtime) {
ret = -ENOMEM;
goto out;
}
substream.runtime = runtime;
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
substream.stream = SNDRV_PCM_STREAM_CAPTURE;
@ -3606,6 +3615,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
}
out:
kfree(runtime);
kfree(params);
return ret;
}

View file

@ -55,7 +55,6 @@ static int snd_line6_impulse_volume_put(struct snd_kcontrol *kcontrol,
err = line6_pcm_acquire(line6pcm, LINE6_STREAM_IMPULSE);
if (err < 0) {
line6pcm->impulse_volume = 0;
line6_pcm_release(line6pcm, LINE6_STREAM_IMPULSE);
return err;
}
} else {
@ -211,7 +210,9 @@ static void line6_stream_stop(struct snd_line6_pcm *line6pcm, int direction,
spin_lock_irqsave(&pstr->lock, flags);
clear_bit(type, &pstr->running);
if (!pstr->running) {
spin_unlock_irqrestore(&pstr->lock, flags);
line6_unlink_audio_urbs(line6pcm, pstr);
spin_lock_irqsave(&pstr->lock, flags);
if (direction == SNDRV_PCM_STREAM_CAPTURE) {
line6pcm->prev_fbuf = NULL;
line6pcm->prev_fsize = 0;

View file

@ -244,8 +244,8 @@ static int pod_set_system_param_int(struct usb_line6_pod *pod, int value,
static ssize_t serial_number_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct usb_interface *interface = to_usb_interface(dev);
struct usb_line6_pod *pod = usb_get_intfdata(interface);
struct snd_card *card = dev_to_snd_card(dev);
struct usb_line6_pod *pod = card->private_data;
return sprintf(buf, "%u\n", pod->serial_number);
}
@ -256,8 +256,8 @@ static ssize_t serial_number_show(struct device *dev,
static ssize_t firmware_version_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct usb_interface *interface = to_usb_interface(dev);
struct usb_line6_pod *pod = usb_get_intfdata(interface);
struct snd_card *card = dev_to_snd_card(dev);
struct usb_line6_pod *pod = card->private_data;
return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
pod->firmware_version % 100);
@ -269,8 +269,8 @@ static ssize_t firmware_version_show(struct device *dev,
static ssize_t device_id_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct usb_interface *interface = to_usb_interface(dev);
struct usb_line6_pod *pod = usb_get_intfdata(interface);
struct snd_card *card = dev_to_snd_card(dev);
struct usb_line6_pod *pod = card->private_data;
return sprintf(buf, "%d\n", pod->device_id);
}

View file

@ -1141,6 +1141,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */
case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */
case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */
case USB_ID(0x1de7, 0x0013): /* Phoenix Audio MT202exe */
case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */
case USB_ID(0x1de7, 0x0114): /* Phoenix Audio MT202pcs */