1675 |
|
|
1676 |
/* Resource manager */ |
/* Resource manager */ |
1677 |
static int resnum[VORTEX_RESOURCE_LAST] = {NR_ADB, NR_SRC, NR_MIXIN, NR_MIXOUT, NR_A3D}; |
static int resnum[VORTEX_RESOURCE_LAST] = {NR_ADB, NR_SRC, NR_MIXIN, NR_MIXOUT, NR_A3D}; |
|
|
|
1678 |
/* |
/* |
1679 |
Checkout/Checkin resource of given type. |
Checkout/Checkin resource of given type. |
1680 |
stream: resource map to be used. If NULL means that we want to allocate |
stream: resource map to be used. If NULL means that we want to allocate |
1725 |
|
|
1726 |
/* Default Connections */ |
/* Default Connections */ |
1727 |
void vortex_connect_default(vortex_t *vortex, int en) { |
void vortex_connect_default(vortex_t *vortex, int en) { |
1728 |
// Connect codec. |
|
1729 |
// FIXME: check if checkout was succesful. |
// FIXME: check if checkout was succesful. |
1730 |
|
// Connect AC97 codec. |
1731 |
vortex->mixplayb[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en, VORTEX_RESOURCE_MIXOUT); |
vortex->mixplayb[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en, VORTEX_RESOURCE_MIXOUT); |
1732 |
vortex->mixplayb[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en, VORTEX_RESOURCE_MIXOUT); |
vortex->mixplayb[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en, VORTEX_RESOURCE_MIXOUT); |
1733 |
if (VORTEX_IS_QUAD(vortex)) { |
if (VORTEX_IS_QUAD(vortex)) { |
1734 |
vortex->mixplayb[2] = vortex_adb_checkinout(vortex, vortex->fixed_res, en, VORTEX_RESOURCE_MIXOUT); |
vortex->mixplayb[2] = vortex_adb_checkinout(vortex, vortex->fixed_res, en, VORTEX_RESOURCE_MIXOUT); |
1735 |
vortex->mixplayb[3] = vortex_adb_checkinout(vortex, vortex->fixed_res, en, VORTEX_RESOURCE_MIXOUT); |
vortex->mixplayb[3] = vortex_adb_checkinout(vortex, vortex->fixed_res, en, VORTEX_RESOURCE_MIXOUT); |
1736 |
} |
} |
1737 |
|
vortex_connect_codecplay(vortex, en, vortex->mixplayb); |
1738 |
|
|
1739 |
vortex->mixcapt[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en, VORTEX_RESOURCE_MIXIN); |
vortex->mixcapt[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en, VORTEX_RESOURCE_MIXIN); |
1740 |
vortex->mixcapt[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en, VORTEX_RESOURCE_MIXIN); |
vortex->mixcapt[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en, VORTEX_RESOURCE_MIXIN); |
|
|
|
|
vortex_connect_codecplay(vortex, en, vortex->mixplayb); |
|
1741 |
vortex_connect_codecrec(vortex, en, MIX_CAPT(0), MIX_CAPT(1)); |
vortex_connect_codecrec(vortex, en, MIX_CAPT(0), MIX_CAPT(1)); |
1742 |
|
|
1743 |
|
// Connect SPDIF |
1744 |
|
vortex->mixspdif[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en, VORTEX_RESOURCE_MIXOUT); |
1745 |
|
vortex->mixspdif[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en, VORTEX_RESOURCE_MIXOUT); |
1746 |
|
vortex_connection_mix_adb(vortex, en, 0x14, vortex->mixspdif[0], ADB_SPDIFOUT(0)); |
1747 |
|
vortex_connection_mix_adb(vortex, en, 0x14, vortex->mixspdif[1], ADB_SPDIFOUT(1)); |
1748 |
|
|
1749 |
|
// Connect I2S |
1750 |
|
|
1751 |
|
// Connect DSP interface (not here i think...) |
1752 |
|
|
1753 |
|
// Connect MODEM |
1754 |
|
|
1755 |
#ifndef CHIP_AU8810 |
#ifndef CHIP_AU8810 |
1756 |
//vortex_connect_wt(vortex, en, vortex->mixplayb); |
//vortex_wt_connect(vortex, en, vortex->mixplayb); |
1757 |
#endif |
#endif |
1758 |
/* Fast Play Workaround */ |
/* Fast Play Workaround */ |
1759 |
#ifndef CHIP_AU8820 |
#ifndef CHIP_AU8820 |
1762 |
} |
} |
1763 |
|
|
1764 |
/* |
/* |
1765 |
Allocate nr_ch pcm audio routesif dma < 0. If dma >= 0, existing routes |
Allocate nr_ch pcm audio routes if dma < 0. If dma >= 0, existing routes |
1766 |
are deallocated. |
are deallocated. |
1767 |
dma: DMA engine routes to be deallocated when dma >= 0. |
dma: DMA engine routes to be deallocated when dma >= 0. |
1768 |
nr_ch: Number of channels to be de/allocated. |
nr_ch: Number of channels to be de/allocated. |
1769 |
dir: direction of stream. Uses same values as substream->stream. |
dir: direction of stream. Uses same values as substream->stream. |
1770 |
|
type: Type of audio output/source (codec, spdif, i2s, dsp, etc) |
1771 |
Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0. |
Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0. |
1772 |
*/ |
*/ |
1773 |
int vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir) { |
int vortex_adb_allocroute(vortex_t *vortex, int dma, int nr_ch, int dir, int type) { |
1774 |
stream_t *stream; |
stream_t *stream; |
1775 |
int i, en; |
int i, en; |
1776 |
|
|
1790 |
stream = &vortex->dma_adb[dma]; |
stream = &vortex->dma_adb[dma]; |
1791 |
stream->dma = dma; |
stream->dma = dma; |
1792 |
stream->dir = dir; |
stream->dir = dir; |
1793 |
|
stream->type = type; |
1794 |
|
|
1795 |
// FIXME: check for success of checkout or checkin. |
// FIXME: check for success of checkout or checkin. |
1796 |
if (dir == SNDRV_PCM_STREAM_PLAYBACK) { |
if (dir == SNDRV_PCM_STREAM_PLAYBACK) { |
1797 |
int src[4], mix[4], ch_top; |
int src[4], mix[4], a3d=0, ch_top; |
1798 |
|
|
1799 |
for (i=0; i<nr_ch; i++) { |
/* Get SRC and MIXER hardware resources. */ |
1800 |
if ((src[i] = vortex_adb_checkinout(vortex, stream->resources, en, VORTEX_RESOURCE_SRC))<0) { |
if (stream->type != VORTEX_PCM_SPDIF) { |
1801 |
memset(stream->resources, 0, sizeof(unsigned char)*VORTEX_RESOURCE_LAST); |
for (i=0; i<nr_ch; i++) { |
1802 |
return -EBUSY; |
if ((src[i] = vortex_adb_checkinout(vortex, stream->resources, en, VORTEX_RESOURCE_SRC))<0) { |
1803 |
|
memset(stream->resources, 0, sizeof(unsigned char)*VORTEX_RESOURCE_LAST); |
1804 |
|
return -EBUSY; |
1805 |
|
} |
1806 |
|
if ((mix[i] = vortex_adb_checkinout(vortex, stream->resources, en, VORTEX_RESOURCE_MIXIN))<0) { |
1807 |
|
memset(stream->resources, 0, sizeof(unsigned char)*VORTEX_RESOURCE_LAST); |
1808 |
|
return -EBUSY; |
1809 |
|
} |
1810 |
} |
} |
1811 |
if ((mix[i] = vortex_adb_checkinout(vortex, stream->resources, en, VORTEX_RESOURCE_MIXIN))<0) { |
} |
1812 |
|
if (stream->type == VORTEX_PCM_A3D) { |
1813 |
|
if ((a3d = vortex_adb_checkinout(vortex, stream->resources, en, VORTEX_RESOURCE_A3D))<0) { |
1814 |
memset(stream->resources, 0, sizeof(unsigned char)*VORTEX_RESOURCE_LAST); |
memset(stream->resources, 0, sizeof(unsigned char)*VORTEX_RESOURCE_LAST); |
1815 |
return -EBUSY; |
return -EBUSY; |
1816 |
} |
} |
1817 |
} |
} |
1818 |
|
/* Make SPDIF out exclusive to "spdif" device when in use. */ |
1819 |
|
if ((stream->type == VORTEX_PCM_SPDIF)&&(en)) { |
1820 |
|
vortex_route(vortex, 0, 0x14, ADB_MIXOUT(vortex->mixspdif[0]), ADB_SPDIFOUT(0)); |
1821 |
|
vortex_route(vortex, 0, 0x14, ADB_MIXOUT(vortex->mixspdif[1]), ADB_SPDIFOUT(1)); |
1822 |
|
} |
1823 |
|
/* Make playback routes. */ |
1824 |
for (i=0; i<nr_ch; i++) { |
for (i=0; i<nr_ch; i++) { |
1825 |
vortex_connection_adbdma_src(vortex, en, src[nr_ch-1], dma, src[i]); |
if (stream->type == VORTEX_PCM_ADB) { |
1826 |
vortex_connection_src_mixin(vortex, en, 0x11, src[i], mix[i]); |
vortex_connection_adbdma_src(vortex, en, src[nr_ch-1], dma, src[i]); |
1827 |
vortex_connection_mixin_mix(vortex, en, mix[i], MIX_PLAYB(i), 0); |
vortex_connection_src_mixin(vortex, en, 0x11, src[i], mix[i]); |
1828 |
} |
vortex_connection_mixin_mix(vortex, en, mix[i], MIX_PLAYB(i), 0); |
1829 |
ch_top = (VORTEX_IS_QUAD(vortex) ? 4 : 2); |
vortex_connection_mixin_mix(vortex, en, mix[i], MIX_SPDIF(i % 2), 0); |
1830 |
for (i=nr_ch; i<ch_top; i++) { |
vortex_mix_setinputvolumebyte(vortex, MIX_SPDIF(i % 2), mix[i], MIX_DEFIGAIN); |
1831 |
vortex_connection_mixin_mix(vortex, en, mix[i % nr_ch], MIX_PLAYB(i), 0); |
} |
1832 |
|
if (stream->type == VORTEX_PCM_A3D) { |
1833 |
|
vortex_connection_adbdma_src(vortex, en, src[nr_ch-1], dma, src[i]); |
1834 |
|
vortex_route(vortex, en, 0x11, ADB_SRCOUT(src[i]), ADB_A3DIN(a3d)); |
1835 |
|
vortex_route(vortex, en, 0x11, ADB_A3DOUT(a3d), ADB_MIXIN(mix[i])); |
1836 |
|
vortex_connection_mixin_mix(vortex, en, mix[i], MIX_PLAYB(i), 0); |
1837 |
|
vortex_connection_mixin_mix(vortex, en, mix[i], MIX_SPDIF(i % 2), 0); |
1838 |
|
vortex_mix_setinputvolumebyte(vortex, MIX_SPDIF(i % 2), mix[i], MIX_DEFIGAIN); |
1839 |
|
} |
1840 |
|
if (stream->type == VORTEX_PCM_SPDIF) |
1841 |
|
vortex_route(vortex, en, 0x14, ADB_DMA(stream->dma), ADB_SPDIFOUT(i)); |
1842 |
|
} |
1843 |
|
if (stream->type != VORTEX_PCM_SPDIF) { |
1844 |
|
ch_top = (VORTEX_IS_QUAD(vortex) ? 4 : 2); |
1845 |
|
for (i=nr_ch; i<ch_top; i++) { |
1846 |
|
vortex_connection_mixin_mix(vortex, en, mix[i % nr_ch], MIX_PLAYB(i), 0); |
1847 |
|
vortex_connection_mixin_mix(vortex, en, mix[i % nr_ch], MIX_SPDIF(i % 2), 0); |
1848 |
|
vortex_mix_setinputvolumebyte(vortex, MIX_SPDIF(i % 2), mix[i % nr_ch], MIX_DEFIGAIN); |
1849 |
|
} |
1850 |
|
} else { |
1851 |
|
if (nr_ch == 1) |
1852 |
|
vortex_route(vortex, en, 0x14, ADB_DMA(stream->dma), ADB_SPDIFOUT(1)); |
1853 |
} |
} |
1854 |
|
/* Reconnect SPDIF out when "spdif" device is down. */ |
1855 |
|
if ((stream->type == VORTEX_PCM_SPDIF)&&(!en)) { |
1856 |
|
vortex_route(vortex, 1, 0x14, ADB_MIXOUT(vortex->mixspdif[0]), ADB_SPDIFOUT(0)); |
1857 |
|
vortex_route(vortex, 1, 0x14, ADB_MIXOUT(vortex->mixspdif[1]), ADB_SPDIFOUT(1)); |
1858 |
|
} |
1859 |
} else { |
} else { |
1860 |
int src[2], mix[2]; |
int src[2], mix[2]; |
1861 |
|
|
1862 |
|
/* Get SRC and MIXER hardware resources. */ |
1863 |
for (i=0; i<nr_ch; i++) { |
for (i=0; i<nr_ch; i++) { |
1864 |
if ((mix[i] = vortex_adb_checkinout(vortex, stream->resources, en, VORTEX_RESOURCE_MIXOUT))<0) { |
if ((mix[i] = vortex_adb_checkinout(vortex, stream->resources, en, VORTEX_RESOURCE_MIXOUT))<0) { |
1865 |
memset(stream->resources, 0, sizeof(unsigned char)*VORTEX_RESOURCE_LAST); |
memset(stream->resources, 0, sizeof(unsigned char)*VORTEX_RESOURCE_LAST); |
1870 |
return -EBUSY; |
return -EBUSY; |
1871 |
} |
} |
1872 |
} |
} |
1873 |
|
|
1874 |
|
/* Make capture routes. */ |
1875 |
vortex_connection_mixin_mix(vortex, en, MIX_CAPT(0), mix[0], 0); |
vortex_connection_mixin_mix(vortex, en, MIX_CAPT(0), mix[0], 0); |
1876 |
vortex_connection_mix_src(vortex, en, 0x11, mix[0], src[0]); |
vortex_connection_mix_src(vortex, en, 0x11, mix[0], src[0]); |
1877 |
if (nr_ch == 1) { |
if (nr_ch == 1) { |
1886 |
vortex->dma_adb[dma].nr_ch = nr_ch; |
vortex->dma_adb[dma].nr_ch = nr_ch; |
1887 |
spin_unlock(vortex->lock); |
spin_unlock(vortex->lock); |
1888 |
|
|
1889 |
if (en) { |
#if 0 |
|
printk(KERN_INFO "vortex: alloc %d\n", dma); |
|
|
//vortex_fifo_adbinitialize(vortex, dma, 0xff); |
|
|
//udelay(2000); |
|
|
} else { |
|
|
printk(KERN_INFO "vortex: de alloc %d\n", dma); |
|
|
//vortex_fifo_setadbvalid(vortex, dma, 0); |
|
|
} |
|
1890 |
/* AC97 Codec channel setup. FIXME: this has no effect !! */ |
/* AC97 Codec channel setup. FIXME: this has no effect !! */ |
1891 |
if (nr_ch < 4) { |
if (nr_ch < 4) { |
1892 |
/* Copy stereo to rear channel (surround) */ |
/* Copy stereo to rear channel (surround) */ |
1895 |
/* Allow separate front a rear channels. */ |
/* Allow separate front a rear channels. */ |
1896 |
snd_ac97_write_cache(vortex->codec, AC97_SIGMATEL_DAC2INVERT, snd_ac97_read(vortex->codec, AC97_SIGMATEL_DAC2INVERT) & ~((u32)4)); |
snd_ac97_write_cache(vortex->codec, AC97_SIGMATEL_DAC2INVERT, snd_ac97_read(vortex->codec, AC97_SIGMATEL_DAC2INVERT) & ~((u32)4)); |
1897 |
} |
} |
1898 |
|
#endif |
1899 |
return dma; |
return dma; |
1900 |
} |
} |
1901 |
/* |
/* |
1904 |
void vortex_adb_setsrc(vortex_t *vortex, int adbdma, unsigned int rate, int dir) { |
void vortex_adb_setsrc(vortex_t *vortex, int adbdma, unsigned int rate, int dir) { |
1905 |
stream_t *stream = &(vortex->dma_adb[adbdma]); |
stream_t *stream = &(vortex->dma_adb[adbdma]); |
1906 |
int i, cvrt; |
int i, cvrt; |
1907 |
|
|
1908 |
/* dir=1:play ; dir=0:rec*/ |
/* dir=1:play ; dir=0:rec */ |
1909 |
if (dir) |
if (dir) |
1910 |
cvrt = SRC_RATIO(rate); |
cvrt = SRC_RATIO(rate,48000); |
1911 |
else |
else |
1912 |
cvrt = SRC_RATIO2(rate); |
cvrt = SRC_RATIO(48000,rate); |
1913 |
|
|
1914 |
|
/* Setup SRC's */ |
1915 |
for (i=0; i<NR_SRC; i++) { |
for (i=0; i<NR_SRC; i++) { |
1916 |
if (stream->resources[VORTEX_RESOURCE_SRC] & (1<<i)) |
if (stream->resources[VORTEX_RESOURCE_SRC] & (1<<i)) |
1917 |
vortex_src_setupchannel(vortex, i, cvrt, 0, 0, i, dir, 0, cvrt, dir); |
vortex_src_setupchannel(vortex, i, cvrt, 0, 0, i, dir, 0, cvrt, dir); |
1918 |
} |
} |
|
/* |
|
|
for (i=0; i<(stream->nr_ch); i++) { |
|
|
vortex_src_setupchannel(vortex, i+((adbdma)*2),cvrt,0,0,((adbdma)*2)+(dma->nr_ch)-1, |
|
|
dir, 0, cvrt, dir); |
|
|
} |
|
|
*/ |
|
1919 |
} |
} |
1920 |
|
|
1921 |
// Timer and ISR functions. |
// Timer and ISR functions. |
2028 |
udelay(1000); |
udelay(1000); |
2029 |
} else { |
} else { |
2030 |
hwwrite(vortex->mmio,VORTEX_CODEC_CTRL,0x00a8); |
hwwrite(vortex->mmio,VORTEX_CODEC_CTRL,0x00a8); |
2031 |
udelay(1000); |
udelay(2000); |
2032 |
hwwrite(vortex->mmio,VORTEX_CODEC_CTRL,0x80a8); |
hwwrite(vortex->mmio,VORTEX_CODEC_CTRL,0x80a8); |
2033 |
udelay(1000); |
udelay(2000); |
2034 |
hwwrite(vortex->mmio,VORTEX_CODEC_CTRL,0x80e8); |
hwwrite(vortex->mmio,VORTEX_CODEC_CTRL,0x80e8); |
2035 |
udelay(1000); |
udelay(2000); |
2036 |
hwwrite(vortex->mmio,VORTEX_CODEC_CTRL,0x80a8); |
hwwrite(vortex->mmio,VORTEX_CODEC_CTRL,0x80a8); |
2037 |
udelay(1000); |
udelay(2000); |
2038 |
hwwrite(vortex->mmio,VORTEX_CODEC_CTRL,0x00a8); |
hwwrite(vortex->mmio,VORTEX_CODEC_CTRL,0x00a8); |
2039 |
udelay(1000); |
udelay(2000); |
2040 |
hwwrite(vortex->mmio,VORTEX_CODEC_CTRL,0x00e8); |
hwwrite(vortex->mmio,VORTEX_CODEC_CTRL,0x00e8); |
2041 |
} |
} |
2042 |
for(i =0; i<32; i++){ |
for(i =0; i<32; i++){ |
2054 |
vortex_t *card = (vortex_t*)codec->private_data; |
vortex_t *card = (vortex_t*)codec->private_data; |
2055 |
unsigned long flags; |
unsigned long flags; |
2056 |
unsigned int lifeboat = 0; |
unsigned int lifeboat = 0; |
|
unsigned long read_addr; |
|
2057 |
spin_lock_irqsave(&card->lock, flags); |
spin_lock_irqsave(&card->lock, flags); |
2058 |
|
|
2059 |
/* wait for transactions to clear */ |
/* wait for transactions to clear */ |
2069 |
hwwrite(card->mmio, VORTEX_CODEC_IO, ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) | |
hwwrite(card->mmio, VORTEX_CODEC_IO, ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) | |
2070 |
((data << VORTEX_CODEC_DATSHIFT) & VORTEX_CODEC_DATMASK) | VORTEX_CODEC_WRITE); |
((data << VORTEX_CODEC_DATSHIFT) & VORTEX_CODEC_DATMASK) | VORTEX_CODEC_WRITE); |
2071 |
|
|
2072 |
/* this is necessary to flush the write */ |
/* Flush Caches.*/ |
2073 |
lifeboat = 0; |
hwread(card->mmio, VORTEX_CODEC_IO); |
2074 |
while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) { |
|
|
udelay(100); |
|
|
if (lifeboat++ > POLL_COUNT) { |
|
|
printk(KERN_ERR "vortex: ac97 codec stuck busy\n"); |
|
|
spin_unlock_irqrestore(&card->lock, flags); |
|
|
return; |
|
|
} |
|
|
} |
|
|
read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK); |
|
|
hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr); |
|
2075 |
spin_unlock_irqrestore(&card->lock, flags); |
spin_unlock_irqrestore(&card->lock, flags); |
2076 |
} |
} |
2077 |
|
|
2078 |
unsigned short vortex_codec_read(ac97_t *codec, unsigned short addr) { |
unsigned short vortex_codec_read(ac97_t *codec, unsigned short addr) { |
2079 |
|
|
|
u32 read_addr; |
|
2080 |
vortex_t *card = (vortex_t*)codec->private_data; |
vortex_t *card = (vortex_t*)codec->private_data; |
2081 |
|
u32 read_addr, data; |
2082 |
unsigned long flags; |
unsigned long flags; |
2083 |
unsigned lifeboat = 0; |
unsigned lifeboat = 0; |
|
u16 x; |
|
2084 |
|
|
2085 |
spin_lock_irqsave(&card->lock, flags); |
spin_lock_irqsave(&card->lock, flags); |
2086 |
|
|
2098 |
hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr); |
hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr); |
2099 |
|
|
2100 |
/* wait for address */ |
/* wait for address */ |
2101 |
lifeboat = 0; |
{ |
|
while ((hwread(card->mmio, VORTEX_CODEC_IO) & VORTEX_CODEC_ADDMASK) != (addr << VORTEX_CODEC_ADDSHIFT)) { |
|
2102 |
udelay(100); |
udelay(100); |
2103 |
|
data = hwread(card->mmio, VORTEX_CODEC_IO); |
2104 |
if (lifeboat++ > POLL_COUNT) { |
if (lifeboat++ > POLL_COUNT) { |
2105 |
printk(KERN_ERR "vortex: ac97 address never arrived\n"); |
printk(KERN_ERR "vortex: ac97 address never arrived\n"); |
2106 |
spin_unlock_irqrestore(&card->lock, flags); |
spin_unlock_irqrestore(&card->lock, flags); |
2107 |
return 0xffff; |
return 0xffff; |
2108 |
} |
} |
2109 |
} |
} while ((data & VORTEX_CODEC_ADDMASK) != (addr << VORTEX_CODEC_ADDSHIFT)); |
2110 |
/* read codec */ |
|
2111 |
x = hwread(card->mmio, VORTEX_CODEC_IO) & VORTEX_CODEC_DATMASK; |
/* Unlock. */ |
2112 |
spin_unlock_irqrestore(&card->lock, flags); |
spin_unlock_irqrestore(&card->lock, flags); |
2113 |
|
|
2114 |
return x; |
/* return data. */ |
2115 |
|
return (u16)(data & VORTEX_CODEC_DATMASK); |
2116 |
|
} |
2117 |
|
|
2118 |
|
/* SPDIF support */ |
2119 |
|
void vortex_spdif_init(vortex_t *vortex, int spdif_sr, int spdif_mode) { |
2120 |
|
int i, this_38 = 0, this_04=0, this_08=0, this_0c=0; |
2121 |
|
|
2122 |
|
/* CAsp4Spdif::InitializeSpdifHardware(void) */ |
2123 |
|
hwwrite(vortex->mmio, VORTEX_SPDIF_FLAGS, hwread(vortex->mmio, VORTEX_SPDIF_FLAGS) & 0xfff3fffd); |
2124 |
|
//for (i=0x291D4; i<0x29200; i+=4) |
2125 |
|
for (i=0; i<11; i++) |
2126 |
|
hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1 + (i<<2), 0); |
2127 |
|
//hwwrite(vortex->mmio, 0x29190, hwread(vortex->mmio, 0x29190) | 0xc0000); |
2128 |
|
hwwrite(vortex->mmio, VORTEX_CODEC_EN, hwread(vortex->mmio, VORTEX_CODEC_EN) | EN_SPDIF); |
2129 |
|
|
2130 |
|
/* CAsp4Spdif::ProgramSRCInHardware(enum SPDIF_SR,enum SPDIFMODE) */ |
2131 |
|
if (this_04 && this_08) { |
2132 |
|
int edi; |
2133 |
|
|
2134 |
|
i = (((0x5DC00000 / spdif_sr) + 1) >> 1); |
2135 |
|
if (i > 0x800) { |
2136 |
|
if (i < 0x1ffff) |
2137 |
|
edi = (i >> 1); |
2138 |
|
else |
2139 |
|
edi = 0x1ffff; |
2140 |
|
} else { |
2141 |
|
i = edi = 0x800; |
2142 |
|
} |
2143 |
|
/* this_04 and this_08 are the CASp4Src's (samplerate converters) */ |
2144 |
|
vortex_src_setupchannel(vortex, this_04, edi, 0, 1, this_0c, 1, 0, edi, 1); |
2145 |
|
vortex_src_setupchannel(vortex, this_08, edi, 0, 1, this_0c, 1, 0, edi, 1); |
2146 |
|
} |
2147 |
|
|
2148 |
|
i = spdif_sr; |
2149 |
|
spdif_sr |= 0x8c; |
2150 |
|
switch (i) { |
2151 |
|
case 32000: |
2152 |
|
this_38 &= 0xFFFFFFFE; |
2153 |
|
this_38 &= 0xFFFFFFFD; |
2154 |
|
this_38 &= 0xF3FFFFFF; |
2155 |
|
this_38 |= 0x03000000; |
2156 |
|
this_38 &= 0xFFFFFF3F; |
2157 |
|
spdif_sr &= 0xFFFFFFFD; |
2158 |
|
spdif_sr |= 1; |
2159 |
|
break; |
2160 |
|
case 44100: |
2161 |
|
this_38 &= 0xFFFFFFFE; |
2162 |
|
this_38 &= 0xFFFFFFFD; |
2163 |
|
this_38 &= 0xF0FFFFFF; |
2164 |
|
this_38 |= 0x03000000; |
2165 |
|
this_38 &= 0xFFFFFF3F; |
2166 |
|
spdif_sr &= 0xFFFFFFFC; |
2167 |
|
break; |
2168 |
|
case 48000: |
2169 |
|
if (spdif_mode == 1) { |
2170 |
|
this_38 &= 0xFFFFFFFE; |
2171 |
|
this_38 &= 0xFFFFFFFD; |
2172 |
|
this_38 &= 0xF2FFFFFF; |
2173 |
|
this_38 |= 0x02000000; |
2174 |
|
this_38 &= 0xFFFFFF3F; |
2175 |
|
} else { |
2176 |
|
this_38 |= 0x00000003; |
2177 |
|
this_38 &= 0xFFFFFFBF; |
2178 |
|
this_38 |= 0x80; |
2179 |
|
} |
2180 |
|
spdif_sr |= 2; |
2181 |
|
spdif_sr &= 0xFFFFFFFE; |
2182 |
|
break; |
2183 |
|
|
2184 |
|
} |
2185 |
|
hwwrite(vortex->mmio, VORTEX_SPDIF_CFG0, this_38 & 0xffff); |
2186 |
|
hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1, this_38 >> 0x10); |
2187 |
|
hwwrite(vortex->mmio, VORTEX_SPDIF_SMPRATE, spdif_sr); |
2188 |
} |
} |
2189 |
|
|
2190 |
/* Initialization */ |
/* Initialization */ |
2217 |
vortex_srcblock_init(vortex); |
vortex_srcblock_init(vortex); |
2218 |
#ifndef CHIP_AU8820 |
#ifndef CHIP_AU8820 |
2219 |
vortex_eq_init(vortex); |
vortex_eq_init(vortex); |
2220 |
|
vortex_spdif_init(vortex, 48000, 1); |
2221 |
#endif |
#endif |
2222 |
#ifndef CHIP_AU8810 |
#ifndef CHIP_AU8810 |
2223 |
vortex_InitializeWTRegs(vortex); |
vortex_wt_InitializeWTRegs(vortex); |
2224 |
#endif |
#endif |
2225 |
// Moved to au88x0.c |
// Moved to au88x0.c |
2226 |
//vortex_connect_default(vortex, 1); |
//vortex_connect_default(vortex, 1); |