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

Commit 3d1596e2 authored by Sudheer Papothi's avatar Sudheer Papothi Committed by Karthikeyan Mani
Browse files

soc: swr-mstr: Add support for platform specific port configuration



Different platforms have different configuration for soundwire
ports. Add support to get the port configuration information
from the machine driver.

Change-Id: If2c006c4d4a43e2a8dc67c076f6d1c0f36eae16b
Signed-off-by: default avatarSudheer Papothi <spapothi@codeaurora.org>
parent d0dd6a62
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved.
 */

#ifndef _LINUX_SWR_COMMON_H
#define _LINUX_SWR_COMMON_H
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/bitops.h>

enum {
	SWR_UC0 = 0,
	SWR_UC1,
	SWR_UC_MAX,
};

struct port_params {
	u8 si;
	u8 off1;
	u8 off2;
	u8 hstart;/* head start */
	u8 hstop; /* head stop */
	u8 wd_len;/* word length */
	u8 bp_mode; /* block pack mode */
	u8 bgp_ctrl;/* block group control */
	u8 lane_ctrl;/* lane to be used */
};

struct swrm_port_config {
	u32 size;
	u32 uc;
	void *params;
};

struct swr_mstr_port_map {
	u32 id;
	u32 uc;
	struct port_params *swr_port_params;
};

#define SWR_MSTR_PORT_LEN      8 /* Number of master ports */

#endif /* _LINUX_SWR_COMMON_H */
+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ enum {
	SWR_DEVICE_SSR_DOWN,
	SWR_DEVICE_SSR_UP,
	SWR_REGISTER_WAKE_IRQ,
	SWR_SET_PORT_MAP,
};

struct swr_mstr_port {
+71 −1
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <soc/soundwire.h>
#include <soc/swr-wcd.h>
#include <soc/swr-common.h>
#include <linux/regmap.h>
#include <dsp/msm-audio-event-notify.h>
#include "swrm_registers.h"
@@ -28,6 +28,7 @@

#define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700
#define SWRM_SYS_SUSPEND_WAIT 1

#define SWR_BROADCAST_CMD_ID            0x0F
#define SWR_AUTO_SUSPEND_DELAY          3 /* delay in sec */
#define SWR_DEV_ID_MASK			0xFFFFFFFFFFFF
@@ -2187,6 +2188,53 @@ int swrm_register_wake_irq(struct swr_mstr_ctrl *swrm)
	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
 * this function
@@ -2200,6 +2248,7 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data)
	int ret = 0;
	struct swr_master *mstr;
	struct swr_device *swr_dev;
	struct swrm_port_config *port_cfg;

	if (!pdev) {
		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);
		}
		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:
		dev_err(swrm->dev, "%s: swr master unknown id %d\n",
			__func__, id);
+3 −12
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <soc/swr-wcd.h>
#include <linux/pm_qos.h>
#include <soc/qcom/pm.h>
#include <soc/swr-common.h>

#define SWR_ROW_48		0
#define SWR_ROW_50		1
@@ -61,18 +62,6 @@ struct usecase {
	u32 chrate;
};

struct port_params {
	u8 si;
	u8 off1;
	u8 off2;
	u8 hstart;/* head start */
	u8 hstop; /* head stop */
	u8 wd_len;/* word length */
	u8 bp_mode; /* block pack mode */
	u8 bgp_ctrl;/* block group control */
	u8 lane_ctrl;/* lane to be used */
};

struct swrm_mports {
	struct list_head port_req_list;
	bool port_en;
@@ -163,6 +152,8 @@ struct swr_mstr_ctrl {
	wait_queue_head_t pm_wq;
	int wlock_holders;
	u32 intr_mask;
	struct port_params **port_param;
	u8 num_usecase;
};

#endif /* _SWR_WCD_CTRL_H */