162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef __Q6APM_H__ 362306a36Sopenharmony_ci#define __Q6APM_H__ 462306a36Sopenharmony_ci#include <linux/types.h> 562306a36Sopenharmony_ci#include <linux/slab.h> 662306a36Sopenharmony_ci#include <linux/wait.h> 762306a36Sopenharmony_ci#include <linux/kernel.h> 862306a36Sopenharmony_ci#include <linux/module.h> 962306a36Sopenharmony_ci#include <linux/sched.h> 1062306a36Sopenharmony_ci#include <linux/of.h> 1162306a36Sopenharmony_ci#include <linux/delay.h> 1262306a36Sopenharmony_ci#include <sound/soc.h> 1362306a36Sopenharmony_ci#include <linux/of_platform.h> 1462306a36Sopenharmony_ci#include <linux/jiffies.h> 1562306a36Sopenharmony_ci#include <linux/soc/qcom/apr.h> 1662306a36Sopenharmony_ci#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h> 1762306a36Sopenharmony_ci#include "audioreach.h" 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define APM_PORT_MAX 127 2062306a36Sopenharmony_ci#define APM_PORT_MAX_AUDIO_CHAN_CNT 8 2162306a36Sopenharmony_ci#define PCM_CHANNEL_NULL 0 2262306a36Sopenharmony_ci#define PCM_CHANNEL_FL 1 /* Front left channel. */ 2362306a36Sopenharmony_ci#define PCM_CHANNEL_FR 2 /* Front right channel. */ 2462306a36Sopenharmony_ci#define PCM_CHANNEL_FC 3 /* Front center channel. */ 2562306a36Sopenharmony_ci#define PCM_CHANNEL_LS 4 /* Left surround channel. */ 2662306a36Sopenharmony_ci#define PCM_CHANNEL_RS 5 /* Right surround channel. */ 2762306a36Sopenharmony_ci#define PCM_CHANNEL_LFE 6 /* Low frequency effect channel. */ 2862306a36Sopenharmony_ci#define PCM_CHANNEL_CS 7 /* Center surround channel; Rear center ch */ 2962306a36Sopenharmony_ci#define PCM_CHANNEL_LB 8 /* Left back channel; Rear left channel. */ 3062306a36Sopenharmony_ci#define PCM_CHANNEL_RB 9 /* Right back channel; Rear right channel. */ 3162306a36Sopenharmony_ci#define PCM_CHANNELS 10 /* Top surround channel. */ 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#define APM_TIMESTAMP_FLAG 0x80000000 3462306a36Sopenharmony_ci#define FORMAT_LINEAR_PCM 0x0000 3562306a36Sopenharmony_ci/* APM client callback events */ 3662306a36Sopenharmony_ci#define APM_CMD_EOS 0x0003 3762306a36Sopenharmony_ci#define APM_CLIENT_EVENT_CMD_EOS_DONE 0x1003 3862306a36Sopenharmony_ci#define APM_CMD_CLOSE 0x0004 3962306a36Sopenharmony_ci#define APM_CLIENT_EVENT_CMD_CLOSE_DONE 0x1004 4062306a36Sopenharmony_ci#define APM_CLIENT_EVENT_CMD_RUN_DONE 0x1008 4162306a36Sopenharmony_ci#define APM_CLIENT_EVENT_DATA_WRITE_DONE 0x1009 4262306a36Sopenharmony_ci#define APM_CLIENT_EVENT_DATA_READ_DONE 0x100a 4362306a36Sopenharmony_ci#define APM_WRITE_TOKEN_MASK GENMASK(15, 0) 4462306a36Sopenharmony_ci#define APM_WRITE_TOKEN_LEN_MASK GENMASK(31, 16) 4562306a36Sopenharmony_ci#define APM_WRITE_TOKEN_LEN_SHIFT 16 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci#define APM_MAX_SESSIONS 8 4862306a36Sopenharmony_ci#define APM_LAST_BUFFER_FLAG BIT(30) 4962306a36Sopenharmony_ci#define NO_TIMESTAMP 0xFF00 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistruct q6apm { 5262306a36Sopenharmony_ci struct device *dev; 5362306a36Sopenharmony_ci gpr_port_t *port; 5462306a36Sopenharmony_ci gpr_device_t *gdev; 5562306a36Sopenharmony_ci /* For Graph OPEN/START/STOP/CLOSE operations */ 5662306a36Sopenharmony_ci wait_queue_head_t wait; 5762306a36Sopenharmony_ci struct gpr_ibasic_rsp_result_t result; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci struct mutex cmd_lock; 6062306a36Sopenharmony_ci struct mutex lock; 6162306a36Sopenharmony_ci uint32_t state; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci struct list_head widget_list; 6462306a36Sopenharmony_ci struct idr graph_idr; 6562306a36Sopenharmony_ci struct idr graph_info_idr; 6662306a36Sopenharmony_ci struct idr sub_graphs_idr; 6762306a36Sopenharmony_ci struct idr containers_idr; 6862306a36Sopenharmony_ci struct idr modules_idr; 6962306a36Sopenharmony_ci}; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_cistruct audio_buffer { 7262306a36Sopenharmony_ci phys_addr_t phys; 7362306a36Sopenharmony_ci uint32_t size; /* size of buffer */ 7462306a36Sopenharmony_ci}; 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistruct audioreach_graph_data { 7762306a36Sopenharmony_ci struct audio_buffer *buf; 7862306a36Sopenharmony_ci uint32_t num_periods; 7962306a36Sopenharmony_ci uint32_t dsp_buf; 8062306a36Sopenharmony_ci uint32_t mem_map_handle; 8162306a36Sopenharmony_ci}; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_cistruct audioreach_graph { 8462306a36Sopenharmony_ci struct audioreach_graph_info *info; 8562306a36Sopenharmony_ci uint32_t id; 8662306a36Sopenharmony_ci int state; 8762306a36Sopenharmony_ci int start_count; 8862306a36Sopenharmony_ci /* Cached Graph data */ 8962306a36Sopenharmony_ci void *graph; 9062306a36Sopenharmony_ci struct kref refcount; 9162306a36Sopenharmony_ci struct q6apm *apm; 9262306a36Sopenharmony_ci}; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_citypedef void (*q6apm_cb) (uint32_t opcode, uint32_t token, 9562306a36Sopenharmony_ci void *payload, void *priv); 9662306a36Sopenharmony_cistruct q6apm_graph { 9762306a36Sopenharmony_ci void *priv; 9862306a36Sopenharmony_ci q6apm_cb cb; 9962306a36Sopenharmony_ci uint32_t id; 10062306a36Sopenharmony_ci struct device *dev; 10162306a36Sopenharmony_ci struct q6apm *apm; 10262306a36Sopenharmony_ci gpr_port_t *port; 10362306a36Sopenharmony_ci struct audioreach_graph_data rx_data; 10462306a36Sopenharmony_ci struct audioreach_graph_data tx_data; 10562306a36Sopenharmony_ci struct gpr_ibasic_rsp_result_t result; 10662306a36Sopenharmony_ci wait_queue_head_t cmd_wait; 10762306a36Sopenharmony_ci struct mutex lock; 10862306a36Sopenharmony_ci struct audioreach_graph *ar_graph; 10962306a36Sopenharmony_ci struct audioreach_graph_info *info; 11062306a36Sopenharmony_ci}; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci/* Graph Operations */ 11362306a36Sopenharmony_cistruct q6apm_graph *q6apm_graph_open(struct device *dev, q6apm_cb cb, 11462306a36Sopenharmony_ci void *priv, int graph_id); 11562306a36Sopenharmony_ciint q6apm_graph_close(struct q6apm_graph *graph); 11662306a36Sopenharmony_ciint q6apm_graph_prepare(struct q6apm_graph *graph); 11762306a36Sopenharmony_ciint q6apm_graph_start(struct q6apm_graph *graph); 11862306a36Sopenharmony_ciint q6apm_graph_stop(struct q6apm_graph *graph); 11962306a36Sopenharmony_ciint q6apm_graph_flush(struct q6apm_graph *graph); 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci/* Media Format */ 12262306a36Sopenharmony_ciint q6apm_graph_media_format_pcm(struct q6apm_graph *graph, 12362306a36Sopenharmony_ci struct audioreach_module_config *cfg); 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ciint q6apm_graph_media_format_shmem(struct q6apm_graph *graph, 12662306a36Sopenharmony_ci struct audioreach_module_config *cfg); 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci/* read/write related */ 12962306a36Sopenharmony_ciint q6apm_read(struct q6apm_graph *graph); 13062306a36Sopenharmony_ciint q6apm_write_async(struct q6apm_graph *graph, uint32_t len, uint32_t msw_ts, 13162306a36Sopenharmony_ci uint32_t lsw_ts, uint32_t wflags); 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci/* Memory Map related */ 13462306a36Sopenharmony_ciint q6apm_map_memory_regions(struct q6apm_graph *graph, 13562306a36Sopenharmony_ci unsigned int dir, phys_addr_t phys, 13662306a36Sopenharmony_ci size_t period_sz, unsigned int periods); 13762306a36Sopenharmony_ciint q6apm_unmap_memory_regions(struct q6apm_graph *graph, 13862306a36Sopenharmony_ci unsigned int dir); 13962306a36Sopenharmony_ci/* Helpers */ 14062306a36Sopenharmony_ciint q6apm_send_cmd_sync(struct q6apm *apm, struct gpr_pkt *pkt, 14162306a36Sopenharmony_ci uint32_t rsp_opcode); 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci/* Callback for graph specific */ 14462306a36Sopenharmony_cistruct audioreach_module *q6apm_find_module_by_mid(struct q6apm_graph *graph, 14562306a36Sopenharmony_ci uint32_t mid); 14662306a36Sopenharmony_ciint q6apm_graph_get_rx_shmem_module_iid(struct q6apm_graph *graph); 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_cibool q6apm_is_adsp_ready(void); 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ciint q6apm_enable_compress_module(struct device *dev, struct q6apm_graph *graph, bool en); 15162306a36Sopenharmony_ciint q6apm_remove_initial_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples); 15262306a36Sopenharmony_ciint q6apm_remove_trailing_silence(struct device *dev, struct q6apm_graph *graph, uint32_t samples); 15362306a36Sopenharmony_ciint q6apm_set_real_module_id(struct device *dev, struct q6apm_graph *graph, uint32_t codec_id); 15462306a36Sopenharmony_ci#endif /* __APM_GRAPH_ */ 155