Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /******************************************************************************
0003 
0004     AudioScience HPI driver
0005     Copyright (C) 1997-2011  AudioScience Inc. <support@audioscience.com>
0006 
0007 
0008 HPI Operating System Specific macros for Linux Kernel driver
0009 
0010 (C) Copyright AudioScience Inc. 1997-2003
0011 ******************************************************************************/
0012 #ifndef _HPIOS_H_
0013 #define _HPIOS_H_
0014 
0015 #undef HPI_OS_LINUX_KERNEL
0016 #define HPI_OS_LINUX_KERNEL
0017 
0018 #define HPI_OS_DEFINED
0019 #define HPI_BUILD_KERNEL_MODE
0020 
0021 #include <linux/io.h>
0022 #include <linux/ioctl.h>
0023 #include <linux/kernel.h>
0024 #include <linux/string.h>
0025 #include <linux/device.h>
0026 #include <linux/firmware.h>
0027 #include <linux/interrupt.h>
0028 #include <linux/pci.h>
0029 #include <linux/mutex.h>
0030 
0031 #define HPI_NO_OS_FILE_OPS
0032 
0033 /** Details of a memory area allocated with  pci_alloc_consistent
0034 Need all info for parameters to pci_free_consistent
0035 */
0036 struct consistent_dma_area {
0037     struct device *pdev;
0038     /* looks like dma-mapping dma_devres ?! */
0039     size_t size;
0040     void *vaddr;
0041     dma_addr_t dma_handle;
0042 };
0043 
0044 static inline u16 hpios_locked_mem_get_phys_addr(struct consistent_dma_area
0045     *locked_mem_handle, u32 *p_physical_addr)
0046 {
0047     *p_physical_addr = locked_mem_handle->dma_handle;
0048     return 0;
0049 }
0050 
0051 static inline u16 hpios_locked_mem_get_virt_addr(struct consistent_dma_area
0052     *locked_mem_handle, void **pp_virtual_addr)
0053 {
0054     *pp_virtual_addr = locked_mem_handle->vaddr;
0055     return 0;
0056 }
0057 
0058 static inline u16 hpios_locked_mem_valid(struct consistent_dma_area
0059     *locked_mem_handle)
0060 {
0061     return locked_mem_handle->size != 0;
0062 }
0063 
0064 struct hpi_ioctl_linux {
0065     void __user *phm;
0066     void __user *phr;
0067 };
0068 
0069 /* Conflict?: H is already used by a number of drivers hid, bluetooth hci,
0070    and some sound drivers sb16, hdsp, emu10k. AFAIK 0xFC is unused command
0071 */
0072 #define HPI_IOCTL_LINUX _IOWR('H', 0xFC, struct hpi_ioctl_linux)
0073 
0074 #define HPI_DEBUG_FLAG_ERROR   KERN_ERR
0075 #define HPI_DEBUG_FLAG_WARNING KERN_WARNING
0076 #define HPI_DEBUG_FLAG_NOTICE  KERN_NOTICE
0077 #define HPI_DEBUG_FLAG_INFO    KERN_INFO
0078 #define HPI_DEBUG_FLAG_DEBUG   KERN_DEBUG
0079 #define HPI_DEBUG_FLAG_VERBOSE KERN_DEBUG   /* kernel has no verbose */
0080 
0081 #include <linux/spinlock.h>
0082 
0083 #define HPI_LOCKING
0084 
0085 struct hpios_spinlock {
0086     spinlock_t lock;    /* SEE hpios_spinlock */
0087     int lock_context;
0088 };
0089 
0090 /* The reason for all this evilness is that ALSA calls some of a drivers
0091  * operators in atomic context, and some not.  But all our functions channel
0092  * through the HPI_Message conduit, so we can't handle the different context
0093  * per function
0094  */
0095 #define IN_LOCK_BH 1
0096 #define IN_LOCK_IRQ 0
0097 static inline void cond_lock(struct hpios_spinlock *l)
0098 {
0099     if (irqs_disabled()) {
0100         /* NO bh or isr can execute on this processor,
0101            so ordinary lock will do
0102          */
0103         spin_lock(&((l)->lock));
0104         l->lock_context = IN_LOCK_IRQ;
0105     } else {
0106         spin_lock_bh(&((l)->lock));
0107         l->lock_context = IN_LOCK_BH;
0108     }
0109 }
0110 
0111 static inline void cond_unlock(struct hpios_spinlock *l)
0112 {
0113     if (l->lock_context == IN_LOCK_BH)
0114         spin_unlock_bh(&((l)->lock));
0115     else
0116         spin_unlock(&((l)->lock));
0117 }
0118 
0119 #define hpios_msgxlock_init(obj)      spin_lock_init(&(obj)->lock)
0120 #define hpios_msgxlock_lock(obj)   cond_lock(obj)
0121 #define hpios_msgxlock_unlock(obj) cond_unlock(obj)
0122 
0123 #define hpios_dsplock_init(obj)       spin_lock_init(&(obj)->dsp_lock.lock)
0124 #define hpios_dsplock_lock(obj)    cond_lock(&(obj)->dsp_lock)
0125 #define hpios_dsplock_unlock(obj)  cond_unlock(&(obj)->dsp_lock)
0126 
0127 #ifdef CONFIG_SND_DEBUG
0128 #define HPI_BUILD_DEBUG
0129 #endif
0130 
0131 #define HPI_ALIST_LOCKING
0132 #define hpios_alistlock_init(obj)    spin_lock_init(&((obj)->list_lock.lock))
0133 #define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock))
0134 #define hpios_alistlock_unlock(obj) spin_unlock(&((obj)->list_lock.lock))
0135 
0136 struct snd_card;
0137 
0138 /** pci drvdata points to an instance of this struct */
0139 struct hpi_adapter {
0140     struct hpi_adapter_obj *adapter;
0141     struct snd_card *snd_card;
0142 
0143     int irq;
0144     int interrupt_mode;
0145     void (*interrupt_callback) (struct hpi_adapter *);
0146 
0147     /* mutex prevents contention for one card
0148        between multiple user programs (via ioctl) */
0149     struct mutex mutex;
0150     char *p_buffer;
0151     size_t buffer_size;
0152 };
0153 
0154 #endif