/* 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 #include #include #include #include #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_64K) #define BUFFER_BYTES_MAX (SZ_1M) #define PERIOD_BYTES_MIN (SZ_16) #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_128) #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 */