Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf4f4c7a authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: wcd_cpe_core: Add LSM topology support"

parents f03ce74a bc36743b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -94,6 +94,8 @@ enum {

	CORE_CUSTOM_TOPOLOGIES_CAL_TYPE,
	ADM_RTAC_AUDVOL_CAL_TYPE,

	ULP_LSM_TOPOLOGY_ID_CAL_TYPE,
	MAX_CAL_TYPES,
};

+180 −1
Original line number Diff line number Diff line
@@ -64,7 +64,7 @@
#define WCD_CPE_STATE_MAX_LEN 11
#define CPE_OFFLINE_WAIT_TIMEOUT (2 * HZ)
#define CPE_READY_WAIT_TIMEOUT (3 * HZ)

#define WCD_CPE_SYSFS_DIR_MAX_LENGTH 32

#define CPE_ERR_IRQ_CB(core) \
	(core->cpe_cdc_cb->cpe_err_irq_control)
@@ -107,6 +107,25 @@ static u32 ramdump_enable;

static int wcd_cpe_afe_svc_cmd_mode(void *core_handle,
				    u8 mode);
struct wcd_cpe_attribute {
	struct attribute attr;
	ssize_t (*show)(struct wcd_cpe_core *core, char *buf);
	ssize_t (*store)(struct wcd_cpe_core *core, const char *buf,
			 ssize_t count);
};

#define WCD_CPE_ATTR(_name, _mode, _show, _store) \
static struct wcd_cpe_attribute cpe_attr_##_name = { \
	.attr = {.name = __stringify(_name), .mode = _mode}, \
	.show = _show, \
	.store = _store, \
}

#define to_wcd_cpe_attr(a) \
	container_of((a), struct wcd_cpe_attribute, attr)

#define kobj_to_cpe_core(kobj) \
	container_of((kobj), struct wcd_cpe_core, cpe_kobj)

/* wcd_cpe_lsm_session_active: check if any session is active
 * return true if any session is active.
@@ -726,6 +745,49 @@ static struct snd_info_entry_ops wcd_cpe_state_proc_ops = {
	.poll = wcd_cpe_state_poll,
};

static int wcd_cpe_check_new_image(struct wcd_cpe_core *core)
{
	int rc = 0;
	char temp_img_name[WCD_CPE_IMAGE_FNAME_MAX];

	if (!strcmp(core->fname, core->dyn_fname) &&
	    core->ssr_type != WCD_CPE_INITIALIZED) {
		dev_dbg(core->dev,
			"%s: Firmware unchanged, fname = %s, ssr_type 0x%x\n",
			__func__, core->fname, core->ssr_type);
		goto done;
	}

	/*
	 * Different firmware name requested,
	 * Re-load the instruction section
	 */
	strlcpy(temp_img_name, core->fname,
		WCD_CPE_IMAGE_FNAME_MAX);
	strlcpy(core->fname, core->dyn_fname,
		WCD_CPE_IMAGE_FNAME_MAX);

	rc = wcd_cpe_load_fw(core, ELF_FLAG_EXECUTE);
	if (rc) {
		dev_err(core->dev,
			"%s: Failed to dload new image %s, err = %d\n",
			__func__, core->fname, rc);
		/* If new image download failed, revert back to old image */
		strlcpy(core->fname, temp_img_name,
			WCD_CPE_IMAGE_FNAME_MAX);
		rc = wcd_cpe_load_fw(core, ELF_FLAG_EXECUTE);
		if (rc)
			dev_err(core->dev,
				"%s: Failed to re-dload image %s, err = %d\n",
				__func__, core->fname, rc);
	} else {
		dev_info(core->dev, "%s: fw changed to %s\n",
			 __func__, core->fname);
	}
done:
	return rc;
}

