xref: /kernel/linux/linux-5.10/sound/pci/asihpi/hpios.h (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/******************************************************************************
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci    AudioScience HPI driver
58c2ecf20Sopenharmony_ci    Copyright (C) 1997-2011  AudioScience Inc. <support@audioscience.com>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ciHPI Operating System Specific macros for Linux Kernel driver
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci(C) Copyright AudioScience Inc. 1997-2003
118c2ecf20Sopenharmony_ci******************************************************************************/
128c2ecf20Sopenharmony_ci#ifndef _HPIOS_H_
138c2ecf20Sopenharmony_ci#define _HPIOS_H_
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#undef HPI_OS_LINUX_KERNEL
168c2ecf20Sopenharmony_ci#define HPI_OS_LINUX_KERNEL
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#define HPI_OS_DEFINED
198c2ecf20Sopenharmony_ci#define HPI_BUILD_KERNEL_MODE
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci#include <linux/io.h>
228c2ecf20Sopenharmony_ci#include <linux/ioctl.h>
238c2ecf20Sopenharmony_ci#include <linux/kernel.h>
248c2ecf20Sopenharmony_ci#include <linux/string.h>
258c2ecf20Sopenharmony_ci#include <linux/device.h>
268c2ecf20Sopenharmony_ci#include <linux/firmware.h>
278c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
288c2ecf20Sopenharmony_ci#include <linux/pci.h>
298c2ecf20Sopenharmony_ci#include <linux/mutex.h>
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#define HPI_NO_OS_FILE_OPS
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci/** Details of a memory area allocated with  pci_alloc_consistent
348c2ecf20Sopenharmony_ciNeed all info for parameters to pci_free_consistent
358c2ecf20Sopenharmony_ci*/
368c2ecf20Sopenharmony_cistruct consistent_dma_area {
378c2ecf20Sopenharmony_ci	struct device *pdev;
388c2ecf20Sopenharmony_ci	/* looks like dma-mapping dma_devres ?! */
398c2ecf20Sopenharmony_ci	size_t size;
408c2ecf20Sopenharmony_ci	void *vaddr;
418c2ecf20Sopenharmony_ci	dma_addr_t dma_handle;
428c2ecf20Sopenharmony_ci};
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_cistatic inline u16 hpios_locked_mem_get_phys_addr(struct consistent_dma_area
458c2ecf20Sopenharmony_ci	*locked_mem_handle, u32 *p_physical_addr)
468c2ecf20Sopenharmony_ci{
478c2ecf20Sopenharmony_ci	*p_physical_addr = locked_mem_handle->dma_handle;
488c2ecf20Sopenharmony_ci	return 0;
498c2ecf20Sopenharmony_ci}
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_cistatic inline u16 hpios_locked_mem_get_virt_addr(struct consistent_dma_area
528c2ecf20Sopenharmony_ci	*locked_mem_handle, void **pp_virtual_addr)
538c2ecf20Sopenharmony_ci{
548c2ecf20Sopenharmony_ci	*pp_virtual_addr = locked_mem_handle->vaddr;
558c2ecf20Sopenharmony_ci	return 0;
568c2ecf20Sopenharmony_ci}
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_cistatic inline u16 hpios_locked_mem_valid(struct consistent_dma_area
598c2ecf20Sopenharmony_ci	*locked_mem_handle)
608c2ecf20Sopenharmony_ci{
618c2ecf20Sopenharmony_ci	return locked_mem_handle->size != 0;
628c2ecf20Sopenharmony_ci}
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_cistruct hpi_ioctl_linux {
658c2ecf20Sopenharmony_ci	void __user *phm;
668c2ecf20Sopenharmony_ci	void __user *phr;
678c2ecf20Sopenharmony_ci};
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci/* Conflict?: H is already used by a number of drivers hid, bluetooth hci,
708c2ecf20Sopenharmony_ci   and some sound drivers sb16, hdsp, emu10k. AFAIK 0xFC is unused command
718c2ecf20Sopenharmony_ci*/
728c2ecf20Sopenharmony_ci#define HPI_IOCTL_LINUX _IOWR('H', 0xFC, struct hpi_ioctl_linux)
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci#define HPI_DEBUG_FLAG_ERROR   KERN_ERR
758c2ecf20Sopenharmony_ci#define HPI_DEBUG_FLAG_WARNING KERN_WARNING
768c2ecf20Sopenharmony_ci#define HPI_DEBUG_FLAG_NOTICE  KERN_NOTICE
778c2ecf20Sopenharmony_ci#define HPI_DEBUG_FLAG_INFO    KERN_INFO
788c2ecf20Sopenharmony_ci#define HPI_DEBUG_FLAG_DEBUG   KERN_DEBUG
798c2ecf20Sopenharmony_ci#define HPI_DEBUG_FLAG_VERBOSE KERN_DEBUG	/* kernel has no verbose */
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci#define HPI_LOCKING
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_cistruct hpios_spinlock {
868c2ecf20Sopenharmony_ci	spinlock_t lock;	/* SEE hpios_spinlock */
878c2ecf20Sopenharmony_ci	int lock_context;
888c2ecf20Sopenharmony_ci};
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci/* The reason for all this evilness is that ALSA calls some of a drivers
918c2ecf20Sopenharmony_ci * operators in atomic context, and some not.  But all our functions channel
928c2ecf20Sopenharmony_ci * through the HPI_Message conduit, so we can't handle the different context
938c2ecf20Sopenharmony_ci * per function
948c2ecf20Sopenharmony_ci */
958c2ecf20Sopenharmony_ci#define IN_LOCK_BH 1
968c2ecf20Sopenharmony_ci#define IN_LOCK_IRQ 0
978c2ecf20Sopenharmony_cistatic inline void cond_lock(struct hpios_spinlock *l)
988c2ecf20Sopenharmony_ci{
998c2ecf20Sopenharmony_ci	if (irqs_disabled()) {
1008c2ecf20Sopenharmony_ci		/* NO bh or isr can execute on this processor,
1018c2ecf20Sopenharmony_ci		   so ordinary lock will do
1028c2ecf20Sopenharmony_ci		 */
1038c2ecf20Sopenharmony_ci		spin_lock(&((l)->lock));
1048c2ecf20Sopenharmony_ci		l->lock_context = IN_LOCK_IRQ;
1058c2ecf20Sopenharmony_ci	} else {
1068c2ecf20Sopenharmony_ci		spin_lock_bh(&((l)->lock));
1078c2ecf20Sopenharmony_ci		l->lock_context = IN_LOCK_BH;
1088c2ecf20Sopenharmony_ci	}
1098c2ecf20Sopenharmony_ci}
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_cistatic inline void cond_unlock(struct hpios_spinlock *l)
1128c2ecf20Sopenharmony_ci{
1138c2ecf20Sopenharmony_ci	if (l->lock_context == IN_LOCK_BH)
1148c2ecf20Sopenharmony_ci		spin_unlock_bh(&((l)->lock));
1158c2ecf20Sopenharmony_ci	else
1168c2ecf20Sopenharmony_ci		spin_unlock(&((l)->lock));
1178c2ecf20Sopenharmony_ci}
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci#define hpios_msgxlock_init(obj)      spin_lock_init(&(obj)->lock)
1208c2ecf20Sopenharmony_ci#define hpios_msgxlock_lock(obj)   cond_lock(obj)
1218c2ecf20Sopenharmony_ci#define hpios_msgxlock_unlock(obj) cond_unlock(obj)
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci#define hpios_dsplock_init(obj)       spin_lock_init(&(obj)->dsp_lock.lock)
1248c2ecf20Sopenharmony_ci#define hpios_dsplock_lock(obj)    cond_lock(&(obj)->dsp_lock)
1258c2ecf20Sopenharmony_ci#define hpios_dsplock_unlock(obj)  cond_unlock(&(obj)->dsp_lock)
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci#ifdef CONFIG_SND_DEBUG
1288c2ecf20Sopenharmony_ci#define HPI_BUILD_DEBUG
1298c2ecf20Sopenharmony_ci#endif
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci#define HPI_ALIST_LOCKING
1328c2ecf20Sopenharmony_ci#define hpios_alistlock_init(obj)    spin_lock_init(&((obj)->list_lock.lock))
1338c2ecf20Sopenharmony_ci#define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock))
1348c2ecf20Sopenharmony_ci#define hpios_alistlock_unlock(obj) spin_unlock(&((obj)->list_lock.lock))
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_cistruct snd_card;
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci/** pci drvdata points to an instance of this struct */
1398c2ecf20Sopenharmony_cistruct hpi_adapter {
1408c2ecf20Sopenharmony_ci	struct hpi_adapter_obj *adapter;
1418c2ecf20Sopenharmony_ci	struct snd_card *snd_card;
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci	int irq;
1448c2ecf20Sopenharmony_ci	int interrupt_mode;
1458c2ecf20Sopenharmony_ci	void (*interrupt_callback) (struct hpi_adapter *);
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	/* mutex prevents contention for one card
1488c2ecf20Sopenharmony_ci	   between multiple user programs (via ioctl) */
1498c2ecf20Sopenharmony_ci	struct mutex mutex;
1508c2ecf20Sopenharmony_ci	char *p_buffer;
1518c2ecf20Sopenharmony_ci	size_t buffer_size;
1528c2ecf20Sopenharmony_ci};
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci#endif
155