ASoc: msm: Add support for adie RX & TX calibration
Add support for adie RX & TX calibration. This calibration
is used for RMC and speaker protection. A non-blocking
function was created for AFE memory map since it is now
being called from an atomic process and the acdb driver
was changed to use to use atomic variables.
Change-Id: Id6c6ca7a303ef5ee5d23a9932e910e6a7a08805d
Signed-off-by: Ben Romberger <bromberg@codeaurora.org>
diff --git a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
index 16751fe..a55dee6 100644
--- a/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
+++ b/arch/arm/mach-msm/include/mach/qdsp6v2/audio_acdb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -28,9 +28,15 @@
uint32_t cal_paddr;
};
+struct acdb_atomic_cal_block {
+ atomic_t cal_size;
+ atomic_t cal_kvaddr;
+ atomic_t cal_paddr;
+};
+
struct acdb_cal_data {
- uint32_t num_cal_blocks;
- struct acdb_cal_block *cal_blocks;
+ uint32_t num_cal_blocks;
+ struct acdb_atomic_cal_block *cal_blocks;
};
uint32_t get_voice_rx_topology(void);
@@ -44,6 +50,7 @@
void get_all_vocstrm_cal(struct acdb_cal_block *cal_block);
void get_all_vocvol_cal(struct acdb_cal_block *cal_block);
void get_anc_cal(struct acdb_cal_block *cal_block);
+void get_afe_cal(int32_t path, struct acdb_cal_block *cal_block);
void get_audproc_cal(int32_t path, struct acdb_cal_block *cal_block);
void get_audstrm_cal(int32_t path, struct acdb_cal_block *cal_block);
void get_audvol_cal(int32_t path, struct acdb_cal_block *cal_block);
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
index 37a6900..2e61e90 100644
--- a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
+++ b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
@@ -22,43 +22,52 @@
#define MAX_NETWORKS 12
+struct sidetone_atomic_cal {
+ atomic_t enable;
+ atomic_t gain;
+};
+
+
struct acdb_data {
struct mutex acdb_mutex;
/* ANC Cal */
- struct acdb_cal_block anc_cal;
+ struct acdb_atomic_cal_block anc_cal;
/* AudProc Cal */
- uint32_t asm_topology;
- uint32_t adm_topology[MAX_AUDPROC_TYPES];
- struct acdb_cal_block audproc_cal[MAX_AUDPROC_TYPES];
- struct acdb_cal_block audstrm_cal[MAX_AUDPROC_TYPES];
- struct acdb_cal_block audvol_cal[MAX_AUDPROC_TYPES];
+ atomic_t asm_topology;
+ atomic_t adm_topology[MAX_AUDPROC_TYPES];
+ struct acdb_atomic_cal_block audproc_cal[MAX_AUDPROC_TYPES];
+ struct acdb_atomic_cal_block audstrm_cal[MAX_AUDPROC_TYPES];
+ struct acdb_atomic_cal_block audvol_cal[MAX_AUDPROC_TYPES];
/* VocProc Cal */
- uint32_t voice_rx_topology;
- uint32_t voice_tx_topology;
- struct acdb_cal_block vocproc_cal[MAX_NETWORKS];
- struct acdb_cal_block vocstrm_cal[MAX_NETWORKS];
- struct acdb_cal_block vocvol_cal[MAX_NETWORKS];
+ atomic_t voice_rx_topology;
+ atomic_t voice_tx_topology;
+ struct acdb_atomic_cal_block vocproc_cal[MAX_NETWORKS];
+ struct acdb_atomic_cal_block vocstrm_cal[MAX_NETWORKS];
+ struct acdb_atomic_cal_block vocvol_cal[MAX_NETWORKS];
/* size of cal block tables above*/
- uint32_t vocproc_cal_size;
- uint32_t vocstrm_cal_size;
- uint32_t vocvol_cal_size;
+ atomic_t vocproc_cal_size;
+ atomic_t vocstrm_cal_size;
+ atomic_t vocvol_cal_size;
/* Total size of cal data for all networks */
- uint32_t vocproc_total_cal_size;
- uint32_t vocstrm_total_cal_size;
- uint32_t vocvol_total_cal_size;
+ atomic_t vocproc_total_cal_size;
+ atomic_t vocstrm_total_cal_size;
+ atomic_t vocvol_total_cal_size;
+
+ /* AFE cal */
+ struct acdb_atomic_cal_block afe_cal[MAX_AUDPROC_TYPES];
/* Sidetone Cal */
- struct sidetone_cal sidetone_cal;
+ struct sidetone_atomic_cal sidetone_cal;
/* PMEM information */
- int pmem_fd;
- unsigned long paddr;
- unsigned long kvaddr;
- unsigned long pmem_len;
- struct file *file;
+ atomic_t pmem_fd;
+ atomic64_t paddr;
+ atomic64_t kvaddr;
+ atomic64_t pmem_len;
+ struct file *file;
};
@@ -67,90 +76,105 @@
uint32_t get_voice_rx_topology(void)
{
- return acdb_data.voice_rx_topology;
+ return atomic_read(&acdb_data.voice_rx_topology);
}
void store_voice_rx_topology(uint32_t topology)
{
- acdb_data.voice_rx_topology = topology;
+ atomic_set(&acdb_data.voice_rx_topology, topology);
}
uint32_t get_voice_tx_topology(void)
{
- return acdb_data.voice_tx_topology;
+ return atomic_read(&acdb_data.voice_tx_topology);
}
void store_voice_tx_topology(uint32_t topology)
{
- acdb_data.voice_tx_topology = topology;
+ atomic_set(&acdb_data.voice_tx_topology, topology);
}
uint32_t get_adm_rx_topology(void)
{
- return acdb_data.adm_topology[RX_CAL];
+ return atomic_read(&acdb_data.adm_topology[RX_CAL]);
}
void store_adm_rx_topology(uint32_t topology)
{
- acdb_data.adm_topology[RX_CAL] = topology;
+ atomic_set(&acdb_data.adm_topology[RX_CAL], topology);
}
uint32_t get_adm_tx_topology(void)
{
- return acdb_data.adm_topology[TX_CAL];
+ return atomic_read(&acdb_data.adm_topology[TX_CAL]);
}
void store_adm_tx_topology(uint32_t topology)
{
- acdb_data.adm_topology[TX_CAL] = topology;
+ atomic_set(&acdb_data.adm_topology[TX_CAL], topology);
}
uint32_t get_asm_topology(void)
{
- return acdb_data.asm_topology;
+ return atomic_read(&acdb_data.asm_topology);
}
void store_asm_topology(uint32_t topology)
{
- acdb_data.asm_topology = topology;
+ atomic_set(&acdb_data.asm_topology, topology);
}
void get_all_voice_cal(struct acdb_cal_block *cal_block)
{
- cal_block->cal_kvaddr = acdb_data.vocproc_cal[0].cal_kvaddr;
- cal_block->cal_paddr = acdb_data.vocproc_cal[0].cal_paddr;
- cal_block->cal_size = acdb_data.vocproc_total_cal_size +
- acdb_data.vocstrm_total_cal_size +
- acdb_data.vocvol_total_cal_size;
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.vocproc_cal[0].cal_kvaddr);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.vocproc_cal[0].cal_paddr);
+ cal_block->cal_size =
+ atomic_read(&acdb_data.vocproc_total_cal_size) +
+ atomic_read(&acdb_data.vocstrm_total_cal_size) +
+ atomic_read(&acdb_data.vocvol_total_cal_size);
}
void get_all_cvp_cal(struct acdb_cal_block *cal_block)
{
- cal_block->cal_kvaddr = acdb_data.vocproc_cal[0].cal_kvaddr;
- cal_block->cal_paddr = acdb_data.vocproc_cal[0].cal_paddr;
- cal_block->cal_size = acdb_data.vocproc_total_cal_size +
- acdb_data.vocvol_total_cal_size;
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.vocproc_cal[0].cal_kvaddr);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.vocproc_cal[0].cal_paddr);
+ cal_block->cal_size =
+ atomic_read(&acdb_data.vocproc_total_cal_size) +
+ atomic_read(&acdb_data.vocvol_total_cal_size);
}
void get_all_vocproc_cal(struct acdb_cal_block *cal_block)
{
- cal_block->cal_kvaddr = acdb_data.vocproc_cal[0].cal_kvaddr;
- cal_block->cal_paddr = acdb_data.vocproc_cal[0].cal_paddr;
- cal_block->cal_size = acdb_data.vocproc_total_cal_size;
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.vocproc_cal[0].cal_kvaddr);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.vocproc_cal[0].cal_paddr);
+ cal_block->cal_size =
+ atomic_read(&acdb_data.vocproc_total_cal_size);
}
void get_all_vocstrm_cal(struct acdb_cal_block *cal_block)
{
- cal_block->cal_kvaddr = acdb_data.vocstrm_cal[0].cal_kvaddr;
- cal_block->cal_paddr = acdb_data.vocstrm_cal[0].cal_paddr;
- cal_block->cal_size = acdb_data.vocstrm_total_cal_size;
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.vocstrm_cal[0].cal_kvaddr);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.vocstrm_cal[0].cal_paddr);
+ cal_block->cal_size =
+ atomic_read(&acdb_data.vocstrm_total_cal_size);
}
void get_all_vocvol_cal(struct acdb_cal_block *cal_block)
{
- cal_block->cal_kvaddr = acdb_data.vocvol_cal[0].cal_kvaddr;
- cal_block->cal_paddr = acdb_data.vocvol_cal[0].cal_paddr;
- cal_block->cal_size = acdb_data.vocvol_total_cal_size;
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.vocvol_cal[0].cal_kvaddr);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.vocvol_cal[0].cal_paddr);
+ cal_block->cal_size =
+ atomic_read(&acdb_data.vocvol_total_cal_size);
}
void get_anc_cal(struct acdb_cal_block *cal_block)
@@ -162,13 +186,12 @@
goto done;
}
- mutex_lock(&acdb_data.acdb_mutex);
-
- cal_block->cal_kvaddr = acdb_data.anc_cal.cal_kvaddr;
- cal_block->cal_paddr = acdb_data.anc_cal.cal_paddr;
- cal_block->cal_size = acdb_data.anc_cal.cal_size;
-
- mutex_unlock(&acdb_data.acdb_mutex);
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.anc_cal.cal_kvaddr);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.anc_cal.cal_paddr);
+ cal_block->cal_size =
+ atomic_read(&acdb_data.anc_cal.cal_size);
done:
return;
}
@@ -177,23 +200,69 @@
{
pr_debug("%s,\n", __func__);
- if (cal_block->cal_offset > acdb_data.pmem_len) {
+ if (cal_block->cal_offset > atomic64_read(&acdb_data.pmem_len)) {
pr_err("%s: offset %d is > pmem_len %ld\n",
__func__, cal_block->cal_offset,
- acdb_data.pmem_len);
+ (long)atomic64_read(&acdb_data.pmem_len));
goto done;
}
- mutex_lock(&acdb_data.acdb_mutex);
+ atomic_set(&acdb_data.anc_cal.cal_kvaddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+ atomic_set(&acdb_data.anc_cal.cal_paddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.anc_cal.cal_size,
+ cal_block->cal_size);
+done:
+ return;
+}
- acdb_data.anc_cal.cal_kvaddr =
- cal_block->cal_offset + acdb_data.kvaddr;
- acdb_data.anc_cal.cal_paddr =
- cal_block->cal_offset + acdb_data.paddr;
- acdb_data.anc_cal.cal_size =
- cal_block->cal_size;
+void store_afe_cal(int32_t path, struct cal_block *cal_block)
+{
+ pr_debug("%s, path = %d\n", __func__, path);
- mutex_unlock(&acdb_data.acdb_mutex);
+ if (cal_block->cal_offset > atomic64_read(&acdb_data.pmem_len)) {
+ pr_err("%s: offset %d is > pmem_len %ld\n",
+ __func__, cal_block->cal_offset,
+ (long)atomic64_read(&acdb_data.pmem_len));
+ goto done;
+ }
+ if ((path >= MAX_AUDPROC_TYPES) || (path < 0)) {
+ pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+ __func__, path);
+ goto done;
+ }
+
+ atomic_set(&acdb_data.afe_cal[path].cal_kvaddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+ atomic_set(&acdb_data.afe_cal[path].cal_paddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.afe_cal[path].cal_size,
+ cal_block->cal_size);
+done:
+ return;
+}
+
+void get_afe_cal(int32_t path, struct acdb_cal_block *cal_block)
+{
+ pr_debug("%s, path = %d\n", __func__, path);
+
+ if (cal_block == NULL) {
+ pr_err("ACDB=> NULL pointer sent to %s\n", __func__);
+ goto done;
+ }
+ if ((path >= MAX_AUDPROC_TYPES) || (path < 0)) {
+ pr_err("ACDB=> Bad path sent to %s, path: %d\n",
+ __func__, path);
+ goto done;
+ }
+
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.afe_cal[path].cal_kvaddr);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.afe_cal[path].cal_paddr);
+ cal_block->cal_size =
+ atomic_read(&acdb_data.afe_cal[path].cal_size);
done:
return;
}
@@ -202,12 +271,10 @@
{
pr_debug("%s, path = %d\n", __func__, path);
- mutex_lock(&acdb_data.acdb_mutex);
-
- if (cal_block->cal_offset > acdb_data.pmem_len) {
+ if (cal_block->cal_offset > atomic64_read(&acdb_data.pmem_len)) {
pr_err("%s: offset %d is > pmem_len %ld\n",
__func__, cal_block->cal_offset,
- acdb_data.pmem_len);
+ (long)atomic64_read(&acdb_data.pmem_len));
goto done;
}
if (path >= MAX_AUDPROC_TYPES) {
@@ -216,15 +283,13 @@
goto done;
}
- acdb_data.audproc_cal[path].cal_kvaddr =
- cal_block->cal_offset + acdb_data.kvaddr;
- acdb_data.audproc_cal[path].cal_paddr =
- cal_block->cal_offset + acdb_data.paddr;
- acdb_data.audproc_cal[path].cal_size =
- cal_block->cal_size;
-
+ atomic_set(&acdb_data.audproc_cal[path].cal_kvaddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+ atomic_set(&acdb_data.audproc_cal[path].cal_paddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.audproc_cal[path].cal_size,
+ cal_block->cal_size);
done:
- mutex_unlock(&acdb_data.acdb_mutex);
return;
}
@@ -242,13 +307,12 @@
goto done;
}
- mutex_lock(&acdb_data.acdb_mutex);
-
- cal_block->cal_kvaddr = acdb_data.audproc_cal[path].cal_kvaddr;
- cal_block->cal_paddr = acdb_data.audproc_cal[path].cal_paddr;
- cal_block->cal_size = acdb_data.audproc_cal[path].cal_size;
-
- mutex_unlock(&acdb_data.acdb_mutex);
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.audproc_cal[path].cal_kvaddr);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.audproc_cal[path].cal_paddr);
+ cal_block->cal_size =
+ atomic_read(&acdb_data.audproc_cal[path].cal_size);
done:
return;
}
@@ -257,12 +321,10 @@
{
pr_debug("%s, path = %d\n", __func__, path);
- mutex_lock(&acdb_data.acdb_mutex);
-
- if (cal_block->cal_offset > acdb_data.pmem_len) {
+ if (cal_block->cal_offset > atomic64_read(&acdb_data.pmem_len)) {
pr_err("%s: offset %d is > pmem_len %ld\n",
__func__, cal_block->cal_offset,
- acdb_data.pmem_len);
+ (long)atomic64_read(&acdb_data.pmem_len));
goto done;
}
if (path >= MAX_AUDPROC_TYPES) {
@@ -271,15 +333,13 @@
goto done;
}
- acdb_data.audstrm_cal[path].cal_kvaddr =
- cal_block->cal_offset + acdb_data.kvaddr;
- acdb_data.audstrm_cal[path].cal_paddr =
- cal_block->cal_offset + acdb_data.paddr;
- acdb_data.audstrm_cal[path].cal_size =
- cal_block->cal_size;
-
+ atomic_set(&acdb_data.audstrm_cal[path].cal_kvaddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+ atomic_set(&acdb_data.audstrm_cal[path].cal_paddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.audstrm_cal[path].cal_size,
+ cal_block->cal_size);
done:
- mutex_unlock(&acdb_data.acdb_mutex);
return;
}
@@ -297,13 +357,12 @@
goto done;
}
- mutex_lock(&acdb_data.acdb_mutex);
-
- cal_block->cal_kvaddr = acdb_data.audstrm_cal[path].cal_kvaddr;
- cal_block->cal_paddr = acdb_data.audstrm_cal[path].cal_paddr;
- cal_block->cal_size = acdb_data.audstrm_cal[path].cal_size;
-
- mutex_unlock(&acdb_data.acdb_mutex);
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.audstrm_cal[path].cal_kvaddr);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.audstrm_cal[path].cal_paddr);
+ cal_block->cal_size =
+ atomic_read(&acdb_data.audstrm_cal[path].cal_size);
done:
return;
}
@@ -312,12 +371,10 @@
{
pr_debug("%s, path = %d\n", __func__, path);
- mutex_lock(&acdb_data.acdb_mutex);
-
- if (cal_block->cal_offset > acdb_data.pmem_len) {
+ if (cal_block->cal_offset > atomic64_read(&acdb_data.pmem_len)) {
pr_err("%s: offset %d is > pmem_len %ld\n",
__func__, cal_block->cal_offset,
- acdb_data.pmem_len);
+ (long)atomic64_read(&acdb_data.pmem_len));
goto done;
}
if (path >= MAX_AUDPROC_TYPES) {
@@ -326,15 +383,13 @@
goto done;
}
- acdb_data.audvol_cal[path].cal_kvaddr =
- cal_block->cal_offset + acdb_data.kvaddr;
- acdb_data.audvol_cal[path].cal_paddr =
- cal_block->cal_offset + acdb_data.paddr;
- acdb_data.audvol_cal[path].cal_size =
- cal_block->cal_size;
-
+ atomic_set(&acdb_data.audvol_cal[path].cal_kvaddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.kvaddr));
+ atomic_set(&acdb_data.audvol_cal[path].cal_paddr,
+ cal_block->cal_offset + atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.audvol_cal[path].cal_size,
+ cal_block->cal_size);
done:
- mutex_unlock(&acdb_data.acdb_mutex);
return;
}
@@ -352,13 +407,12 @@
goto done;
}
- mutex_lock(&acdb_data.acdb_mutex);
-
- cal_block->cal_kvaddr = acdb_data.audvol_cal[path].cal_kvaddr;
- cal_block->cal_paddr = acdb_data.audvol_cal[path].cal_paddr;
- cal_block->cal_size = acdb_data.audvol_cal[path].cal_size;
-
- mutex_unlock(&acdb_data.acdb_mutex);
+ cal_block->cal_kvaddr =
+ atomic_read(&acdb_data.audvol_cal[path].cal_kvaddr);
+ cal_block->cal_paddr =
+ atomic_read(&acdb_data.audvol_cal[path].cal_paddr);
+ cal_block->cal_size =
+ atomic_read(&acdb_data.audvol_cal[path].cal_size);
done:
return;
}
@@ -375,31 +429,28 @@
goto done;
}
-
- mutex_lock(&acdb_data.acdb_mutex);
-
- acdb_data.vocproc_total_cal_size = 0;
+ atomic_set(&acdb_data.vocproc_total_cal_size, 0);
for (i = 0; i < len; i++) {
- if (cal_blocks[i].cal_offset > acdb_data.pmem_len) {
+ if (cal_blocks[i].cal_offset >
+ atomic64_read(&acdb_data.pmem_len)) {
pr_err("%s: offset %d is > pmem_len %ld\n",
__func__, cal_blocks[i].cal_offset,
- acdb_data.pmem_len);
- acdb_data.vocproc_cal[i].cal_size = 0;
+ (long)atomic64_read(&acdb_data.pmem_len));
+ atomic_set(&acdb_data.vocproc_cal[i].cal_size, 0);
} else {
- acdb_data.vocproc_total_cal_size +=
- cal_blocks[i].cal_size;
- acdb_data.vocproc_cal[i].cal_size =
- cal_blocks[i].cal_size;
- acdb_data.vocproc_cal[i].cal_paddr =
+ atomic_add(cal_blocks[i].cal_size,
+ &acdb_data.vocproc_total_cal_size);
+ atomic_set(&acdb_data.vocproc_cal[i].cal_size,
+ cal_blocks[i].cal_size);
+ atomic_set(&acdb_data.vocproc_cal[i].cal_paddr,
cal_blocks[i].cal_offset +
- acdb_data.paddr;
- acdb_data.vocproc_cal[i].cal_kvaddr =
+ atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.vocproc_cal[i].cal_kvaddr,
cal_blocks[i].cal_offset +
- acdb_data.kvaddr;
+ atomic64_read(&acdb_data.kvaddr));
}
}
- acdb_data.vocproc_cal_size = len;
- mutex_unlock(&acdb_data.acdb_mutex);
+ atomic_set(&acdb_data.vocproc_cal_size, len);
done:
return;
}
@@ -413,12 +464,8 @@
goto done;
}
- mutex_lock(&acdb_data.acdb_mutex);
-
- cal_data->num_cal_blocks = acdb_data.vocproc_cal_size;
+ cal_data->num_cal_blocks = atomic_read(&acdb_data.vocproc_cal_size);
cal_data->cal_blocks = &acdb_data.vocproc_cal[0];
-
- mutex_unlock(&acdb_data.acdb_mutex);
done:
return;
}
@@ -434,30 +481,28 @@
goto done;
}
- mutex_lock(&acdb_data.acdb_mutex);
-
- acdb_data.vocstrm_total_cal_size = 0;
+ atomic_set(&acdb_data.vocstrm_total_cal_size, 0);
for (i = 0; i < len; i++) {
- if (cal_blocks[i].cal_offset > acdb_data.pmem_len) {
+ if (cal_blocks[i].cal_offset >
+ atomic64_read(&acdb_data.pmem_len)) {
pr_err("%s: offset %d is > pmem_len %ld\n",
__func__, cal_blocks[i].cal_offset,
- acdb_data.pmem_len);
- acdb_data.vocstrm_cal[i].cal_size = 0;
+ (long)atomic64_read(&acdb_data.pmem_len));
+ atomic_set(&acdb_data.vocstrm_cal[i].cal_size, 0);
} else {
- acdb_data.vocstrm_total_cal_size +=
- cal_blocks[i].cal_size;
- acdb_data.vocstrm_cal[i].cal_size =
- cal_blocks[i].cal_size;
- acdb_data.vocstrm_cal[i].cal_paddr =
+ atomic_add(cal_blocks[i].cal_size,
+ &acdb_data.vocstrm_total_cal_size);
+ atomic_set(&acdb_data.vocstrm_cal[i].cal_size,
+ cal_blocks[i].cal_size);
+ atomic_set(&acdb_data.vocstrm_cal[i].cal_paddr,
cal_blocks[i].cal_offset +
- acdb_data.paddr;
- acdb_data.vocstrm_cal[i].cal_kvaddr =
+ atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.vocstrm_cal[i].cal_kvaddr,
cal_blocks[i].cal_offset +
- acdb_data.kvaddr;
+ atomic64_read(&acdb_data.kvaddr));
}
}
- acdb_data.vocstrm_cal_size = len;
- mutex_unlock(&acdb_data.acdb_mutex);
+ atomic_set(&acdb_data.vocstrm_cal_size, len);
done:
return;
}
@@ -471,12 +516,8 @@
goto done;
}
- mutex_lock(&acdb_data.acdb_mutex);
-
- cal_data->num_cal_blocks = acdb_data.vocstrm_cal_size;
+ cal_data->num_cal_blocks = atomic_read(&acdb_data.vocstrm_cal_size);
cal_data->cal_blocks = &acdb_data.vocstrm_cal[0];
-
- mutex_unlock(&acdb_data.acdb_mutex);
done:
return;
}
@@ -492,30 +533,28 @@
goto done;
}
- mutex_lock(&acdb_data.acdb_mutex);
-
- acdb_data.vocvol_total_cal_size = 0;
+ atomic_set(&acdb_data.vocvol_total_cal_size, 0);
for (i = 0; i < len; i++) {
- if (cal_blocks[i].cal_offset > acdb_data.pmem_len) {
+ if (cal_blocks[i].cal_offset >
+ atomic64_read(&acdb_data.pmem_len)) {
pr_err("%s: offset %d is > pmem_len %ld\n",
__func__, cal_blocks[i].cal_offset,
- acdb_data.pmem_len);
- acdb_data.vocvol_cal[i].cal_size = 0;
+ (long)atomic64_read(&acdb_data.pmem_len));
+ atomic_set(&acdb_data.vocvol_cal[i].cal_size, 0);
} else {
- acdb_data.vocvol_total_cal_size +=
- cal_blocks[i].cal_size;
- acdb_data.vocvol_cal[i].cal_size =
- cal_blocks[i].cal_size;
- acdb_data.vocvol_cal[i].cal_paddr =
+ atomic_add(cal_blocks[i].cal_size,
+ &acdb_data.vocvol_total_cal_size);
+ atomic_set(&acdb_data.vocvol_cal[i].cal_size,
+ cal_blocks[i].cal_size);
+ atomic_set(&acdb_data.vocvol_cal[i].cal_paddr,
cal_blocks[i].cal_offset +
- acdb_data.paddr;
- acdb_data.vocvol_cal[i].cal_kvaddr =
+ atomic64_read(&acdb_data.paddr));
+ atomic_set(&acdb_data.vocvol_cal[i].cal_kvaddr,
cal_blocks[i].cal_offset +
- acdb_data.kvaddr;
+ atomic64_read(&acdb_data.kvaddr));
}
}
- acdb_data.vocvol_cal_size = len;
- mutex_unlock(&acdb_data.acdb_mutex);
+ atomic_set(&acdb_data.vocvol_cal_size, len);
done:
return;
}
@@ -529,12 +568,8 @@
goto done;
}
- mutex_lock(&acdb_data.acdb_mutex);
-
- cal_data->num_cal_blocks = acdb_data.vocvol_cal_size;
+ cal_data->num_cal_blocks = atomic_read(&acdb_data.vocvol_cal_size);
cal_data->cal_blocks = &acdb_data.vocvol_cal[0];
-
- mutex_unlock(&acdb_data.acdb_mutex);
done:
return;
}
@@ -543,12 +578,8 @@
{
pr_debug("%s\n", __func__);
- mutex_lock(&acdb_data.acdb_mutex);
-
- acdb_data.sidetone_cal.enable = cal_data->enable;
- acdb_data.sidetone_cal.gain = cal_data->gain;
-
- mutex_unlock(&acdb_data.acdb_mutex);
+ atomic_set(&acdb_data.sidetone_cal.enable, cal_data->enable);
+ atomic_set(&acdb_data.sidetone_cal.gain, cal_data->gain);
}
@@ -561,12 +592,8 @@
goto done;
}
- mutex_lock(&acdb_data.acdb_mutex);
-
- cal_data->enable = acdb_data.sidetone_cal.enable;
- cal_data->gain = acdb_data.sidetone_cal.gain;
-
- mutex_unlock(&acdb_data.acdb_mutex);
+ cal_data->enable = atomic_read(&acdb_data.sidetone_cal.enable);
+ cal_data->gain = atomic_read(&acdb_data.sidetone_cal.gain);
done:
return;
}
@@ -574,14 +601,12 @@
static int acdb_open(struct inode *inode, struct file *f)
{
s32 result = 0;
- pr_info("%s\n", __func__);
+ pr_debug("%s\n", __func__);
- mutex_lock(&acdb_data.acdb_mutex);
- if (acdb_data.pmem_fd) {
- pr_info("%s: ACDB opened but PMEM allocated, using existing PMEM!\n",
+ if (atomic_read(&acdb_data.pmem_fd)) {
+ pr_debug("%s: ACDB opened but PMEM allocated, using existing PMEM!\n",
__func__);
}
- mutex_unlock(&acdb_data.acdb_mutex);
atomic_inc(&usage_count);
return result;
@@ -589,9 +614,11 @@
static int deregister_pmem(void)
{
- if (acdb_data.pmem_fd) {
+ if (atomic_read(&acdb_data.pmem_fd)) {
+ mutex_lock(&acdb_data.acdb_mutex);
put_pmem_file(acdb_data.file);
- acdb_data.pmem_fd = 0;
+ mutex_unlock(&acdb_data.acdb_mutex);
+ atomic_set(&acdb_data.pmem_fd, 0);
}
return 0;
}
@@ -599,19 +626,30 @@
static int register_pmem(void)
{
int result;
+ unsigned long paddr;
+ unsigned long kvaddr;
+ unsigned long pmem_len;
- result = get_pmem_file(acdb_data.pmem_fd, &acdb_data.paddr,
- &acdb_data.kvaddr, &acdb_data.pmem_len,
+ mutex_lock(&acdb_data.acdb_mutex);
+ result = get_pmem_file(atomic_read(&acdb_data.pmem_fd),
+ &paddr, &kvaddr, &pmem_len,
&acdb_data.file);
+ mutex_unlock(&acdb_data.acdb_mutex);
if (result != 0) {
- acdb_data.pmem_fd = 0;
+ atomic_set(&acdb_data.pmem_fd, 0);
+ atomic64_set(&acdb_data.pmem_len, 0);
pr_err("%s: Could not register PMEM!!!\n", __func__);
goto done;
}
+ atomic64_set(&acdb_data.paddr, paddr);
+ atomic64_set(&acdb_data.kvaddr, kvaddr);
+ atomic64_set(&acdb_data.pmem_len, pmem_len);
pr_debug("AUDIO_REGISTER_PMEM done! paddr = 0x%lx, "
- "kvaddr = 0x%lx, len = x%lx\n", acdb_data.paddr,
- acdb_data.kvaddr, acdb_data.pmem_len);
+ "kvaddr = 0x%lx, len = x%lx\n",
+ (long)atomic64_read(&acdb_data.paddr),
+ (long)atomic64_read(&acdb_data.kvaddr),
+ (long)atomic64_read(&acdb_data.pmem_len));
done:
return result;
@@ -619,37 +657,33 @@
static long acdb_ioctl(struct file *f,
unsigned int cmd, unsigned long arg)
{
- s32 result = 0;
- s32 audproc_path;
- s32 size;
- u32 topology;
+ int32_t result = 0;
+ int32_t size;
+ int32_t pmem_fd;
+ uint32_t topology;
struct cal_block data[MAX_NETWORKS];
pr_debug("%s\n", __func__);
switch (cmd) {
case AUDIO_REGISTER_PMEM:
pr_debug("AUDIO_REGISTER_PMEM\n");
- mutex_lock(&acdb_data.acdb_mutex);
- if (acdb_data.pmem_fd) {
+ if (atomic_read(&acdb_data.pmem_fd)) {
deregister_pmem();
- pr_info("Remove the existing PMEM\n");
+ pr_debug("Remove the existing PMEM\n");
}
- if (copy_from_user(&acdb_data.pmem_fd, (void *)arg,
- sizeof(acdb_data.pmem_fd))) {
+ if (copy_from_user(&pmem_fd, (void *)arg, sizeof(pmem_fd))) {
pr_err("%s: fail to copy pmem handle!\n", __func__);
result = -EFAULT;
} else {
+ atomic_set(&acdb_data.pmem_fd, pmem_fd);
result = register_pmem();
}
- mutex_unlock(&acdb_data.acdb_mutex);
goto done;
case AUDIO_DEREGISTER_PMEM:
pr_debug("AUDIO_DEREGISTER_PMEM\n");
- mutex_lock(&acdb_data.acdb_mutex);
deregister_pmem();
- mutex_unlock(&acdb_data.acdb_mutex);
goto done;
case AUDIO_SET_VOICE_RX_TOPOLOGY:
if (copy_from_user(&topology, (void *)arg,
@@ -721,45 +755,51 @@
switch (cmd) {
case AUDIO_SET_AUDPROC_TX_CAL:
- audproc_path = TX_CAL;
if (size > sizeof(struct cal_block))
pr_err("%s: More Audproc Cal then expected, "
"size received: %d\n", __func__, size);
- store_audproc_cal(audproc_path, data);
+ store_audproc_cal(TX_CAL, data);
break;
case AUDIO_SET_AUDPROC_RX_CAL:
- audproc_path = RX_CAL;
if (size > sizeof(struct cal_block))
pr_err("%s: More Audproc Cal then expected, "
"size received: %d\n", __func__, size);
- store_audproc_cal(audproc_path, data);
+ store_audproc_cal(RX_CAL, data);
break;
case AUDIO_SET_AUDPROC_TX_STREAM_CAL:
- audproc_path = TX_CAL;
if (size > sizeof(struct cal_block))
pr_err("%s: More Audproc Cal then expected, "
"size received: %d\n", __func__, size);
- store_audstrm_cal(audproc_path, data);
+ store_audstrm_cal(TX_CAL, data);
break;
case AUDIO_SET_AUDPROC_RX_STREAM_CAL:
- audproc_path = RX_CAL;
if (size > sizeof(struct cal_block))
pr_err("%s: More Audproc Cal then expected, "
"size received: %d\n", __func__, size);
- store_audstrm_cal(audproc_path, data);
+ store_audstrm_cal(RX_CAL, data);
break;
case AUDIO_SET_AUDPROC_TX_VOL_CAL:
- audproc_path = TX_CAL;
if (size > sizeof(struct cal_block))
pr_err("%s: More Audproc Cal then expected, "
"size received: %d\n", __func__, size);
- store_audvol_cal(audproc_path, data);
+ store_audvol_cal(TX_CAL, data);
case AUDIO_SET_AUDPROC_RX_VOL_CAL:
- audproc_path = RX_CAL;
if (size > sizeof(struct cal_block))
pr_err("%s: More Audproc Cal then expected, "
"size received: %d\n", __func__, size);
- store_audvol_cal(audproc_path, data);
+ store_audvol_cal(RX_CAL, data);
+ break;
+ case AUDIO_SET_AFE_TX_CAL:
+ if (size > sizeof(struct cal_block))
+ pr_err("%s: More AFE Cal then expected, "
+ "size received: %d\n", __func__, size);
+ store_afe_cal(TX_CAL, data);
+ break;
+ case AUDIO_SET_AFE_RX_CAL:
+ if (size > sizeof(struct cal_block))
+ pr_err("%s: More AFE Cal then expected, "
+ "size received: %d\n", __func__, size);
+ store_afe_cal(RX_CAL, data);
break;
case AUDIO_SET_VOCPROC_CAL:
store_vocproc_cal(size / sizeof(struct cal_block), data);
@@ -794,14 +834,13 @@
pr_debug("%s\n", __func__);
- mutex_lock(&acdb_data.acdb_mutex);
- if (acdb_data.pmem_fd) {
- if (size <= acdb_data.pmem_len) {
+ if (atomic_read(&acdb_data.pmem_fd)) {
+ if (size <= atomic64_read(&acdb_data.pmem_len)) {
vma->vm_page_prot = pgprot_noncached(
vma->vm_page_prot);
result = remap_pfn_range(vma,
vma->vm_start,
- acdb_data.paddr >> PAGE_SHIFT,
+ atomic64_read(&acdb_data.paddr) >> PAGE_SHIFT,
size,
vma->vm_page_prot);
} else {
@@ -812,7 +851,6 @@
pr_err("%s: PMEM is not allocated, yet!\n", __func__);
result = -ENODEV;
}
- mutex_unlock(&acdb_data.acdb_mutex);
return result;
}
@@ -824,16 +862,13 @@
atomic_dec(&usage_count);
atomic_read(&usage_count);
- pr_info("%s: ref count %d!\n", __func__,
+ pr_debug("%s: ref count %d!\n", __func__,
atomic_read(&usage_count));
- if (atomic_read(&usage_count) >= 1) {
+ if (atomic_read(&usage_count) >= 1)
result = -EBUSY;
- } else {
- mutex_lock(&acdb_data.acdb_mutex);
+ else
result = deregister_pmem();
- mutex_unlock(&acdb_data.acdb_mutex);
- }
return result;
}
diff --git a/arch/arm/mach-msm/qdsp6v2/q6voice.c b/arch/arm/mach-msm/qdsp6v2/q6voice.c
index d0fec7c..12a02c5 100644
--- a/arch/arm/mach-msm/qdsp6v2/q6voice.c
+++ b/arch/arm/mach-msm/qdsp6v2/q6voice.c
@@ -791,7 +791,7 @@
struct apr_hdr cvs_cal_cmd_hdr;
uint32_t *cmd_buf;
struct acdb_cal_data cal_data;
- struct acdb_cal_block *cal_blk;
+ struct acdb_atomic_cal_block *cal_blk;
int32_t cal_size_per_network;
uint32_t *cal_data_per_network;
int index = 0;
@@ -830,11 +830,12 @@
pr_debug("cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
for (; index < cal_data.num_cal_blocks; index++) {
- cal_size_per_network = cal_blk[index].cal_size;
+ cal_size_per_network = atomic_read(&cal_blk[index].cal_size);
pr_debug(" cal size =%d\n", cal_size_per_network);
if (cal_size_per_network >= BUFFER_PAYLOAD_SIZE)
pr_err("Cal size is too big\n");
- cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
+ cal_data_per_network =
+ (u32 *)atomic_read(&cal_blk[index].cal_kvaddr);
pr_debug(" cal data=%x\n", (uint32_t)cal_data_per_network);
cvs_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
cal_size_per_network);
@@ -868,7 +869,7 @@
struct apr_hdr cvp_cal_cmd_hdr;
uint32_t *cmd_buf;
struct acdb_cal_data cal_data;
- struct acdb_cal_block *cal_blk;
+ struct acdb_atomic_cal_block *cal_blk;
int32_t cal_size_per_network;
uint32_t *cal_data_per_network;
int index = 0;
@@ -907,11 +908,12 @@
pr_debug(" cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
for (; index < cal_data.num_cal_blocks; index++) {
- cal_size_per_network = cal_blk[index].cal_size;
+ cal_size_per_network = atomic_read(&cal_blk[index].cal_size);
if (cal_size_per_network >= BUFFER_PAYLOAD_SIZE)
pr_err("Cal size is too big\n");
pr_debug(" cal size =%d\n", cal_size_per_network);
- cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
+ cal_data_per_network =
+ (u32 *)atomic_read(&cal_blk[index].cal_kvaddr);
pr_debug(" cal data=%x\n", (uint32_t)cal_data_per_network);
cvp_cal_cmd_hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
@@ -945,7 +947,7 @@
struct apr_hdr cvp_vol_cal_cmd_hdr;
uint32_t *cmd_buf;
struct acdb_cal_data cal_data;
- struct acdb_cal_block *cal_blk;
+ struct acdb_atomic_cal_block *cal_blk;
int32_t cal_size_per_network;
uint32_t *cal_data_per_network;
int index = 0;
@@ -984,8 +986,9 @@
pr_debug("Cal_blk =%x\n", (uint32_t)cal_data.cal_blocks);
for (; index < cal_data.num_cal_blocks; index++) {
- cal_size_per_network = cal_blk[index].cal_size;
- cal_data_per_network = (u32 *)cal_blk[index].cal_kvaddr;
+ cal_size_per_network = atomic_read(&cal_blk[index].cal_size);
+ cal_data_per_network =
+ (u32 *)atomic_read(&cal_blk[index].cal_kvaddr);
pr_debug("Cal size =%d, index=%d\n", cal_size_per_network,
index);
diff --git a/include/linux/msm_audio_acdb.h b/include/linux/msm_audio_acdb.h
index 3d756c2..e7f06b5 100644
--- a/include/linux/msm_audio_acdb.h
+++ b/include/linux/msm_audio_acdb.h
@@ -35,6 +35,13 @@
(AUDIO_MAX_COMMON_IOCTL_NUM+14), unsigned)
#define AUDIO_SET_ASM_TOPOLOGY _IOW(AUDIO_IOCTL_MAGIC, \
(AUDIO_MAX_COMMON_IOCTL_NUM+15), unsigned)
+#define AUDIO_SET_AFE_TX_CAL _IOW(AUDIO_IOCTL_MAGIC, \
+ (AUDIO_MAX_COMMON_IOCTL_NUM+16), unsigned)
+#define AUDIO_SET_AFE_RX_CAL _IOW(AUDIO_IOCTL_MAGIC, \
+ (AUDIO_MAX_COMMON_IOCTL_NUM+17), unsigned)
+
+
+#define AUDIO_MAX_ACDB_IOCTL (AUDIO_MAX_COMMON_IOCTL_NUM+30)
/* ACDB structures */
struct cal_block {
@@ -49,25 +56,26 @@
/* For Real-Time Audio Calibration */
#define AUDIO_GET_RTAC_ADM_INFO _IOR(AUDIO_IOCTL_MAGIC, \
- (AUDIO_MAX_COMMON_IOCTL_NUM+16), unsigned)
+ (AUDIO_MAX_ACDB_IOCTL+1), unsigned)
#define AUDIO_GET_RTAC_VOICE_INFO _IOR(AUDIO_IOCTL_MAGIC, \
- (AUDIO_MAX_COMMON_IOCTL_NUM+17), unsigned)
+ (AUDIO_MAX_ACDB_IOCTL+2), unsigned)
#define AUDIO_GET_RTAC_ADM_CAL _IOWR(AUDIO_IOCTL_MAGIC, \
- (AUDIO_MAX_COMMON_IOCTL_NUM+18), unsigned)
+ (AUDIO_MAX_ACDB_IOCTL+3), unsigned)
#define AUDIO_SET_RTAC_ADM_CAL _IOWR(AUDIO_IOCTL_MAGIC, \
- (AUDIO_MAX_COMMON_IOCTL_NUM+19), unsigned)
+ (AUDIO_MAX_ACDB_IOCTL+4), unsigned)
#define AUDIO_GET_RTAC_ASM_CAL _IOWR(AUDIO_IOCTL_MAGIC, \
- (AUDIO_MAX_COMMON_IOCTL_NUM+20), unsigned)
+ (AUDIO_MAX_ACDB_IOCTL+5), unsigned)
#define AUDIO_SET_RTAC_ASM_CAL _IOWR(AUDIO_IOCTL_MAGIC, \
- (AUDIO_MAX_COMMON_IOCTL_NUM+21), unsigned)
+ (AUDIO_MAX_ACDB_IOCTL+6), unsigned)
#define AUDIO_GET_RTAC_CVS_CAL _IOWR(AUDIO_IOCTL_MAGIC, \
- (AUDIO_MAX_COMMON_IOCTL_NUM+22), unsigned)
+ (AUDIO_MAX_ACDB_IOCTL+7), unsigned)
#define AUDIO_SET_RTAC_CVS_CAL _IOWR(AUDIO_IOCTL_MAGIC, \
- (AUDIO_MAX_COMMON_IOCTL_NUM+23), unsigned)
+ (AUDIO_MAX_ACDB_IOCTL+8), unsigned)
#define AUDIO_GET_RTAC_CVP_CAL _IOWR(AUDIO_IOCTL_MAGIC, \
- (AUDIO_MAX_COMMON_IOCTL_NUM+24), unsigned)
+ (AUDIO_MAX_ACDB_IOCTL+9), unsigned)
#define AUDIO_SET_RTAC_CVP_CAL _IOWR(AUDIO_IOCTL_MAGIC, \
- (AUDIO_MAX_COMMON_IOCTL_NUM+25), unsigned)
+ (AUDIO_MAX_ACDB_IOCTL+10), unsigned)
+#define AUDIO_MAX_RTAC_IOCTL (AUDIO_MAX_ACDB_IOCTL+20)
#endif /* __MSM_AUDIO_ACDB_H */
diff --git a/include/sound/apr_audio.h b/include/sound/apr_audio.h
index 798ed89..30f1a7c 100644
--- a/include/sound/apr_audio.h
+++ b/include/sound/apr_audio.h
@@ -1,7 +1,6 @@
-
/*
*
- * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -353,6 +352,12 @@
struct afe_param_payload payload;
} __attribute__ ((packed));
+struct afe_port_cmd_set_param_no_payload {
+ struct apr_hdr hdr;
+ u16 port_id;
+ u16 payload_size;
+ u32 payload_address;
+} __packed;
#define AFE_EVENT_GET_ACTIVE_PORTS 0x00010100
struct afe_get_active_ports_rsp {
diff --git a/include/sound/q6afe.h b/include/sound/q6afe.h
index 6206838..2d0f53f 100644
--- a/include/sound/q6afe.h
+++ b/include/sound/q6afe.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -76,7 +76,9 @@
int afe_start_pseudo_port(u16 port_id);
int afe_stop_pseudo_port(u16 port_id);
int afe_cmd_memory_map(u32 dma_addr_p, u32 dma_buf_sz);
+int afe_cmd_memory_map_nowait(u32 dma_addr_p, u32 dma_buf_sz);
int afe_cmd_memory_unmap(u32 dma_addr_p);
+int afe_cmd_memory_unmap_nowait(u32 dma_addr_p);
int afe_register_get_events(u16 port_id,
void (*cb) (uint32_t opcode,
diff --git a/sound/soc/msm/qdsp6/q6adm.c b/sound/soc/msm/qdsp6/q6adm.c
index 18dfc01..d8d9c64 100644
--- a/sound/soc/msm/qdsp6/q6adm.c
+++ b/sound/soc/msm/qdsp6/q6adm.c
@@ -457,7 +457,7 @@
int i = 0;
int cmd_size = 0;
- pr_info("%s\n", __func__);
+ pr_debug("%s\n", __func__);
if (this_adm.apr == NULL) {
this_adm.apr = apr_register("ADSP", "ADM", adm_callback,
0xFFFFFFFF, &this_adm);
@@ -532,7 +532,7 @@
int i = 0;
int cmd_size = 0;
- pr_info("%s\n", __func__);
+ pr_debug("%s\n", __func__);
if (this_adm.apr == NULL) {
pr_err("%s APR handle NULL\n", __func__);
diff --git a/sound/soc/msm/qdsp6/q6afe.c b/sound/soc/msm/qdsp6/q6afe.c
index 74a66945..a214529 100644
--- a/sound/soc/msm/qdsp6/q6afe.c
+++ b/sound/soc/msm/qdsp6/q6afe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. 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
@@ -17,6 +17,7 @@
#include <linux/wait.h>
#include <linux/jiffies.h>
#include <linux/sched.h>
+#include <mach/qdsp6v2/audio_acdb.h>
#include <sound/apr_audio.h>
#include <sound/q6afe.h>
@@ -36,6 +37,8 @@
static struct afe_ctl this_afe;
+static uint32_t afe_cal_addr[MAX_AUDPROC_TYPES];
+
#define TIMEOUT_MS 1000
#define Q6AFE_MAX_VOLUME 0x3FFF
@@ -314,6 +317,63 @@
return ret;
}
+static void afe_send_cal_block(int32_t path, u16 port_id)
+{
+ int result = 0;
+ struct acdb_cal_block cal_block;
+ struct afe_port_cmd_set_param_no_payload afe_cal;
+ pr_debug("%s: path %d\n", __func__, path);
+
+ get_afe_cal(path, &cal_block);
+ if (cal_block.cal_size <= 0) {
+ pr_debug("%s: No AFE cal to send!\n", __func__);
+ goto done;
+ }
+
+ if (afe_cal_addr[path] != cal_block.cal_paddr) {
+ if (afe_cal_addr[path] != 0)
+ afe_cmd_memory_unmap_nowait(afe_cal_addr[path]);
+ afe_cmd_memory_map_nowait(cal_block.cal_paddr,
+ cal_block.cal_size);
+ afe_cal_addr[path] = cal_block.cal_paddr;
+ }
+
+ afe_cal.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ afe_cal.hdr.pkt_size = sizeof(afe_cal);
+ afe_cal.hdr.src_port = 0;
+ afe_cal.hdr.dest_port = 0;
+ afe_cal.hdr.token = 0;
+ afe_cal.hdr.opcode = AFE_PORT_CMD_SET_PARAM;
+ afe_cal.port_id = port_id;
+ afe_cal.payload_size = cal_block.cal_size;
+ afe_cal.payload_address = cal_block.cal_paddr;
+
+ pr_debug("%s: AFE cal sent for device port = %d, path = %d, "
+ "cal size = %d, cal addr = 0x%x\n", __func__,
+ port_id, path, cal_block.cal_size, cal_block.cal_paddr);
+
+ result = apr_send_pkt(this_afe.apr, (uint32_t *) &afe_cal);
+ if (result < 0) {
+ pr_err("%s: AFE cal for port %d failed\n",
+ __func__, port_id);
+ }
+
+ pr_debug("%s: AFE cal sent for path %d device!\n", __func__, path);
+done:
+ return;
+}
+
+void afe_send_cal(u16 port_id)
+{
+ pr_debug("%s\n", __func__);
+
+ if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX)
+ afe_send_cal_block(TX_CAL, port_id);
+ else if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_RX)
+ afe_send_cal_block(RX_CAL, port_id);
+}
+
int afe_port_start_nowait(u16 port_id, union afe_port_config *afe_config,
u32 rate) /* This function is no blocking */
{
@@ -365,6 +425,10 @@
ret = -EINVAL;
goto fail_cmd;
}
+
+ /* send AFE cal */
+ afe_send_cal(port_id);
+
start.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
start.hdr.pkt_size = sizeof(start);
@@ -875,6 +939,45 @@
return 0;
}
+int afe_cmd_memory_map_nowait(u32 dma_addr_p, u32 dma_buf_sz)
+{
+ int ret = 0;
+ struct afe_cmd_memory_map mregion;
+
+ pr_debug("%s:\n", __func__);
+
+ if (this_afe.apr == NULL) {
+ this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
+ 0xFFFFFFFF, &this_afe);
+ pr_debug("%s: Register AFE\n", __func__);
+ if (this_afe.apr == NULL) {
+ pr_err("%s: Unable to register AFE\n", __func__);
+ ret = -ENODEV;
+ return ret;
+ }
+ }
+
+ mregion.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ mregion.hdr.pkt_size = sizeof(mregion);
+ mregion.hdr.src_port = 0;
+ mregion.hdr.dest_port = 0;
+ mregion.hdr.token = 0;
+ mregion.hdr.opcode = AFE_SERVICE_CMD_MEMORY_MAP;
+ mregion.phy_addr = dma_addr_p;
+ mregion.mem_sz = dma_buf_sz;
+ mregion.mem_id = 0;
+ mregion.rsvd = 0;
+
+ ret = apr_send_pkt(this_afe.apr, (uint32_t *) &mregion);
+ if (ret < 0) {
+ pr_err("%s: AFE memory map cmd failed %d\n",
+ __func__, ret);
+ ret = -EINVAL;
+ }
+ return 0;
+}
+
int afe_cmd_memory_unmap(u32 dma_addr_p)
{
int ret = 0;
@@ -905,7 +1008,7 @@
atomic_set(&this_afe.state, 1);
ret = apr_send_pkt(this_afe.apr, (uint32_t *) &mregion);
if (ret < 0) {
- pr_err("%s: AFE memory map cmd failed %d\n",
+ pr_err("%s: AFE memory unmap cmd failed %d\n",
__func__, ret);
ret = -EINVAL;
return ret;
@@ -919,7 +1022,42 @@
ret = -EINVAL;
return ret;
}
+ return 0;
+}
+int afe_cmd_memory_unmap_nowait(u32 dma_addr_p)
+{
+ int ret = 0;
+ struct afe_cmd_memory_unmap mregion;
+
+ pr_debug("%s:\n", __func__);
+
+ if (this_afe.apr == NULL) {
+ this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
+ 0xFFFFFFFF, &this_afe);
+ pr_debug("%s: Register AFE\n", __func__);
+ if (this_afe.apr == NULL) {
+ pr_err("%s: Unable to register AFE\n", __func__);
+ ret = -ENODEV;
+ return ret;
+ }
+ }
+
+ mregion.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ mregion.hdr.pkt_size = sizeof(mregion);
+ mregion.hdr.src_port = 0;
+ mregion.hdr.dest_port = 0;
+ mregion.hdr.token = 0;
+ mregion.hdr.opcode = AFE_SERVICE_CMD_MEMORY_UNMAP;
+ mregion.phy_addr = dma_addr_p;
+
+ ret = apr_send_pkt(this_afe.apr, (uint32_t *) &mregion);
+ if (ret < 0) {
+ pr_err("%s: AFE memory unmap cmd failed %d\n",
+ __func__, ret);
+ ret = -EINVAL;
+ }
return 0;
}
@@ -1389,12 +1527,17 @@
static void __exit afe_exit(void)
{
+ int i;
#ifdef CONFIG_DEBUG_FS
if (debugfs_afelb)
debugfs_remove(debugfs_afelb);
if (debugfs_afelb_gain)
debugfs_remove(debugfs_afelb_gain);
#endif
+ for (i = 0; i < MAX_AUDPROC_TYPES; i++) {
+ if (afe_cal_addr[i] != 0)
+ afe_cmd_memory_unmap_nowait(afe_cal_addr[i]);
+ }
}
device_initcall(afe_init);