18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
48c2ecf20Sopenharmony_ci *  I/O routines for GF1/InterWave synthesizer chips
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include <linux/delay.h>
88c2ecf20Sopenharmony_ci#include <linux/time.h>
98c2ecf20Sopenharmony_ci#include <sound/core.h>
108c2ecf20Sopenharmony_ci#include <sound/gus.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_civoid snd_gf1_delay(struct snd_gus_card * gus)
138c2ecf20Sopenharmony_ci{
148c2ecf20Sopenharmony_ci	int i;
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci	for (i = 0; i < 6; i++) {
178c2ecf20Sopenharmony_ci		mb();
188c2ecf20Sopenharmony_ci		inb(GUSP(gus, DRAM));
198c2ecf20Sopenharmony_ci	}
208c2ecf20Sopenharmony_ci}
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci/*
238c2ecf20Sopenharmony_ci *  =======================================================================
248c2ecf20Sopenharmony_ci */
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci/*
278c2ecf20Sopenharmony_ci *  ok.. stop of control registers (wave & ramp) need some special things..
288c2ecf20Sopenharmony_ci *       big UltraClick (tm) elimination...
298c2ecf20Sopenharmony_ci */
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistatic inline void __snd_gf1_ctrl_stop(struct snd_gus_card * gus, unsigned char reg)
328c2ecf20Sopenharmony_ci{
338c2ecf20Sopenharmony_ci	unsigned char value;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	outb(reg | 0x80, gus->gf1.reg_regsel);
368c2ecf20Sopenharmony_ci	mb();
378c2ecf20Sopenharmony_ci	value = inb(gus->gf1.reg_data8);
388c2ecf20Sopenharmony_ci	mb();
398c2ecf20Sopenharmony_ci	outb(reg, gus->gf1.reg_regsel);
408c2ecf20Sopenharmony_ci	mb();
418c2ecf20Sopenharmony_ci	outb((value | 0x03) & ~(0x80 | 0x20), gus->gf1.reg_data8);
428c2ecf20Sopenharmony_ci	mb();
438c2ecf20Sopenharmony_ci}
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_cistatic inline void __snd_gf1_write8(struct snd_gus_card * gus,
468c2ecf20Sopenharmony_ci				    unsigned char reg,
478c2ecf20Sopenharmony_ci				    unsigned char data)
488c2ecf20Sopenharmony_ci{
498c2ecf20Sopenharmony_ci	outb(reg, gus->gf1.reg_regsel);
508c2ecf20Sopenharmony_ci	mb();
518c2ecf20Sopenharmony_ci	outb(data, gus->gf1.reg_data8);
528c2ecf20Sopenharmony_ci	mb();
538c2ecf20Sopenharmony_ci}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cistatic inline unsigned char __snd_gf1_look8(struct snd_gus_card * gus,
568c2ecf20Sopenharmony_ci					    unsigned char reg)
578c2ecf20Sopenharmony_ci{
588c2ecf20Sopenharmony_ci	outb(reg, gus->gf1.reg_regsel);
598c2ecf20Sopenharmony_ci	mb();
608c2ecf20Sopenharmony_ci	return inb(gus->gf1.reg_data8);
618c2ecf20Sopenharmony_ci}
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_cistatic inline void __snd_gf1_write16(struct snd_gus_card * gus,
648c2ecf20Sopenharmony_ci				     unsigned char reg, unsigned int data)
658c2ecf20Sopenharmony_ci{
668c2ecf20Sopenharmony_ci	outb(reg, gus->gf1.reg_regsel);
678c2ecf20Sopenharmony_ci	mb();
688c2ecf20Sopenharmony_ci	outw((unsigned short) data, gus->gf1.reg_data16);
698c2ecf20Sopenharmony_ci	mb();
708c2ecf20Sopenharmony_ci}
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_cistatic inline unsigned short __snd_gf1_look16(struct snd_gus_card * gus,
738c2ecf20Sopenharmony_ci					      unsigned char reg)
748c2ecf20Sopenharmony_ci{
758c2ecf20Sopenharmony_ci	outb(reg, gus->gf1.reg_regsel);
768c2ecf20Sopenharmony_ci	mb();
778c2ecf20Sopenharmony_ci	return inw(gus->gf1.reg_data16);
788c2ecf20Sopenharmony_ci}
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_cistatic inline void __snd_gf1_adlib_write(struct snd_gus_card * gus,
818c2ecf20Sopenharmony_ci					 unsigned char reg, unsigned char data)
828c2ecf20Sopenharmony_ci{
838c2ecf20Sopenharmony_ci	outb(reg, gus->gf1.reg_timerctrl);
848c2ecf20Sopenharmony_ci	inb(gus->gf1.reg_timerctrl);
858c2ecf20Sopenharmony_ci	inb(gus->gf1.reg_timerctrl);
868c2ecf20Sopenharmony_ci	outb(data, gus->gf1.reg_timerdata);
878c2ecf20Sopenharmony_ci	inb(gus->gf1.reg_timerctrl);
888c2ecf20Sopenharmony_ci	inb(gus->gf1.reg_timerctrl);
898c2ecf20Sopenharmony_ci}
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_cistatic inline void __snd_gf1_write_addr(struct snd_gus_card * gus, unsigned char reg,
928c2ecf20Sopenharmony_ci                                        unsigned int addr, int w_16bit)
938c2ecf20Sopenharmony_ci{
948c2ecf20Sopenharmony_ci	if (gus->gf1.enh_mode) {
958c2ecf20Sopenharmony_ci		if (w_16bit)
968c2ecf20Sopenharmony_ci			addr = ((addr >> 1) & ~0x0000000f) | (addr & 0x0000000f);
978c2ecf20Sopenharmony_ci		__snd_gf1_write8(gus, SNDRV_GF1_VB_UPPER_ADDRESS, (unsigned char) ((addr >> 26) & 0x03));
988c2ecf20Sopenharmony_ci	} else if (w_16bit)
998c2ecf20Sopenharmony_ci		addr = (addr & 0x00c0000f) | ((addr & 0x003ffff0) >> 1);
1008c2ecf20Sopenharmony_ci	__snd_gf1_write16(gus, reg, (unsigned short) (addr >> 11));
1018c2ecf20Sopenharmony_ci	__snd_gf1_write16(gus, reg + 1, (unsigned short) (addr << 5));
1028c2ecf20Sopenharmony_ci}
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_cistatic inline unsigned int __snd_gf1_read_addr(struct snd_gus_card * gus,
1058c2ecf20Sopenharmony_ci					       unsigned char reg, short w_16bit)
1068c2ecf20Sopenharmony_ci{
1078c2ecf20Sopenharmony_ci	unsigned int res;
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	res = ((unsigned int) __snd_gf1_look16(gus, reg | 0x80) << 11) & 0xfff800;
1108c2ecf20Sopenharmony_ci	res |= ((unsigned int) __snd_gf1_look16(gus, (reg + 1) | 0x80) >> 5) & 0x0007ff;
1118c2ecf20Sopenharmony_ci	if (gus->gf1.enh_mode) {
1128c2ecf20Sopenharmony_ci		res |= (unsigned int) __snd_gf1_look8(gus, SNDRV_GF1_VB_UPPER_ADDRESS | 0x80) << 26;
1138c2ecf20Sopenharmony_ci		if (w_16bit)
1148c2ecf20Sopenharmony_ci			res = ((res << 1) & 0xffffffe0) | (res & 0x0000000f);
1158c2ecf20Sopenharmony_ci	} else if (w_16bit)
1168c2ecf20Sopenharmony_ci		res = ((res & 0x001ffff0) << 1) | (res & 0x00c0000f);
1178c2ecf20Sopenharmony_ci	return res;
1188c2ecf20Sopenharmony_ci}
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci/*
1228c2ecf20Sopenharmony_ci *  =======================================================================
1238c2ecf20Sopenharmony_ci */
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_civoid snd_gf1_ctrl_stop(struct snd_gus_card * gus, unsigned char reg)
1268c2ecf20Sopenharmony_ci{
1278c2ecf20Sopenharmony_ci	__snd_gf1_ctrl_stop(gus, reg);
1288c2ecf20Sopenharmony_ci}
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_civoid snd_gf1_write8(struct snd_gus_card * gus,
1318c2ecf20Sopenharmony_ci		    unsigned char reg,
1328c2ecf20Sopenharmony_ci		    unsigned char data)
1338c2ecf20Sopenharmony_ci{
1348c2ecf20Sopenharmony_ci	__snd_gf1_write8(gus, reg, data);
1358c2ecf20Sopenharmony_ci}
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ciunsigned char snd_gf1_look8(struct snd_gus_card * gus, unsigned char reg)
1388c2ecf20Sopenharmony_ci{
1398c2ecf20Sopenharmony_ci	return __snd_gf1_look8(gus, reg);
1408c2ecf20Sopenharmony_ci}
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_civoid snd_gf1_write16(struct snd_gus_card * gus,
1438c2ecf20Sopenharmony_ci		     unsigned char reg,
1448c2ecf20Sopenharmony_ci		     unsigned int data)
1458c2ecf20Sopenharmony_ci{
1468c2ecf20Sopenharmony_ci	__snd_gf1_write16(gus, reg, data);
1478c2ecf20Sopenharmony_ci}
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ciunsigned short snd_gf1_look16(struct snd_gus_card * gus, unsigned char reg)
1508c2ecf20Sopenharmony_ci{
1518c2ecf20Sopenharmony_ci	return __snd_gf1_look16(gus, reg);
1528c2ecf20Sopenharmony_ci}
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_civoid snd_gf1_adlib_write(struct snd_gus_card * gus,
1558c2ecf20Sopenharmony_ci                         unsigned char reg,
1568c2ecf20Sopenharmony_ci                         unsigned char data)
1578c2ecf20Sopenharmony_ci{
1588c2ecf20Sopenharmony_ci	__snd_gf1_adlib_write(gus, reg, data);
1598c2ecf20Sopenharmony_ci}
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_civoid snd_gf1_write_addr(struct snd_gus_card * gus, unsigned char reg,
1628c2ecf20Sopenharmony_ci                        unsigned int addr, short w_16bit)
1638c2ecf20Sopenharmony_ci{
1648c2ecf20Sopenharmony_ci	__snd_gf1_write_addr(gus, reg, addr, w_16bit);
1658c2ecf20Sopenharmony_ci}
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ciunsigned int snd_gf1_read_addr(struct snd_gus_card * gus,
1688c2ecf20Sopenharmony_ci                               unsigned char reg,
1698c2ecf20Sopenharmony_ci                               short w_16bit)
1708c2ecf20Sopenharmony_ci{
1718c2ecf20Sopenharmony_ci	return __snd_gf1_read_addr(gus, reg, w_16bit);
1728c2ecf20Sopenharmony_ci}
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_ci/*
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci */
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_civoid snd_gf1_i_ctrl_stop(struct snd_gus_card * gus, unsigned char reg)
1798c2ecf20Sopenharmony_ci{
1808c2ecf20Sopenharmony_ci	unsigned long flags;
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	spin_lock_irqsave(&gus->reg_lock, flags);
1838c2ecf20Sopenharmony_ci	__snd_gf1_ctrl_stop(gus, reg);
1848c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&gus->reg_lock, flags);
1858c2ecf20Sopenharmony_ci}
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_civoid snd_gf1_i_write8(struct snd_gus_card * gus,
1888c2ecf20Sopenharmony_ci		      unsigned char reg,
1898c2ecf20Sopenharmony_ci                      unsigned char data)
1908c2ecf20Sopenharmony_ci{
1918c2ecf20Sopenharmony_ci	unsigned long flags;
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci	spin_lock_irqsave(&gus->reg_lock, flags);
1948c2ecf20Sopenharmony_ci	__snd_gf1_write8(gus, reg, data);
1958c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&gus->reg_lock, flags);
1968c2ecf20Sopenharmony_ci}
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ciunsigned char snd_gf1_i_look8(struct snd_gus_card * gus, unsigned char reg)
1998c2ecf20Sopenharmony_ci{
2008c2ecf20Sopenharmony_ci	unsigned long flags;
2018c2ecf20Sopenharmony_ci	unsigned char res;
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci	spin_lock_irqsave(&gus->reg_lock, flags);
2048c2ecf20Sopenharmony_ci	res = __snd_gf1_look8(gus, reg);
2058c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&gus->reg_lock, flags);
2068c2ecf20Sopenharmony_ci	return res;
2078c2ecf20Sopenharmony_ci}
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_civoid snd_gf1_i_write16(struct snd_gus_card * gus,
2108c2ecf20Sopenharmony_ci		       unsigned char reg,
2118c2ecf20Sopenharmony_ci		       unsigned int data)
2128c2ecf20Sopenharmony_ci{
2138c2ecf20Sopenharmony_ci	unsigned long flags;
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci	spin_lock_irqsave(&gus->reg_lock, flags);
2168c2ecf20Sopenharmony_ci	__snd_gf1_write16(gus, reg, data);
2178c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&gus->reg_lock, flags);
2188c2ecf20Sopenharmony_ci}
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ciunsigned short snd_gf1_i_look16(struct snd_gus_card * gus, unsigned char reg)
2218c2ecf20Sopenharmony_ci{
2228c2ecf20Sopenharmony_ci	unsigned long flags;
2238c2ecf20Sopenharmony_ci	unsigned short res;
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci	spin_lock_irqsave(&gus->reg_lock, flags);
2268c2ecf20Sopenharmony_ci	res = __snd_gf1_look16(gus, reg);
2278c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&gus->reg_lock, flags);
2288c2ecf20Sopenharmony_ci	return res;
2298c2ecf20Sopenharmony_ci}
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci#if 0
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_civoid snd_gf1_i_adlib_write(struct snd_gus_card * gus,
2348c2ecf20Sopenharmony_ci		           unsigned char reg,
2358c2ecf20Sopenharmony_ci		           unsigned char data)
2368c2ecf20Sopenharmony_ci{
2378c2ecf20Sopenharmony_ci	unsigned long flags;
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_ci	spin_lock_irqsave(&gus->reg_lock, flags);
2408c2ecf20Sopenharmony_ci	__snd_gf1_adlib_write(gus, reg, data);
2418c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&gus->reg_lock, flags);
2428c2ecf20Sopenharmony_ci}
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_civoid snd_gf1_i_write_addr(struct snd_gus_card * gus, unsigned char reg,
2458c2ecf20Sopenharmony_ci			  unsigned int addr, short w_16bit)
2468c2ecf20Sopenharmony_ci{
2478c2ecf20Sopenharmony_ci	unsigned long flags;
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ci	spin_lock_irqsave(&gus->reg_lock, flags);
2508c2ecf20Sopenharmony_ci	__snd_gf1_write_addr(gus, reg, addr, w_16bit);
2518c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&gus->reg_lock, flags);
2528c2ecf20Sopenharmony_ci}
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci#endif  /*  0  */
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_ci#ifdef CONFIG_SND_DEBUG
2578c2ecf20Sopenharmony_cistatic unsigned int snd_gf1_i_read_addr(struct snd_gus_card * gus,
2588c2ecf20Sopenharmony_ci					unsigned char reg, short w_16bit)
2598c2ecf20Sopenharmony_ci{
2608c2ecf20Sopenharmony_ci	unsigned int res;
2618c2ecf20Sopenharmony_ci	unsigned long flags;
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci	spin_lock_irqsave(&gus->reg_lock, flags);
2648c2ecf20Sopenharmony_ci	res = __snd_gf1_read_addr(gus, reg, w_16bit);
2658c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&gus->reg_lock, flags);
2668c2ecf20Sopenharmony_ci	return res;
2678c2ecf20Sopenharmony_ci}
2688c2ecf20Sopenharmony_ci#endif
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci/*
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci */
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_civoid snd_gf1_dram_addr(struct snd_gus_card * gus, unsigned int addr)
2758c2ecf20Sopenharmony_ci{
2768c2ecf20Sopenharmony_ci	outb(0x43, gus->gf1.reg_regsel);
2778c2ecf20Sopenharmony_ci	mb();
2788c2ecf20Sopenharmony_ci	outw((unsigned short) addr, gus->gf1.reg_data16);
2798c2ecf20Sopenharmony_ci	mb();
2808c2ecf20Sopenharmony_ci	outb(0x44, gus->gf1.reg_regsel);
2818c2ecf20Sopenharmony_ci	mb();
2828c2ecf20Sopenharmony_ci	outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
2838c2ecf20Sopenharmony_ci	mb();
2848c2ecf20Sopenharmony_ci}
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_civoid snd_gf1_poke(struct snd_gus_card * gus, unsigned int addr, unsigned char data)
2878c2ecf20Sopenharmony_ci{
2888c2ecf20Sopenharmony_ci	unsigned long flags;
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_ci	spin_lock_irqsave(&gus->reg_lock, flags);
2918c2ecf20Sopenharmony_ci	outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
2928c2ecf20Sopenharmony_ci	mb();
2938c2ecf20Sopenharmony_ci	outw((unsigned short) addr, gus->gf1.reg_data16);
2948c2ecf20Sopenharmony_ci	mb();
2958c2ecf20Sopenharmony_ci	outb(SNDRV_GF1_GB_DRAM_IO_HIGH, gus->gf1.reg_regsel);
2968c2ecf20Sopenharmony_ci	mb();
2978c2ecf20Sopenharmony_ci	outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
2988c2ecf20Sopenharmony_ci	mb();
2998c2ecf20Sopenharmony_ci	outb(data, gus->gf1.reg_dram);
3008c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&gus->reg_lock, flags);
3018c2ecf20Sopenharmony_ci}
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ciunsigned char snd_gf1_peek(struct snd_gus_card * gus, unsigned int addr)
3048c2ecf20Sopenharmony_ci{
3058c2ecf20Sopenharmony_ci	unsigned long flags;
3068c2ecf20Sopenharmony_ci	unsigned char res;
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci	spin_lock_irqsave(&gus->reg_lock, flags);
3098c2ecf20Sopenharmony_ci	outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
3108c2ecf20Sopenharmony_ci	mb();
3118c2ecf20Sopenharmony_ci	outw((unsigned short) addr, gus->gf1.reg_data16);
3128c2ecf20Sopenharmony_ci	mb();
3138c2ecf20Sopenharmony_ci	outb(SNDRV_GF1_GB_DRAM_IO_HIGH, gus->gf1.reg_regsel);
3148c2ecf20Sopenharmony_ci	mb();
3158c2ecf20Sopenharmony_ci	outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
3168c2ecf20Sopenharmony_ci	mb();
3178c2ecf20Sopenharmony_ci	res = inb(gus->gf1.reg_dram);
3188c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&gus->reg_lock, flags);
3198c2ecf20Sopenharmony_ci	return res;
3208c2ecf20Sopenharmony_ci}
3218c2ecf20Sopenharmony_ci
3228c2ecf20Sopenharmony_ci#if 0
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_civoid snd_gf1_pokew(struct snd_gus_card * gus, unsigned int addr, unsigned short data)
3258c2ecf20Sopenharmony_ci{
3268c2ecf20Sopenharmony_ci	unsigned long flags;
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_ci#ifdef CONFIG_SND_DEBUG
3298c2ecf20Sopenharmony_ci	if (!gus->interwave)
3308c2ecf20Sopenharmony_ci		snd_printk(KERN_DEBUG "snd_gf1_pokew - GF1!!!\n");
3318c2ecf20Sopenharmony_ci#endif
3328c2ecf20Sopenharmony_ci	spin_lock_irqsave(&gus->reg_lock, flags);
3338c2ecf20Sopenharmony_ci	outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
3348c2ecf20Sopenharmony_ci	mb();
3358c2ecf20Sopenharmony_ci	outw((unsigned short) addr, gus->gf1.reg_data16);
3368c2ecf20Sopenharmony_ci	mb();
3378c2ecf20Sopenharmony_ci	outb(SNDRV_GF1_GB_DRAM_IO_HIGH, gus->gf1.reg_regsel);
3388c2ecf20Sopenharmony_ci	mb();
3398c2ecf20Sopenharmony_ci	outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
3408c2ecf20Sopenharmony_ci	mb();
3418c2ecf20Sopenharmony_ci	outb(SNDRV_GF1_GW_DRAM_IO16, gus->gf1.reg_regsel);
3428c2ecf20Sopenharmony_ci	mb();
3438c2ecf20Sopenharmony_ci	outw(data, gus->gf1.reg_data16);
3448c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&gus->reg_lock, flags);
3458c2ecf20Sopenharmony_ci}
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ciunsigned short snd_gf1_peekw(struct snd_gus_card * gus, unsigned int addr)
3488c2ecf20Sopenharmony_ci{
3498c2ecf20Sopenharmony_ci	unsigned long flags;
3508c2ecf20Sopenharmony_ci	unsigned short res;
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ci#ifdef CONFIG_SND_DEBUG
3538c2ecf20Sopenharmony_ci	if (!gus->interwave)
3548c2ecf20Sopenharmony_ci		snd_printk(KERN_DEBUG "snd_gf1_peekw - GF1!!!\n");
3558c2ecf20Sopenharmony_ci#endif
3568c2ecf20Sopenharmony_ci	spin_lock_irqsave(&gus->reg_lock, flags);
3578c2ecf20Sopenharmony_ci	outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
3588c2ecf20Sopenharmony_ci	mb();
3598c2ecf20Sopenharmony_ci	outw((unsigned short) addr, gus->gf1.reg_data16);
3608c2ecf20Sopenharmony_ci	mb();
3618c2ecf20Sopenharmony_ci	outb(SNDRV_GF1_GB_DRAM_IO_HIGH, gus->gf1.reg_regsel);
3628c2ecf20Sopenharmony_ci	mb();
3638c2ecf20Sopenharmony_ci	outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
3648c2ecf20Sopenharmony_ci	mb();
3658c2ecf20Sopenharmony_ci	outb(SNDRV_GF1_GW_DRAM_IO16, gus->gf1.reg_regsel);
3668c2ecf20Sopenharmony_ci	mb();
3678c2ecf20Sopenharmony_ci	res = inw(gus->gf1.reg_data16);
3688c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&gus->reg_lock, flags);
3698c2ecf20Sopenharmony_ci	return res;
3708c2ecf20Sopenharmony_ci}
3718c2ecf20Sopenharmony_ci
3728c2ecf20Sopenharmony_civoid snd_gf1_dram_setmem(struct snd_gus_card * gus, unsigned int addr,
3738c2ecf20Sopenharmony_ci			 unsigned short value, unsigned int count)
3748c2ecf20Sopenharmony_ci{
3758c2ecf20Sopenharmony_ci	unsigned long port;
3768c2ecf20Sopenharmony_ci	unsigned long flags;
3778c2ecf20Sopenharmony_ci
3788c2ecf20Sopenharmony_ci#ifdef CONFIG_SND_DEBUG
3798c2ecf20Sopenharmony_ci	if (!gus->interwave)
3808c2ecf20Sopenharmony_ci		snd_printk(KERN_DEBUG "snd_gf1_dram_setmem - GF1!!!\n");
3818c2ecf20Sopenharmony_ci#endif
3828c2ecf20Sopenharmony_ci	addr &= ~1;
3838c2ecf20Sopenharmony_ci	count >>= 1;
3848c2ecf20Sopenharmony_ci	port = GUSP(gus, GF1DATALOW);
3858c2ecf20Sopenharmony_ci	spin_lock_irqsave(&gus->reg_lock, flags);
3868c2ecf20Sopenharmony_ci	outb(SNDRV_GF1_GW_DRAM_IO_LOW, gus->gf1.reg_regsel);
3878c2ecf20Sopenharmony_ci	mb();
3888c2ecf20Sopenharmony_ci	outw((unsigned short) addr, gus->gf1.reg_data16);
3898c2ecf20Sopenharmony_ci	mb();
3908c2ecf20Sopenharmony_ci	outb(SNDRV_GF1_GB_DRAM_IO_HIGH, gus->gf1.reg_regsel);
3918c2ecf20Sopenharmony_ci	mb();
3928c2ecf20Sopenharmony_ci	outb((unsigned char) (addr >> 16), gus->gf1.reg_data8);
3938c2ecf20Sopenharmony_ci	mb();
3948c2ecf20Sopenharmony_ci	outb(SNDRV_GF1_GW_DRAM_IO16, gus->gf1.reg_regsel);
3958c2ecf20Sopenharmony_ci	while (count--)
3968c2ecf20Sopenharmony_ci		outw(value, port);
3978c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&gus->reg_lock, flags);
3988c2ecf20Sopenharmony_ci}
3998c2ecf20Sopenharmony_ci
4008c2ecf20Sopenharmony_ci#endif  /*  0  */
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_civoid snd_gf1_select_active_voices(struct snd_gus_card * gus)
4038c2ecf20Sopenharmony_ci{
4048c2ecf20Sopenharmony_ci	unsigned short voices;
4058c2ecf20Sopenharmony_ci
4068c2ecf20Sopenharmony_ci	static const unsigned short voices_tbl[32 - 14 + 1] =
4078c2ecf20Sopenharmony_ci	{
4088c2ecf20Sopenharmony_ci	    44100, 41160, 38587, 36317, 34300, 32494, 30870, 29400, 28063, 26843,
4098c2ecf20Sopenharmony_ci	    25725, 24696, 23746, 22866, 22050, 21289, 20580, 19916, 19293
4108c2ecf20Sopenharmony_ci	};
4118c2ecf20Sopenharmony_ci
4128c2ecf20Sopenharmony_ci	voices = gus->gf1.active_voices;
4138c2ecf20Sopenharmony_ci	if (voices > 32)
4148c2ecf20Sopenharmony_ci		voices = 32;
4158c2ecf20Sopenharmony_ci	if (voices < 14)
4168c2ecf20Sopenharmony_ci		voices = 14;
4178c2ecf20Sopenharmony_ci	if (gus->gf1.enh_mode)
4188c2ecf20Sopenharmony_ci		voices = 32;
4198c2ecf20Sopenharmony_ci	gus->gf1.active_voices = voices;
4208c2ecf20Sopenharmony_ci	gus->gf1.playback_freq =
4218c2ecf20Sopenharmony_ci	    gus->gf1.enh_mode ? 44100 : voices_tbl[voices - 14];
4228c2ecf20Sopenharmony_ci	if (!gus->gf1.enh_mode) {
4238c2ecf20Sopenharmony_ci		snd_gf1_i_write8(gus, SNDRV_GF1_GB_ACTIVE_VOICES, 0xc0 | (voices - 1));
4248c2ecf20Sopenharmony_ci		udelay(100);
4258c2ecf20Sopenharmony_ci	}
4268c2ecf20Sopenharmony_ci}
4278c2ecf20Sopenharmony_ci
4288c2ecf20Sopenharmony_ci#ifdef CONFIG_SND_DEBUG
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_civoid snd_gf1_print_voice_registers(struct snd_gus_card * gus)
4318c2ecf20Sopenharmony_ci{
4328c2ecf20Sopenharmony_ci	unsigned char mode;
4338c2ecf20Sopenharmony_ci	int voice, ctrl;
4348c2ecf20Sopenharmony_ci
4358c2ecf20Sopenharmony_ci	voice = gus->gf1.active_voice;
4368c2ecf20Sopenharmony_ci	printk(KERN_INFO " -%i- GF1  voice ctrl, ramp ctrl  = 0x%x, 0x%x\n", voice, ctrl = snd_gf1_i_read8(gus, 0), snd_gf1_i_read8(gus, 0x0d));
4378c2ecf20Sopenharmony_ci	printk(KERN_INFO " -%i- GF1  frequency              = 0x%x\n", voice, snd_gf1_i_read16(gus, 1));
4388c2ecf20Sopenharmony_ci	printk(KERN_INFO " -%i- GF1  loop start, end        = 0x%x (0x%x), 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 2, ctrl & 4), snd_gf1_i_read_addr(gus, 2, (ctrl & 4) ^ 4), snd_gf1_i_read_addr(gus, 4, ctrl & 4), snd_gf1_i_read_addr(gus, 4, (ctrl & 4) ^ 4));
4398c2ecf20Sopenharmony_ci	printk(KERN_INFO " -%i- GF1  ramp start, end, rate  = 0x%x, 0x%x, 0x%x\n", voice, snd_gf1_i_read8(gus, 7), snd_gf1_i_read8(gus, 8), snd_gf1_i_read8(gus, 6));
4408c2ecf20Sopenharmony_ci	printk(KERN_INFO" -%i- GF1  volume                 = 0x%x\n", voice, snd_gf1_i_read16(gus, 9));
4418c2ecf20Sopenharmony_ci	printk(KERN_INFO " -%i- GF1  position               = 0x%x (0x%x)\n", voice, snd_gf1_i_read_addr(gus, 0x0a, ctrl & 4), snd_gf1_i_read_addr(gus, 0x0a, (ctrl & 4) ^ 4));
4428c2ecf20Sopenharmony_ci	if (gus->interwave && snd_gf1_i_read8(gus, 0x19) & 0x01) {	/* enhanced mode */
4438c2ecf20Sopenharmony_ci		mode = snd_gf1_i_read8(gus, 0x15);
4448c2ecf20Sopenharmony_ci		printk(KERN_INFO " -%i- GFA1 mode                   = 0x%x\n", voice, mode);
4458c2ecf20Sopenharmony_ci		if (mode & 0x01) {	/* Effect processor */
4468c2ecf20Sopenharmony_ci			printk(KERN_INFO " -%i- GFA1 effect address         = 0x%x\n", voice, snd_gf1_i_read_addr(gus, 0x11, ctrl & 4));
4478c2ecf20Sopenharmony_ci			printk(KERN_INFO " -%i- GFA1 effect volume          = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x16));
4488c2ecf20Sopenharmony_ci			printk(KERN_INFO " -%i- GFA1 effect volume final    = 0x%x\n", voice, snd_gf1_i_read16(gus, 0x1d));
4498c2ecf20Sopenharmony_ci			printk(KERN_INFO " -%i- GFA1 effect accumulator     = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x14));
4508c2ecf20Sopenharmony_ci		}
4518c2ecf20Sopenharmony_ci		if (mode & 0x20) {
4528c2ecf20Sopenharmony_ci			printk(KERN_INFO " -%i- GFA1 left offset            = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x13), snd_gf1_i_read16(gus, 0x13) >> 4);
4538c2ecf20Sopenharmony_ci			printk(KERN_INFO " -%i- GFA1 left offset final      = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1c), snd_gf1_i_read16(gus, 0x1c) >> 4);
4548c2ecf20Sopenharmony_ci			printk(KERN_INFO " -%i- GFA1 right offset           = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x0c), snd_gf1_i_read16(gus, 0x0c) >> 4);
4558c2ecf20Sopenharmony_ci			printk(KERN_INFO " -%i- GFA1 right offset final     = 0x%x (%i)\n", voice, snd_gf1_i_read16(gus, 0x1b), snd_gf1_i_read16(gus, 0x1b) >> 4);
4568c2ecf20Sopenharmony_ci		} else
4578c2ecf20Sopenharmony_ci			printk(KERN_INFO " -%i- GF1  pan                    = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
4588c2ecf20Sopenharmony_ci	} else
4598c2ecf20Sopenharmony_ci		printk(KERN_INFO " -%i- GF1  pan                    = 0x%x\n", voice, snd_gf1_i_read8(gus, 0x0c));
4608c2ecf20Sopenharmony_ci}
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci#if 0
4638c2ecf20Sopenharmony_ci
4648c2ecf20Sopenharmony_civoid snd_gf1_print_global_registers(struct snd_gus_card * gus)
4658c2ecf20Sopenharmony_ci{
4668c2ecf20Sopenharmony_ci	unsigned char global_mode = 0x00;
4678c2ecf20Sopenharmony_ci
4688c2ecf20Sopenharmony_ci	printk(KERN_INFO " -G- GF1 active voices            = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ACTIVE_VOICES));
4698c2ecf20Sopenharmony_ci	if (gus->interwave) {
4708c2ecf20Sopenharmony_ci		global_mode = snd_gf1_i_read8(gus, SNDRV_GF1_GB_GLOBAL_MODE);
4718c2ecf20Sopenharmony_ci		printk(KERN_INFO " -G- GF1 global mode              = 0x%x\n", global_mode);
4728c2ecf20Sopenharmony_ci	}
4738c2ecf20Sopenharmony_ci	if (global_mode & 0x02)	/* LFO enabled? */
4748c2ecf20Sopenharmony_ci		printk(KERN_INFO " -G- GF1 LFO base                 = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_LFO_BASE));
4758c2ecf20Sopenharmony_ci	printk(KERN_INFO " -G- GF1 voices IRQ read          = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VOICES_IRQ_READ));
4768c2ecf20Sopenharmony_ci	printk(KERN_INFO " -G- GF1 DRAM DMA control         = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL));
4778c2ecf20Sopenharmony_ci	printk(KERN_INFO " -G- GF1 DRAM DMA high/low        = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_DMA_LOW));
4788c2ecf20Sopenharmony_ci	printk(KERN_INFO " -G- GF1 DRAM IO high/low         = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_IO_HIGH), snd_gf1_i_read16(gus, SNDRV_GF1_GW_DRAM_IO_LOW));
4798c2ecf20Sopenharmony_ci	if (!gus->interwave)
4808c2ecf20Sopenharmony_ci		printk(KERN_INFO " -G- GF1 record DMA control       = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL));
4818c2ecf20Sopenharmony_ci	printk(KERN_INFO " -G- GF1 DRAM IO 16               = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_DRAM_IO16));
4828c2ecf20Sopenharmony_ci	if (gus->gf1.enh_mode) {
4838c2ecf20Sopenharmony_ci		printk(KERN_INFO " -G- GFA1 memory config           = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG));
4848c2ecf20Sopenharmony_ci		printk(KERN_INFO " -G- GFA1 memory control          = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MEMORY_CONTROL));
4858c2ecf20Sopenharmony_ci		printk(KERN_INFO " -G- GFA1 FIFO record base        = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_RECORD_BASE_ADDR));
4868c2ecf20Sopenharmony_ci		printk(KERN_INFO " -G- GFA1 FIFO playback base      = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_FIFO_PLAY_BASE_ADDR));
4878c2ecf20Sopenharmony_ci		printk(KERN_INFO " -G- GFA1 interleave control      = 0x%x\n", snd_gf1_i_look16(gus, SNDRV_GF1_GW_INTERLEAVE));
4888c2ecf20Sopenharmony_ci	}
4898c2ecf20Sopenharmony_ci}
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_civoid snd_gf1_print_setup_registers(struct snd_gus_card * gus)
4928c2ecf20Sopenharmony_ci{
4938c2ecf20Sopenharmony_ci	printk(KERN_INFO " -S- mix control                  = 0x%x\n", inb(GUSP(gus, MIXCNTRLREG)));
4948c2ecf20Sopenharmony_ci	printk(KERN_INFO " -S- IRQ status                   = 0x%x\n", inb(GUSP(gus, IRQSTAT)));
4958c2ecf20Sopenharmony_ci	printk(KERN_INFO " -S- timer control                = 0x%x\n", inb(GUSP(gus, TIMERCNTRL)));
4968c2ecf20Sopenharmony_ci	printk(KERN_INFO " -S- timer data                   = 0x%x\n", inb(GUSP(gus, TIMERDATA)));
4978c2ecf20Sopenharmony_ci	printk(KERN_INFO " -S- status read                  = 0x%x\n", inb(GUSP(gus, REGCNTRLS)));
4988c2ecf20Sopenharmony_ci	printk(KERN_INFO " -S- Sound Blaster control        = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL));
4998c2ecf20Sopenharmony_ci	printk(KERN_INFO " -S- AdLib timer 1/2              = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_1), snd_gf1_i_look8(gus, SNDRV_GF1_GB_ADLIB_TIMER_2));
5008c2ecf20Sopenharmony_ci	printk(KERN_INFO " -S- reset                        = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET));
5018c2ecf20Sopenharmony_ci	if (gus->interwave) {
5028c2ecf20Sopenharmony_ci		printk(KERN_INFO " -S- compatibility                = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_COMPATIBILITY));
5038c2ecf20Sopenharmony_ci		printk(KERN_INFO " -S- decode control               = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_DECODE_CONTROL));
5048c2ecf20Sopenharmony_ci		printk(KERN_INFO " -S- version number               = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_VERSION_NUMBER));
5058c2ecf20Sopenharmony_ci		printk(KERN_INFO " -S- MPU-401 emul. control A/B    = 0x%x/0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A), snd_gf1_i_look8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B));
5068c2ecf20Sopenharmony_ci		printk(KERN_INFO " -S- emulation IRQ                = 0x%x\n", snd_gf1_i_look8(gus, SNDRV_GF1_GB_EMULATION_IRQ));
5078c2ecf20Sopenharmony_ci	}
5088c2ecf20Sopenharmony_ci}
5098c2ecf20Sopenharmony_ci
5108c2ecf20Sopenharmony_civoid snd_gf1_peek_print_block(struct snd_gus_card * gus, unsigned int addr, int count, int w_16bit)
5118c2ecf20Sopenharmony_ci{
5128c2ecf20Sopenharmony_ci	if (!w_16bit) {
5138c2ecf20Sopenharmony_ci		while (count-- > 0)
5148c2ecf20Sopenharmony_ci			printk(count > 0 ? "%02x:" : "%02x", snd_gf1_peek(gus, addr++));
5158c2ecf20Sopenharmony_ci	} else {
5168c2ecf20Sopenharmony_ci		while (count-- > 0) {
5178c2ecf20Sopenharmony_ci			printk(count > 0 ? "%04x:" : "%04x", snd_gf1_peek(gus, addr) | (snd_gf1_peek(gus, addr + 1) << 8));
5188c2ecf20Sopenharmony_ci			addr += 2;
5198c2ecf20Sopenharmony_ci		}
5208c2ecf20Sopenharmony_ci	}
5218c2ecf20Sopenharmony_ci}
5228c2ecf20Sopenharmony_ci
5238c2ecf20Sopenharmony_ci#endif  /*  0  */
5248c2ecf20Sopenharmony_ci
5258c2ecf20Sopenharmony_ci#endif
526