static int wcd_cpe_enable(struct wcd_cpe_core *core,
		bool enable)
{
@@ -739,6 +801,10 @@ static int wcd_cpe_enable(struct wcd_cpe_core *core,
				__func__, ret);
			goto done;
		}
		ret = wcd_cpe_check_new_image(core);
		if (ret)
			goto fail_boot;

		/* Dload data section */
		ret = wcd_cpe_load_fw(core, ELF_FLAG_RW);
		if (ret) {
@@ -1393,6 +1459,11 @@ static int wcd_cpe_get_cal_index(int32_t cal_type)
		cal_index = WCD_CPE_LSM_CAL_AFE;
	else if (cal_type == ULP_LSM_CAL_TYPE)
		cal_index = WCD_CPE_LSM_CAL_LSM;
	else if (cal_type == ULP_LSM_TOPOLOGY_ID_CAL_TYPE)
		cal_index = WCD_CPE_LSM_CAL_TOPOLOGY_ID;
	else
		pr_err("%s: invalid cal_type %d\n",
			__func__, cal_type);

	return cal_index;
}
@@ -1474,6 +1545,11 @@ static int wcd_cpe_cal_init(struct wcd_cpe_core *core)
		 {wcd_cpe_alloc_cal, wcd_cpe_dealloc_cal, NULL,
		  wcd_cpe_set_cal, NULL, NULL} },
		 {NULL, NULL, cal_utils_match_buf_num} },

		{{ULP_LSM_TOPOLOGY_ID_CAL_TYPE,
		 {wcd_cpe_alloc_cal, wcd_cpe_dealloc_cal, NULL,
		  wcd_cpe_set_cal, NULL, NULL} },
		 {NULL, NULL, cal_utils_match_buf_num} },
	};

	ret = cal_utils_create_cal_types(WCD_CPE_LSM_CAL_MAX,
@@ -1576,6 +1652,106 @@ err_create_dir:
	return rc;
}

static ssize_t fw_name_show(struct wcd_cpe_core *core, char *buf)
{
	return snprintf(buf, WCD_CPE_IMAGE_FNAME_MAX, "%s",
			core->dyn_fname);
}

static ssize_t fw_name_store(struct wcd_cpe_core *core,
		const char *buf, ssize_t count)
{
	int copy_count = count;
	const char *pos;

	pos = memchr(buf, '\n', count);
	if (pos)
		copy_count = pos - buf;

	if (copy_count > WCD_CPE_IMAGE_FNAME_MAX) {
		dev_err(core->dev,
			"%s: Invalid length %d, max allowed %d\n",
			__func__, copy_count, WCD_CPE_IMAGE_FNAME_MAX);
		return -EINVAL;
	}

	strlcpy(core->dyn_fname, buf, copy_count + 1);

	return count;
}

WCD_CPE_ATTR(fw_name, 0660, fw_name_show, fw_name_store);

static ssize_t wcd_cpe_sysfs_show(struct kobject *kobj,
		struct attribute *attr, char *buf)
{
	struct wcd_cpe_attribute *cpe_attr = to_wcd_cpe_attr(attr);
	struct wcd_cpe_core *core = kobj_to_cpe_core(kobj);
	ssize_t ret = -EINVAL;

	if (core && cpe_attr->show)
		ret = cpe_attr->show(core, buf);

	return ret;
}

static ssize_t wcd_cpe_sysfs_store(struct kobject *kobj,
		struct attribute *attr, const char *buf,
		size_t count)
{
	struct wcd_cpe_attribute *cpe_attr = to_wcd_cpe_attr(attr);
	struct wcd_cpe_core *core = kobj_to_cpe_core(kobj);
	ssize_t ret = -EINVAL;

	if (core && cpe_attr->store)
		ret = cpe_attr->store(core, buf, count);

	return ret;
}

static const struct sysfs_ops wcd_cpe_sysfs_ops = {
	.show = wcd_cpe_sysfs_show,
	.store = wcd_cpe_sysfs_store,
};

static struct kobj_type wcd_cpe_ktype = {
	.sysfs_ops = &wcd_cpe_sysfs_ops,
};

