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

Commit c77b19f5 authored by Bhalchandra Gajare's avatar Bhalchandra Gajare Committed by Gerrit - the friendly Code Review server
Browse files

soc: wcd-spi-ac: add wcd spi access control driver



Add driver to perform WCD SPI bus arbitration between two
masters. The two masters could reside on two different
processors and QMI is used to arbitrate the bus access.
This driver also exposes character driver interface to
userspace to indicate use case start/stop, etc.

Change-Id: I4f6fe6bb0bca524f10a34cf89149c6b2055b00e1
Signed-off-by: default avatarBhalchandra Gajare <gajare@codeaurora.org>
parent e039f16f
Loading
Loading
Loading
Loading
+44 −0
Original line number Diff line number Diff line
/* Copyright (c) 2018-2019, 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
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#ifndef __WCD_SPI_AC_H__
#define __WCD_SPI_AC_H__

#include <linux/types.h>
#include <linux/bitops.h>

enum wcd_spi_acc_req {
	WCD_SPI_ACCESS_REQUEST,
	WCD_SPI_ACCESS_RELEASE,
	WCD_SPI_ACCESS_MAX,
};

#define WCD_SPI_AC_DATA_TRANSFER	BIT(0)
#define WCD_SPI_AC_CONCURRENCY		BIT(1)
#define WCD_SPI_AC_REMOTE_DOWN		BIT(2)
#define WCD_SPI_AC_SVC_OFFLINE		BIT(3)
#define WCD_SPI_AC_UNINITIALIZED	BIT(4)

#if IS_ENABLED(CONFIG_WCD_SPI_AC)
int wcd_spi_access_ctl(struct device *dev,
		       enum wcd_spi_acc_req req,
		       u32 reason);
#else
int wcd_spi_access_ctl(struct device *dev,
		       enum wcd_spi_acc_req req,
		       u32 reason)
{
	return 0;
}
#endif /* end of CONFIG_WCD_SPI_AC */

#endif /* end of __WCD_SPI_AC_H__ */
+8 −0
Original line number Diff line number Diff line
@@ -101,6 +101,11 @@ ifdef CONFIG_SND_EVENT
	SND_EVENT_OBJS += snd_event.o
endif

ifdef CONFIG_WCD_SPI_AC
	WCD_SPI_ACC_CTL_OBJS += wcd-spi-ac.o
	WCD_SPI_ACC_CTL_OBJS += wcd_spi_ctl_v01.o
endif

LINUX_INC +=	-Iinclude/linux

INCS +=		$(COMMON_INC) \
@@ -159,5 +164,8 @@ obj-$(CONFIG_SOUNDWIRE_WCD_CTRL) += swr_ctrl_dlkm.o
obj-$(CONFIG_SOUNDWIRE_MSTR_CTRL) += swr_ctrl_dlkm.o
swr_ctrl_dlkm-y := $(SWR_CTRL_OBJS)

obj-$(CONFIG_WCD_SPI_AC) += wcd_spi_acc_ctl_dlkm.o
wcd_spi_acc_ctl_dlkm-y := $(WCD_SPI_ACC_CTL_OBJS)

# inject some build related information
DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\"

soc/wcd-spi-ac.c

0 → 100644
+998 −0

File added.

Preview size limit exceeded, changes collapsed.

soc/wcd_spi_ctl_v01.c

0 → 100644
+138 −0
Original line number Diff line number Diff line
/* Copyright (c) 2018-2019, 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
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */
#include <linux/qmi_encdec.h>
#include <soc/qcom/msm_qmi_interface.h>
#include "wcd_spi_ctl_v01.h"

struct elem_info wcd_spi_req_access_msg_v01_ei[] = {
	{
		.data_type      = QMI_OPT_FLAG,
		.elem_len       = 1,
		.elem_size      = sizeof(u8),
		.is_array       = NO_ARRAY,
		.tlv_type       = 0x10,
		.offset         = offsetof(struct wcd_spi_req_access_msg_v01,
					   reason_valid),
	},
	{
		.data_type      = QMI_UNSIGNED_8_BYTE,
		.elem_len       = 1,
		.elem_size      = sizeof(u64),
		.is_array       = NO_ARRAY,
		.tlv_type       = 0x10,
		.offset         = offsetof(struct wcd_spi_req_access_msg_v01,
					   reason),
	},
	{
		.data_type      = QMI_EOTI,
		.is_array       = NO_ARRAY,
		.tlv_type       = QMI_COMMON_TLV_TYPE,
	},
};

struct elem_info wcd_spi_req_access_resp_v01_ei[] = {
	{
		.data_type      = QMI_STRUCT,
		.elem_len       = 1,
		.elem_size      = sizeof(struct qmi_response_type_v01),
		.is_array       = NO_ARRAY,
		.tlv_type       = 0x02,
		.offset         = offsetof(struct wcd_spi_req_access_resp_v01,
					   resp),
		.ei_array      = get_qmi_response_type_v01_ei(),
	},
	{
		.data_type      = QMI_EOTI,
		.is_array       = NO_ARRAY,
		.tlv_type       = QMI_COMMON_TLV_TYPE,
	},
};

struct elem_info wcd_spi_rel_access_msg_v01_ei[] = {
	{
		.data_type      = QMI_EOTI,
		.is_array       = NO_ARRAY,
		.tlv_type       = QMI_COMMON_TLV_TYPE,
	},
};

