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 | |
8 | HPI 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 |
34 | Need all info for parameters to pci_free_consistent |
35 | */ |
36 | struct 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 | |
44 | static 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 | |
51 | static 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 | |
58 | static inline u16 hpios_locked_mem_valid(struct consistent_dma_area |
59 | *locked_mem_handle) |
60 | { |
61 | return locked_mem_handle->size != 0; |
62 | } |
63 | |
64 | struct 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 | |
85 | struct 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 |
97 | static 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(lock: &((l)->lock)); |
104 | l->lock_context = IN_LOCK_IRQ; |
105 | } else { |
106 | spin_lock_bh(lock: &((l)->lock)); |
107 | l->lock_context = IN_LOCK_BH; |
108 | } |
109 | } |
110 | |
111 | static inline void cond_unlock(struct hpios_spinlock *l) |
112 | { |
113 | if (l->lock_context == IN_LOCK_BH) |
114 | spin_unlock_bh(lock: &((l)->lock)); |
115 | else |
116 | spin_unlock(lock: &((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 | |
136 | struct snd_card; |
137 | |
138 | /** pci drvdata points to an instance of this struct */ |
139 | struct 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 | |