Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *   ALSA driver for ATI IXP 150/200/250 AC97 modem controllers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *	Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <sound/pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <sound/pcm_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <sound/info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <sound/ac97_codec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) MODULE_DESCRIPTION("ATI IXP MC97 controller");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250}}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) static int index = -2; /* Exclude the first card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) static int ac97_clock = 48000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) module_param(index, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) module_param(id, charp, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) MODULE_PARM_DESC(id, "ID string for ATI IXP controller.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) module_param(ac97_clock, int, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) /* just for backward compatibility */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) static bool enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) module_param(enable, bool, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define ATI_REG_ISR			0x00	/* interrupt source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define  ATI_REG_ISR_MODEM_IN_XRUN	(1U<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #define  ATI_REG_ISR_MODEM_IN_STATUS	(1U<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define  ATI_REG_ISR_MODEM_OUT1_XRUN	(1U<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define  ATI_REG_ISR_MODEM_OUT1_STATUS	(1U<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define  ATI_REG_ISR_MODEM_OUT2_XRUN	(1U<<4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define  ATI_REG_ISR_MODEM_OUT2_STATUS	(1U<<5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define  ATI_REG_ISR_MODEM_OUT3_XRUN	(1U<<6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define  ATI_REG_ISR_MODEM_OUT3_STATUS	(1U<<7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define  ATI_REG_ISR_PHYS_INTR		(1U<<8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #define  ATI_REG_ISR_PHYS_MISMATCH	(1U<<9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define  ATI_REG_ISR_CODEC0_NOT_READY	(1U<<10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define  ATI_REG_ISR_CODEC1_NOT_READY	(1U<<11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define  ATI_REG_ISR_CODEC2_NOT_READY	(1U<<12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #define  ATI_REG_ISR_NEW_FRAME		(1U<<13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define  ATI_REG_ISR_MODEM_GPIO_DATA	(1U<<14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define ATI_REG_IER			0x04	/* interrupt enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define  ATI_REG_IER_MODEM_IN_XRUN_EN	(1U<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #define  ATI_REG_IER_MODEM_STATUS_EN	(1U<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define  ATI_REG_IER_MODEM_OUT1_XRUN_EN	(1U<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #define  ATI_REG_IER_MODEM_OUT2_XRUN_EN	(1U<<4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define  ATI_REG_IER_MODEM_OUT3_XRUN_EN	(1U<<6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #define  ATI_REG_IER_PHYS_INTR_EN	(1U<<8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #define  ATI_REG_IER_PHYS_MISMATCH_EN	(1U<<9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #define  ATI_REG_IER_CODEC0_INTR_EN	(1U<<10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #define  ATI_REG_IER_CODEC1_INTR_EN	(1U<<11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) #define  ATI_REG_IER_CODEC2_INTR_EN	(1U<<12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define  ATI_REG_IER_NEW_FRAME_EN	(1U<<13)	/* (RO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define  ATI_REG_IER_MODEM_GPIO_DATA_EN	(1U<<14)	/* (WO) modem is running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define  ATI_REG_IER_MODEM_SET_BUS_BUSY	(1U<<15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define ATI_REG_CMD			0x08	/* command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #define  ATI_REG_CMD_POWERDOWN	(1U<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define  ATI_REG_CMD_MODEM_RECEIVE_EN	(1U<<1)	/* modem only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) #define  ATI_REG_CMD_MODEM_SEND1_EN	(1U<<2)	/* modem only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) #define  ATI_REG_CMD_MODEM_SEND2_EN	(1U<<3)	/* modem only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) #define  ATI_REG_CMD_MODEM_SEND3_EN	(1U<<4)	/* modem only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) #define  ATI_REG_CMD_MODEM_STATUS_MEM	(1U<<5)	/* modem only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #define  ATI_REG_CMD_MODEM_IN_DMA_EN	(1U<<8)	/* modem only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) #define  ATI_REG_CMD_MODEM_OUT_DMA1_EN	(1U<<9)	/* modem only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) #define  ATI_REG_CMD_MODEM_OUT_DMA2_EN	(1U<<10)	/* modem only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #define  ATI_REG_CMD_MODEM_OUT_DMA3_EN	(1U<<11)	/* modem only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) #define  ATI_REG_CMD_AUDIO_PRESENT	(1U<<20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #define  ATI_REG_CMD_MODEM_GPIO_THRU_DMA	(1U<<22)	/* modem only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #define  ATI_REG_CMD_LOOPBACK_EN	(1U<<23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) #define  ATI_REG_CMD_PACKED_DIS		(1U<<24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) #define  ATI_REG_CMD_BURST_EN		(1U<<25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) #define  ATI_REG_CMD_PANIC_EN		(1U<<26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) #define  ATI_REG_CMD_MODEM_PRESENT	(1U<<27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) #define  ATI_REG_CMD_ACLINK_ACTIVE	(1U<<28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) #define  ATI_REG_CMD_AC_SOFT_RESET	(1U<<29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) #define  ATI_REG_CMD_AC_SYNC		(1U<<30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) #define  ATI_REG_CMD_AC_RESET		(1U<<31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) #define ATI_REG_PHYS_OUT_ADDR		0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) #define  ATI_REG_PHYS_OUT_CODEC_MASK	(3U<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) #define  ATI_REG_PHYS_OUT_RW		(1U<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) #define  ATI_REG_PHYS_OUT_ADDR_EN	(1U<<8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) #define  ATI_REG_PHYS_OUT_ADDR_SHIFT	9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) #define  ATI_REG_PHYS_OUT_DATA_SHIFT	16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) #define ATI_REG_PHYS_IN_ADDR		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) #define  ATI_REG_PHYS_IN_READ_FLAG	(1U<<8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) #define  ATI_REG_PHYS_IN_ADDR_SHIFT	9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) #define  ATI_REG_PHYS_IN_DATA_SHIFT	16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) #define ATI_REG_SLOTREQ			0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) #define ATI_REG_COUNTER			0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) #define  ATI_REG_COUNTER_SLOT		(3U<<0)	/* slot # */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) #define  ATI_REG_COUNTER_BITCLOCK	(31U<<8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) #define ATI_REG_IN_FIFO_THRESHOLD	0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) #define ATI_REG_MODEM_IN_DMA_LINKPTR	0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) #define ATI_REG_MODEM_IN_DMA_DT_START	0x24	/* RO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) #define ATI_REG_MODEM_IN_DMA_DT_NEXT	0x28	/* RO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) #define ATI_REG_MODEM_IN_DMA_DT_CUR	0x2c	/* RO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) #define ATI_REG_MODEM_IN_DMA_DT_SIZE	0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) #define ATI_REG_MODEM_OUT_FIFO		0x34	/* output threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) #define  ATI_REG_MODEM_OUT1_DMA_THRESHOLD_MASK	(0xf<<16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) #define  ATI_REG_MODEM_OUT1_DMA_THRESHOLD_SHIFT	16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) #define ATI_REG_MODEM_OUT_DMA1_LINKPTR	0x38
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) #define ATI_REG_MODEM_OUT_DMA2_LINKPTR	0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) #define ATI_REG_MODEM_OUT_DMA3_LINKPTR	0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) #define ATI_REG_MODEM_OUT_DMA1_DT_START	0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) #define ATI_REG_MODEM_OUT_DMA1_DT_NEXT	0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) #define ATI_REG_MODEM_OUT_DMA1_DT_CUR	0x4c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) #define ATI_REG_MODEM_OUT_DMA2_DT_START	0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) #define ATI_REG_MODEM_OUT_DMA2_DT_NEXT	0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) #define ATI_REG_MODEM_OUT_DMA2_DT_CUR	0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) #define ATI_REG_MODEM_OUT_DMA3_DT_START	0x5c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) #define ATI_REG_MODEM_OUT_DMA3_DT_NEXT	0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) #define ATI_REG_MODEM_OUT_DMA3_DT_CUR	0x64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) #define ATI_REG_MODEM_OUT_DMA12_DT_SIZE	0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) #define ATI_REG_MODEM_OUT_DMA3_DT_SIZE	0x6c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) #define ATI_REG_MODEM_OUT_FIFO_USED     0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) #define ATI_REG_MODEM_OUT_GPIO		0x74
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) #define  ATI_REG_MODEM_OUT_GPIO_EN	   1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) #define  ATI_REG_MODEM_OUT_GPIO_DATA_SHIFT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) #define ATI_REG_MODEM_IN_GPIO		0x78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) #define ATI_REG_MODEM_MIRROR		0x7c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) #define ATI_REG_AUDIO_MIRROR		0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) #define ATI_REG_MODEM_FIFO_FLUSH	0x88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) #define  ATI_REG_MODEM_FIFO_OUT1_FLUSH	(1U<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) #define  ATI_REG_MODEM_FIFO_OUT2_FLUSH	(1U<<1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) #define  ATI_REG_MODEM_FIFO_OUT3_FLUSH	(1U<<2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) #define  ATI_REG_MODEM_FIFO_IN_FLUSH	(1U<<3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) /* LINKPTR */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) #define  ATI_REG_LINKPTR_EN		(1U<<0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) #define ATI_MAX_DESCRIPTORS	256	/* max number of descriptor packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) struct atiixp_modem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  * DMA packate descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) struct atiixp_dma_desc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	__le32 addr;	/* DMA buffer address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	u16 status;	/* status bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	u16 size;	/* size of the packet in dwords */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	__le32 next;	/* address of the next packet descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179)  * stream enum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) enum { ATI_DMA_PLAYBACK, ATI_DMA_CAPTURE, NUM_ATI_DMAS }; /* DMAs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) enum { ATI_PCM_OUT, ATI_PCM_IN, NUM_ATI_PCMS }; /* AC97 pcm slots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) enum { ATI_PCMDEV_ANALOG, NUM_ATI_PCMDEVS }; /* pcm devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) #define NUM_ATI_CODECS	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189)  * constants and callbacks for each DMA type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) struct atiixp_dma_ops {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	int type;			/* ATI_DMA_XXX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	unsigned int llp_offset;	/* LINKPTR offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	unsigned int dt_cur;		/* DT_CUR offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	/* called from open callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	void (*enable_dma)(struct atiixp_modem *chip, int on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	/* called from trigger (START/STOP) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	void (*enable_transfer)(struct atiixp_modem *chip, int on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199)  	/* called from trigger (STOP only) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	void (*flush_dma)(struct atiixp_modem *chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204)  * DMA stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) struct atiixp_dma {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	const struct atiixp_dma_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	struct snd_dma_buffer desc_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	struct snd_pcm_substream *substream;	/* assigned PCM substream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	unsigned int buf_addr, buf_bytes;	/* DMA buffer address, bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	unsigned int period_bytes, periods;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	int opened;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	int running;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	int pcm_open_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	int ac97_pcm_type;	/* index # of ac97_pcm to access, -1 = not used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219)  * ATI IXP chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) struct atiixp_modem {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	struct pci_dev *pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	struct resource *res;		/* memory i/o */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	unsigned long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	void __iomem *remap_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	struct snd_ac97_bus *ac97_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	struct snd_ac97 *ac97[NUM_ATI_CODECS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	spinlock_t reg_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	struct atiixp_dma dmas[NUM_ATI_DMAS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	struct ac97_pcm *pcms[NUM_ATI_PCMS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	struct snd_pcm *pcmdevs[NUM_ATI_PCMDEVS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	int max_channels;		/* max. channels for PCM out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	unsigned int codec_not_ready_bits;	/* for codec detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	int spdif_over_aclink;		/* passed from the module option */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	struct mutex open_mutex;	/* playback open mutex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) static const struct pci_device_id snd_atiixp_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	{ PCI_VDEVICE(ATI, 0x434d), 0 }, /* SB200 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	{ PCI_VDEVICE(ATI, 0x4378), 0 }, /* SB400 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	{ 0, }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) MODULE_DEVICE_TABLE(pci, snd_atiixp_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260)  * lowlevel functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264)  * update the bits of the given register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265)  * return 1 if the bits changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) static int snd_atiixp_update_bits(struct atiixp_modem *chip, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 				  unsigned int mask, unsigned int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	void __iomem *addr = chip->remap_addr + reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	unsigned int data, old_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	old_data = data = readl(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	data &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	data |= value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	if (old_data == data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	writel(data, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282)  * macros for easy use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) #define atiixp_write(chip,reg,value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	writel(value, chip->remap_addr + ATI_REG_##reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) #define atiixp_read(chip,reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	readl(chip->remap_addr + ATI_REG_##reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) #define atiixp_update(chip,reg,mask,val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	snd_atiixp_update_bits(chip, ATI_REG_##reg, mask, val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292)  * handling DMA packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294)  * we allocate a linear buffer for the DMA, and split it to  each packet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295)  * in a future version, a scatter-gather buffer should be implemented.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) #define ATI_DESC_LIST_SIZE \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	PAGE_ALIGN(ATI_MAX_DESCRIPTORS * sizeof(struct atiixp_dma_desc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302)  * build packets ring for the given buffer size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304)  * IXP handles the buffer descriptors, which are connected as a linked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305)  * list.  although we can change the list dynamically, in this version,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306)  * a static RING of buffer descriptors is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308)  * the ring is built in this function, and is set up to the hardware. 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) static int atiixp_build_dma_packets(struct atiixp_modem *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 				    struct atiixp_dma *dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 				    struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 				    unsigned int periods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 				    unsigned int period_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	u32 addr, desc_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	if (periods > ATI_MAX_DESCRIPTORS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	if (dma->desc_buf.area == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &chip->pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 					ATI_DESC_LIST_SIZE, &dma->desc_buf) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		dma->period_bytes = dma->periods = 0; /* clear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	if (dma->periods == periods && dma->period_bytes == period_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	/* reset DMA before changing the descriptor table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	spin_lock_irqsave(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	writel(0, chip->remap_addr + dma->ops->llp_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	dma->ops->enable_dma(chip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	dma->ops->enable_dma(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	spin_unlock_irqrestore(&chip->reg_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	/* fill the entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	addr = (u32)substream->runtime->dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	desc_addr = (u32)dma->desc_buf.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	for (i = 0; i < periods; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 		struct atiixp_dma_desc *desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		desc = &((struct atiixp_dma_desc *)dma->desc_buf.area)[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		desc->addr = cpu_to_le32(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 		desc->status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 		desc->size = period_bytes >> 2; /* in dwords */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		desc_addr += sizeof(struct atiixp_dma_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		if (i == periods - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 			desc->next = cpu_to_le32((u32)dma->desc_buf.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 			desc->next = cpu_to_le32(desc_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 		addr += period_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	       chip->remap_addr + dma->ops->llp_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	dma->period_bytes = period_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	dma->periods = periods;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367)  * remove the ring buffer and release it if assigned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) static void atiixp_clear_dma_packets(struct atiixp_modem *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 				     struct atiixp_dma *dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 				     struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	if (dma->desc_buf.area) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		writel(0, chip->remap_addr + dma->ops->llp_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 		snd_dma_free_pages(&dma->desc_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		dma->desc_buf.area = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381)  * AC97 interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) static int snd_atiixp_acquire_codec(struct atiixp_modem *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	int timeout = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	while (atiixp_read(chip, PHYS_OUT_ADDR) & ATI_REG_PHYS_OUT_ADDR_EN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		if (! timeout--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 			dev_warn(chip->card->dev, "codec acquire timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) static unsigned short snd_atiixp_codec_read(struct atiixp_modem *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 					    unsigned short codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 					    unsigned short reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	unsigned int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	if (snd_atiixp_acquire_codec(chip) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		return 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	data = (reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		ATI_REG_PHYS_OUT_ADDR_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 		ATI_REG_PHYS_OUT_RW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 		codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	atiixp_write(chip, PHYS_OUT_ADDR, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	if (snd_atiixp_acquire_codec(chip) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 		return 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	timeout = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 		data = atiixp_read(chip, PHYS_IN_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		if (data & ATI_REG_PHYS_IN_READ_FLAG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 			return data >> ATI_REG_PHYS_IN_DATA_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 		udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	} while (--timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	/* time out may happen during reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	if (reg < 0x7c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 		dev_warn(chip->card->dev, "codec read timeout (reg %x)\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	return 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) static void snd_atiixp_codec_write(struct atiixp_modem *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 				   unsigned short codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 				   unsigned short reg, unsigned short val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	unsigned int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	if (snd_atiixp_acquire_codec(chip) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	data = ((unsigned int)val << ATI_REG_PHYS_OUT_DATA_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		((unsigned int)reg << ATI_REG_PHYS_OUT_ADDR_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		ATI_REG_PHYS_OUT_ADDR_EN | codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	atiixp_write(chip, PHYS_OUT_ADDR, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) static unsigned short snd_atiixp_ac97_read(struct snd_ac97 *ac97,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 					   unsigned short reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	struct atiixp_modem *chip = ac97->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	return snd_atiixp_codec_read(chip, ac97->num, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) static void snd_atiixp_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 				  unsigned short val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	struct atiixp_modem *chip = ac97->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	if (reg == AC97_GPIO_STATUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		atiixp_write(chip, MODEM_OUT_GPIO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 			(val << ATI_REG_MODEM_OUT_GPIO_DATA_SHIFT) | ATI_REG_MODEM_OUT_GPIO_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	snd_atiixp_codec_write(chip, ac97->num, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463)  * reset AC link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) static int snd_atiixp_aclink_reset(struct atiixp_modem *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	/* reset powerdoewn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	if (atiixp_update(chip, CMD, ATI_REG_CMD_POWERDOWN, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 		udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	/* perform a software reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	atiixp_update(chip, CMD, ATI_REG_CMD_AC_SOFT_RESET, ATI_REG_CMD_AC_SOFT_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	atiixp_read(chip, CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	atiixp_update(chip, CMD, ATI_REG_CMD_AC_SOFT_RESET, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478)     
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	while (! (atiixp_read(chip, CMD) & ATI_REG_CMD_ACLINK_ACTIVE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 		/* do a hard reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		atiixp_update(chip, CMD, ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 			      ATI_REG_CMD_AC_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		atiixp_read(chip, CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 		if (!--timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 			dev_err(chip->card->dev, "codec reset timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	/* deassert RESET and assert SYNC to make sure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	atiixp_update(chip, CMD, ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		      ATI_REG_CMD_AC_SYNC|ATI_REG_CMD_AC_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) static int snd_atiixp_aclink_down(struct atiixp_modem *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	// if (atiixp_read(chip, MODEM_MIRROR) & 0x1) /* modem running, too? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	//	return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	atiixp_update(chip, CMD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		     ATI_REG_CMD_POWERDOWN | ATI_REG_CMD_AC_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 		     ATI_REG_CMD_POWERDOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513)  * auto-detection of codecs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515)  * the IXP chip can generate interrupts for the non-existing codecs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516)  * NEW_FRAME interrupt is used to make sure that the interrupt is generated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517)  * even if all three codecs are connected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) #define ALL_CODEC_NOT_READY \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 	    (ATI_REG_ISR_CODEC0_NOT_READY |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	     ATI_REG_ISR_CODEC1_NOT_READY |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	     ATI_REG_ISR_CODEC2_NOT_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) #define CODEC_CHECK_BITS (ALL_CODEC_NOT_READY|ATI_REG_ISR_NEW_FRAME)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) static int snd_atiixp_codec_detect(struct atiixp_modem *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	chip->codec_not_ready_bits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	atiixp_write(chip, IER, CODEC_CHECK_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	/* wait for the interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	timeout = 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	while (timeout-- > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 		if (chip->codec_not_ready_bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	atiixp_write(chip, IER, 0); /* disable irqs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	if ((chip->codec_not_ready_bits & ALL_CODEC_NOT_READY) == ALL_CODEC_NOT_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		dev_err(chip->card->dev, "no codec detected!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550)  * enable DMA and irqs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) static int snd_atiixp_chip_start(struct atiixp_modem *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	/* set up spdif, enable burst mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	reg = atiixp_read(chip, CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	reg |= ATI_REG_CMD_BURST_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	if(!(reg & ATI_REG_CMD_MODEM_PRESENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 		reg |= ATI_REG_CMD_MODEM_PRESENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	atiixp_write(chip, CMD, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	/* clear all interrupt source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	atiixp_write(chip, ISR, 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	/* enable irqs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	atiixp_write(chip, IER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		     ATI_REG_IER_MODEM_STATUS_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 		     ATI_REG_IER_MODEM_IN_XRUN_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 		     ATI_REG_IER_MODEM_OUT1_XRUN_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575)  * disable DMA and IRQs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) static int snd_atiixp_chip_stop(struct atiixp_modem *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	/* clear interrupt source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	atiixp_write(chip, ISR, atiixp_read(chip, ISR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	/* disable irqs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	atiixp_write(chip, IER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588)  * PCM section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592)  * pointer callback simplly reads XXX_DMA_DT_CUR register as the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593)  * position.  when SG-buffer is implemented, the offset must be calculated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594)  * correctly...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) static snd_pcm_uframes_t snd_atiixp_pcm_pointer(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	struct atiixp_dma *dma = runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	unsigned int curptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	int timeout = 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	while (timeout--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		curptr = readl(chip->remap_addr + dma->ops->dt_cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		if (curptr < dma->buf_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		curptr -= dma->buf_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		if (curptr >= dma->buf_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		return bytes_to_frames(runtime, curptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	dev_dbg(chip->card->dev, "invalid DMA pointer read 0x%x (buf=%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		   readl(chip->remap_addr + dma->ops->dt_cur), dma->buf_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619)  * XRUN detected, and stop the PCM substream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) static void snd_atiixp_xrun_dma(struct atiixp_modem *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 				struct atiixp_dma *dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	if (! dma->substream || ! dma->running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	dev_dbg(chip->card->dev, "XRUN detected (DMA %d)\n", dma->ops->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	snd_pcm_stop_xrun(dma->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631)  * the period ack.  update the substream.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) static void snd_atiixp_update_dma(struct atiixp_modem *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 				  struct atiixp_dma *dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	if (! dma->substream || ! dma->running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	snd_pcm_period_elapsed(dma->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) /* set BUS_BUSY interrupt bit if any DMA is running */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) /* call with spinlock held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) static void snd_atiixp_check_bus_busy(struct atiixp_modem *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	unsigned int bus_busy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	if (atiixp_read(chip, CMD) & (ATI_REG_CMD_MODEM_SEND1_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 				      ATI_REG_CMD_MODEM_RECEIVE_EN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		bus_busy = ATI_REG_IER_MODEM_SET_BUS_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		bus_busy = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	atiixp_update(chip, IER, ATI_REG_IER_MODEM_SET_BUS_BUSY, bus_busy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) /* common trigger callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655)  * calling the lowlevel callbacks in it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	struct atiixp_dma *dma = substream->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	if (snd_BUG_ON(!dma->ops->enable_transfer ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		       !dma->ops->flush_dma))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	spin_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	switch(cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		dma->ops->enable_transfer(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 		dma->running = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 		dma->ops->enable_transfer(chip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 		dma->running = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	if (! err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	snd_atiixp_check_bus_busy(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	if (cmd == SNDRV_PCM_TRIGGER_STOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 		dma->ops->flush_dma(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		snd_atiixp_check_bus_busy(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694)  * lowlevel callbacks for each DMA type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696)  * every callback is supposed to be called in chip->reg_lock spinlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) /* flush FIFO of analog OUT DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) static void atiixp_out_flush_dma(struct atiixp_modem *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	atiixp_write(chip, MODEM_FIFO_FLUSH, ATI_REG_MODEM_FIFO_OUT1_FLUSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) /* enable/disable analog OUT DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) static void atiixp_out_enable_dma(struct atiixp_modem *chip, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	unsigned int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	data = atiixp_read(chip, CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		if (data & ATI_REG_CMD_MODEM_OUT_DMA1_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		atiixp_out_flush_dma(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 		data |= ATI_REG_CMD_MODEM_OUT_DMA1_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 		data &= ~ATI_REG_CMD_MODEM_OUT_DMA1_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	atiixp_write(chip, CMD, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) /* start/stop transfer over OUT DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) static void atiixp_out_enable_transfer(struct atiixp_modem *chip, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	atiixp_update(chip, CMD, ATI_REG_CMD_MODEM_SEND1_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		      on ? ATI_REG_CMD_MODEM_SEND1_EN : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) /* enable/disable analog IN DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) static void atiixp_in_enable_dma(struct atiixp_modem *chip, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	atiixp_update(chip, CMD, ATI_REG_CMD_MODEM_IN_DMA_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		      on ? ATI_REG_CMD_MODEM_IN_DMA_EN : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) /* start/stop analog IN DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) static void atiixp_in_enable_transfer(struct atiixp_modem *chip, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		unsigned int data = atiixp_read(chip, CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		if (! (data & ATI_REG_CMD_MODEM_RECEIVE_EN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 			data |= ATI_REG_CMD_MODEM_RECEIVE_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 			atiixp_write(chip, CMD, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		atiixp_update(chip, CMD, ATI_REG_CMD_MODEM_RECEIVE_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) /* flush FIFO of analog IN DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) static void atiixp_in_flush_dma(struct atiixp_modem *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	atiixp_write(chip, MODEM_FIFO_FLUSH, ATI_REG_MODEM_FIFO_IN_FLUSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) /* set up slots and formats for analog OUT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) static int snd_atiixp_playback_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	unsigned int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	spin_lock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	/* set output threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	data = atiixp_read(chip, MODEM_OUT_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	data &= ~ATI_REG_MODEM_OUT1_DMA_THRESHOLD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	data |= 0x04 << ATI_REG_MODEM_OUT1_DMA_THRESHOLD_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	atiixp_write(chip, MODEM_OUT_FIFO, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	spin_unlock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) /* set up slots and formats for analog IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) static int snd_atiixp_capture_prepare(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776)  * hw_params - allocate the buffer and set up buffer descriptors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) static int snd_atiixp_pcm_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 				   struct snd_pcm_hw_params *hw_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	struct atiixp_dma *dma = substream->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	dma->buf_addr = substream->runtime->dma_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	dma->buf_bytes = params_buffer_bytes(hw_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	err = atiixp_build_dma_packets(chip, dma, substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 				       params_periods(hw_params),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 				       params_period_bytes(hw_params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	/* set up modem rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	for (i = 0; i < NUM_ATI_CODECS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		if (! chip->ac97[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		snd_ac97_write(chip->ac97[i], AC97_LINE1_RATE, params_rate(hw_params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		snd_ac97_write(chip->ac97[i], AC97_LINE1_LEVEL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) static int snd_atiixp_pcm_hw_free(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	struct atiixp_dma *dma = substream->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	atiixp_clear_dma_packets(chip, dma, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817)  * pcm hardware definition, identical for all DMA types
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) static const struct snd_pcm_hardware snd_atiixp_pcm_hw =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	.info =			(SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 				 SNDRV_PCM_INFO_MMAP_VALID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	.formats =		SNDRV_PCM_FMTBIT_S16_LE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	.rates =		(SNDRV_PCM_RATE_8000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 				 SNDRV_PCM_RATE_16000 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 				 SNDRV_PCM_RATE_KNOT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	.rate_min =		8000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	.rate_max =		16000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	.channels_min =		2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	.channels_max =		2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	.buffer_bytes_max =	256 * 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	.period_bytes_min =	32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	.period_bytes_max =	128 * 1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	.periods_min =		2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	.periods_max =		ATI_MAX_DESCRIPTORS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 			       struct atiixp_dma *dma, int pcm_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	static const unsigned int rates[] = { 8000,  9600, 12000, 16000 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	static const struct snd_pcm_hw_constraint_list hw_constraints_rates = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		.count = ARRAY_SIZE(rates),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		.list = rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 		.mask = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	if (dma->opened)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	dma->substream = substream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	runtime->hw = snd_atiixp_pcm_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	dma->ac97_pcm_type = pcm_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	if ((err = snd_pcm_hw_constraint_list(runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 					      SNDRV_PCM_HW_PARAM_RATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 					      &hw_constraints_rates)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	if ((err = snd_pcm_hw_constraint_integer(runtime,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 						 SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	runtime->private_data = dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	/* enable DMA bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	spin_lock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	dma->ops->enable_dma(chip, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	spin_unlock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	dma->opened = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 				struct atiixp_dma *dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	/* disable DMA bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	spin_lock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	dma->ops->enable_dma(chip, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	spin_unlock_irq(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	dma->substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	dma->opened = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) static int snd_atiixp_playback_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	mutex_lock(&chip->open_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	mutex_unlock(&chip->open_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) static int snd_atiixp_playback_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	mutex_lock(&chip->open_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	mutex_unlock(&chip->open_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) static int snd_atiixp_capture_open(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	return snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_CAPTURE], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) static int snd_atiixp_capture_close(struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	struct atiixp_modem *chip = snd_pcm_substream_chip(substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	return snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_CAPTURE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) /* AC97 playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) static const struct snd_pcm_ops snd_atiixp_playback_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	.open =		snd_atiixp_playback_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	.close =	snd_atiixp_playback_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	.hw_params =	snd_atiixp_pcm_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	.hw_free =	snd_atiixp_pcm_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	.prepare =	snd_atiixp_playback_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	.trigger =	snd_atiixp_pcm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	.pointer =	snd_atiixp_pcm_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) /* AC97 capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) static const struct snd_pcm_ops snd_atiixp_capture_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	.open =		snd_atiixp_capture_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	.close =	snd_atiixp_capture_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	.hw_params =	snd_atiixp_pcm_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	.hw_free =	snd_atiixp_pcm_hw_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	.prepare =	snd_atiixp_capture_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	.trigger =	snd_atiixp_pcm_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	.pointer =	snd_atiixp_pcm_pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) static const struct atiixp_dma_ops snd_atiixp_playback_dma_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	.type = ATI_DMA_PLAYBACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	.llp_offset = ATI_REG_MODEM_OUT_DMA1_LINKPTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	.dt_cur = ATI_REG_MODEM_OUT_DMA1_DT_CUR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	.enable_dma = atiixp_out_enable_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	.enable_transfer = atiixp_out_enable_transfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	.flush_dma = atiixp_out_flush_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) static const struct atiixp_dma_ops snd_atiixp_capture_dma_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	.type = ATI_DMA_CAPTURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	.llp_offset = ATI_REG_MODEM_IN_DMA_LINKPTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	.dt_cur = ATI_REG_MODEM_IN_DMA_DT_CUR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	.enable_dma = atiixp_in_enable_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	.enable_transfer = atiixp_in_enable_transfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	.flush_dma = atiixp_in_flush_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) static int snd_atiixp_pcm_new(struct atiixp_modem *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	struct snd_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	/* initialize constants */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	chip->dmas[ATI_DMA_PLAYBACK].ops = &snd_atiixp_playback_dma_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	chip->dmas[ATI_DMA_CAPTURE].ops = &snd_atiixp_capture_dma_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	/* PCM #0: analog I/O */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	err = snd_pcm_new(chip->card, "ATI IXP MC97", ATI_PCMDEV_ANALOG, 1, 1, &pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	pcm->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	strcpy(pcm->name, "ATI IXP MC97");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 				       &chip->pci->dev, 64*1024, 128*1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)  * interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	struct atiixp_modem *chip = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	status = atiixp_read(chip, ISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	if (! status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	/* process audio DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	if (status & ATI_REG_ISR_MODEM_OUT1_XRUN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		snd_atiixp_xrun_dma(chip,  &chip->dmas[ATI_DMA_PLAYBACK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	else if (status & ATI_REG_ISR_MODEM_OUT1_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		snd_atiixp_update_dma(chip, &chip->dmas[ATI_DMA_PLAYBACK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	if (status & ATI_REG_ISR_MODEM_IN_XRUN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		snd_atiixp_xrun_dma(chip,  &chip->dmas[ATI_DMA_CAPTURE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	else if (status & ATI_REG_ISR_MODEM_IN_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		snd_atiixp_update_dma(chip, &chip->dmas[ATI_DMA_CAPTURE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	/* for codec detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	if (status & CODEC_CHECK_BITS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 		unsigned int detected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 		detected = status & CODEC_CHECK_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 		spin_lock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		chip->codec_not_ready_bits |= detected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 		atiixp_update(chip, IER, detected, 0); /* disable the detected irqs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		spin_unlock(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	/* ack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	atiixp_write(chip, ISR, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)  * ac97 mixer section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) static int snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	struct snd_ac97_bus *pbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	struct snd_ac97_template ac97;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	int codec_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	static const struct snd_ac97_bus_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		.write = snd_atiixp_ac97_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		.read = snd_atiixp_ac97_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	static const unsigned int codec_skip[NUM_ATI_CODECS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		ATI_REG_ISR_CODEC0_NOT_READY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 		ATI_REG_ISR_CODEC1_NOT_READY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		ATI_REG_ISR_CODEC2_NOT_READY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	if (snd_atiixp_codec_detect(chip) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	pbus->clock = clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	chip->ac97_bus = pbus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	codec_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	for (i = 0; i < NUM_ATI_CODECS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		if (chip->codec_not_ready_bits & codec_skip[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		memset(&ac97, 0, sizeof(ac97));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		ac97.private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		ac97.pci = chip->pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		ac97.num = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 			chip->ac97[i] = NULL; /* to be sure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 			dev_dbg(chip->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 				"codec %d not available for modem\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		codec_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	if (! codec_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		dev_err(chip->card->dev, "no codec available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	/* snd_ac97_tune_hardware(chip->ac97, ac97_quirks); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098)  * power management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) static int snd_atiixp_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	struct snd_card *card = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	struct atiixp_modem *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	for (i = 0; i < NUM_ATI_CODECS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		snd_ac97_suspend(chip->ac97[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	snd_atiixp_aclink_down(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	snd_atiixp_chip_stop(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) static int snd_atiixp_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	struct snd_card *card = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	struct atiixp_modem *chip = card->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	snd_atiixp_aclink_reset(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	snd_atiixp_chip_start(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	for (i = 0; i < NUM_ATI_CODECS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 		snd_ac97_resume(chip->ac97[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) static SIMPLE_DEV_PM_OPS(snd_atiixp_pm, snd_atiixp_suspend, snd_atiixp_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) #define SND_ATIIXP_PM_OPS	&snd_atiixp_pm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) #define SND_ATIIXP_PM_OPS	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)  * proc interface for register dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) static void snd_atiixp_proc_read(struct snd_info_entry *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 				 struct snd_info_buffer *buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	struct atiixp_modem *chip = entry->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	for (i = 0; i < 256; i += 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 		snd_iprintf(buffer, "%02x: %08x\n", i, readl(chip->remap_addr + i));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) static void snd_atiixp_proc_init(struct atiixp_modem *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	snd_card_ro_proc_new(chip->card, "atiixp-modem", chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 			     snd_atiixp_proc_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)  * destructor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) static int snd_atiixp_free(struct atiixp_modem *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	if (chip->irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		goto __hw_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	snd_atiixp_chip_stop(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)       __hw_end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	if (chip->irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		free_irq(chip->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	iounmap(chip->remap_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	pci_release_regions(chip->pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	pci_disable_device(chip->pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) static int snd_atiixp_dev_free(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	struct atiixp_modem *chip = device->device_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	return snd_atiixp_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)  * constructor for chip instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) static int snd_atiixp_create(struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 			     struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 			     struct atiixp_modem **r_chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	static const struct snd_device_ops ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 		.dev_free =	snd_atiixp_dev_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	struct atiixp_modem *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	if ((err = pci_enable_device(pci)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	if (chip == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 		pci_disable_device(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	spin_lock_init(&chip->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	mutex_init(&chip->open_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	chip->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	chip->pci = pci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	chip->irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	if ((err = pci_request_regions(pci, "ATI IXP MC97")) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		pci_disable_device(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	chip->addr = pci_resource_start(pci, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	chip->remap_addr = pci_ioremap_bar(pci, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	if (chip->remap_addr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 		dev_err(card->dev, "AC'97 space ioremap problem\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 		snd_atiixp_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 			KBUILD_MODNAME, chip)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 		dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		snd_atiixp_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	chip->irq = pci->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	card->sync_irq = chip->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	pci_set_master(pci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 		snd_atiixp_free(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	*r_chip = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) static int snd_atiixp_probe(struct pci_dev *pci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 			    const struct pci_device_id *pci_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	struct snd_card *card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	struct atiixp_modem *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	err = snd_card_new(&pci->dev, index, id, THIS_MODULE, 0, &card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	strcpy(card->driver, "ATIIXP-MODEM");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	strcpy(card->shortname, "ATI IXP Modem");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	if ((err = snd_atiixp_create(card, pci, &chip)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 		goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	card->private_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	if ((err = snd_atiixp_aclink_reset(chip)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 		goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	if ((err = snd_atiixp_mixer_new(chip, ac97_clock)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 		goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	if ((err = snd_atiixp_pcm_new(chip)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 		goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	snd_atiixp_proc_init(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	snd_atiixp_chip_start(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	sprintf(card->longname, "%s rev %x at 0x%lx, irq %i",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 		card->shortname, pci->revision, chip->addr, chip->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	if ((err = snd_card_register(card)) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 		goto __error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	pci_set_drvdata(pci, card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)  __error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	snd_card_free(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) static void snd_atiixp_remove(struct pci_dev *pci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	snd_card_free(pci_get_drvdata(pci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) static struct pci_driver atiixp_modem_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	.name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	.id_table = snd_atiixp_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	.probe = snd_atiixp_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 	.remove = snd_atiixp_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 		.pm = SND_ATIIXP_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) module_pci_driver(atiixp_modem_driver);