struct elem_info wcd_spi_rel_access_resp_v01_ei[] = {
	{
		.data_type      = QMI_STRUCT,
		.elem_len       = 1,
		.elem_size      = sizeof(struct qmi_response_type_v01),
		.is_array       = NO_ARRAY,
		.tlv_type       = 0x02,
		.offset         = offsetof(struct wcd_spi_rel_access_resp_v01,
					   resp),
		.ei_array      = get_qmi_response_type_v01_ei(),
	},
	{
		.data_type      = QMI_EOTI,
		.is_array       = NO_ARRAY,
		.tlv_type       = QMI_COMMON_TLV_TYPE,
	},
};

struct elem_info wcd_spi_buff_msg_v01_ei[] = {
	{
		.data_type      = QMI_UNSIGNED_4_BYTE,
		.elem_len       = WCD_SPI_BUFF_CHANNELS_MAX_V01,
		.elem_size      = sizeof(u32),
		.is_array       = STATIC_ARRAY,
		.tlv_type       = 0x01,
		.offset         = offsetof(struct wcd_spi_buff_msg_v01,
					   buff_addr_1),
	},
	{
		.data_type      = QMI_OPT_FLAG,
		.elem_len       = 1,
		.elem_size      = sizeof(u8),
		.is_array       = NO_ARRAY,
		.tlv_type       = 0x10,
		.offset         = offsetof(struct wcd_spi_buff_msg_v01,
					   buff_addr_2_valid),
	},
	{
		.data_type      = QMI_UNSIGNED_4_BYTE,
		.elem_len       = WCD_SPI_BUFF_CHANNELS_MAX_V01,
		.elem_size      = sizeof(u32),
		.is_array       = STATIC_ARRAY,
		.tlv_type       = 0x10,
		.offset         = offsetof(struct wcd_spi_buff_msg_v01,
					   buff_addr_2),
	},
	{
		.data_type      = QMI_EOTI,
		.is_array       = NO_ARRAY,
		.tlv_type       = QMI_COMMON_TLV_TYPE,
	},
};

struct elem_info wcd_spi_buff_resp_v01_ei[] = {
	{
		.data_type      = QMI_STRUCT,
		.elem_len       = 1,
		.elem_size      = sizeof(struct qmi_response_type_v01),
		.is_array       = NO_ARRAY,
		.tlv_type       = 0x02,
		.offset         = offsetof(struct wcd_spi_buff_resp_v01,
					   resp),
		.ei_array      = get_qmi_response_type_v01_ei(),
	},
	{
		.data_type      = QMI_EOTI,
		.is_array       = NO_ARRAY,
		.tlv_type       = QMI_COMMON_TLV_TYPE,
	},
};

soc/wcd_spi_ctl_v01.h

0 → 100644
+71 −0
Original line number Diff line number Diff line
/* Copyright (c) 2018-2019, 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
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */
#ifndef WCD_SPI_CTL_V01_H
#define WCD_SPI_CTL_V01_H

#define WCD_SPI_CTL_SERVICE_ID_V01 0x421
#define WCD_SPI_CTL_SERVICE_VERS_V01 0x01

#define WCD_SPI_BUFF_RESP_V01 0x0022
#define WCD_SPI_REL_ACCESS_RESP_V01 0x0021
#define WCD_SPI_REQ_ACCESS_MSG_V01 0x0020
#define WCD_SPI_BUFF_MSG_V01 0x0022
#define WCD_SPI_REL_ACCESS_MSG_V01 0x0021
#define WCD_SPI_REQ_ACCESS_RESP_V01 0x0020

#define WCD_SPI_BUFF_CHANNELS_MAX_V01 0x08

#define WCD_SPI_REQ_DATA_TRANSFER_V01 ((u64)0x01ULL)
#define WCD_SPI_REQ_CONCURRENCY_V01 ((u64)0x02ULL)
#define WCD_SPI_REQ_REMOTE_DOWN_V01 ((u64)0x04ULL)

struct wcd_spi_req_access_msg_v01 {
	u8 reason_valid;
	u64 reason;
};
#define WCD_SPI_REQ_ACCESS_MSG_V01_MAX_MSG_LEN 11
extern struct elem_info wcd_spi_req_access_msg_v01_ei[];

struct wcd_spi_req_access_resp_v01 {
	struct qmi_response_type_v01 resp;
};
#define WCD_SPI_REQ_ACCESS_RESP_V01_MAX_MSG_LEN 7
extern struct elem_info wcd_spi_req_access_resp_v01_ei[];

struct wcd_spi_rel_access_msg_v01 {
	char placeholder;
};
#define WCD_SPI_REL_ACCESS_MSG_V01_MAX_MSG_LEN 0
extern struct elem_info wcd_spi_rel_access_msg_v01_ei[];

struct wcd_spi_rel_access_resp_v01 {
	struct qmi_response_type_v01 resp;
};
#define WCD_SPI_REL_ACCESS_RESP_V01_MAX_MSG_LEN 7
extern struct elem_info wcd_spi_rel_access_resp_v01_ei[];

struct wcd_spi_buff_msg_v01 {
	u32 buff_addr_1[WCD_SPI_BUFF_CHANNELS_MAX_V01];
	u8 buff_addr_2_valid;
	u32 buff_addr_2[WCD_SPI_BUFF_CHANNELS_MAX_V01];
};
#define WCD_SPI_BUFF_MSG_V01_MAX_MSG_LEN 70
extern struct elem_info wcd_spi_buff_msg_v01_ei[];

struct wcd_spi_buff_resp_v01 {
	struct qmi_response_type_v01 resp;
};
#define WCD_SPI_BUFF_RESP_V01_MAX_MSG_LEN 7
extern struct elem_info wcd_spi_buff_resp_v01_ei[];

#endif