kernel_samsung_a53x/sound/soc/samsung/abox/abox.h

953 lines
25 KiB
C
Raw Normal View History

2024-06-15 16:02:09 -03:00
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* ALSA SoC - Samsung Abox driver
*
* Copyright (c) 2016 Samsung Electronics Co. Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __SND_SOC_ABOX_H
#define __SND_SOC_ABOX_H
#include <sound/samsung/abox.h>
#include <linux/miscdevice.h>
#include <linux/dma-direction.h>
#include <soc/samsung/memlogger.h>
#include <soc/samsung/sysevent.h>
#include "abox_qos.h"
#define DEFAULT_CPU_GEAR_ID (0xAB0CDEFA)
#define TEST_CPU_GEAR_ID (DEFAULT_CPU_GEAR_ID + 1)
#define DEFAULT_LIT_FREQ_ID DEFAULT_CPU_GEAR_ID
#define DEFAULT_BIG_FREQ_ID DEFAULT_CPU_GEAR_ID
#define DEFAULT_HMP_BOOST_ID DEFAULT_CPU_GEAR_ID
#define DEFAULT_INT_FREQ_ID DEFAULT_CPU_GEAR_ID
#define DEFAULT_MIF_FREQ_ID DEFAULT_CPU_GEAR_ID
#define DEFAULT_SYS_POWER_ID DEFAULT_CPU_GEAR_ID
#define BUFFER_BYTES_MIN (SZ_512K)
2024-06-15 16:02:09 -03:00
#define BUFFER_BYTES_MAX (SZ_1M)
#define PERIOD_BYTES_MIN (SZ_64)
2024-06-15 16:02:09 -03:00
#define PERIOD_BYTES_MAX (BUFFER_BYTES_MAX / 2)
#define SRAM_FIRMWARE_SIZE CONFIG_SND_SOC_SAMSUNG_ABOX_SRAM_SIZE
#define DRAM_FIRMWARE_SIZE CONFIG_SND_SOC_SAMSUNG_ABOX_DRAM_SIZE
#define IOVA_DRAM_FIRMWARE (0x80000000)
#define IOVA_RDMA_BUFFER_BASE (0x91000000)
#define IOVA_RDMA_BUFFER(x) (IOVA_RDMA_BUFFER_BASE + (SZ_1M * (x)))
#define IOVA_WDMA_BUFFER_BASE (0x92000000)
#define IOVA_WDMA_BUFFER(x) (IOVA_WDMA_BUFFER_BASE + (SZ_1M * (x)))
#define IOVA_COMPR_BUFFER_BASE (0x93000000)
#define IOVA_COMPR_BUFFER(x) (IOVA_COMPR_BUFFER_BASE + (SZ_1M * (x)))
#define IOVA_VDMA_BUFFER_BASE (0x94000000)
#define IOVA_VDMA_BUFFER(x) (IOVA_VDMA_BUFFER_BASE + (SZ_1M * (x)))
#define IOVA_DUAL_BUFFER_BASE (0x98000000)
#define IOVA_DUAL_BUFFER(x) (IOVA_DUAL_BUFFER_BASE + (SZ_1M * (x)))
#define IOVA_DDMA_BUFFER_BASE (0x99000000)
#define IOVA_DDMA_BUFFER(x) (IOVA_DDMA_BUFFER_BASE + (SZ_1M * (x)))
#define IOVA_UDMA_RD_BUFFER_BASE (0x9C000000)
#define IOVA_UDMA_RD_BUFFER(x) (IOVA_UDMA_RD_BUFFER_BASE + \
(SZ_1M * (x)))
#define IOVA_UDMA_WR_BUFFER_BASE (0x9C400000)
#define IOVA_UDMA_WR_BUFFER(x) (IOVA_UDMA_WR_BUFFER_BASE + \
(SZ_1M * (x)))
#define IOVA_UDMA_WR_DUAL_BUFFER_BASE (0x9C800000)
#define IOVA_UDMA_WR_DUAL_BUFFER(x) (IOVA_UDMA_WR_DUAL_BUFFER_BASE + \
(SZ_1M * (x)))
#define IOVA_UDMA_WR_DBG_BUFFER_BASE (0x9CC00000)
#define IOVA_UDMA_WR_DBG_BUFFER(x) (IOVA_UDMA_WR_DBG_BUFFER_BASE + \
(SZ_1M * (x)))
#define IOVA_VSS_FIRMWARE (0xA0000000)
#define IOVA_VSS_PARAMETER (0xA1000000)
#define IOVA_VSS_PCI (0xA2000000)
#define IOVA_VSS_PCI_DOORBELL (0xA3000000)
#define IOVA_DUMP_BUFFER (0xD0000000)
#define IOVA_SILENT_LOG (0xE0000000)
#define PHSY_VSS_FIRMWARE (0xFEE00000)
#define PHSY_VSS_SIZE (SZ_8M)
#define ABOX_LOG_OFFSET (0xb00000)
#define ABOX_LOG_MAJOR_OFFSET (0x900000)
#define ABOX_LOG_SIZE (SZ_1M)
#define ABOX_SLOG_OFFSET (9 * SZ_1M)
#define ABOX_SLOG_DATA_OFFSET (ABOX_SLOG_OFFSET + 0x10)
#define ABOX_PCI_DOORBELL_OFFSET (0x10000)
#define ABOX_PCI_DOORBELL_SIZE (SZ_16K)
#define LIMIT_IN_JIFFIES (msecs_to_jiffies(1000))
#define ABOX_CPU_GEAR_CALL_VSS (0xCA11)
#define ABOX_CPU_GEAR_CALL_KERNEL (0xCA12)
#define ABOX_CPU_GEAR_CALL ABOX_CPU_GEAR_CALL_VSS
#define ABOX_CPU_GEAR_ABSOLUTE (0xABC0ABC0)
#define ABOX_CPU_GEAR_BOOT (0xB00D)
#define ABOX_CPU_GEAR_MAX (1)
#define ABOX_CPU_GEAR_MIN (100)
#define ABOX_CPU_GEAR_DAI 0xDA100000
#define ABOX_SAMPLING_RATES (SNDRV_PCM_RATE_KNOT)
#define ABOX_SAMPLE_FORMATS (SNDRV_PCM_FMTBIT_S16\
| SNDRV_PCM_FMTBIT_S24\
| SNDRV_PCM_FMTBIT_S24_3LE\
| SNDRV_PCM_FMTBIT_S32)
#define ABOX_SUPPLEMENT_SIZE (SZ_128)
#define ABOX_IPC_QUEUE_SIZE (SZ_64)
2024-06-15 16:02:09 -03:00
#define CALLIOPE_VERSION(class, year, month, minor) \
((class << 24) | \
((year - 1 + 'A') << 16) | \
((month - 1 + 'A') << 8) | \
((minor + '0') << 0))
#define ABOX_QUIRK_BIT_ARAM_MODE BIT(0)
#define ABOX_QUIRK_STR_ARAM_MODE "aram mode"
#define ABOX_QUIRK_BIT_INT_SKEW BIT(1)
#define ABOX_QUIRK_STR_INT_SKEW "int skew"
#define ABOX_QUIRK_BIT_SILENT_RESET BIT(2)
#define ABOX_QUIRK_STR_SILENT_RESET "silent reset"
#define ABOX_QUIRK_BIT_FORCE_32BIT BIT(3)
#define ABOX_QUIRK_STR_FORCE_32BIT "force 32bit"
enum abox_dai {
ABOX_NONE,
ABOX_SIFSM,
ABOX_SIFST,
ABOX_RDMA0 = 0x10,
ABOX_RDMA1,
ABOX_RDMA2,
ABOX_RDMA3,
ABOX_RDMA4,
ABOX_RDMA5,
ABOX_RDMA6,
ABOX_RDMA7,
ABOX_RDMA8,
ABOX_RDMA9,
ABOX_RDMA10,
ABOX_RDMA11,
ABOX_WDMA0 = 0x20,
ABOX_WDMA1,
ABOX_WDMA2,
ABOX_WDMA3,
ABOX_WDMA4,
ABOX_WDMA5,
ABOX_WDMA6,
ABOX_WDMA7,
ABOX_WDMA8,
ABOX_WDMA9,
ABOX_WDMA10,
ABOX_WDMA11,
ABOX_WDMA0_DUAL = 0x30,
ABOX_WDMA1_DUAL,
ABOX_WDMA2_DUAL,
ABOX_WDMA3_DUAL,
ABOX_WDMA4_DUAL,
ABOX_WDMA5_DUAL,
ABOX_WDMA6_DUAL,
ABOX_WDMA7_DUAL,
ABOX_WDMA8_DUAL,
ABOX_WDMA9_DUAL,
ABOX_WDMA10_DUAL,
ABOX_WDMA11_DUAL,
ABOX_DDMA0 = 0x40,
ABOX_DDMA1,
ABOX_DDMA2,
ABOX_DDMA3,
ABOX_DDMA4,
ABOX_DDMA5,
ABOX_UAIF0 = 0x50,
ABOX_UAIF1,
ABOX_UAIF2,
ABOX_UAIF3,
ABOX_UAIF4,
ABOX_UAIF5,
ABOX_UAIF6,
ABOX_DSIF,
ABOX_SPDY,
ABOX_RDMA0_BE = 0x60,
ABOX_RDMA1_BE,
ABOX_RDMA2_BE,
ABOX_RDMA3_BE,
ABOX_RDMA4_BE,
ABOX_RDMA5_BE,
ABOX_RDMA6_BE,
ABOX_RDMA7_BE,
ABOX_RDMA8_BE,
ABOX_RDMA9_BE,
ABOX_RDMA10_BE,
ABOX_RDMA11_BE,
ABOX_WDMA0_BE = 0x70,
ABOX_WDMA1_BE,
ABOX_WDMA2_BE,
ABOX_WDMA3_BE,
ABOX_WDMA4_BE,
ABOX_WDMA5_BE,
ABOX_WDMA6_BE,
ABOX_WDMA7_BE,
ABOX_WDMA8_BE,
ABOX_WDMA9_BE,
ABOX_WDMA10_BE,
ABOX_WDMA11_BE,
ABOX_SIFS0 = 0x80, /* Virtual DAI */
ABOX_SIFS1, /* Virtual DAI */
ABOX_SIFS2, /* Virtual DAI */
ABOX_SIFS3, /* Virtual DAI */
ABOX_SIFS4, /* Virtual DAI */
ABOX_SIFS5, /* Virtual DAI */
ABOX_SIFS6, /* Virtual DAI */
ABOX_NSRC0 = 0x90, /* Virtual DAI */
ABOX_NSRC1, /* Virtual DAI */
ABOX_NSRC2, /* Virtual DAI */
ABOX_NSRC3, /* Virtual DAI */
ABOX_NSRC4, /* Virtual DAI */
ABOX_NSRC5, /* Virtual DAI */
ABOX_NSRC6, /* Virtual DAI */
ABOX_NSRC7, /* Virtual DAI */
ABOX_NSRC8, /* Virtual DAI */
ABOX_NSRC9, /* Virtual DAI */
ABOX_NSRC10, /* Virtual DAI */
ABOX_NSRC11, /* Virtual DAI */
ABOX_USB = 0xA0, /* Virtual DAI */
ABOX_FWD, /* Virtual DAI */
ABOX_UDMA_RD0 = 0xC0,
ABOX_UDMA_RD1,
ABOX_UDMA_WR0,
ABOX_UDMA_WR1,
ABOX_UDMA_WR0_DUAL,
ABOX_UDMA_WR1_DUAL,
ABOX_UDMA_WR_DBG0,
};
/* SIFS should be treated as DAI to manage bclk usage and count value */
#define ABOX_DAI_COUNT (ABOX_NSRC0 - ABOX_UAIF0 + 1)
enum abox_widget {
ABOX_WIDGET_SPUS_IN0,
ABOX_WIDGET_SPUS_IN1,
ABOX_WIDGET_SPUS_IN2,
ABOX_WIDGET_SPUS_IN3,
ABOX_WIDGET_SPUS_IN4,
ABOX_WIDGET_SPUS_IN5,
ABOX_WIDGET_SPUS_IN6,
ABOX_WIDGET_SPUS_IN7,
ABOX_WIDGET_SPUS_IN8,
ABOX_WIDGET_SPUS_IN9,
ABOX_WIDGET_SPUS_IN10,
ABOX_WIDGET_SPUS_IN11,
ABOX_WIDGET_SPUS_ASRC0,
ABOX_WIDGET_SPUS_ASRC1,
ABOX_WIDGET_SPUS_ASRC2,
ABOX_WIDGET_SPUS_ASRC3,
ABOX_WIDGET_SPUS_ASRC4,
ABOX_WIDGET_SPUS_ASRC5,
ABOX_WIDGET_SPUS_ASRC6,
ABOX_WIDGET_SPUS_ASRC7,
ABOX_WIDGET_SIFS0,
ABOX_WIDGET_SIFS1,
ABOX_WIDGET_SIFS2,
ABOX_WIDGET_SIFS3,
ABOX_WIDGET_SIFS4,
ABOX_WIDGET_SIFS5,
ABOX_WIDGET_SIFS6,
ABOX_WIDGET_SIFS7,
ABOX_WIDGET_NSRC0,
ABOX_WIDGET_NSRC1,
ABOX_WIDGET_NSRC2,
ABOX_WIDGET_NSRC3,
ABOX_WIDGET_NSRC4,
ABOX_WIDGET_NSRC5,
ABOX_WIDGET_NSRC6,
ABOX_WIDGET_NSRC7,
ABOX_WIDGET_NSRC8,
ABOX_WIDGET_NSRC9,
ABOX_WIDGET_NSRC10,
ABOX_WIDGET_NSRC11,
ABOX_WIDGET_SPUM_ASRC0,
ABOX_WIDGET_SPUM_ASRC1,
ABOX_WIDGET_SPUM_ASRC2,
ABOX_WIDGET_SPUM_ASRC3,
ABOX_WIDGET_UDMA_RD0,
ABOX_WIDGET_UDMA_RD1,
ABOX_WIDGET_UDMA_WR0,
ABOX_WIDGET_UDMA_WR1,
ABOX_WIDGET_COUNT,
};
enum calliope_state {
CALLIOPE_DISABLED,
CALLIOPE_DISABLING,
CALLIOPE_ENABLING,
CALLIOPE_ENABLED,
CALLIOPE_STATE_COUNT,
};
enum system_state {
SYSTEM_CALL,
SYSTEM_OFFLOAD,
SYSTEM_IDLE,
SYSTEM_STATE_COUNT
};
enum llc_state {
LLC_CALL_BUSY,
LLC_CALL_IDLE,
LLC_OFFLOAD_BUSY,
LLC_OFFLOAD_IDLE,
LLC_STATE_COUNT,
};
enum audio_mode {
MODE_NORMAL,
MODE_RINGTONE,
MODE_IN_CALL,
MODE_IN_COMMUNICATION,
MODE_IN_VIDEOCALL,
MODE_RESERVED0,
MODE_RESERVED1,
MODE_IN_LOOPBACK,
};
enum sound_type {
SOUND_TYPE_VOICE,
SOUND_TYPE_SPEAKER,
SOUND_TYPE_HEADSET,
SOUND_TYPE_BTVOICE,
SOUND_TYPE_USB,
SOUND_TYPE_CALLFWD,
};
enum qchannel {
ABOX_CCLK_CORE,
ABOX_ACLK,
ABOX_BCLK_UAIF0,
ABOX_BCLK_UAIF1,
ABOX_BCLK_UAIF2,
ABOX_BCLK_UAIF3,
ABOX_BCLK_UAIF4,
ABOX_BCLK_UAIF5,
ABOX_BCLK_UAIF6,
ABOX_BCLK_RESERVED,
ABOX_BCLK_DSIF,
ABOX_CCLK_ASB = 16,
ABOX_PCMC_CLK,
ABOX_XCLK0,
ABOX_XCLK1,
ABOX_XCLK2,
ABOX_CCLK_ACP,
};
enum abox_region {
ABOX_REG_SFR,
ABOX_REG_SYSREG,
ABOX_REG_SRAM,
ABOX_REG_DEVICE_LAST,
ABOX_REG_GPR = ABOX_REG_DEVICE_LAST,
ABOX_REG_GICD,
ABOX_REG_INT_LAST,
ABOX_REG_DRAM = ABOX_REG_INT_LAST,
ABOX_REG_DUMP,
ABOX_REG_LOG,
ABOX_REG_SLOG,
ABOX_REG_COUNT,
};
enum mux_pcmc {
ABOX_PCMC_OSC,
ABOX_PCMC_CP,
ABOX_PCMC_AUD
};
enum debug_mode {
DEBUG_MODE_NONE,
DEBUG_MODE_DRAM,
DEBUG_MODE_FILE,
DEBUG_MODE_COUNT,
};
struct abox_ipc {
struct device *dev;
int hw_irq;
unsigned long long put_time;
unsigned long long get_time;
size_t size;
ABOX_IPC_MSG msg;
};
struct abox_ipc_action {
struct list_head list;
const struct device *dev;
int ipc_id;
abox_ipc_handler_t handler;
void *data;
};
struct abox_iommu_mapping {
struct list_head list;
unsigned long iova; /* IO virtual address */
unsigned char *area; /* virtual pointer */
dma_addr_t addr; /* physical address */
size_t bytes; /* buffer size in bytes */
};
struct abox_dram_request {
unsigned int id;
bool on;
unsigned long long updated;
};
struct abox_extra_firmware {
struct list_head list;
struct mutex lock;
const struct firmware *firmware;
char name[SZ_32];
unsigned int idx;
unsigned int area;
unsigned int offset;
unsigned int iova;
bool kcontrol;
bool changeable;
};
struct abox_event_notifier {
void *priv;
int (*notify)(void *priv, bool en);
};
struct abox_component {
struct ABOX_COMPONENT_DESCRIPTIOR *desc;
bool registered;
struct list_head value_list;
};
struct abox_component_kcontrol_value {
struct ABOX_COMPONENT_DESCRIPTIOR *desc;
struct ABOX_COMPONENT_CONTROL *control;
struct list_head list;
bool cache_only;
int cache[];
};
struct abox_sram_vts {
struct device *dev;
bool enable;
bool enabled;
struct work_struct request_work;
};
struct abox_pcmc {
struct clk *clk_cp_pcmc;
struct clk *clk_aud_pcmc;
enum mux_pcmc next;
enum mux_pcmc cur;
unsigned long rate_osc;
unsigned long rate_cp_pcmc;
unsigned long rate_aud_pcmc;
struct work_struct request_work;
};
struct abox_data {
struct device *dev;
struct snd_soc_component *cmpnt;
struct regmap *regmap;
struct regmap *timer_regmap;
void __iomem *sfr_base;
void __iomem *sysreg_base;
void __iomem *sram_base;
void __iomem *timer_base;
phys_addr_t sfr_phys;
size_t sfr_size;
phys_addr_t sysreg_phys;
size_t sysreg_size;
phys_addr_t sram_phys;
size_t sram_size;
void *dram_base;
dma_addr_t dram_phys;
void *dump_base;
phys_addr_t dump_phys;
void *slog_base;
phys_addr_t slog_phys;
size_t slog_size;
struct iommu_domain *iommu_domain;
void *ipc_tx_addr;
size_t ipc_tx_size;
void *ipc_rx_addr;
size_t ipc_rx_size;
void *shm_addr;
size_t shm_size;
struct abox2host_hndshk_tag *hndshk_tag;
int clk_diff_ppb;
unsigned int bootargs_offset;
unsigned int slogargs_offset;
unsigned int if_count;
unsigned int rdma_count;
unsigned int wdma_count;
unsigned int udma_rd_count;
unsigned int udma_wr_count;
unsigned int atune_count;
unsigned int calliope_version;
struct list_head firmware_extra;
const char *bootargs;
struct device *dev_gic;
struct device *dev_if[9];
struct device *dev_rdma[16];
struct device *dev_wdma[16];
struct device *dev_udma_rd[4];
struct device *dev_udma_wr[4];
struct workqueue_struct *ipc_workqueue;
struct work_struct ipc_work;
struct abox_ipc ipc_queue[ABOX_IPC_QUEUE_SIZE];
int ipc_queue_start;
int ipc_queue_end;
spinlock_t ipc_queue_lock;
wait_queue_head_t ipc_wait_queue;
wait_queue_head_t boot_wait_queue;
wait_queue_head_t wait_queue;
wait_queue_head_t offline_poll_wait;
struct clk *clk_pll;
struct clk *clk_pll1;
struct clk *clk_audif;
struct clk *clk_cpu;
struct clk *clk_dmic;
struct clk *clk_bus;
struct clk *clk_cnt;
struct clk *clk_sclk;
unsigned int uaif_max_div;
struct pinctrl *pinctrl;
unsigned long quirks;
unsigned int cpu_gear_min;
struct abox_dram_request dram_requests[16];
unsigned long audif_rates[ABOX_DAI_COUNT];
unsigned int sif_rate[SET_SIFS0_FORMAT - SET_SIFS0_RATE];
snd_pcm_format_t sif_format[SET_SIFS0_FORMAT - SET_SIFS0_RATE];
unsigned int sif_channels[SET_SIFS0_FORMAT - SET_SIFS0_RATE];
struct abox_event_notifier event_notifier[ABOX_WIDGET_COUNT];
int apf_coef[2][16];
struct work_struct register_component_work;
struct abox_component components[16];
struct list_head ipc_actions;
struct list_head iommu_maps;
spinlock_t iommu_lock;
bool enabled;
bool restored;
bool no_profiling;
enum debug_mode debug_mode;
bool vss_disabled;
bool system_state[SYSTEM_STATE_COUNT];
bool sifs_cnt_dirty[SET_SIFM0_RATE - SET_SIFS0_RATE];
enum calliope_state calliope_state;
bool failsafe;
bool error;
struct notifier_block qos_nb;
struct notifier_block pm_nb;
struct notifier_block itmon_nb;
int pm_qos_int[5];
int pm_qos_aud[16];
unsigned int pm_qos_stable_min;
unsigned int sys_acp_con[2];
int llc_way[LLC_STATE_COUNT];
struct work_struct restore_data_work;
struct work_struct boot_done_work;
struct delayed_work boot_clear_work;
struct delayed_work wdt_work;
unsigned long long audio_mode_time;
enum audio_mode audio_mode;
enum sound_type sound_type;
struct wakeup_source *ws;
struct memlog *drvlog_desc;
struct memlog_obj *drv_log_file_obj;
struct memlog_obj *drv_log_obj;
struct memlog *dump_desc;
struct sysevent_desc sysevent_desc;
struct sysevent_device *sysevent_dev;
struct abox_sram_vts sram_vts;
struct abox_pcmc pcmc;
};
/* sub-driver list */
extern struct platform_driver samsung_abox_debug_driver;
extern struct platform_driver samsung_abox_pci_driver;
extern struct platform_driver samsung_abox_core_driver;
extern struct platform_driver samsung_abox_dump_driver;
extern struct platform_driver samsung_abox_dma_driver;
extern struct platform_driver samsung_abox_vdma_driver;
extern struct platform_driver samsung_abox_wdma_driver;
extern struct platform_driver samsung_abox_rdma_driver;
extern struct platform_driver samsung_abox_if_driver;
extern struct platform_driver samsung_abox_vss_driver;
extern struct platform_driver samsung_abox_effect_driver;
extern struct platform_driver samsung_abox_tplg_driver;
/**
* Test quirk
* @param[in] data pointer to abox_data structure
* @param[in] quirk quirk bit
* @return true or false
*/
static inline bool abox_test_quirk(struct abox_data *data, unsigned long quirk)
{
return !!(data->quirks & quirk);
}
/**
* Get SFR of sample format
* @param[in] width count of bit in sample
* @param[in] channel count of channel
* @return SFR of sample format
*/
static inline u32 abox_get_format(u32 width, u32 channels)
{
return ((((width / 8) - 1) << 3) | (channels - 1));
}
/**
* Get channel from sample format
* @param[in] format SFR of sample format
* @return count of channel
*/
static inline u32 abox_get_channels(u32 format)
{
return ((format & 0x7) + 1);
}
/**
* Get width from sample format
* @param[in] format SFR of sample format
* @return count of bit in sample
*/
static inline u32 abox_get_width(u32 format)
{
return (((format >> 3) + 1) * 8);
}
/**
* Get enum IPC_ID from SNDRV_PCM_STREAM_*
* @param[in] stream SNDRV_PCM_STREAM_*
* @return IPC_PCMPLAYBACK or IPC_PCMCAPTURE
*/
static inline enum IPC_ID abox_stream_to_ipcid(int stream)
{
if (stream == SNDRV_PCM_STREAM_PLAYBACK)
return IPC_PCMPLAYBACK;
else if (stream == SNDRV_PCM_STREAM_CAPTURE)
return IPC_PCMCAPTURE;
else
return -EINVAL;
}
/**
* Get SNDRV_PCM_STREAM_* from enum IPC_ID
* @param[in] ipcid IPC_PCMPLAYBACK or IPC_PCMCAPTURE
* @return SNDRV_PCM_STREAM_*
*/
static inline int abox_ipcid_to_stream(enum IPC_ID ipcid)
{
if (ipcid == IPC_PCMPLAYBACK)
return SNDRV_PCM_STREAM_PLAYBACK;
else if (ipcid == IPC_PCMCAPTURE)
return SNDRV_PCM_STREAM_CAPTURE;
else
return -EINVAL;
}
/**
* set magic value for the firmware
* @param[in] data pointer to abox_data structure
* @param[in] val magic value
*/
extern void abox_set_magic(struct abox_data *data, unsigned int val);
/**
* test given device is abox or not
* @param[in]
* @return true or false
*/
extern bool is_abox(struct device *dev);
/**
* get pointer to abox_data (internal use only)
* @return pointer to abox_data
*/
extern struct abox_data *abox_get_abox_data(void);
/**
* get pointer to abox_data
* @param[in] dev pointer to struct dev which invokes this API
* @return pointer to abox_data
*/
extern struct abox_data *abox_get_data(struct device *dev);
/**
* set system state
* @param[in] data pointer to abox_data structure
* @param[in] state state
* @param[in] en enable or disable
*/
extern int abox_set_system_state(struct abox_data *data,
enum system_state state, bool en);
/**
* get physical address from abox virtual address
* @param[in] data pointer to abox_data structure
* @param[in] addr abox virtual address
* @return physical address
*/
extern phys_addr_t abox_addr_to_phys_addr(struct abox_data *data,
unsigned int addr);
/**
* get resource information
* @param[in] data pointer to abox_data structure
* @param[in] rid abox region index
* @param[in] kaddr returning kernel virtual address is required
* @param[in] buf_size Pointer to size_t value
* @return resource base address
*/
extern void *abox_get_resource_info(struct abox_data *data, enum abox_region rid,
bool kaddr, size_t *buf_size);
/**
* get kernel address from abox virtual address
* @param[in] data pointer to abox_data structure
* @param[in] addr abox virtual address
* @return kernel address
*/
extern void *abox_addr_to_kernel_addr(struct abox_data *data,
unsigned int addr);
/**
* parse address and size from the offset based description
* @param[in] data pointer to abox_data structure
* @param[in] np device node which contains the property
* @param[in] name name of the property
* @param[out] addr virtual address
* @param[out] dma dma address
* @param[out] size size
* @return 0 or error code
*/
extern int abox_of_get_addr(struct abox_data *data, struct device_node *np,
const char *name, void **addr, dma_addr_t *dma, size_t *size);
/**
* Check specific cpu gear request is idle
* @param[in] dev pointer to struct dev which invokes this API
* @param[in] id key which is used as unique handle
* @return true if it is idle or not has been requested, false on otherwise
*/
extern bool abox_cpu_gear_idle(struct device *dev, unsigned int id);
/**
* Request abox cpu clock level
* @param[in] dev pointer to struct dev which invokes this API
* @param[in] data pointer to abox_data structure
* @param[in] id key which is used as unique handle
* @param[in] level gear level or frequency in kHz
* @param[in] name cookie for logging
* @return error code if any
*/
extern int abox_request_cpu_gear(struct device *dev, struct abox_data *data,
unsigned int id, unsigned int level, const char *name);
/**
* Wait for pending cpu gear change
*/
extern void abox_cpu_gear_barrier(void);
/**
* Request abox cpu clock level synchronously
* @param[in] dev pointer to struct dev which invokes this API
* @param[in] data pointer to abox_data structure
* @param[in] id key which is used as unique handle
* @param[in] level gear level or frequency in kHz
* @param[in] name cookie for logging
* @return error code if any
*/
extern int abox_request_cpu_gear_sync(struct device *dev,
struct abox_data *data, unsigned int id, unsigned int level,
const char *name);
/**
* Clear abox cpu clock requests
* @param[in] dev pointer to struct dev which invokes this API
*/
extern void abox_clear_cpu_gear_requests(struct device *dev);
/**
* Clear mif clock requests
* @param[in] dev pointer to struct dev which invokes this API
*/
extern void abox_clear_mif_requests(struct device *dev);
/**
* Request abox cpu clock level with dai
* @param[in] dev pointer to struct dev which invokes this API
* @param[in] data pointer to abox_data structure
* @param[in] dai DAI which is used as unique handle
* @param[in] level gear level or frequency in kHz
* @return error code if any
*/
static inline int abox_request_cpu_gear_dai(struct device *dev,
struct abox_data *data, struct snd_soc_dai *dai,
unsigned int level)
{
unsigned int id = ABOX_CPU_GEAR_DAI | dai->id;
return abox_request_cpu_gear(dev, data, id, level, dai->name);
}
/**
* Request cluster 0 clock level with DAI
* @param[in] dev pointer to struct dev which invokes this API
* @param[in] dai DAI which is used as unique handle
* @param[in] freq frequency in kHz
* @return error code if any
*/
static inline int abox_request_cl0_freq_dai(struct device *dev,
struct snd_soc_dai *dai, unsigned int freq)
{
unsigned int id = ABOX_CPU_GEAR_DAI | dai->id;
return abox_qos_request_cl0(dev, id, freq, dai->name);
}
/**
* Request cluster 1 clock level with DAI
* @param[in] dev pointer to struct dev which invokes this API
* @param[in] dai DAI which is used as unique handle
* @param[in] freq frequency in kHz
* @return error code if any
*/
static inline int abox_request_cl1_freq_dai(struct device *dev,
struct snd_soc_dai *dai, unsigned int freq)
{
unsigned int id = ABOX_CPU_GEAR_DAI | dai->id;
return abox_qos_request_cl1(dev, id, freq, dai->name);
}
/**
* Request cluster 2 clock level with DAI
* @param[in] dev pointer to struct dev which invokes this API
* @param[in] dai DAI which is used as unique handle
* @param[in] freq frequency in kHz
* @return error code if any
*/
static inline int abox_request_cl2_freq_dai(struct device *dev,
struct snd_soc_dai *dai, unsigned int freq)
{
unsigned int id = ABOX_CPU_GEAR_DAI | dai->id;
return abox_qos_request_cl2(dev, id, freq, dai->name);
}
/**
* Register an notifier to power change notification chain
* @param[in] nb new entry in notifier chain
* @return error code if any
*/
int abox_power_notifier_register(struct notifier_block *nb);
/**
* Unregister an notifier from power change notification chain
* @param[in] nb entry in notifier chain
* @return error code if any
*/
int abox_power_notifier_unregister(struct notifier_block *nb);
/**
* Register uaif to abox
* @param[in] dev pointer to struct dev which invokes this API
* @param[in] data pointer to abox_data structure
* @param[in] id id of the uaif
* @param[in] rate sampling rate
* @param[in] channels number of channels
* @param[in] width number of bit in sample
* @return error code if any
*/
extern int abox_register_bclk_usage(struct device *dev, struct abox_data *data,
enum abox_dai id, unsigned int rate, unsigned int channels,
unsigned int width);
/**
* disable or enable qchannel of a clock
* @param[in] dev pointer to struct dev which invokes this API
* @param[in] data pointer to abox_data structure
* @param[in] clk clock id
* @param[in] disable disable or enable
*/
extern int abox_disable_qchannel(struct device *dev, struct abox_data *data,
enum qchannel clk, int disable);
/**
* wait for restoring abox from suspend
* @param[in] data pointer to abox_data structure
*/
extern void abox_wait_restored(struct abox_data *data);
/**
* register sound card with specific order
* @param[in] dev calling device
* @param[in] card sound card to register
* @param[in] idx order of the sound card
* @return 0 or error code
*/
extern int abox_register_extra_sound_card(struct device *dev,
struct snd_soc_card *card, unsigned int idx);
/**
* add controls for extra firmwares
* @param[in] data pointer to abox_data structure
* @return 0 or error code
*/
extern int abox_add_extra_firmware_controls(struct abox_data *data);
/**
* add or update extra firmware
* @param[in] dev calling device
* @param[in] data pointer to abox_data structure
* @param[in] idx index of firmware. It should be unique.
* @param[in] name name of firmware
* @param[in] area download area of firmware
* @param[in] offset offset of firmware
* @param[in] changeable changeable of firmware
* @return 0 or error code
*/
extern int abox_add_extra_firmware(struct device *dev,
struct abox_data *data, int idx,
const char *name, unsigned int area,
unsigned int offset, bool changeable);
/**
* abox silent reset for abox recovery
* @param[in] data pointer to abox_data structure
* @param[in] reset whether abox silent reset is required
*/
extern void abox_silent_reset(struct abox_data *data, bool reset);
/**
* wait until abox is booted
* @param[in] data pointer to abox_data structure
* @param[in] jiffies timeout in jiffies
* @return if the time is elapsed, 0 or 1. if not, remaining jiffies.
* refer to the wait_event_timeout().
*/
long abox_wait_for_boot(struct abox_data *data, unsigned long jiffies);
/**
* get waiting time in nano seconds
* @param[in] coarse parameter to determine time
*/
extern unsigned long abox_get_waiting_ns(bool coarse);
/**
* get waiting time in jiffies
* @param[in] coarse parameter to determine time
*/
static inline unsigned long abox_get_waiting_jiffies(bool coarse)
{
return nsecs_to_jiffies(abox_get_waiting_ns(coarse));
}
#endif /* __SND_SOC_ABOX_H */