xref: /openbmc/linux/sound/pci/asihpi/hpios.h (revision 719f82d3)
1719f82d3SEliot Blennerhassett /******************************************************************************
2719f82d3SEliot Blennerhassett 
3719f82d3SEliot Blennerhassett     AudioScience HPI driver
4719f82d3SEliot Blennerhassett     Copyright (C) 1997-2010  AudioScience Inc. <support@audioscience.com>
5719f82d3SEliot Blennerhassett 
6719f82d3SEliot Blennerhassett     This program is free software; you can redistribute it and/or modify
7719f82d3SEliot Blennerhassett     it under the terms of version 2 of the GNU General Public License as
8719f82d3SEliot Blennerhassett     published by the Free Software Foundation;
9719f82d3SEliot Blennerhassett 
10719f82d3SEliot Blennerhassett     This program is distributed in the hope that it will be useful,
11719f82d3SEliot Blennerhassett     but WITHOUT ANY WARRANTY; without even the implied warranty of
12719f82d3SEliot Blennerhassett     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13719f82d3SEliot Blennerhassett     GNU General Public License for more details.
14719f82d3SEliot Blennerhassett 
15719f82d3SEliot Blennerhassett     You should have received a copy of the GNU General Public License
16719f82d3SEliot Blennerhassett     along with this program; if not, write to the Free Software
17719f82d3SEliot Blennerhassett     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18719f82d3SEliot Blennerhassett 
19719f82d3SEliot Blennerhassett HPI Operating System Specific macros for Linux Kernel driver
20719f82d3SEliot Blennerhassett 
21719f82d3SEliot Blennerhassett (C) Copyright AudioScience Inc. 1997-2003
22719f82d3SEliot Blennerhassett ******************************************************************************/
23719f82d3SEliot Blennerhassett #ifndef _HPIOS_H_
24719f82d3SEliot Blennerhassett #define _HPIOS_H_
25719f82d3SEliot Blennerhassett 
26719f82d3SEliot Blennerhassett #undef HPI_OS_LINUX_KERNEL
27719f82d3SEliot Blennerhassett #define HPI_OS_LINUX_KERNEL
28719f82d3SEliot Blennerhassett 
29719f82d3SEliot Blennerhassett #define HPI_OS_DEFINED
30719f82d3SEliot Blennerhassett #define HPI_KERNEL_MODE
31719f82d3SEliot Blennerhassett 
32719f82d3SEliot Blennerhassett #define HPI_REASSIGN_DUPLICATE_ADAPTER_IDX
33719f82d3SEliot Blennerhassett 
34719f82d3SEliot Blennerhassett #include <linux/io.h>
35719f82d3SEliot Blennerhassett #include <asm/system.h>
36719f82d3SEliot Blennerhassett #include <linux/ioctl.h>
37719f82d3SEliot Blennerhassett #include <linux/kernel.h>
38719f82d3SEliot Blennerhassett #include <linux/string.h>
39719f82d3SEliot Blennerhassett #include <linux/device.h>
40719f82d3SEliot Blennerhassett #include <linux/firmware.h>
41719f82d3SEliot Blennerhassett #include <linux/interrupt.h>
42719f82d3SEliot Blennerhassett #include <linux/pci.h>
43719f82d3SEliot Blennerhassett 
44719f82d3SEliot Blennerhassett #define HPI_NO_OS_FILE_OPS
45719f82d3SEliot Blennerhassett 
46719f82d3SEliot Blennerhassett #ifdef CONFIG_64BIT
47719f82d3SEliot Blennerhassett #define HPI64BIT
48719f82d3SEliot Blennerhassett #endif
49719f82d3SEliot Blennerhassett 
50719f82d3SEliot Blennerhassett /** Details of a memory area allocated with  pci_alloc_consistent
51719f82d3SEliot Blennerhassett Need all info for parameters to pci_free_consistent
52719f82d3SEliot Blennerhassett */
53719f82d3SEliot Blennerhassett struct consistent_dma_area {
54719f82d3SEliot Blennerhassett 	struct device *pdev;
55719f82d3SEliot Blennerhassett 	/* looks like dma-mapping dma_devres ?! */
56719f82d3SEliot Blennerhassett 	size_t size;
57719f82d3SEliot Blennerhassett 	void *vaddr;
58719f82d3SEliot Blennerhassett 	dma_addr_t dma_handle;
59719f82d3SEliot Blennerhassett };
60719f82d3SEliot Blennerhassett 
61719f82d3SEliot Blennerhassett static inline u16 hpios_locked_mem_get_phys_addr(struct consistent_dma_area
62719f82d3SEliot Blennerhassett 	*locked_mem_handle, u32 *p_physical_addr)
63719f82d3SEliot Blennerhassett {
64719f82d3SEliot Blennerhassett 	*p_physical_addr = locked_mem_handle->dma_handle;
65719f82d3SEliot Blennerhassett 	return 0;
66719f82d3SEliot Blennerhassett }
67719f82d3SEliot Blennerhassett 
68719f82d3SEliot Blennerhassett static inline u16 hpios_locked_mem_get_virt_addr(struct consistent_dma_area
69719f82d3SEliot Blennerhassett 	*locked_mem_handle, void **pp_virtual_addr)
70719f82d3SEliot Blennerhassett {
71719f82d3SEliot Blennerhassett 	*pp_virtual_addr = locked_mem_handle->vaddr;
72719f82d3SEliot Blennerhassett 	return 0;
73719f82d3SEliot Blennerhassett }
74719f82d3SEliot Blennerhassett 
75719f82d3SEliot Blennerhassett static inline u16 hpios_locked_mem_valid(struct consistent_dma_area
76719f82d3SEliot Blennerhassett 	*locked_mem_handle)
77719f82d3SEliot Blennerhassett {
78719f82d3SEliot Blennerhassett 	return locked_mem_handle->size != 0;
79719f82d3SEliot Blennerhassett }
80719f82d3SEliot Blennerhassett 
81719f82d3SEliot Blennerhassett struct hpi_ioctl_linux {
82719f82d3SEliot Blennerhassett 	void __user *phm;
83719f82d3SEliot Blennerhassett 	void __user *phr;
84719f82d3SEliot Blennerhassett };
85719f82d3SEliot Blennerhassett 
86719f82d3SEliot Blennerhassett /* Conflict?: H is already used by a number of drivers hid, bluetooth hci,
87719f82d3SEliot Blennerhassett    and some sound drivers sb16, hdsp, emu10k. AFAIK 0xFC is ununsed command
88719f82d3SEliot Blennerhassett */
89719f82d3SEliot Blennerhassett #define HPI_IOCTL_LINUX _IOWR('H', 0xFC, struct hpi_ioctl_linux)
90719f82d3SEliot Blennerhassett 
91719f82d3SEliot Blennerhassett #define HPI_DEBUG_FLAG_ERROR   KERN_ERR
92719f82d3SEliot Blennerhassett #define HPI_DEBUG_FLAG_WARNING KERN_WARNING
93719f82d3SEliot Blennerhassett #define HPI_DEBUG_FLAG_NOTICE  KERN_NOTICE
94719f82d3SEliot Blennerhassett #define HPI_DEBUG_FLAG_INFO    KERN_INFO
95719f82d3SEliot Blennerhassett #define HPI_DEBUG_FLAG_DEBUG   KERN_DEBUG
96719f82d3SEliot Blennerhassett #define HPI_DEBUG_FLAG_VERBOSE KERN_DEBUG	/* kernel has no verbose */
97719f82d3SEliot Blennerhassett 
98719f82d3SEliot Blennerhassett #include <linux/spinlock.h>
99719f82d3SEliot Blennerhassett 
100719f82d3SEliot Blennerhassett #define HPI_LOCKING
101719f82d3SEliot Blennerhassett 
102719f82d3SEliot Blennerhassett struct hpios_spinlock {
103719f82d3SEliot Blennerhassett 	spinlock_t lock;	/* SEE hpios_spinlock */
104719f82d3SEliot Blennerhassett 	int lock_context;
105719f82d3SEliot Blennerhassett };
106719f82d3SEliot Blennerhassett 
107719f82d3SEliot Blennerhassett /* The reason for all this evilness is that ALSA calls some of a drivers
108719f82d3SEliot Blennerhassett  * operators in atomic context, and some not.  But all our functions channel
109719f82d3SEliot Blennerhassett  * through the HPI_Message conduit, so we can't handle the different context
110719f82d3SEliot Blennerhassett  * per function
111719f82d3SEliot Blennerhassett  */
112719f82d3SEliot Blennerhassett #define IN_LOCK_BH 1
113719f82d3SEliot Blennerhassett #define IN_LOCK_IRQ 0
114719f82d3SEliot Blennerhassett static inline void cond_lock(struct hpios_spinlock *l)
115719f82d3SEliot Blennerhassett {
116719f82d3SEliot Blennerhassett 	if (irqs_disabled()) {
117719f82d3SEliot Blennerhassett 		/* NO bh or isr can execute on this processor,
118719f82d3SEliot Blennerhassett 		   so ordinary lock will do
119719f82d3SEliot Blennerhassett 		 */
120719f82d3SEliot Blennerhassett 		spin_lock(&((l)->lock));
121719f82d3SEliot Blennerhassett 		l->lock_context = IN_LOCK_IRQ;
122719f82d3SEliot Blennerhassett 	} else {
123719f82d3SEliot Blennerhassett 		spin_lock_bh(&((l)->lock));
124719f82d3SEliot Blennerhassett 		l->lock_context = IN_LOCK_BH;
125719f82d3SEliot Blennerhassett 	}
126719f82d3SEliot Blennerhassett }
127719f82d3SEliot Blennerhassett 
128719f82d3SEliot Blennerhassett static inline void cond_unlock(struct hpios_spinlock *l)
129719f82d3SEliot Blennerhassett {
130719f82d3SEliot Blennerhassett 	if (l->lock_context == IN_LOCK_BH)
131719f82d3SEliot Blennerhassett 		spin_unlock_bh(&((l)->lock));
132719f82d3SEliot Blennerhassett 	else
133719f82d3SEliot Blennerhassett 		spin_unlock(&((l)->lock));
134719f82d3SEliot Blennerhassett }
135719f82d3SEliot Blennerhassett 
136719f82d3SEliot Blennerhassett #define hpios_msgxlock_init(obj)      spin_lock_init(&(obj)->lock)
137719f82d3SEliot Blennerhassett #define hpios_msgxlock_lock(obj)   cond_lock(obj)
138719f82d3SEliot Blennerhassett #define hpios_msgxlock_un_lock(obj) cond_unlock(obj)
139719f82d3SEliot Blennerhassett 
140719f82d3SEliot Blennerhassett #define hpios_dsplock_init(obj)       spin_lock_init(&(obj)->dsp_lock.lock)
141719f82d3SEliot Blennerhassett #define hpios_dsplock_lock(obj)    cond_lock(&(obj)->dsp_lock)
142719f82d3SEliot Blennerhassett #define hpios_dsplock_unlock(obj)  cond_unlock(&(obj)->dsp_lock)
143719f82d3SEliot Blennerhassett 
144719f82d3SEliot Blennerhassett #ifdef CONFIG_SND_DEBUG
145719f82d3SEliot Blennerhassett #define HPI_DEBUG
146719f82d3SEliot Blennerhassett #endif
147719f82d3SEliot Blennerhassett 
148719f82d3SEliot Blennerhassett #define HPI_ALIST_LOCKING
149719f82d3SEliot Blennerhassett #define hpios_alistlock_init(obj)    spin_lock_init(&((obj)->list_lock.lock))
150719f82d3SEliot Blennerhassett #define hpios_alistlock_lock(obj) spin_lock(&((obj)->list_lock.lock))
151719f82d3SEliot Blennerhassett #define hpios_alistlock_un_lock(obj) spin_unlock(&((obj)->list_lock.lock))
152719f82d3SEliot Blennerhassett 
153719f82d3SEliot Blennerhassett struct hpi_adapter {
154719f82d3SEliot Blennerhassett 	/* mutex prevents contention for one card
155719f82d3SEliot Blennerhassett 	   between multiple user programs (via ioctl) */
156719f82d3SEliot Blennerhassett 	struct mutex mutex;
157719f82d3SEliot Blennerhassett 	u16 index;
158719f82d3SEliot Blennerhassett 	u16 type;
159719f82d3SEliot Blennerhassett 
160719f82d3SEliot Blennerhassett 	/* ALSA card structure */
161719f82d3SEliot Blennerhassett 	void *snd_card_asihpi;
162719f82d3SEliot Blennerhassett 
163719f82d3SEliot Blennerhassett 	char *p_buffer;
164719f82d3SEliot Blennerhassett 	size_t buffer_size;
165719f82d3SEliot Blennerhassett 	struct pci_dev *pci;
166719f82d3SEliot Blennerhassett 	void __iomem *ap_remapped_mem_base[HPI_MAX_ADAPTER_MEM_SPACES];
167719f82d3SEliot Blennerhassett };
168719f82d3SEliot Blennerhassett 
169719f82d3SEliot Blennerhassett static inline void hpios_unmap_io(void __iomem *addr,
170719f82d3SEliot Blennerhassett 	unsigned long size)
171719f82d3SEliot Blennerhassett {
172719f82d3SEliot Blennerhassett 	iounmap(addr);
173719f82d3SEliot Blennerhassett }
174719f82d3SEliot Blennerhassett 
175719f82d3SEliot Blennerhassett void __iomem *hpios_map_io(struct pci_dev *pci_dev, int idx,
176719f82d3SEliot Blennerhassett 	unsigned int length);
177719f82d3SEliot Blennerhassett 
178719f82d3SEliot Blennerhassett #endif
179