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(&((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 111 static 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 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