xref: /openbmc/linux/sound/pci/asihpi/hpios.h (revision 2b987515)
107d7fe7bSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
2719f82d3SEliot Blennerhassett /******************************************************************************
3719f82d3SEliot Blennerhassett 
4719f82d3SEliot Blennerhassett     AudioScience HPI driver
540818b62SEliot Blennerhassett     Copyright (C) 1997-2011  AudioScience Inc. <support@audioscience.com>
6719f82d3SEliot Blennerhassett 
7719f82d3SEliot Blennerhassett 
8719f82d3SEliot Blennerhassett HPI Operating System Specific macros for Linux Kernel driver
9719f82d3SEliot Blennerhassett 
10719f82d3SEliot Blennerhassett (C) Copyright AudioScience Inc. 1997-2003
11719f82d3SEliot Blennerhassett ******************************************************************************/
12719f82d3SEliot Blennerhassett #ifndef _HPIOS_H_
13719f82d3SEliot Blennerhassett #define _HPIOS_H_
14719f82d3SEliot Blennerhassett 
15719f82d3SEliot Blennerhassett #undef HPI_OS_LINUX_KERNEL
16719f82d3SEliot Blennerhassett #define HPI_OS_LINUX_KERNEL
17719f82d3SEliot Blennerhassett 
18719f82d3SEliot Blennerhassett #define HPI_OS_DEFINED
19a287ca2aSEliot Blennerhassett #define HPI_BUILD_KERNEL_MODE
20719f82d3SEliot Blennerhassett 
21719f82d3SEliot Blennerhassett #include <linux/io.h>
22719f82d3SEliot Blennerhassett #include <linux/ioctl.h>
23719f82d3SEliot Blennerhassett #include <linux/kernel.h>
24719f82d3SEliot Blennerhassett #include <linux/string.h>
25719f82d3SEliot Blennerhassett #include <linux/device.h>
26719f82d3SEliot Blennerhassett #include <linux/firmware.h>
27719f82d3SEliot Blennerhassett #include <linux/interrupt.h>
28719f82d3SEliot Blennerhassett #include <linux/pci.h>
295ddc5befSEliot Blennerhassett #include <linux/mutex.h>
30719f82d3SEliot Blennerhassett 
31719f82d3SEliot Blennerhassett #define HPI_NO_OS_FILE_OPS
32719f82d3SEliot Blennerhassett 
33719f82d3SEliot Blennerhassett /** Details of a memory area allocated with  pci_alloc_consistent
34719f82d3SEliot Blennerhassett Need all info for parameters to pci_free_consistent
35719f82d3SEliot Blennerhassett */
36719f82d3SEliot Blennerhassett struct consistent_dma_area {
37719f82d3SEliot Blennerhassett 	struct device *pdev;
38719f82d3SEliot Blennerhassett 	/* looks like dma-mapping dma_devres ?! */
39719f82d3SEliot Blennerhassett 	size_t size;
40719f82d3SEliot Blennerhassett 	void *vaddr;
41719f82d3SEliot Blennerhassett 	dma_addr_t dma_handle;
42719f82d3SEliot Blennerhassett };
43719f82d3SEliot Blennerhassett 
hpios_locked_mem_get_phys_addr(struct consistent_dma_area * locked_mem_handle,u32 * p_physical_addr)44719f82d3SEliot Blennerhassett static inline u16 hpios_locked_mem_get_phys_addr(struct consistent_dma_area
45719f82d3SEliot Blennerhassett 	*locked_mem_handle, u32 *p_physical_addr)
46719f82d3SEliot Blennerhassett {
47719f82d3SEliot Blennerhassett 	*p_physical_addr = locked_mem_handle->dma_handle;
48719f82d3SEliot Blennerhassett 	return 0;
49719f82d3SEliot Blennerhassett }
50719f82d3SEliot Blennerhassett 
hpios_locked_mem_get_virt_addr(struct consistent_dma_area * locked_mem_handle,void ** pp_virtual_addr)51719f82d3SEliot Blennerhassett static inline u16 hpios_locked_mem_get_virt_addr(struct consistent_dma_area
52719f82d3SEliot Blennerhassett 	*locked_mem_handle, void **pp_virtual_addr)
53719f82d3SEliot Blennerhassett {
54719f82d3SEliot Blennerhassett 	*pp_virtual_addr = locked_mem_handle->vaddr;
55719f82d3SEliot Blennerhassett 	return 0;
56719f82d3SEliot Blennerhassett }
57719f82d3SEliot Blennerhassett 
hpios_locked_mem_valid(struct consistent_dma_area * locked_mem_handle)58719f82d3SEliot Blennerhassett static inline u16 hpios_locked_mem_valid(struct consistent_dma_area
59719f82d3SEliot Blennerhassett 	*locked_mem_handle)
60719f82d3SEliot Blennerhassett {
61719f82d3SEliot Blennerhassett 	return locked_mem_handle->size != 0;
62719f82d3SEliot Blennerhassett }
63719f82d3SEliot Blennerhassett 
64719f82d3SEliot Blennerhassett struct hpi_ioctl_linux {
65719f82d3SEliot Blennerhassett 	void __user *phm;
66719f82d3SEliot Blennerhassett 	void __user *phr;
67719f82d3SEliot Blennerhassett };
68719f82d3SEliot Blennerhassett 
69719f82d3SEliot Blennerhassett /* Conflict?: H is already used by a number of drivers hid, bluetooth hci,
702b987515SWang Qing    and some sound drivers sb16, hdsp, emu10k. AFAIK 0xFC is unused command
71719f82d3SEliot Blennerhassett */
72719f82d3SEliot Blennerhassett #define HPI_IOCTL_LINUX _IOWR('H', 0xFC, struct hpi_ioctl_linux)
73719f82d3SEliot Blennerhassett 
74719f82d3SEliot Blennerhassett #define HPI_DEBUG_FLAG_ERROR   KERN_ERR
75719f82d3SEliot Blennerhassett #define HPI_DEBUG_FLAG_WARNING KERN_WARNING
76719f82d3SEliot Blennerhassett #define HPI_DEBUG_FLAG_NOTICE  KERN_NOTICE
77719f82d3SEliot Blennerhassett #define HPI_DEBUG_FLAG_INFO    KERN_INFO
78719f82d3SEliot Blennerhassett #define HPI_DEBUG_FLAG_DEBUG   KERN_DEBUG
79719f82d3SEliot Blennerhassett #define HPI_DEBUG_FLAG_VERBOSE KERN_DEBUG	/* kernel has no verbose */
80719f82d3SEliot Blennerhassett 
81719f82d3SEliot Blennerhassett #include <linux/spinlock.h>
82719f82d3SEliot Blennerhassett 
83719f82d3SEliot Blennerhassett #define HPI_LOCKING
84719f82d3SEliot Blennerhassett 
85719f82d3SEliot Blennerhassett struct hpios_spinlock {
86719f82d3SEliot Blennerhassett 	spinlock_t lock;	/* SEE hpios_spinlock */
87719f82d3SEliot Blennerhassett 	int lock_context;
88719f82d3SEliot Blennerhassett };
89719f82d3SEliot Blennerhassett 
90719f82d3SEliot Blennerhassett /* The reason for all this evilness is that ALSA calls some of a drivers
91719f82d3SEliot Blennerhassett  * operators in atomic context, and some not.  But all our functions channel
92719f82d3SEliot Blennerhassett  * through the HPI_Message conduit, so we can't handle the different context
93719f82d3SEliot Blennerhassett  * per function
94719f82d3SEliot Blennerhassett  */
95719f82d3SEliot Blennerhassett #define IN_LOCK_BH 1
96719f82d3SEliot Blennerhassett #define IN_LOCK_IRQ 0
cond_lock(struct hpios_spinlock * l)97719f82d3SEliot Blennerhassett static inline void cond_lock(struct hpios_spinlock *l)
98719f82d3SEliot Blennerhassett {
99719f82d3SEliot Blennerhassett 	if (irqs_disabled()) {
100719f82d3SEliot Blennerhassett 		/* NO bh or isr can execute on this processor,
101719f82d3SEliot Blennerhassett 		   so ordinary lock will do
102719f82d3SEliot Blennerhassett 		 */
103719f82d3SEliot Blennerhassett 		spin_lock(&((l)->lock));
104719f82d3SEliot Blennerhassett 		l->lock_context = IN_LOCK_IRQ;
105719f82d3SEliot Blennerhassett 	} else {
106719f82d3SEliot Blennerhassett 		spin_lock_bh(&((l)->lock));
107719f82d3SEliot Blennerhassett 		l->lock_context = IN_LOCK_BH;
108719f82d3SEliot Blennerhassett 	}
109719f82d3SEliot Blennerhassett }
110719f82d3SEliot Blennerhassett 
cond_unlock(struct hpios_spinlock * l)111719f82d3SEliot Blennerhassett static inline void cond_unlock(struct hpios_spinlock *l)
112719f82d3SEliot Blennerhassett {
113719f82d3SEliot Blennerhassett 	if (l->lock_context == IN_LOCK_BH)
114719f82d3SEliot Blennerhassett 		spin_unlock_bh(&((l)->lock));
115719f82d3SEliot Blennerhassett 	else
116719f82d3SEliot Blennerhassett 		spin_unlock(&((l)->lock));
117719f82d3SEliot Blennerhassett }
118719f82d3SEliot Blennerhassett 
119719f82d3SEliot Blennerhassett #define hpios_msgxlock_init(obj)      spin_lock_init(&(obj)->lock)
120719f82d3SEliot Blennerhassett #define hpios_msgxlock_lock(obj)   cond_lock(obj)
1213285ea10SEliot Blennerhassett #define hpios_msgxlock_unlock(obj) cond_unlock(obj)
122719f82d3SEliot Blennerhassett 
123719f82d3SEliot Blennerhassett #define hpios_dsplock_init(obj)       spin_lock_init(&(obj)->dsp_lock.lock)
124719f82d3SEliot Blennerhassett #define hpios_dsplock_lock(obj)    cond_lock(&(obj)->dsp_lock)
125719f82d3SEliot Blennerhassett #define hpios_dsplock_unlock(obj)  cond_unlock(&(obj)->dsp_lock)
126719f82d3SEliot Blennerhassett 
127719f82d3SEliot Blennerhassett #ifdef CONFIG_SND_DEBUG
128a287ca2aSEliot Blennerhassett #define HPI_BUILD_DEBUG
129719f82d3SEliot Blennerhassett #endif
130719f82d3SEliot Blennerhassett 
131719f82d3SEliot Blennerhassett #define HPI_ALIST_LOCKING
132719f82d3SEliot Blennerhassett #define hpios_alistlock_init(obj)    spin_lock_init(&((obj)->list_lock.lock))
133719f82d3SEliot Blennerhassett #define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock))
1343285ea10SEliot Blennerhassett #define hpios_alistlock_unlock(obj) spin_unlock(&((obj)->list_lock.lock))
135719f82d3SEliot Blennerhassett 
1367036b92dSEliot Blennerhassett struct snd_card;
1377036b92dSEliot Blennerhassett 
1387036b92dSEliot Blennerhassett /** pci drvdata points to an instance of this struct */
139719f82d3SEliot Blennerhassett struct hpi_adapter {
1407036b92dSEliot Blennerhassett 	struct hpi_adapter_obj *adapter;
1417036b92dSEliot Blennerhassett 	struct snd_card *snd_card;
1427036b92dSEliot Blennerhassett 
143f9a376c3SEliot Blennerhassett 	int irq;
144f9a376c3SEliot Blennerhassett 	int interrupt_mode;
145f9a376c3SEliot Blennerhassett 	void (*interrupt_callback) (struct hpi_adapter *);
146f9a376c3SEliot Blennerhassett 
147719f82d3SEliot Blennerhassett 	/* mutex prevents contention for one card
148719f82d3SEliot Blennerhassett 	   between multiple user programs (via ioctl) */
149719f82d3SEliot Blennerhassett 	struct mutex mutex;
150719f82d3SEliot Blennerhassett 	char *p_buffer;
151719f82d3SEliot Blennerhassett 	size_t buffer_size;
152719f82d3SEliot Blennerhassett };
153719f82d3SEliot Blennerhassett 
154719f82d3SEliot Blennerhassett #endif
155