1/* SPDX-License-Identifier: GPL-2.0-only */
2/******************************************************************************
3
4    AudioScience HPI driver
5    Copyright (C) 1997-2011  AudioScience Inc. <support@audioscience.com>
6
7
8HPI Operating System Specific macros for Linux Kernel driver
9
10(C) Copyright AudioScience Inc. 1997-2003
11******************************************************************************/
12#ifndef _HPIOS_H_
13#define _HPIOS_H_
14
15#undef HPI_OS_LINUX_KERNEL
16#define HPI_OS_LINUX_KERNEL
17
18#define HPI_OS_DEFINED
19#define HPI_BUILD_KERNEL_MODE
20
21#include <linux/io.h>
22#include <linux/ioctl.h>
23#include <linux/kernel.h>
24#include <linux/string.h>
25#include <linux/device.h>
26#include <linux/firmware.h>
27#include <linux/interrupt.h>
28#include <linux/pci.h>
29#include <linux/mutex.h>
30
31#define HPI_NO_OS_FILE_OPS
32
33/** Details of a memory area allocated with  pci_alloc_consistent
34Need all info for parameters to pci_free_consistent
35*/
36struct consistent_dma_area {
37	struct device *pdev;
38	/* looks like dma-mapping dma_devres ?! */
39	size_t size;
40	void *vaddr;
41	dma_addr_t dma_handle;
42};
43
44static inline u16 hpios_locked_mem_get_phys_addr(struct consistent_dma_area
45	*locked_mem_handle, u32 *p_physical_addr)
46{
47	*p_physical_addr = locked_mem_handle->dma_handle;
48	return 0;
49}
50
51static inline u16 hpios_locked_mem_get_virt_addr(struct consistent_dma_area
52	*locked_mem_handle, void **pp_virtual_addr)
53{
54	*pp_virtual_addr = locked_mem_handle->vaddr;
55	return 0;
56}
57
58static inline u16 hpios_locked_mem_valid(struct consistent_dma_area
59	*locked_mem_handle)
60{
61	return locked_mem_handle->size != 0;
62}
63
64struct hpi_ioctl_linux {
65	void __user *phm;
66	void __user *phr;
67};
68
69/* Conflict?: H is already used by a number of drivers hid, bluetooth hci,
70   and some sound drivers sb16, hdsp, emu10k. AFAIK 0xFC is unused command
71*/
72#define HPI_IOCTL_LINUX _IOWR('H', 0xFC, struct hpi_ioctl_linux)
73
74#define HPI_DEBUG_FLAG_ERROR   KERN_ERR
75#define HPI_DEBUG_FLAG_WARNING KERN_WARNING
76#define HPI_DEBUG_FLAG_NOTICE  KERN_NOTICE
77#define HPI_DEBUG_FLAG_INFO    KERN_INFO
78#define HPI_DEBUG_FLAG_DEBUG   KERN_DEBUG
79#define HPI_DEBUG_FLAG_VERBOSE KERN_DEBUG	/* kernel has no verbose */
80
81#include <linux/spinlock.h>
82
83#define HPI_LOCKING
84
85struct hpios_spinlock {
86	spinlock_t lock;	/* SEE hpios_spinlock */
87	int lock_context;
88};
89
90/* The reason for all this evilness is that ALSA calls some of a drivers
91 * operators in atomic context, and some not.  But all our functions channel
92 * through the HPI_Message conduit, so we can't handle the different context
93 * per function
94 */
95#define IN_LOCK_BH 1
96#define IN_LOCK_IRQ 0
97static inline void cond_lock(struct hpios_spinlock *l)
98{
99	if (irqs_disabled()) {
100		/* NO bh or isr can execute on this processor,
101		   so ordinary lock will do
102		 */
103		spin_lock(&((l)->lock));
104		l->lock_context = IN_LOCK_IRQ;
105	} else {
106		spin_lock_bh(&((l)->lock));
107		l->lock_context = IN_LOCK_BH;
108	}
109}
110
111static inline void cond_unlock(struct hpios_spinlock *l)
112{
113	if (l->lock_context == IN_LOCK_BH)
114		spin_unlock_bh(&((l)->lock));
115	else
116		spin_unlock(&((l)->lock));
117}
118
119#define hpios_msgxlock_init(obj)      spin_lock_init(&(obj)->lock)
120#define hpios_msgxlock_lock(obj)   cond_lock(obj)
121#define hpios_msgxlock_unlock(obj) cond_unlock(obj)
122
123#define hpios_dsplock_init(obj)       spin_lock_init(&(obj)->dsp_lock.lock)
124#define hpios_dsplock_lock(obj)    cond_lock(&(obj)->dsp_lock)
125#define hpios_dsplock_unlock(obj)  cond_unlock(&(obj)->dsp_lock)
126
127#ifdef CONFIG_SND_DEBUG
128#define HPI_BUILD_DEBUG
129#endif
130
131#define HPI_ALIST_LOCKING
132#define hpios_alistlock_init(obj)    spin_lock_init(&((obj)->list_lock.lock))
133#define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock))
134#define hpios_alistlock_unlock(obj) spin_unlock(&((obj)->list_lock.lock))
135
136struct snd_card;
137
138/** pci drvdata points to an instance of this struct */
139struct hpi_adapter {
140	struct hpi_adapter_obj *adapter;
141	struct snd_card *snd_card;
142
143	int irq;
144	int interrupt_mode;
145	void (*interrupt_callback) (struct hpi_adapter *);
146
147	/* mutex prevents contention for one card
148	   between multiple user programs (via ioctl) */
149	struct mutex mutex;
150	char *p_buffer;
151	size_t buffer_size;
152};
153
154#endif
155