|
@@ -19,7 +19,7 @@
|
|
#include <linux/debugfs.h>
|
|
#include <linux/debugfs.h>
|
|
#include <linux/uaccess.h>
|
|
#include <linux/uaccess.h>
|
|
#include <soc/soundwire.h>
|
|
#include <soc/soundwire.h>
|
|
-#include <soc/swr-wcd.h>
|
|
|
|
|
|
+#include <soc/swr-common.h>
|
|
#include <linux/regmap.h>
|
|
#include <linux/regmap.h>
|
|
#include <dsp/msm-audio-event-notify.h>
|
|
#include <dsp/msm-audio-event-notify.h>
|
|
#include "swrm_registers.h"
|
|
#include "swrm_registers.h"
|
|
@@ -28,6 +28,7 @@
|
|
|
|
|
|
#define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700
|
|
#define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700
|
|
#define SWRM_SYS_SUSPEND_WAIT 1
|
|
#define SWRM_SYS_SUSPEND_WAIT 1
|
|
|
|
+
|
|
#define SWR_BROADCAST_CMD_ID 0x0F
|
|
#define SWR_BROADCAST_CMD_ID 0x0F
|
|
#define SWR_AUTO_SUSPEND_DELAY 3 /* delay in sec */
|
|
#define SWR_AUTO_SUSPEND_DELAY 3 /* delay in sec */
|
|
#define SWR_DEV_ID_MASK 0xFFFFFFFFFFFF
|
|
#define SWR_DEV_ID_MASK 0xFFFFFFFFFFFF
|
|
@@ -2187,6 +2188,53 @@ int swrm_register_wake_irq(struct swr_mstr_ctrl *swrm)
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int swrm_alloc_port_mem(struct device *dev, struct swr_mstr_ctrl *swrm,
|
|
|
|
+ u32 uc, u32 size)
|
|
|
|
+{
|
|
|
|
+ if (!swrm->port_param) {
|
|
|
|
+ swrm->port_param = devm_kzalloc(dev,
|
|
|
|
+ sizeof(swrm->port_param) * SWR_UC_MAX,
|
|
|
|
+ GFP_KERNEL);
|
|
|
|
+ if (!swrm->port_param)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ }
|
|
|
|
+ if (!swrm->port_param[uc]) {
|
|
|
|
+ swrm->port_param[uc] = devm_kcalloc(dev, size,
|
|
|
|
+ sizeof(struct port_params),
|
|
|
|
+ GFP_KERNEL);
|
|
|
|
+ if (!swrm->port_param[uc])
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ } else {
|
|
|
|
+ dev_err_ratelimited(swrm->dev, "%s: called more than once\n",
|
|
|
|
+ __func__);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int swrm_copy_port_config(struct swr_mstr_ctrl *swrm,
|
|
|
|
+ struct swrm_port_config *port_cfg,
|
|
|
|
+ u32 size)
|
|
|
|
+{
|
|
|
|
+ int idx;
|
|
|
|
+ struct port_params *params;
|
|
|
|
+ int uc = port_cfg->uc;
|
|
|
|
+ int ret = 0;
|
|
|
|
+
|
|
|
|
+ for (idx = 0; idx < size; idx++) {
|
|
|
|
+ params = &((struct port_params *)port_cfg->params)[idx];
|
|
|
|
+ if (!params) {
|
|
|
|
+ dev_err(swrm->dev, "%s: Invalid params\n", __func__);
|
|
|
|
+ ret = -EINVAL;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ memcpy(&swrm->port_param[uc][idx], params,
|
|
|
|
+ sizeof(struct port_params));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* swrm_wcd_notify - parent device can notify to soundwire master through
|
|
* swrm_wcd_notify - parent device can notify to soundwire master through
|
|
* this function
|
|
* this function
|
|
@@ -2200,6 +2248,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
|
|
int ret = 0;
|
|
int ret = 0;
|
|
struct swr_master *mstr;
|
|
struct swr_master *mstr;
|
|
struct swr_device *swr_dev;
|
|
struct swr_device *swr_dev;
|
|
|
|
+ struct swrm_port_config *port_cfg;
|
|
|
|
|
|
if (!pdev) {
|
|
if (!pdev) {
|
|
pr_err("%s: pdev is NULL\n", __func__);
|
|
pr_err("%s: pdev is NULL\n", __func__);
|
|
@@ -2327,6 +2376,27 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
|
|
mutex_unlock(&swrm->mlock);
|
|
mutex_unlock(&swrm->mlock);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
|
|
+ case SWR_SET_PORT_MAP:
|
|
|
|
+ if (!data) {
|
|
|
|
+ dev_err(swrm->dev, "%s: data is NULL for id=%d\n",
|
|
|
|
+ __func__, id);
|
|
|
|
+ ret = -EINVAL;
|
|
|
|
+ } else {
|
|
|
|
+ mutex_lock(&swrm->mlock);
|
|
|
|
+ port_cfg = (struct swrm_port_config *)data;
|
|
|
|
+ if (!port_cfg->size) {
|
|
|
|
+ ret = -EINVAL;
|
|
|
|
+ goto done;
|
|
|
|
+ }
|
|
|
|
+ ret = swrm_alloc_port_mem(&pdev->dev, swrm,
|
|
|
|
+ port_cfg->uc, port_cfg->size);
|
|
|
|
+ if (!ret)
|
|
|
|
+ swrm_copy_port_config(swrm, port_cfg,
|
|
|
|
+ port_cfg->size);
|
|
|
|
+done:
|
|
|
|
+ mutex_unlock(&swrm->mlock);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
dev_err(swrm->dev, "%s: swr master unknown id %d\n",
|
|
dev_err(swrm->dev, "%s: swr master unknown id %d\n",
|
|
__func__, id);
|
|
__func__, id);
|