summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/core/control.c2
-rw-r--r--sound/core/info.c5
-rw-r--r--sound/core/pcm_native.c4
-rw-r--r--sound/core/seq/seq_clientmgr.c13
-rw-r--r--sound/core/seq/seq_queue.c14
-rw-r--r--sound/core/seq/seq_queue.h2
-rw-r--r--sound/pci/hda/patch_conexant.c1
-rw-r--r--sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c16
-rw-r--r--sound/soc/codecs/sdm660_cdc/msm-analog-cdc.h1
-rw-r--r--sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c109
-rw-r--r--sound/soc/codecs/sdm660_cdc/msm-digital-cdc.h2
-rw-r--r--sound/soc/codecs/wcd-dsp-mgr.c3
-rw-r--r--sound/soc/generic/simple-card.c2
-rw-r--r--sound/soc/msm/apq8096-auto.c1476
-rw-r--r--sound/soc/msm/msm-pcm-hostless.c6
-rw-r--r--sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c9
-rw-r--r--sound/soc/msm/qdsp6v2/msm-lsm-client.c2
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c329
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c2
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c61
-rw-r--r--sound/soc/sh/rcar/adg.c2
-rw-r--r--sound/soc/sh/rcar/core.c21
-rw-r--r--sound/soc/sh/rcar/src.c18
-rw-r--r--sound/soc/sh/rcar/ssi.c3
-rw-r--r--sound/usb/mixer.c2
-rw-r--r--sound/usb/mixer.h1
-rw-r--r--sound/usb/mixer_quirks.c6
-rw-r--r--sound/usb/quirks.c1
28 files changed, 1779 insertions, 334 deletions
diff --git a/sound/core/control.c b/sound/core/control.c
index b4fe9b002512..bd01d492f46a 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1126,7 +1126,7 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
mutex_lock(&ue->card->user_ctl_lock);
change = ue->tlv_data_size != size;
if (!change)
- change = memcmp(ue->tlv_data, new_data, size);
+ change = memcmp(ue->tlv_data, new_data, size) != 0;
kfree(ue->tlv_data);
ue->tlv_data = new_data;
ue->tlv_data_size = size;
diff --git a/sound/core/info.c b/sound/core/info.c
index 79dee33b5035..a04016c19f6d 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -754,8 +754,11 @@ snd_info_create_entry(const char *name, struct snd_info_entry *parent)
INIT_LIST_HEAD(&entry->children);
INIT_LIST_HEAD(&entry->list);
entry->parent = parent;
- if (parent)
+ if (parent) {
+ mutex_lock(&parent->access);
list_add_tail(&entry->list, &parent->children);
+ mutex_unlock(&parent->access);
+ }
return entry;
}
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 1f062aaa5414..9af294c72a4d 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -654,7 +654,9 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
if (substream->ops->hw_free)
result = substream->ops->hw_free(substream);
snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
- pm_qos_remove_request(&substream->latency_pm_qos_req);
+ if (pm_qos_request_active(&substream->latency_pm_qos_req))
+ pm_qos_remove_request(&substream->latency_pm_qos_req);
+
return result;
}
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index c67f9c212dd1..e326c1d80416 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -1530,19 +1530,14 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client,
void __user *arg)
{
struct snd_seq_queue_info info;
- int result;
struct snd_seq_queue *q;
if (copy_from_user(&info, arg, sizeof(info)))
return -EFAULT;
- result = snd_seq_queue_alloc(client->number, info.locked, info.flags);
- if (result < 0)
- return result;
-
- q = queueptr(result);
- if (q == NULL)
- return -EINVAL;
+ q = snd_seq_queue_alloc(client->number, info.locked, info.flags);
+ if (IS_ERR(q))
+ return PTR_ERR(q);
info.queue = q->queue;
info.locked = q->locked;
@@ -1552,7 +1547,7 @@ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client,
if (! info.name[0])
snprintf(info.name, sizeof(info.name), "Queue-%d", q->queue);
strlcpy(q->name, info.name, sizeof(q->name));
- queuefree(q);
+ snd_use_lock_free(&q->use_lock);
if (copy_to_user(arg, &info, sizeof(info)))
return -EFAULT;
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
index 450c5187eecb..79e0c5604ef8 100644
--- a/sound/core/seq/seq_queue.c
+++ b/sound/core/seq/seq_queue.c
@@ -184,22 +184,26 @@ void __exit snd_seq_queues_delete(void)
static void queue_use(struct snd_seq_queue *queue, int client, int use);
/* allocate a new queue -
- * return queue index value or negative value for error
+ * return pointer to new queue or ERR_PTR(-errno) for error
+ * The new queue's use_lock is set to 1. It is the caller's responsibility to
+ * call snd_use_lock_free(&q->use_lock).
*/
-int snd_seq_queue_alloc(int client, int locked, unsigned int info_flags)
+struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int info_flags)
{
struct snd_seq_queue *q;
q = queue_new(client, locked);
if (q == NULL)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
q->info_flags = info_flags;
queue_use(q, client, 1);
+ snd_use_lock_use(&q->use_lock);
if (queue_list_add(q) < 0) {
+ snd_use_lock_free(&q->use_lock);
queue_delete(q);
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
}
- return q->queue;
+ return q;
}
/* delete a queue - queue must be owned by the client */
diff --git a/sound/core/seq/seq_queue.h b/sound/core/seq/seq_queue.h
index 30c8111477f6..719093489a2c 100644
--- a/sound/core/seq/seq_queue.h
+++ b/sound/core/seq/seq_queue.h
@@ -71,7 +71,7 @@ void snd_seq_queues_delete(void);
/* create new queue (constructor) */
-int snd_seq_queue_alloc(int client, int locked, unsigned int flags);
+struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int flags);
/* delete queue (destructor) */
int snd_seq_queue_delete(int client, int queueid);
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 46f7b023f69c..ac5de4365e15 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -854,6 +854,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
SND_PCI_QUIRK(0x17aa, 0x390b, "Lenovo G50-80", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x17aa, 0x3977, "Lenovo IdeaPad U310", CXT_FIXUP_STEREO_DMIC),
+ SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo G50-70", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC),
SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", CXT_FIXUP_THINKPAD_ACPI),
SND_PCI_QUIRK(0x1c06, 0x2011, "Lemote A1004", CXT_PINCFG_LEMOTE_A1004),
diff --git a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c
index cc7132d190b8..55eef61a01de 100644
--- a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c
+++ b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c
@@ -49,10 +49,10 @@
#define BUS_DOWN 1
/*
- * 50 Milliseconds sufficient for DSP bring up in the lpass
+ * 200 Milliseconds sufficient for DSP bring up in the lpass
* after Sub System Restart
*/
-#define ADSP_STATE_READY_TIMEOUT_MS 50
+#define ADSP_STATE_READY_TIMEOUT_MS 200
#define EAR_PMD 0
#define EAR_PMU 1
@@ -2619,6 +2619,17 @@ static int msm_anlg_cdc_codec_enable_micbias(struct snd_soc_dapm_widget *w,
return 0;
}
+static void set_compander_mode(void *handle, int val)
+{
+ struct sdm660_cdc_priv *handle_cdc = handle;
+ struct snd_soc_codec *codec = handle_cdc->codec;
+
+ if (get_codec_version(handle_cdc) >= DIANGU) {
+ snd_soc_update_bits(codec,
+ MSM89XX_PMIC_ANALOG_RX_COM_BIAS_DAC,
+ 0x08, val);
+ };
+}
static void update_clkdiv(void *handle, int val)
{
struct sdm660_cdc_priv *handle_cdc = handle;
@@ -4636,6 +4647,7 @@ static int msm_anlg_cdc_probe(struct platform_device *pdev)
BLOCKING_INIT_NOTIFIER_HEAD(&sdm660_cdc->notifier_mbhc);
sdm660_cdc->dig_plat_data.handle = (void *) sdm660_cdc;
+ sdm660_cdc->dig_plat_data.set_compander_mode = set_compander_mode;
sdm660_cdc->dig_plat_data.update_clkdiv = update_clkdiv;
sdm660_cdc->dig_plat_data.get_cdc_version = get_cdc_version;
sdm660_cdc->dig_plat_data.register_notifier =
diff --git a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.h b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.h
index 9563565f36d2..d07d1bee4d6b 100644
--- a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.h
+++ b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.h
@@ -168,6 +168,7 @@ struct msm_dig_ctrl_data {
struct msm_dig_ctrl_platform_data {
void *handle;
+ void (*set_compander_mode)(void *handle, int val);
void (*update_clkdiv)(void *handle, int val);
int (*get_cdc_version)(void *handle);
int (*register_notifier)(void *handle,
diff --git a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c
index e64956aa2f40..5f9dc9c0c392 100644
--- a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c
+++ b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c
@@ -214,60 +214,92 @@ static int msm_dig_cdc_codec_config_compander(struct snd_soc_codec *codec,
int interp_n, int event)
{
struct msm_dig_priv *dig_cdc = snd_soc_codec_get_drvdata(codec);
+ int comp_ch_bits_set = 0x03;
+ int comp_ch_value;
dev_dbg(codec->dev, "%s: event %d shift %d, enabled %d\n",
__func__, event, interp_n,
dig_cdc->comp_enabled[interp_n]);
- /* compander is not enabled */
- if (!dig_cdc->comp_enabled[interp_n])
+ /* compander is invalid */
+ if (dig_cdc->comp_enabled[interp_n] != COMPANDER_1 &&
+ dig_cdc->comp_enabled[interp_n]) {
+ dev_dbg(codec->dev, "%s: Invalid compander %d\n", __func__,
+ dig_cdc->comp_enabled[interp_n]);
return 0;
+ }
- switch (dig_cdc->comp_enabled[interp_n]) {
- case COMPANDER_1:
- if (SND_SOC_DAPM_EVENT_ON(event)) {
- /* Enable Compander Clock */
- snd_soc_update_bits(codec,
- MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x09);
- snd_soc_update_bits(codec,
- MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x01, 0x01);
+ if (SND_SOC_DAPM_EVENT_ON(event)) {
+ /* compander is not enabled */
+ if (!dig_cdc->comp_enabled[interp_n]) {
+ dig_cdc->set_compander_mode(dig_cdc->handle, 0x00);
+ return 0;
+ };
+ comp_ch_value = snd_soc_read(codec,
+ MSM89XX_CDC_CORE_COMP0_B1_CTL);
+ if (interp_n == 0) {
+ if ((comp_ch_value & 0x02) == 0x02) {
+ dev_dbg(codec->dev,
+ "%s comp ch already enabled\n",
+ __func__);
+ return 0;
+ }
+ }
+ if (interp_n == 1) {
+ if ((comp_ch_value & 0x01) == 0x01) {
+ dev_dbg(codec->dev,
+ "%s comp ch already enabled\n",
+ __func__);
+ return 0;
+ }
+ }
+ dig_cdc->set_compander_mode(dig_cdc->handle, 0x08);
+ /* Enable Compander Clock */
+ snd_soc_update_bits(codec,
+ MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x09);
+ snd_soc_update_bits(codec,
+ MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x01, 0x01);
+ if (dig_cdc->comp_enabled[MSM89XX_RX1]) {
snd_soc_update_bits(codec,
MSM89XX_CDC_CORE_COMP0_B1_CTL,
- 1 << interp_n, 1 << interp_n);
- snd_soc_update_bits(codec,
- MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x01);
- snd_soc_update_bits(codec,
- MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0x50);
- /* add sleep for compander to settle */
- usleep_range(1000, 1100);
- snd_soc_update_bits(codec,
- MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x28);
+ 0x02, 0x02);
+ }
+ if (dig_cdc->comp_enabled[MSM89XX_RX2]) {
snd_soc_update_bits(codec,
- MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0xB0);
+ MSM89XX_CDC_CORE_COMP0_B1_CTL,
+ 0x01, 0x01);
+ }
+ snd_soc_update_bits(codec,
+ MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x01);
+ snd_soc_update_bits(codec,
+ MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0x50);
+ /* add sleep for compander to settle */
+ usleep_range(1000, 1100);
+ snd_soc_update_bits(codec,
+ MSM89XX_CDC_CORE_COMP0_B3_CTL, 0xFF, 0x28);
+ snd_soc_update_bits(codec,
+ MSM89XX_CDC_CORE_COMP0_B2_CTL, 0xF0, 0xB0);
- /* Enable Compander GPIO */
- if (dig_cdc->codec_hph_comp_gpio)
- dig_cdc->codec_hph_comp_gpio(1, codec);
- } else if (SND_SOC_DAPM_EVENT_OFF(event)) {
- /* Disable Compander GPIO */
- if (dig_cdc->codec_hph_comp_gpio)
- dig_cdc->codec_hph_comp_gpio(0, codec);
+ /* Enable Compander GPIO */
+ if (dig_cdc->codec_hph_comp_gpio)
+ dig_cdc->codec_hph_comp_gpio(1, codec);
+ } else if (SND_SOC_DAPM_EVENT_OFF(event)) {
+ /* Disable Compander GPIO */
+ if (dig_cdc->codec_hph_comp_gpio)
+ dig_cdc->codec_hph_comp_gpio(0, codec);
+ snd_soc_update_bits(codec,
+ MSM89XX_CDC_CORE_COMP0_B1_CTL,
+ 1 << interp_n, 0);
+ comp_ch_bits_set = snd_soc_read(codec,
+ MSM89XX_CDC_CORE_COMP0_B1_CTL);
+ if ((comp_ch_bits_set & 0x03) == 0x00) {
snd_soc_update_bits(codec,
MSM89XX_CDC_CORE_COMP0_B2_CTL, 0x0F, 0x05);
- snd_soc_update_bits(codec,
- MSM89XX_CDC_CORE_COMP0_B1_CTL,
- 1 << interp_n, 0);
- snd_soc_update_bits(codec,
+ snd_soc_update_bits(codec,
MSM89XX_CDC_CORE_CLK_RX_B2_CTL, 0x01, 0x00);
}
- break;
- default:
- dev_dbg(codec->dev, "%s: Invalid compander %d\n", __func__,
- dig_cdc->comp_enabled[interp_n]);
- break;
- };
-
+ }
return 0;
}
@@ -2107,6 +2139,7 @@ static int msm_dig_cdc_probe(struct platform_device *pdev)
msm_dig_cdc->dig_base, &msm_digital_regmap_config);
msm_dig_cdc->update_clkdiv = pdata->update_clkdiv;
+ msm_dig_cdc->set_compander_mode = pdata->set_compander_mode;
msm_dig_cdc->get_cdc_version = pdata->get_cdc_version;
msm_dig_cdc->handle = pdata->handle;
msm_dig_cdc->register_notifier = pdata->register_notifier;
diff --git a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.h b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.h
index f0e7a9cf9228..11f36f99f1bd 100644
--- a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.h
+++ b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.h
@@ -49,6 +49,7 @@ struct msm_dig_priv {
u32 mute_mask;
int dapm_bias_off;
void *handle;
+ void (*set_compander_mode)(void *handle, int val);
void (*update_clkdiv)(void *handle, int val);
int (*get_cdc_version)(void *handle);
int (*register_notifier)(void *handle,
@@ -58,6 +59,7 @@ struct msm_dig_priv {
struct dig_ctrl_platform_data {
void *handle;
+ void (*set_compander_mode)(void *handle, int val);
void (*update_clkdiv)(void *handle, int val);
int (*get_cdc_version)(void *handle);
int (*register_notifier)(void *handle,
diff --git a/sound/soc/codecs/wcd-dsp-mgr.c b/sound/soc/codecs/wcd-dsp-mgr.c
index 1613c5baa9c7..f995bf22c1c3 100644
--- a/sound/soc/codecs/wcd-dsp-mgr.c
+++ b/sound/soc/codecs/wcd-dsp-mgr.c
@@ -25,7 +25,8 @@
static char *wdsp_get_cmpnt_type_string(enum wdsp_cmpnt_type);
/* Component related macros */
-#define WDSP_GET_COMPONENT(wdsp, x) (&(wdsp->cmpnts[x]))
+#define WDSP_GET_COMPONENT(wdsp, x) ((x >= WDSP_CMPNT_TYPE_MAX || x < 0) ? \
+ NULL : (&(wdsp->cmpnts[x])))
#define WDSP_GET_CMPNT_TYPE_STR(x) wdsp_get_cmpnt_type_string(x)
/*
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 54c33204541f..ff6fcd9f92f7 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -100,7 +100,7 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
if (ret && ret != -ENOTSUPP)
goto err;
}
-
+ return 0;
err:
return ret;
}
diff --git a/sound/soc/msm/apq8096-auto.c b/sound/soc/msm/apq8096-auto.c
index b1dff8764618..749f386852c6 100644
--- a/sound/soc/msm/apq8096-auto.c
+++ b/sound/soc/msm/apq8096-auto.c
@@ -61,6 +61,16 @@ static int msm_quat_mi2s_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE;
static int msm_sec_mi2s_rate = SAMPLING_RATE_48KHZ;
/* TDM default channels */
+static int msm_pri_tdm_tx_0_ch = 2;
+static int msm_pri_tdm_tx_1_ch = 2;
+static int msm_pri_tdm_tx_2_ch = 2;
+static int msm_pri_tdm_tx_3_ch = 2;
+
+static int msm_pri_tdm_rx_0_ch = 2;
+static int msm_pri_tdm_rx_1_ch = 2;
+static int msm_pri_tdm_rx_2_ch = 2;
+static int msm_pri_tdm_rx_3_ch = 2;
+
static int msm_sec_tdm_tx_0_ch = 2; /* STEREO MIC */
static int msm_sec_tdm_tx_1_ch = 2;
static int msm_sec_tdm_tx_2_ch = 2;
@@ -88,6 +98,16 @@ static int msm_quat_tdm_tx_2_ch = 2; /*ENT RECORD*/
static int msm_quat_tdm_tx_3_ch;
/* TDM default bit format */
+static int msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_pri_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_pri_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_pri_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+
+static int msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_pri_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_pri_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_pri_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+
static int msm_sec_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
static int msm_sec_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
static int msm_sec_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
@@ -114,6 +134,10 @@ static int msm_quat_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
static int msm_quat_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
static int msm_quat_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_pri_tdm_rate = SAMPLING_RATE_48KHZ;
+static int msm_pri_tdm_slot_width = 32;
+static int msm_pri_tdm_slot_num = 8;
+
/* EC Reference default values are set in mixer_paths.xml */
static int msm_ec_ref_ch = 4;
static int msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S16_LE;
@@ -174,11 +198,26 @@ enum {
SECONDARY_TDM_TX_5,
SECONDARY_TDM_TX_6,
SECONDARY_TDM_TX_7,
+ PRIMARY_TDM_RX_0,
+ PRIMARY_TDM_RX_1,
+ PRIMARY_TDM_RX_2,
+ PRIMARY_TDM_RX_3,
+ PRIMARY_TDM_RX_4,
+ PRIMARY_TDM_RX_5,
+ PRIMARY_TDM_RX_6,
+ PRIMARY_TDM_RX_7,
+ PRIMARY_TDM_TX_0,
+ PRIMARY_TDM_TX_1,
+ PRIMARY_TDM_TX_2,
+ PRIMARY_TDM_TX_3,
+ PRIMARY_TDM_TX_4,
+ PRIMARY_TDM_TX_5,
+ PRIMARY_TDM_TX_6,
+ PRIMARY_TDM_TX_7,
TDM_MAX,
};
#define TDM_SLOT_OFFSET_MAX 8
-
/* TDM default offset */
static unsigned int tdm_slot_offset[TDM_MAX][TDM_SLOT_OFFSET_MAX] = {
/* QUAT_TDM_RX */
@@ -235,6 +274,24 @@ static unsigned int tdm_slot_offset[TDM_MAX][TDM_SLOT_OFFSET_MAX] = {
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
+ /* PRI_TDM_RX */
+ {0, 4, 0xFFFF},
+ {8, 12, 0xFFFF},
+ {16, 20, 0xFFFF},
+ {24, 28, 0xFFFF},
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ /* PRI_TDM_TX */
+ {0, 4, 0xFFFF},
+ {8, 12, 0xFFFF},
+ {16, 20, 0xFFFF},
+ {24, 28, 0xFFFF},
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
};
@@ -300,6 +357,24 @@ static unsigned int tdm_slot_offset_adp_mmxf[TDM_MAX][TDM_SLOT_OFFSET_MAX] = {
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
+ /* PRI_TDM_RX */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ /* PRI_TDM_TX */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
};
static unsigned int tdm_slot_offset_custom[TDM_MAX][TDM_SLOT_OFFSET_MAX] = {
@@ -357,6 +432,24 @@ static unsigned int tdm_slot_offset_custom[TDM_MAX][TDM_SLOT_OFFSET_MAX] = {
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
+ /* PRI_TDM_RX */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ /* PRI_TDM_TX */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
};
static char const *hdmi_rx_ch_text[] = {"Two", "Three", "Four", "Five",
@@ -389,6 +482,14 @@ static const char *const ec_ref_rate_text[] = {"0", "8000", "16000",
static const char *const mi2s_rate_text[] = {"32000", "44100", "48000"};
+static const char *const pri_tdm_rate_text[] = {"8000", "16000", "48000"};
+
+static const char *const pri_tdm_slot_num_text[] = {"One", "Two", "Four",
+ "Eight", "Sixteen", "Thirtytwo"};
+
+
+static const char *const pri_tdm_slot_width_text[] = {"16", "24", "32"};
+
static struct afe_clk_set sec_mi2s_tx_clk = {
AFE_API_VERSION_I2S_CONFIG,
Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT,
@@ -698,6 +799,150 @@ static int msm_sec_mi2s_tx_bit_format_put(struct snd_kcontrol *kcontrol,
return 0;
}
+static int msm_pri_tdm_tx_0_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_pri_tdm_tx_0_ch = %d\n", __func__,
+ msm_pri_tdm_tx_0_ch);
+ ucontrol->value.integer.value[0] = msm_pri_tdm_tx_0_ch - 1;
+ return 0;
+}
+
+static int msm_pri_tdm_tx_0_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_pri_tdm_tx_0_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_pri_tdm_tx_0_ch = %d\n", __func__,
+ msm_pri_tdm_tx_0_ch);
+ return 0;
+}
+
+static int msm_pri_tdm_tx_1_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: pri_tdm_tx_1_ch = %d\n", __func__,
+ msm_pri_tdm_tx_1_ch);
+ ucontrol->value.integer.value[0] = msm_pri_tdm_tx_1_ch - 1;
+ return 0;
+}
+
+static int msm_pri_tdm_tx_1_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_pri_tdm_tx_1_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_pri_tdm_tx_1_ch = %d\n", __func__,
+ msm_pri_tdm_tx_1_ch);
+ return 0;
+}
+
+static int msm_pri_tdm_tx_2_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_pri_tdm_tx_2_ch = %d\n", __func__,
+ msm_pri_tdm_tx_2_ch);
+ ucontrol->value.integer.value[0] = msm_pri_tdm_tx_2_ch - 1;
+ return 0;
+}
+
+static int msm_pri_tdm_tx_2_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_pri_tdm_tx_2_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_pri_tdm_tx_2_ch = %d\n", __func__,
+ msm_pri_tdm_tx_2_ch);
+ return 0;
+}
+
+static int msm_pri_tdm_tx_3_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_pri_tdm_tx_3_ch = %d\n", __func__,
+ msm_pri_tdm_tx_3_ch);
+ ucontrol->value.integer.value[0] = msm_pri_tdm_tx_3_ch - 1;
+ return 0;
+}
+
+static int msm_pri_tdm_tx_3_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_pri_tdm_tx_3_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_pri_tdm_tx_3_ch = %d\n", __func__,
+ msm_pri_tdm_tx_3_ch);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_0_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_pri_tdm_rx_0_ch = %d\n", __func__,
+ msm_pri_tdm_rx_0_ch);
+ ucontrol->value.integer.value[0] = msm_pri_tdm_rx_0_ch - 1;
+ return 0;
+}
+
+static int msm_pri_tdm_rx_0_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_pri_tdm_rx_0_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_pri_tdm_rx_0_ch = %d\n", __func__,
+ msm_pri_tdm_rx_0_ch);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_1_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_pri_tdm_rx_1_ch = %d\n", __func__,
+ msm_pri_tdm_rx_1_ch);
+ ucontrol->value.integer.value[0] = msm_pri_tdm_rx_1_ch - 1;
+ return 0;
+}
+
+static int msm_pri_tdm_rx_1_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_pri_tdm_rx_1_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_pri_tdm_rx_1_ch = %d\n", __func__,
+ msm_pri_tdm_rx_1_ch);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_2_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_pri_tdm_rx_2_ch = %d\n", __func__,
+ msm_pri_tdm_rx_2_ch);
+ ucontrol->value.integer.value[0] = msm_pri_tdm_rx_2_ch - 1;
+ return 0;
+}
+
+static int msm_pri_tdm_rx_2_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_pri_tdm_rx_2_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_pri_tdm_rx_2_ch = %d\n", __func__,
+ msm_pri_tdm_rx_2_ch);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_3_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_pri_tdm_rx_3_ch = %d\n", __func__,
+ msm_pri_tdm_rx_3_ch);
+ ucontrol->value.integer.value[0] = msm_pri_tdm_rx_3_ch - 1;
+ return 0;
+}
+
+static int msm_pri_tdm_rx_3_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_pri_tdm_rx_3_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("%s: msm_pri_tdm_rx_3_ch = %d\n", __func__,
+ msm_pri_tdm_rx_3_ch);
+ return 0;
+}
+
static int msm_sec_mi2s_rate_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -728,6 +973,174 @@ static int msm_sec_mi2s_rate_put(struct snd_kcontrol *kcontrol,
return 0;
}
+static int msm_pri_tdm_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = msm_pri_tdm_rate;
+ pr_debug("%s: msm_pri_tdm_rate = %d\n", __func__, msm_pri_tdm_rate);
+ return 0;
+}
+
+static int msm_pri_tdm_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 0:
+ msm_pri_tdm_rate = SAMPLING_RATE_8KHZ;
+ break;
+ case 1:
+ msm_pri_tdm_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 2:
+ msm_pri_tdm_rate = SAMPLING_RATE_48KHZ;
+ break;
+ default:
+ msm_pri_tdm_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_rate = %d\n",
+ __func__, msm_pri_tdm_rate);
+ return 0;
+}
+
+static int msm_pri_tdm_slot_width_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = msm_pri_tdm_slot_width;
+ pr_debug("%s: msm_pri_tdm_slot_width = %d\n",
+ __func__, msm_pri_tdm_slot_width);
+ return 0;
+}
+
+static int msm_pri_tdm_slot_width_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 0:
+ msm_pri_tdm_slot_width = 16;
+ break;
+ case 1:
+ msm_pri_tdm_slot_width = 24;
+ break;
+ case 2:
+ msm_pri_tdm_slot_width = 32;
+ break;
+ default:
+ msm_pri_tdm_slot_width = 32;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_slot_width= %d\n",
+ __func__, msm_pri_tdm_slot_width);
+ return 0;
+}
+
+static int msm_pri_tdm_slot_num_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_pri_tdm_slot_num) {
+ case 1:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ case 2:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case 4:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case 8:
+ ucontrol->value.integer.value[0] = 3;
+ break;
+ case 16:
+ ucontrol->value.integer.value[0] = 4;
+ break;
+ case 32:
+ default:
+ ucontrol->value.integer.value[0] = 5;
+ break;
+ }
+
+ pr_debug("%s: msm_pri_tdm_slot_num = %d\n",
+ __func__, msm_pri_tdm_slot_num);
+ return 0;
+}
+
+static int msm_pri_tdm_slot_num_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 0:
+ msm_pri_tdm_slot_num = 1;
+ break;
+ case 1:
+ msm_pri_tdm_slot_num = 2;
+ break;
+ case 2:
+ msm_pri_tdm_slot_num = 4;
+ break;
+ case 3:
+ msm_pri_tdm_slot_num = 8;
+ break;
+ case 4:
+ msm_pri_tdm_slot_num = 16;
+ break;
+ case 5:
+ msm_pri_tdm_slot_num = 32;
+ break;
+ default:
+ msm_pri_tdm_slot_num = 8;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_slot_num = %d\n",
+ __func__, msm_pri_tdm_slot_num);
+ return 0;
+}
+
+static int msm_tdm_slot_mapping_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct soc_multi_mixer_control *mc =
+ (struct soc_multi_mixer_control *)kcontrol->private_value;
+ unsigned int *slot_offset;
+ int i;
+
+ if (mc->shift >= TDM_MAX) {
+ pr_err("%s invalid port index %d\n", __func__, mc->shift);
+ return -EINVAL;
+ }
+
+ slot_offset = tdm_slot_offset[mc->shift];
+ for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) {
+ ucontrol->value.integer.value[i] = slot_offset[i];
+ pr_debug("%s port index %d offset %d value %d\n",
+ __func__, mc->shift, i, slot_offset[i]);
+ }
+
+ return 0;
+}
+
+static int msm_tdm_slot_mapping_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct soc_multi_mixer_control *mc =
+ (struct soc_multi_mixer_control *)kcontrol->private_value;
+ unsigned int *slot_offset;
+ int i;
+
+ if (mc->shift >= TDM_MAX) {
+ pr_err("%s invalid port index %d\n", __func__, mc->shift);
+ return -EINVAL;
+ }
+
+ slot_offset = tdm_slot_offset[mc->shift];
+
+ for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) {
+ slot_offset[i] = ucontrol->value.integer.value[i];
+ pr_debug("%s port index %d offset %d value %d\n",
+ __func__, mc->shift, i, slot_offset[i]);
+ }
+
+ return 0;
+}
static int msm_sec_tdm_tx_0_ch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@@ -1107,6 +1520,278 @@ static int msm_quat_tdm_tx_3_ch_put(struct snd_kcontrol *kcontrol,
return 0;
}
+static int msm_pri_tdm_tx_0_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_pri_tdm_tx_0_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_tx_0_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_pri_tdm_tx_0_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_tx_0_bit_format = %d\n",
+ __func__, msm_pri_tdm_tx_0_bit_format);
+ return 0;
+}
+
+static int msm_pri_tdm_tx_1_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_pri_tdm_tx_1_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_tx_1_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_pri_tdm_tx_1_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_pri_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_pri_tdm_tx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_tx_1_bit_format = %d\n",
+ __func__, msm_pri_tdm_tx_1_bit_format);
+ return 0;
+}
+
+static int msm_pri_tdm_tx_2_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_pri_tdm_tx_2_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_tx_2_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_pri_tdm_tx_2_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_pri_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_pri_tdm_tx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_tx_2_bit_format = %d\n",
+ __func__, msm_pri_tdm_tx_2_bit_format);
+ return 0;
+}
+
+static int msm_pri_tdm_tx_3_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_pri_tdm_tx_3_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_tx_3_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_pri_tdm_tx_3_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_pri_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_pri_tdm_tx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_tx_3_bit_format = %d\n",
+ __func__, msm_pri_tdm_tx_3_bit_format);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_0_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_pri_tdm_rx_0_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_rx_0_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_0_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_rx_0_bit_format = %d\n",
+ __func__, msm_pri_tdm_rx_0_bit_format);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_1_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_pri_tdm_rx_1_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_rx_1_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_1_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_pri_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_pri_tdm_rx_1_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_rx_1_bit_format = %d\n",
+ __func__, msm_pri_tdm_rx_1_bit_format);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_2_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_pri_tdm_rx_2_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_rx_2_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_2_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_pri_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_pri_tdm_rx_2_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_rx_2_bit_format = %d\n",
+ __func__, msm_pri_tdm_rx_2_bit_format);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_3_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_pri_tdm_rx_3_bit_format) {
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_rx_3_bit_format = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_3_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ msm_pri_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_pri_tdm_rx_3_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: msm_pri_tdm_rx_3_bit_format = %d\n",
+ __func__, msm_pri_tdm_rx_3_bit_format);
+ return 0;
+}
+
static int msm_sec_tdm_tx_0_bit_format_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -2070,7 +2755,57 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_interval *channels = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_CHANNELS);
+ rate->min = rate->max = SAMPLING_RATE_48KHZ;
+
switch (cpu_dai->id) {
+ case AFE_PORT_ID_PRIMARY_TDM_TX:
+ channels->min = channels->max = msm_pri_tdm_tx_0_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_pri_tdm_tx_0_bit_format);
+ rate->min = rate->max = msm_pri_tdm_rate;
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX_1:
+ channels->min = channels->max = msm_pri_tdm_tx_1_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_pri_tdm_tx_1_bit_format);
+ rate->min = rate->max = msm_pri_tdm_rate;
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX_2:
+ channels->min = channels->max = msm_pri_tdm_tx_2_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_pri_tdm_tx_2_bit_format);
+ rate->min = rate->max = msm_pri_tdm_rate;
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX_3:
+ channels->min = channels->max = msm_pri_tdm_tx_3_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_pri_tdm_tx_3_bit_format);
+ rate->min = rate->max = msm_pri_tdm_rate;
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_RX:
+ channels->min = channels->max = msm_pri_tdm_rx_0_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_pri_tdm_rx_0_bit_format);
+ rate->min = rate->max = msm_pri_tdm_rate;
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_RX_1:
+ channels->min = channels->max = msm_pri_tdm_rx_1_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_pri_tdm_rx_1_bit_format);
+ rate->min = rate->max = msm_pri_tdm_rate;
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_RX_2:
+ channels->min = channels->max = msm_pri_tdm_rx_2_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_pri_tdm_rx_2_bit_format);
+ rate->min = rate->max = msm_pri_tdm_rate;
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_RX_3:
+ channels->min = channels->max = msm_pri_tdm_rx_3_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_pri_tdm_rx_3_bit_format);
+ rate->min = rate->max = msm_pri_tdm_rate;
+ break;
case AFE_PORT_ID_SECONDARY_TDM_TX:
channels->min = channels->max = msm_sec_tdm_tx_0_ch;
param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
@@ -2181,7 +2916,6 @@ static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
__func__, cpu_dai->id);
return -EINVAL;
}
- rate->min = rate->max = SAMPLING_RATE_48KHZ;
pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n",
__func__, cpu_dai->id, channels->max, rate->max,
@@ -2300,99 +3034,18 @@ static struct snd_soc_ops apq8096_mi2s_be_ops = {
.shutdown = apq8096_mi2s_snd_shutdown,
};
-static unsigned int tdm_param_set_slot_mask(u16 port_id,
- int slot_width, int slots)
+static unsigned int tdm_param_set_slot_mask(int slots)
{
unsigned int slot_mask = 0;
- int upper, lower, i, j;
- unsigned int *slot_offset;
+ unsigned int i = 0;
- switch (port_id) {
- case AFE_PORT_ID_SECONDARY_TDM_RX:
- case AFE_PORT_ID_SECONDARY_TDM_RX_1:
- case AFE_PORT_ID_SECONDARY_TDM_RX_2:
- case AFE_PORT_ID_SECONDARY_TDM_RX_3:
- case AFE_PORT_ID_SECONDARY_TDM_RX_4:
- case AFE_PORT_ID_SECONDARY_TDM_RX_5:
- case AFE_PORT_ID_SECONDARY_TDM_RX_6:
- case AFE_PORT_ID_SECONDARY_TDM_RX_7:
- lower = SECONDARY_TDM_RX_0;
- upper = SECONDARY_TDM_RX_7;
- break;
- case AFE_PORT_ID_SECONDARY_TDM_TX:
- case AFE_PORT_ID_SECONDARY_TDM_TX_1:
- case AFE_PORT_ID_SECONDARY_TDM_TX_2:
- case AFE_PORT_ID_SECONDARY_TDM_TX_3:
- case AFE_PORT_ID_SECONDARY_TDM_TX_4:
- case AFE_PORT_ID_SECONDARY_TDM_TX_5:
- case AFE_PORT_ID_SECONDARY_TDM_TX_6:
- case AFE_PORT_ID_SECONDARY_TDM_TX_7:
- lower = SECONDARY_TDM_TX_0;
- upper = SECONDARY_TDM_TX_7;
- break;
- case AFE_PORT_ID_TERTIARY_TDM_RX:
- case AFE_PORT_ID_TERTIARY_TDM_RX_1:
- case AFE_PORT_ID_TERTIARY_TDM_RX_2:
- case AFE_PORT_ID_TERTIARY_TDM_RX_3:
- case AFE_PORT_ID_TERTIARY_TDM_RX_4:
- case AFE_PORT_ID_TERTIARY_TDM_RX_5:
- case AFE_PORT_ID_TERTIARY_TDM_RX_6:
- case AFE_PORT_ID_TERTIARY_TDM_RX_7:
- lower = TERTIARY_TDM_RX_0;
- upper = TERTIARY_TDM_RX_7;
- break;
- case AFE_PORT_ID_TERTIARY_TDM_TX:
- case AFE_PORT_ID_TERTIARY_TDM_TX_1:
- case AFE_PORT_ID_TERTIARY_TDM_TX_2:
- case AFE_PORT_ID_TERTIARY_TDM_TX_3:
- case AFE_PORT_ID_TERTIARY_TDM_TX_4:
- case AFE_PORT_ID_TERTIARY_TDM_TX_5:
- case AFE_PORT_ID_TERTIARY_TDM_TX_6:
- case AFE_PORT_ID_TERTIARY_TDM_TX_7:
- lower = TERTIARY_TDM_TX_0;
- upper = TERTIARY_TDM_TX_7;
- break;
- case AFE_PORT_ID_QUATERNARY_TDM_RX:
- case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
- case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
- case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
- case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
- case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
- case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
- case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
- lower = QUATERNARY_TDM_RX_0;
- upper = QUATERNARY_TDM_RX_7;
- break;
- case AFE_PORT_ID_QUATERNARY_TDM_TX:
- case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
- case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
- case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
- case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
- case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
- case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
- case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
- lower = QUATERNARY_TDM_TX_0;
- upper = QUATERNARY_TDM_TX_7;
- break;
- default:
- return slot_mask;
- }
-
- for (i = lower; i <= upper; i++) {
- slot_offset = tdm_slot_offset[i];
- for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) {
- if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID)
- /*
- * set the mask of active slot according to
- * the offset table for the group of devices
- */
- slot_mask |=
- (1 << ((slot_offset[j] * 8) / slot_width));
- else
- break;
- }
+ if ((slots != 16) && (slots != 8)) {
+ pr_err("%s: invalid slot number %d\n", __func__, slots);
+ return -EINVAL;
}
+ for (i = 0; i < slots ; i++)
+ slot_mask |= 1 << i;
return slot_mask;
}
@@ -2402,14 +3055,16 @@ static int apq8096_tdm_snd_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret = 0;
- int channels, slot_width, slots;
+ int channels, slot_width, slots, rate;
unsigned int slot_mask;
unsigned int *slot_offset;
int offset_channels = 0;
int i;
+ int clk_freq;
pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
+ rate = params_rate(params);
channels = params_channels(params);
if (channels < 1 || channels > 8) {
pr_err("%s: invalid param channels %d\n",
@@ -2435,15 +3090,88 @@ static int apq8096_tdm_snd_hw_params(struct snd_pcm_substream *substream,
}
slots = msm_tdm_num_slots;
- slot_mask = tdm_param_set_slot_mask(cpu_dai->id,
- slot_width, slots);
- if (!slot_mask) {
- pr_err("%s: invalid slot_mask 0x%x\n",
- __func__, slot_mask);
- return -EINVAL;
- }
switch (cpu_dai->id) {
+ case AFE_PORT_ID_PRIMARY_TDM_RX:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_0];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_RX_1:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_1];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_RX_2:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_2];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_RX_3:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_3];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_RX_4:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_4];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_RX_5:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_5];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_RX_6:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_6];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_RX_7:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_7];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_0];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX_1:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_1];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX_2:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_2];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX_3:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_3];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX_4:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_4];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX_5:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_5];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX_6:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_6];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX_7:
+ slots = msm_pri_tdm_slot_num;
+ slot_width = msm_pri_tdm_slot_width;
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_7];
+ break;
case AFE_PORT_ID_SECONDARY_TDM_RX:
slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_0];
break;
@@ -2613,6 +3341,13 @@ static int apq8096_tdm_snd_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}
+ slot_mask = tdm_param_set_slot_mask(slots);
+ if (!slot_mask) {
+ pr_err("%s: invalid slot_mask 0x%x\n",
+ __func__, slot_mask);
+ return -EINVAL;
+ }
+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
slots, slot_width);
@@ -2647,6 +3382,13 @@ static int apq8096_tdm_snd_hw_params(struct snd_pcm_substream *substream,
}
}
+ clk_freq = rate * slot_width * slots;
+ ret = snd_soc_dai_set_sysclk(cpu_dai, 0, clk_freq, SND_SOC_CLOCK_OUT);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm clk, err:%d\n",
+ __func__, ret);
+ }
+
end:
return ret;
}
@@ -2668,6 +3410,9 @@ static const struct soc_enum msm_snd_enum[] = {
SOC_ENUM_SINGLE_EXT(3, ec_ref_bit_format_text),
SOC_ENUM_SINGLE_EXT(9, ec_ref_rate_text),
SOC_ENUM_SINGLE_EXT(3, mi2s_rate_text),
+ SOC_ENUM_SINGLE_EXT(3, pri_tdm_rate_text),
+ SOC_ENUM_SINGLE_EXT(6, pri_tdm_slot_num_text),
+ SOC_ENUM_SINGLE_EXT(3, pri_tdm_slot_width_text),
};
static const struct snd_kcontrol_new msm_snd_controls[] = {
@@ -2681,6 +3426,22 @@ static const struct snd_kcontrol_new msm_snd_controls[] = {
msm_proxy_rx_ch_get, msm_proxy_rx_ch_put),
SOC_ENUM_EXT("HDMI_RX SampleRate", msm_snd_enum[4],
hdmi_rx_sample_rate_get, hdmi_rx_sample_rate_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", msm_snd_enum[5],
+ msm_pri_tdm_tx_0_ch_get, msm_pri_tdm_tx_0_ch_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_1 Channels", msm_snd_enum[5],
+ msm_pri_tdm_tx_1_ch_get, msm_pri_tdm_tx_1_ch_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_2 Channels", msm_snd_enum[5],
+ msm_pri_tdm_tx_2_ch_get, msm_pri_tdm_tx_2_ch_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_3 Channels", msm_snd_enum[5],
+ msm_pri_tdm_tx_3_ch_get, msm_pri_tdm_tx_3_ch_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", msm_snd_enum[5],
+ msm_pri_tdm_rx_0_ch_get, msm_pri_tdm_rx_0_ch_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_1 Channels", msm_snd_enum[5],
+ msm_pri_tdm_rx_1_ch_get, msm_pri_tdm_rx_1_ch_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_2 Channels", msm_snd_enum[5],
+ msm_pri_tdm_rx_2_ch_get, msm_pri_tdm_rx_2_ch_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_3 Channels", msm_snd_enum[5],
+ msm_pri_tdm_rx_3_ch_get, msm_pri_tdm_rx_3_ch_put),
SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", msm_snd_enum[5],
msm_sec_tdm_tx_0_ch_get, msm_sec_tdm_tx_0_ch_put),
SOC_ENUM_EXT("SEC_TDM_TX_1 Channels", msm_snd_enum[5],
@@ -2723,6 +3484,30 @@ static const struct snd_kcontrol_new msm_snd_controls[] = {
msm_quat_tdm_tx_2_ch_get, msm_quat_tdm_tx_2_ch_put),
SOC_ENUM_EXT("QUAT_TDM_TX_3 Channels", msm_snd_enum[5],
msm_quat_tdm_tx_3_ch_get, msm_quat_tdm_tx_3_ch_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_0 Bit Format", msm_snd_enum[6],
+ msm_pri_tdm_tx_0_bit_format_get,
+ msm_pri_tdm_tx_0_bit_format_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_1 Bit Format", msm_snd_enum[6],
+ msm_pri_tdm_tx_1_bit_format_get,
+ msm_pri_tdm_tx_1_bit_format_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_2 Bit Format", msm_snd_enum[6],
+ msm_pri_tdm_tx_2_bit_format_get,
+ msm_pri_tdm_tx_2_bit_format_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_3 Bit Format", msm_snd_enum[6],
+ msm_pri_tdm_tx_3_bit_format_get,
+ msm_pri_tdm_tx_3_bit_format_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_0 Bit Format", msm_snd_enum[6],
+ msm_pri_tdm_rx_0_bit_format_get,
+ msm_pri_tdm_rx_0_bit_format_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_1 Bit Format", msm_snd_enum[6],
+ msm_pri_tdm_rx_1_bit_format_get,
+ msm_pri_tdm_rx_1_bit_format_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_2 Bit Format", msm_snd_enum[6],
+ msm_pri_tdm_rx_2_bit_format_get,
+ msm_pri_tdm_rx_2_bit_format_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_3 Bit Format", msm_snd_enum[6],
+ msm_pri_tdm_rx_3_bit_format_get,
+ msm_pri_tdm_rx_3_bit_format_put),
SOC_ENUM_EXT("SEC_TDM_TX_0 Bit Format", msm_snd_enum[6],
msm_sec_tdm_tx_0_bit_format_get,
msm_sec_tdm_tx_0_bit_format_put),
@@ -2797,6 +3582,268 @@ static const struct snd_kcontrol_new msm_snd_controls[] = {
msm_sec_mi2s_tx_bit_format_put),
SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", msm_snd_enum[11],
msm_sec_mi2s_rate_get, msm_sec_mi2s_rate_put),
+ SOC_ENUM_EXT("PRI_TDM SampleRate", msm_snd_enum[12],
+ msm_pri_tdm_rate_get, msm_pri_tdm_rate_put),
+ SOC_ENUM_EXT("PRI_TDM Slot Number", msm_snd_enum[13],
+ msm_pri_tdm_slot_num_get, msm_pri_tdm_slot_num_put),
+ SOC_ENUM_EXT("PRI_TDM Slot Width", msm_snd_enum[14],
+ msm_pri_tdm_slot_width_get, msm_pri_tdm_slot_width_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_0 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_RX_0, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_1 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_RX_1, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_2 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_RX_2, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_3 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_RX_3, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_4 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_RX_4, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_5 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_RX_5, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_6 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_RX_6, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_7 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_RX_7, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_0 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_TX_0, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_1 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_TX_1, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_2 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_TX_2, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_3 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_TX_3, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_4 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_TX_4, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_5 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_TX_5, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_6 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_TX_6, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("PRI_TDM_TX_7 Slot Mapping", SND_SOC_NOPM,
+ PRIMARY_TDM_TX_7, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_0 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_RX_0, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_1 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_RX_1, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_2 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_RX_2, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_3 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_RX_3, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_4 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_RX_4, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_5 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_RX_5, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_6 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_RX_6, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_RX_7 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_RX_7, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_0 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_TX_0, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_1 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_TX_1, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_2 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_TX_2, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_3 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_TX_3, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_4 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_TX_4, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_5 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_TX_5, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_6 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_TX_6, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("SEC_TDM_TX_7 Slot Mapping", SND_SOC_NOPM,
+ SECONDARY_TDM_TX_7, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_0 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_RX_0, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_1 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_RX_1, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_2 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_RX_2, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_3 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_RX_3, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_4 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_RX_4, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_5 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_RX_5, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_6 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_RX_6, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_RX_7 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_RX_7, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_0 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_TX_0, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_1 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_TX_1, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_2 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_TX_2, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_3 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_TX_3, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_4 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_TX_4, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_5 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_TX_5, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_6 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_TX_6, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("TERT_TDM_TX_7 Slot Mapping", SND_SOC_NOPM,
+ TERTIARY_TDM_TX_7, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_0 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_RX_0, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_1 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_RX_1, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_2 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_RX_2, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_3 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_RX_3, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_4 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_RX_4, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_5 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_RX_5, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_6 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_RX_6, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_RX_7 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_RX_7, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_0 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_TX_0, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_1 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_TX_1, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_2 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_TX_2, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_3 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_TX_3, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_4 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_TX_4, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_5 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_TX_5, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_6 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_TX_6, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
+ SOC_SINGLE_MULTI_EXT("QUAT_TDM_TX_7 Slot Mapping", SND_SOC_NOPM,
+ QUATERNARY_TDM_TX_7, 0xFFFF,
+ 0, 8, msm_tdm_slot_mapping_get,
+ msm_tdm_slot_mapping_put),
SOC_ENUM_EXT("EC Reference Channels", msm_snd_enum[8],
msm_ec_ref_ch_get, msm_ec_ref_ch_put),
SOC_ENUM_EXT("EC Reference Bit Format", msm_snd_enum[9],
@@ -3806,6 +4853,126 @@ static struct snd_soc_dai_link apq8096_auto_fe_dai_links[] = {
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
},
+ {
+ .name = "Primary TDM RX 0 Hostless",
+ .stream_name = "Primary TDM RX 0 Hostless",
+ .cpu_dai_name = "PRI_TDM_RX_0_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Primary TDM RX 1 Hostless",
+ .stream_name = "Primary TDM RX 1 Hostless",
+ .cpu_dai_name = "PRI_TDM_RX_1_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Primary TDM RX 2 Hostless",
+ .stream_name = "Primary TDM RX 2 Hostless",
+ .cpu_dai_name = "PRI_TDM_RX_2_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Primary TDM RX 3 Hostless",
+ .stream_name = "Primary TDM RX 3 Hostless",
+ .cpu_dai_name = "PRI_TDM_RX_3_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Primary TDM TX 0 Hostless",
+ .stream_name = "Primary TDM TX 0 Hostless",
+ .cpu_dai_name = "PRI_TDM_TX_0_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Primary TDM TX 1 Hostless",
+ .stream_name = "Primary TDM TX 1 Hostless",
+ .cpu_dai_name = "PRI_TDM_TX_1_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Primary TDM TX 2 Hostless",
+ .stream_name = "Primary TDM TX 2 Hostless",
+ .cpu_dai_name = "PRI_TDM_TX_2_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Primary TDM TX 3 Hostless",
+ .stream_name = "Primary TDM TX 3 Hostless",
+ .cpu_dai_name = "PRI_TDM_TX_3_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ }
};
static struct snd_soc_dai_link apq8096_custom_fe_dai_links[] = {
@@ -4452,6 +5619,118 @@ static struct snd_soc_dai_link apq8096_auto_be_dai_links[] = {
.ops = &apq8096_tdm_be_ops,
.ignore_suspend = 1,
},
+ {
+ .name = LPASS_BE_PRI_TDM_RX_0,
+ .stream_name = "Primary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36864",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_TDM_RX_1,
+ .stream_name = "Primary TDM1 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36866",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_1,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_TDM_RX_2,
+ .stream_name = "Primary TDM2 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36868",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_2,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_TDM_RX_3,
+ .stream_name = "Primary TDM3 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36870",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_3,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_TDM_TX_0,
+ .stream_name = "Primary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36865",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_TDM_TX_1,
+ .stream_name = "Primary TDM1 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36867",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_1,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_TDM_TX_2,
+ .stream_name = "Primary TDM2 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36869",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_TDM_TX_3,
+ .stream_name = "Primary TDM3 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36871",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &apq8096_tdm_be_ops,
+ .ignore_suspend = 1,
+ }
};
static struct snd_soc_dai_link apq8096_hdmi_dai_link[] = {
@@ -4795,7 +6074,6 @@ static int apq8096_asoc_machine_probe(struct platform_device *pdev)
goto err;
}
dev_info(&pdev->dev, "Sound card %s registered\n", card->name);
-
return 0;
err:
diff --git a/sound/soc/msm/msm-pcm-hostless.c b/sound/soc/msm/msm-pcm-hostless.c
index 57932433afe9..51b0a7208462 100644
--- a/sound/soc/msm/msm-pcm-hostless.c
+++ b/sound/soc/msm/msm-pcm-hostless.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -25,7 +25,9 @@ static int msm_pcm_hostless_prepare(struct snd_pcm_substream *substream)
pr_err("%s: invalid params\n", __func__);
return -EINVAL;
}
- pm_qos_remove_request(&substream->latency_pm_qos_req);
+ if (pm_qos_request_active(&substream->latency_pm_qos_req))
+ pm_qos_remove_request(&substream->latency_pm_qos_req);
+
return 0;
}
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index c462f682e160..471be3294881 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -397,12 +397,9 @@ static int msm_compr_set_volume(struct snd_compr_stream *cstream,
} else {
gain_list[0] = volume_l;
gain_list[1] = volume_r;
- /* force sending FR/FL/FC volume for mono */
- if (prtd->num_channels == 1) {
- gain_list[2] = volume_l;
- num_channels = 3;
- use_default = true;
- }
+ gain_list[2] = volume_l;
+ num_channels = 3;
+ use_default = true;
rc = q6asm_set_multich_gain(prtd->audio_client, num_channels,
gain_list, chmap, use_default);
}
diff --git a/sound/soc/msm/qdsp6v2/msm-lsm-client.c b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
index 35270e3340ec..ae6767d26921 100644
--- a/sound/soc/msm/qdsp6v2/msm-lsm-client.c
+++ b/sound/soc/msm/qdsp6v2/msm-lsm-client.c
@@ -1167,7 +1167,7 @@ static int msm_lsm_ioctl_shared(struct snd_pcm_substream *substream,
case SNDRV_LSM_SET_FWK_MODE_CONFIG: {
u32 mode;
- if (copy_from_user(&mode, arg, sizeof(mode))) {
+ if (copy_from_user(&mode, (void __user *) arg, sizeof(mode))) {
dev_err(rtd->dev, "%s: %s: copy_frm_user failed\n",
__func__, "LSM_SET_FWK_MODE_CONFIG");
return -EFAULT;
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index b94eb6fbfeea..0d01803e634d 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -1448,12 +1448,13 @@ static int msm_pcm_add_compress_control(struct snd_soc_pcm_runtime *rtd)
if (pdata) {
if (!pdata->pcm) {
pdata->pcm = rtd->pcm;
- snd_soc_add_platform_controls(rtd->platform,
- pcm_compress_control,
- ARRAY_SIZE
- (pcm_compress_control));
- pr_debug("%s: add control success plt = %pK\n",
- __func__, rtd->platform);
+ ret = snd_soc_add_platform_controls(rtd->platform,
+ pcm_compress_control,
+ ARRAY_SIZE
+ (pcm_compress_control));
+ if (ret < 0)
+ pr_err("%s: failed add ctl %s. err = %d\n",
+ __func__, mixer_str, ret);
}
} else {
pr_err("%s: NULL pdata\n", __func__);
@@ -1603,24 +1604,47 @@ done:
return ret;
}
+static int msm_pcm_playback_pan_scale_ctl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
+ uinfo->count = sizeof(struct asm_stream_pan_ctrl_params);
+ return 0;
+}
+
static int msm_pcm_playback_pan_scale_ctl_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int ret = 0;
int len = 0;
int i = 0;
- struct snd_pcm_usr *usr_info = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_component *usr_info = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_platform *platform;
+ struct msm_plat_data *pdata;
struct snd_pcm_substream *substream;
struct msm_audio *prtd;
struct asm_stream_pan_ctrl_params pan_param;
-
+ char *usr_value = NULL;
+ uint32_t *gain_ptr = NULL;
if (!usr_info) {
pr_err("%s: usr_info is null\n", __func__);
ret = -EINVAL;
goto done;
}
- substream = usr_info->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
+ platform = snd_soc_component_to_platform(usr_info);
+ if (!platform) {
+ pr_err("%s: platform is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ pdata = dev_get_drvdata(platform->dev);
+ if (!pdata) {
+ pr_err("%s: pdata is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
if (!substream) {
pr_err("%s substream not found\n", __func__);
ret = -EINVAL;
@@ -1637,54 +1661,71 @@ static int msm_pcm_playback_pan_scale_ctl_put(struct snd_kcontrol *kcontrol,
ret = -EINVAL;
goto done;
}
- pan_param.num_output_channels =
- ucontrol->value.integer.value[len++];
+ usr_value = (char *) ucontrol->value.bytes.data;
+ if (!usr_value) {
+ pr_err("%s ucontrol data is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ memcpy(&pan_param.num_output_channels, &usr_value[len],
+ sizeof(pan_param.num_output_channels));
+ len += sizeof(pan_param.num_output_channels);
if (pan_param.num_output_channels >
PCM_FORMAT_MAX_NUM_CHANNEL) {
ret = -EINVAL;
goto done;
}
- pan_param.num_input_channels =
- ucontrol->value.integer.value[len++];
+ memcpy(&pan_param.num_input_channels, &usr_value[len],
+ sizeof(pan_param.num_input_channels));
+ len += sizeof(pan_param.num_input_channels);
if (pan_param.num_input_channels >
PCM_FORMAT_MAX_NUM_CHANNEL) {
ret = -EINVAL;
goto done;
}
- if (ucontrol->value.integer.value[len++]) {
- for (i = 0; i < pan_param.num_output_channels; i++) {
- pan_param.output_channel_map[i] =
- ucontrol->value.integer.value[len++];
- }
+ if (usr_value[len++]) {
+ memcpy(pan_param.output_channel_map, &usr_value[len],
+ (pan_param.num_output_channels *
+ sizeof(pan_param.output_channel_map[0])));
+ len += (pan_param.num_output_channels *
+ sizeof(pan_param.output_channel_map[0]));
}
- if (ucontrol->value.integer.value[len++]) {
- for (i = 0; i < pan_param.num_input_channels; i++) {
- pan_param.input_channel_map[i] =
- ucontrol->value.integer.value[len++];
- }
+ if (usr_value[len++]) {
+ memcpy(pan_param.input_channel_map, &usr_value[len],
+ (pan_param.num_input_channels *
+ sizeof(pan_param.input_channel_map[0])));
+ len += (pan_param.num_input_channels *
+ sizeof(pan_param.input_channel_map[0]));
}
- if (ucontrol->value.integer.value[len++]) {
+ if (usr_value[len++]) {
+ gain_ptr = (uint32_t *) &usr_value[len];
for (i = 0; i < pan_param.num_output_channels *
pan_param.num_input_channels; i++) {
pan_param.gain[i] =
- !(ucontrol->value.integer.value[len++] > 0) ?
+ !(gain_ptr[i] > 0) ?
0 : 2 << 13;
+ len += sizeof(pan_param.gain[i]);
}
+ len += (pan_param.num_input_channels *
+ pan_param.num_output_channels * sizeof(pan_param.gain[0]));
}
ret = q6asm_set_mfc_panning_params(prtd->audio_client,
&pan_param);
len -= pan_param.num_output_channels *
- pan_param.num_input_channels;
- for (i = 0; i < pan_param.num_output_channels *
- pan_param.num_input_channels; i++) {
- /*
- * The data userspace passes is already in Q14 format.
- * For volume gain is in Q28.
- */
- pan_param.gain[i] =
- ucontrol->value.integer.value[len++] << 14;
+ pan_param.num_input_channels * sizeof(pan_param.gain[0]);
+ if (gain_ptr) {
+ for (i = 0; i < pan_param.num_output_channels *
+ pan_param.num_input_channels; i++) {
+ /*
+ * The data userspace passes is already in Q14 format.
+ * For volume gain is in Q28.
+ */
+ pan_param.gain[i] =
+ (gain_ptr[i]) << 14;
+ len += sizeof(pan_param.gain[i]);
+ }
}
ret = q6asm_set_vol_ctrl_gain_pair(prtd->audio_client,
&pan_param);
@@ -1701,40 +1742,60 @@ static int msm_pcm_playback_pan_scale_ctl_get(struct snd_kcontrol *kcontrol,
static int msm_add_stream_pan_scale_controls(struct snd_soc_pcm_runtime *rtd)
{
- struct snd_pcm *pcm;
- struct snd_pcm_usr *pan_ctl_info;
- struct snd_kcontrol *kctl;
const char *playback_mixer_ctl_name = "Audio Stream";
const char *deviceNo = "NN";
const char *suffix = "Pan Scale Control";
- int ctl_len, ret = 0;
+ char *mixer_str = NULL;
+ int ctl_len;
+ int ret = 0;
+ struct msm_plat_data *pdata;
+ struct snd_kcontrol_new pan_scale_control[1] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "?",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = msm_pcm_playback_pan_scale_ctl_info,
+ .get = msm_pcm_playback_pan_scale_ctl_get,
+ .put = msm_pcm_playback_pan_scale_ctl_put,
+ .private_value = 0,
+ }
+ };
if (!rtd) {
- pr_err("%s: rtd is NULL\n", __func__);
- ret = -EINVAL;
- goto done;
+ pr_err("%s: NULL rtd\n", __func__);
+ return -EINVAL;
}
- pcm = rtd->pcm;
- ctl_len = strlen(playback_mixer_ctl_name) + 1 + strlen(deviceNo) + 1 +
- strlen(suffix) + 1;
-
- ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- NULL, 1, ctl_len, rtd->dai_link->be_id,
- &pan_ctl_info);
-
- if (ret < 0) {
- pr_err("%s: failed add ctl %s. err = %d\n",
- __func__, suffix, ret);
+ ctl_len = strlen(playback_mixer_ctl_name) + 1 +
+ strlen(deviceNo) + 1 + strlen(suffix) + 1;
+ mixer_str = kzalloc(ctl_len, GFP_KERNEL);
+ if (!mixer_str) {
+ ret = -ENOMEM;
goto done;
}
- kctl = pan_ctl_info->kctl;
- snprintf(kctl->id.name, ctl_len, "%s %d %s", playback_mixer_ctl_name,
- rtd->pcm->device, suffix);
- kctl->put = msm_pcm_playback_pan_scale_ctl_put;
- kctl->get = msm_pcm_playback_pan_scale_ctl_get;
- pr_debug("%s: Registering new mixer ctl = %s\n", __func__,
- kctl->id.name);
+
+ snprintf(mixer_str, ctl_len, "%s %d %s",
+ playback_mixer_ctl_name, rtd->pcm->device, suffix);
+ pan_scale_control[0].name = mixer_str;
+ pan_scale_control[0].private_value = rtd->dai_link->be_id;
+ pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
+ pdata = dev_get_drvdata(rtd->platform->dev);
+ if (pdata) {
+ if (!pdata->pcm)
+ pdata->pcm = rtd->pcm;
+ ret = snd_soc_add_platform_controls(rtd->platform,
+ pan_scale_control,
+ ARRAY_SIZE
+ (pan_scale_control));
+ if (ret < 0)
+ pr_err("%s: failed add ctl %s. err = %d\n",
+ __func__, mixer_str, ret);
+ } else {
+ pr_err("%s: NULL pdata\n", __func__);
+ ret = -EINVAL;
+ }
+
+ kfree(mixer_str);
done:
return ret;
@@ -1746,18 +1807,28 @@ static int msm_pcm_playback_dnmix_ctl_get(struct snd_kcontrol *kcontrol,
return 0;
}
+static int msm_pcm_playback_dnmix_ctl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
+ uinfo->count = sizeof(struct asm_stream_pan_ctrl_params);
+ return 0;
+}
+
static int msm_pcm_playback_dnmix_ctl_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int ret = 0;
int len = 0;
- int i = 0;
- struct snd_pcm_usr *usr_info = snd_kcontrol_chip(kcontrol);
+
+ struct snd_soc_component *usr_info = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_platform *platform;
+ struct msm_plat_data *pdata;
struct snd_pcm_substream *substream;
struct msm_audio *prtd;
struct asm_stream_pan_ctrl_params dnmix_param;
-
- int be_id = ucontrol->value.integer.value[len++];
+ char *usr_value;
+ int be_id = 0;
int stream_id = 0;
if (!usr_info) {
@@ -1765,7 +1836,19 @@ static int msm_pcm_playback_dnmix_ctl_put(struct snd_kcontrol *kcontrol,
ret = -EINVAL;
goto done;
}
- substream = usr_info->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
+ platform = snd_soc_component_to_platform(usr_info);
+ if (!platform) {
+ pr_err("%s platform is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ pdata = dev_get_drvdata(platform->dev);
+ if (!pdata) {
+ pr_err("%s pdata is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
if (!substream) {
pr_err("%s substream not found\n", __func__);
ret = -EINVAL;
@@ -1781,40 +1864,51 @@ static int msm_pcm_playback_dnmix_ctl_put(struct snd_kcontrol *kcontrol,
ret = -EINVAL;
goto done;
}
+ usr_value = (char *) ucontrol->value.bytes.data;
+ if (!usr_value) {
+ pr_err("%s usrvalue is null\n", __func__);
+ goto done;
+ }
+ memcpy(&be_id, usr_value, sizeof(be_id));
+ len += sizeof(be_id);
stream_id = prtd->audio_client->session;
- dnmix_param.num_output_channels =
- ucontrol->value.integer.value[len++];
+ memcpy(&dnmix_param.num_output_channels, &usr_value[len],
+ sizeof(dnmix_param.num_output_channels));
+ len += sizeof(dnmix_param.num_output_channels);
if (dnmix_param.num_output_channels >
PCM_FORMAT_MAX_NUM_CHANNEL) {
ret = -EINVAL;
goto done;
}
- dnmix_param.num_input_channels =
- ucontrol->value.integer.value[len++];
+ memcpy(&dnmix_param.num_input_channels, &usr_value[len],
+ sizeof(dnmix_param.num_input_channels));
+ len += sizeof(dnmix_param.num_input_channels);
if (dnmix_param.num_input_channels >
PCM_FORMAT_MAX_NUM_CHANNEL) {
ret = -EINVAL;
goto done;
}
-
- if (ucontrol->value.integer.value[len++]) {
- for (i = 0; i < dnmix_param.num_output_channels; i++) {
- dnmix_param.output_channel_map[i] =
- ucontrol->value.integer.value[len++];
- }
- }
- if (ucontrol->value.integer.value[len++]) {
- for (i = 0; i < dnmix_param.num_input_channels; i++) {
- dnmix_param.input_channel_map[i] =
- ucontrol->value.integer.value[len++];
- }
- }
- if (ucontrol->value.integer.value[len++]) {
- for (i = 0; i < dnmix_param.num_output_channels *
- dnmix_param.num_input_channels; i++) {
- dnmix_param.gain[i] =
- ucontrol->value.integer.value[len++];
- }
+ if (usr_value[len++]) {
+ memcpy(dnmix_param.output_channel_map, &usr_value[len],
+ (dnmix_param.num_output_channels *
+ sizeof(dnmix_param.output_channel_map[0])));
+ len += (dnmix_param.num_output_channels *
+ sizeof(dnmix_param.output_channel_map[0]));
+ }
+ if (usr_value[len++]) {
+ memcpy(dnmix_param.input_channel_map, &usr_value[len],
+ (dnmix_param.num_input_channels *
+ sizeof(dnmix_param.input_channel_map[0])));
+ len += (dnmix_param.num_input_channels *
+ sizeof(dnmix_param.input_channel_map[0]));
+ }
+ if (usr_value[len++]) {
+ memcpy(dnmix_param.gain, (uint32_t *) &usr_value[len],
+ (dnmix_param.num_input_channels *
+ dnmix_param.num_output_channels *
+ sizeof(dnmix_param.gain[0])));
+ len += (dnmix_param.num_input_channels *
+ dnmix_param.num_output_channels * sizeof(dnmix_param.gain[0]));
}
msm_routing_set_downmix_control_data(be_id,
stream_id,
@@ -1826,39 +1920,58 @@ done:
static int msm_add_device_down_mix_controls(struct snd_soc_pcm_runtime *rtd)
{
- struct snd_pcm *pcm;
- struct snd_pcm_usr *usr_info;
- struct snd_kcontrol *kctl;
const char *playback_mixer_ctl_name = "Audio Device";
const char *deviceNo = "NN";
const char *suffix = "Downmix Control";
- int ctl_len, ret = 0;
+ char *mixer_str = NULL;
+ int ctl_len = 0, ret = 0;
+ struct msm_plat_data *pdata;
+ struct snd_kcontrol_new device_downmix_control[1] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "?",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = msm_pcm_playback_dnmix_ctl_info,
+ .get = msm_pcm_playback_dnmix_ctl_get,
+ .put = msm_pcm_playback_dnmix_ctl_put,
+ .private_value = 0,
+ }
+ };
if (!rtd) {
- pr_err("%s: rtd is NULL\n", __func__);
+ pr_err("%s NULL rtd\n", __func__);
ret = -EINVAL;
goto done;
}
-
- pcm = rtd->pcm;
ctl_len = strlen(playback_mixer_ctl_name) + 1 +
- strlen(deviceNo) + 1 + strlen(suffix) + 1;
- ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
- NULL, 1, ctl_len, rtd->dai_link->be_id,
- &usr_info);
- if (ret < 0) {
- pr_err("%s: downmix control add failed: %d\n",
- __func__, ret);
+ strlen(deviceNo) + 1 + strlen(suffix) + 1;
+ mixer_str = kzalloc(ctl_len, GFP_KERNEL);
+ if (!mixer_str) {
+ ret = -ENOMEM;
goto done;
}
- kctl = usr_info->kctl;
- snprintf(kctl->id.name, ctl_len, "%s %d %s",
- playback_mixer_ctl_name, rtd->pcm->device, suffix);
- kctl->put = msm_pcm_playback_dnmix_ctl_put;
- kctl->get = msm_pcm_playback_dnmix_ctl_get;
- pr_debug("%s: downmix control name = %s\n",
- __func__, playback_mixer_ctl_name);
+ snprintf(mixer_str, ctl_len, "%s %d %s",
+ playback_mixer_ctl_name, rtd->pcm->device, suffix);
+ device_downmix_control[0].name = mixer_str;
+ device_downmix_control[0].private_value = rtd->dai_link->be_id;
+ pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
+ pdata = dev_get_drvdata(rtd->platform->dev);
+ if (pdata) {
+ if (!pdata->pcm)
+ pdata->pcm = rtd->pcm;
+ ret = snd_soc_add_platform_controls(rtd->platform,
+ device_downmix_control,
+ ARRAY_SIZE
+ (device_downmix_control));
+ if (ret < 0)
+ pr_err("%s: failed add ctl %s. err = %d\n",
+ __func__, mixer_str, ret);
+ } else {
+ pr_err("%s: NULL pdata\n", __func__);
+ ret = -EINVAL;
+ }
+ kfree(mixer_str);
done:
return ret;
}
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 2114adae72d7..a45d89f80106 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -11119,7 +11119,7 @@ static int msm_routing_put_app_type_cfg_control(struct snd_kcontrol *kcontrol,
static const struct snd_kcontrol_new app_type_cfg_controls[] = {
SOC_SINGLE_MULTI_EXT("App Type Config", SND_SOC_NOPM, 0,
- 0xFFFFFFFF, 0, 128, msm_routing_get_app_type_cfg_control,
+ 0x7FFFFFFF, 0, 128, msm_routing_get_app_type_cfg_control,
msm_routing_put_app_type_cfg_control),
};
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 14f9411104b3..c3d86e6cced2 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -44,7 +44,7 @@
#define TRUE 0x01
#define FALSE 0x00
-#define SESSION_MAX 8
+#define SESSION_MAX 9
#define ASM_MAX_CHANNELS 8
enum {
ASM_TOPOLOGY_CAL = 0,
@@ -1338,7 +1338,7 @@ int q6asm_audio_client_buf_alloc(unsigned int dir,
pr_debug("%s: session[%d]bufsz[%d]bufcnt[%d]\n", __func__, ac->session,
bufsz, bufcnt);
- if (ac->session <= 0 || ac->session > 8) {
+ if (ac->session <= 0 || ac->session > ASM_ACTIVE_STREAMS_ALLOWED) {
pr_err("%s: Session ID is invalid, session = %d\n", __func__,
ac->session);
goto fail;
@@ -1429,7 +1429,7 @@ int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir,
__func__, ac->session,
bufsz, bufcnt);
- if (ac->session <= 0 || ac->session > 8) {
+ if (ac->session <= 0 || ac->session > ASM_ACTIVE_STREAMS_ALLOWED) {
pr_err("%s: Session ID is invalid, session = %d\n", __func__,
ac->session);
goto fail;
@@ -1738,7 +1738,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
return -EINVAL;
}
- if (ac->session <= 0 || ac->session > 8) {
+ if (ac->session <= 0 || ac->session > ASM_ACTIVE_STREAMS_ALLOWED) {
pr_err("%s: Session ID is invalid, session = %d\n", __func__,
ac->session);
return -EINVAL;
@@ -3368,6 +3368,15 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac,
int bytes_to_alloc, rc;
size_t len;
+ mutex_lock(&ac->cmd_lock);
+
+ if (ac->port[dir].buf) {
+ pr_err("%s: Buffer already allocated\n", __func__);
+ rc = -EINVAL;
+ mutex_unlock(&ac->cmd_lock);
+ goto done;
+ }
+
buf_circ = kzalloc(sizeof(struct audio_buffer), GFP_KERNEL);
if (!buf_circ) {
@@ -3375,10 +3384,6 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac,
goto done;
}
- mutex_lock(&ac->cmd_lock);
-
- ac->port[dir].buf = buf_circ;
-
bytes_to_alloc = bufsz * bufcnt;
bytes_to_alloc = PAGE_ALIGN(bytes_to_alloc);
@@ -3390,11 +3395,12 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac,
if (rc) {
pr_err("%s: Audio ION alloc is failed, rc = %d\n", __func__,
rc);
- mutex_unlock(&ac->cmd_lock);
kfree(buf_circ);
+ mutex_unlock(&ac->cmd_lock);
goto done;
}
+ ac->port[dir].buf = buf_circ;
buf_circ->used = dir ^ 1;
buf_circ->size = bytes_to_alloc;
buf_circ->actual_size = bytes_to_alloc;
@@ -3559,12 +3565,6 @@ int q6asm_open_shared_io(struct audio_client *ac,
goto done;
}
- if (ac->port[dir].buf) {
- pr_err("%s: Buffer already allocated\n", __func__);
- rc = -EINVAL;
- goto done;
- }
-
rc = q6asm_set_shared_circ_buff(ac, open, bufsz, bufcnt, dir);
if (rc)
@@ -7215,10 +7215,9 @@ int q6asm_send_rtic_event_ack(struct audio_client *ac,
goto done;
}
- q6asm_add_hdr_async(ac, &ack.hdr,
+ q6asm_stream_add_hdr_async(ac, &ack.hdr,
sizeof(struct avs_param_rtic_event_ack) +
- params_length, TRUE);
- atomic_set(&ac->cmd_state, -1);
+ params_length, TRUE, ac->stream_id);
ack.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM_V2;
ack.encdec.param_id = AVS_PARAM_ID_RTIC_EVENT_ACK;
ack.encdec.param_size = params_length;
@@ -7228,31 +7227,11 @@ int q6asm_send_rtic_event_ack(struct audio_client *ac,
memcpy(asm_params + sizeof(struct avs_param_rtic_event_ack),
param, params_length);
rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params);
- if (rc < 0) {
+ if (rc < 0)
pr_err("%s: apr pkt failed for rtic event ack\n", __func__);
- rc = -EINVAL;
- goto fail_send_param;
- }
-
- rc = wait_event_timeout(ac->cmd_wait,
- (atomic_read(&ac->cmd_state) >= 0), 1 * HZ);
- if (!rc) {
- pr_err("%s: timeout for rtic event ack cmd\n", __func__);
- rc = -ETIMEDOUT;
- goto fail_send_param;
- }
-
- if (atomic_read(&ac->cmd_state) > 0) {
- pr_err("%s: DSP returned error[%s] for rtic event ack cmd\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&ac->cmd_state)));
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&ac->cmd_state));
- goto fail_send_param;
- }
- rc = 0;
+ else
+ rc = 0;
-fail_send_param:
kfree(asm_params);
done:
return rc;
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c
index 2a5b3a293cd2..b123734f9fbd 100644
--- a/sound/soc/sh/rcar/adg.c
+++ b/sound/soc/sh/rcar/adg.c
@@ -437,7 +437,7 @@ static void rsnd_adg_get_clkout(struct rsnd_priv *priv,
struct device *dev = rsnd_priv_to_dev(priv);
struct device_node *np = dev->of_node;
u32 ckr, rbgx, rbga, rbgb;
- u32 rate, req_rate, div;
+ u32 rate, req_rate = 0, div;
uint32_t count = 0;
unsigned long req_48kHz_rate, req_441kHz_rate;
int i;
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index deed48ef28b8..362446c36c9e 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -192,19 +192,16 @@ void rsnd_mod_interrupt(struct rsnd_mod *mod,
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
struct rsnd_dai_stream *io;
struct rsnd_dai *rdai;
- int i, j;
-
- for_each_rsnd_dai(rdai, priv, j) {
+ int i;
- for (i = 0; i < RSND_MOD_MAX; i++) {
- io = &rdai->playback;
- if (mod == io->mod[i])
- callback(mod, io);
+ for_each_rsnd_dai(rdai, priv, i) {
+ io = &rdai->playback;
+ if (mod == io->mod[mod->type])
+ callback(mod, io);
- io = &rdai->capture;
- if (mod == io->mod[i])
- callback(mod, io);
- }
+ io = &rdai->capture;
+ if (mod == io->mod[mod->type])
+ callback(mod, io);
}
}
@@ -1019,7 +1016,7 @@ static int rsnd_kctrl_put(struct snd_kcontrol *kctrl,
}
}
- if (change)
+ if (change && cfg->update)
cfg->update(cfg->io, mod);
return change;
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c
index 68b439ed22d7..460d29cbaaa5 100644
--- a/sound/soc/sh/rcar/src.c
+++ b/sound/soc/sh/rcar/src.c
@@ -691,13 +691,27 @@ static int _rsnd_src_stop_gen2(struct rsnd_mod *mod)
{
rsnd_src_irq_disable_gen2(mod);
- rsnd_mod_write(mod, SRC_CTRL, 0);
+ /*
+ * stop SRC output only
+ * see rsnd_src_quit_gen2
+ */
+ rsnd_mod_write(mod, SRC_CTRL, 0x01);
rsnd_src_error_record_gen2(mod);
return rsnd_src_stop(mod);
}
+static int rsnd_src_quit_gen2(struct rsnd_mod *mod,
+ struct rsnd_dai_stream *io,
+ struct rsnd_priv *priv)
+{
+ /* stop both out/in */
+ rsnd_mod_write(mod, SRC_CTRL, 0);
+
+ return 0;
+}
+
static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod,
struct rsnd_dai_stream *io)
{
@@ -971,7 +985,7 @@ static struct rsnd_mod_ops rsnd_src_gen2_ops = {
.probe = rsnd_src_probe_gen2,
.remove = rsnd_src_remove_gen2,
.init = rsnd_src_init_gen2,
- .quit = rsnd_src_quit,
+ .quit = rsnd_src_quit_gen2,
.start = rsnd_src_start_gen2,
.stop = rsnd_src_stop_gen2,
.hw_params = rsnd_src_hw_params,
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c
index 1427ec21bd7e..c62a2947ac14 100644
--- a/sound/soc/sh/rcar/ssi.c
+++ b/sound/soc/sh/rcar/ssi.c
@@ -39,6 +39,7 @@
#define SCKP (1 << 13) /* Serial Bit Clock Polarity */
#define SWSP (1 << 12) /* Serial WS Polarity */
#define SDTA (1 << 10) /* Serial Data Alignment */
+#define PDTA (1 << 9) /* Parallel Data Alignment */
#define DEL (1 << 8) /* Serial Data Delay */
#define CKDV(v) (v << 4) /* Serial Clock Division Ratio */
#define TRMD (1 << 1) /* Transmit/Receive Mode Select */
@@ -286,7 +287,7 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io);
u32 cr;
- cr = FORCE;
+ cr = FORCE | PDTA;
/*
* always use 32bit system word for easy clock calculation.
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index d5cc315a5eb4..ad139d45f5b2 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -553,6 +553,8 @@ int snd_usb_mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
if (size < sizeof(scale))
return -ENOMEM;
+ if (cval->min_mute)
+ scale[0] = SNDRV_CTL_TLVT_DB_MINMAX_MUTE;
scale[2] = cval->dBmin;
scale[3] = cval->dBmax;
if (copy_to_user(_tlv, scale, sizeof(scale)))
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index 3417ef347e40..2b4b067646ab 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -64,6 +64,7 @@ struct usb_mixer_elem_info {
int cached;
int cache_val[MAX_CHANNELS];
u8 initialized;
+ u8 min_mute;
void *private_data;
};
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 04991b009132..5d2fc5f58bfe 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -1873,6 +1873,12 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
if (unitid == 7 && cval->control == UAC_FU_VOLUME)
snd_dragonfly_quirk_db_scale(mixer, cval, kctl);
break;
+ /* lowest playback value is muted on C-Media devices */
+ case USB_ID(0x0d8c, 0x000c):
+ case USB_ID(0x0d8c, 0x0014):
+ if (strstr(kctl->id.name, "Playback"))
+ cval->min_mute = 1;
+ break;
}
}
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 29f38e2b4ca9..1cc20d138dae 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1143,6 +1143,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(0x1395, 0x740a): /* Sennheiser DECT */
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 */