static int wcd_cpe_sysfs_init(struct wcd_cpe_core *core, int id)
{
	char sysfs_dir_name[WCD_CPE_SYSFS_DIR_MAX_LENGTH];
	int rc = 0;

	snprintf(sysfs_dir_name, WCD_CPE_SYSFS_DIR_MAX_LENGTH,
		 "%s%d", "wcd_cpe", id);

	rc = kobject_init_and_add(&core->cpe_kobj, &wcd_cpe_ktype,
				  kernel_kobj,
				  sysfs_dir_name);
	if (unlikely(rc)) {
		dev_err(core->dev,
			"%s: Failed to add kobject %s, err = %d\n",
			__func__, sysfs_dir_name, rc);
		goto done;
	}

	rc = sysfs_create_file(&core->cpe_kobj, &cpe_attr_fw_name.attr);
	if (rc) {
		dev_err(core->dev,
			"%s: Failed to fw_name sysfs entry to %s\n",
			__func__, sysfs_dir_name);
		goto fail_create_file;
	}

	return 0;

fail_create_file:
	kobject_put(&core->cpe_kobj);
done:
	return rc;
}

static int wcd_cpe_validate_params(
	struct snd_soc_codec *codec,
	struct wcd_cpe_params *params)
@@ -1638,6 +1814,7 @@ struct wcd_cpe_core *wcd_cpe_init(const char *img_fname,
	}

	snprintf(core->fname, sizeof(core->fname), "%s", img_fname);
	strlcpy(core->dyn_fname, core->fname, WCD_CPE_IMAGE_FNAME_MAX);

	wcd_get_cpe_core = params->get_cpe_core;

@@ -1733,6 +1910,8 @@ struct wcd_cpe_core *wcd_cpe_init(const char *img_fname,

	wcd_cpe_debugfs_init(core);

	wcd_cpe_sysfs_init(core, id);

	/* Setup the ramdump device and buffer */
	core->cpe_ramdump_dev = create_ramdump_device("cpe",
						      core->dev);
+10 −1
Original line number Diff line number Diff line
@@ -34,9 +34,12 @@
#define WCD_CPE_LOAD_ALL \
	(WCD_CPE_LOAD_IMEM | WCD_CPE_LOAD_DATA)

#define WCD_CPE_IMAGE_FNAME_MAX 64

enum {
	WCD_CPE_LSM_CAL_AFE = 0,
	WCD_CPE_LSM_CAL_LSM,
	WCD_CPE_LSM_CAL_TOPOLOGY_ID,
	WCD_CPE_LSM_CAL_MAX,
};

@@ -111,7 +114,10 @@ struct wcd_cpe_core {
	struct device *dev;

	/* firmware image file name */
	char fname[64];
	char fname[WCD_CPE_IMAGE_FNAME_MAX];

	/* firmware image file name from sysfs */
	char dyn_fname[WCD_CPE_IMAGE_FNAME_MAX];

	/* codec information needed by cpe services */
	struct cpe_svc_codec_info_v1 cdc_info;
@@ -173,6 +179,9 @@ struct wcd_cpe_core {

	/* IRQ information for CPE interrupts */
	struct wcd_cpe_irq_info irq_info;

	/* Kobject for sysfs entry */
	struct kobject cpe_kobj;
};

struct wcd_cpe_params {
+6 −0
Original line number Diff line number Diff line
@@ -107,6 +107,9 @@ size_t get_cal_info_size(int32_t cal_type)
	case LSM_TOPOLOGY_CAL_TYPE:
		size = sizeof(struct audio_cal_info_lsm_top);
		break;
	case ULP_LSM_TOPOLOGY_ID_CAL_TYPE:
		size = sizeof(struct audio_cal_info_lsm_top);
		break;
	case LSM_CAL_TYPE:
		size = sizeof(struct audio_cal_info_lsm);
		break;
@@ -234,6 +237,9 @@ size_t get_user_cal_type_size(int32_t cal_type)
	case LSM_TOPOLOGY_CAL_TYPE:
		size = sizeof(struct audio_cal_type_lsm_top);
		break;
	case ULP_LSM_TOPOLOGY_ID_CAL_TYPE:
		size = sizeof(struct audio_cal_type_lsm_top);
		break;
	case LSM_CAL_TYPE:
		size = sizeof(struct audio_cal_type_lsm);
		break;