Advertisement
Guest User

Untitled

a guest
May 30th, 2017
588
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 119.27 KB | None | 0 0
  1. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/trident.c linux.ac/trident.c
  2. --- linux.vanilla/trident.c   Thu Jan  1 01:00:00 1970
  3. +++ linux.ac/trident.c   Mon Feb 26 15:29:49 2001
  4. @@ -0,0 +1,3602 @@
  5. +/*
  6. + *
  7. + *   Trident 4D-Wave/SiS 7018/ALi 5451 OSS driver for Linux 2.2.x
  8. + *
  9. + *   Driver: Alan Cox <alan@redhat.com>
  10. + *
  11. + *  Built from:
  12. + *   Low level code: <audio@tridentmicro.com> from ALSA
  13. + *   Framework: Thomas Sailer <sailer@ife.ee.ethz.ch>
  14. + *   Extended by: Zach Brown <zab@redhat.com>  
  15. + *
  16. + *  Hacked up by:
  17. + *   Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
  18. + *   Ollie Lho <ollie@sis.com.tw> SiS 7018 Audio Core Support
  19. + *   Ching-Ling Lee <cling-li@ali.com.tw> ALi 5451 Audio Core Support
  20. + *   Matt Wu <mattwu@acersoftech.com.cn> ALi 5451 Audio Core Support
  21. + *
  22. + *
  23. + *   This program is free software; you can redistribute it and/or modify
  24. + *   it under the terms of the GNU General Public License as published by
  25. + *   the Free Software Foundation; either version 2 of the License, or
  26. + *   (at your option) any later version.
  27. + *
  28. + *   This program is distributed in the hope that it will be useful,
  29. + *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  30. + *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  31. + *   GNU General Public License for more details.
  32. + *
  33. + *   You should have received a copy of the GNU General Public License
  34. + *   along with this program; if not, write to the Free Software
  35. + *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  36. + *
  37. + *  History
  38. + *  v0.14.7
  39. + *   Feb 06 2001 Matt Wu
  40. + *   Fix ac97 initialization
  41. + *   Fix bug: an extra tail will be played when playing
  42. + *   Jan 05 2001 Matt Wu
  43. + *   Implement multi-channels and S/PDIF in support for ALi 1535+
  44. + *  v0.14.6
  45. + *   Nov 1 2000 Ching-Ling Lee
  46. + *   Fix the bug of memory leak when swithing 5.1-channels to 2 channels.
  47. + *   Add lock protection into dynamic changing format of data.
  48. + *   Oct 18 2000 Ching-Ling Lee
  49. + *   5.1-channels support for ALi
  50. + *   June 28 2000 Ching-Ling Lee
  51. + *   S/PDIF out/in(playback/record) support for ALi 1535+, using /proc to be selected by user
  52. + *   Simple Power Management support for ALi
  53. + *  v0.14.5 May 23 2000 Ollie Lho
  54. + *     Misc bug fix from the Net
  55. + *  v0.14.4 May 20 2000 Aaron Holtzman
  56. + *     Fix kfree'd memory access in release
  57. + *     Fix race in open while looking for a free virtual channel slot
  58. + *     remove open_wait wq (which appears to be unused)
  59. + *  v0.14.3 May 10 2000 Ollie Lho
  60. + *   fixed a small bug in trident_update_ptr, xmms 1.0.1 no longer uses 100% CPU
  61. + *  v0.14.2 Mar 29 2000 Ching-Ling Lee
  62. + *   Add clear to silence advance in trident_update_ptr
  63. + *   fix invalid data of the end of the sound
  64. + *  v0.14.1 Mar 24 2000 Ching-Ling Lee
  65. + *   ALi 5451 support added, playback and recording O.K.
  66. + *   ALi 5451 originally developed and structured based on sonicvibes, and
  67. + *   suggested to merge into this file by Alan Cox.
  68. + *  v0.14 Mar 15 2000 Ollie Lho
  69. + *   5.1 channel output support with channel binding. What's the Matrix ?
  70. + *  v0.13.1 Mar 10 2000 Ollie Lho
  71. + *   few minor bugs on dual codec support, needs more testing
  72. + *  v0.13 Mar 03 2000 Ollie Lho
  73. + *   new pci_* for 2.4 kernel, back ported to 2.2
  74. + *  v0.12 Feb 23 2000 Ollie Lho
  75. + *   Preliminary Recording support
  76. + *  v0.11.2 Feb 19 2000 Ollie Lho
  77. + *   removed incomplete full-dulplex support
  78. + *  v0.11.1 Jan 28 2000 Ollie Lho
  79. + *   small bug in setting sample rate for 4d-nx (reported by Aaron)
  80. + *  v0.11 Jan 27 2000 Ollie Lho
  81. + *   DMA bug, scheduler latency, second try
  82. + *  v0.10 Jan 24 2000 Ollie Lho
  83. + *   DMA bug fixed, found kernel scheduling problem
  84. + *  v0.09 Jan 20 2000 Ollie Lho
  85. + *   Clean up of channel register access routine (prepare for channel binding)
  86. + *  v0.08 Jan 14 2000 Ollie Lho
  87. + *   Isolation of AC97 codec code
  88. + *  v0.07 Jan 13 2000 Ollie Lho
  89. + *   Get rid of ugly old low level access routines (e.g. CHRegs.lp****)
  90. + *  v0.06 Jan 11 2000 Ollie Lho
  91. + *   Preliminary support for dual (more ?) AC97 codecs
  92. + *  v0.05 Jan 08 2000 Luca Montecchiani <m.luca@iname.com>
  93. + *   adapt to 2.3.x new __setup/__init call
  94. + *  v0.04 Dec 31 1999 Ollie Lho
  95. + *   Multiple Open, using Middle Loop Interrupt to smooth playback
  96. + *  v0.03 Dec 24 1999 Ollie Lho
  97. + *   mem leak in prog_dmabuf and dealloc_dmabuf removed
  98. + *  v0.02 Dec 15 1999 Ollie Lho
  99. + *   SiS 7018 support added, playback O.K.
  100. + *  v0.01 Alan Cox et. al.
  101. + *   Initial Release in kernel 2.3.30, does not work
  102. + *
  103. + *  ToDo
  104. + *   Clean up of low level channel register access code. (done)
  105. + *   Fix the bug on dma buffer management in update_ptr, read/write, drain_dac (done)
  106. + *   Dual AC97 codecs support (done)
  107. + *   Recording support (done)
  108. + *   Mmap support
  109. + *   "Channel Binding" ioctl extension (done)
  110. + *   new pci device driver interface for 2.4 kernel (done)
  111. + */
  112. +
  113. +#include <linux/config.h>
  114. +#include <linux/module.h>
  115. +#include <linux/version.h>
  116. +#include <linux/string.h>
  117. +#include <linux/ctype.h>
  118. +#include <linux/ioport.h>
  119. +#include <linux/sched.h>
  120. +#include <linux/delay.h>
  121. +#include <linux/sound.h>
  122. +#include <linux/malloc.h>
  123. +#include <linux/soundcard.h>
  124. +#include <linux/pci.h>
  125. +#include <asm/io.h>
  126. +#include <asm/dma.h>
  127. +#include <linux/init.h>
  128. +#include <linux/poll.h>
  129. +#include <linux/spinlock.h>
  130. +#include <linux/smp_lock.h>
  131. +#include <linux/ac97_codec.h>
  132. +#include <linux/wrapper.h>
  133. +#include <asm/uaccess.h>
  134. +#include <asm/hardirq.h>
  135. +#include <linux/bitops.h>
  136. +#include <linux/proc_fs.h>
  137. +
  138. +#include "trident.h"
  139. +
  140. +#include <linux/pm.h>
  141. +
  142. +#define DRIVER_VERSION "0.14.6"
  143. +
  144. +//#define DEBUG
  145. +#undef DEBUG
  146. +
  147. +/* magic numbers to protect our data structures */
  148. +#define TRIDENT_CARD_MAGIC   0x5072696E /* "Prin" */
  149. +#define TRIDENT_STATE_MAGIC   0x63657373 /* "cess" */
  150. +
  151. +#define TRIDENT_DMA_MASK   0x3fffffff /* DMA buffer mask for pci_alloc_consist */
  152. +
  153. +#define NR_HW_CH      32
  154. +
  155. +/* maxinum nuber of AC97 codecs connected, AC97 2.0 defined 4, but 7018 and 4D-NX only
  156. +   have 2 SDATA_IN lines (currently) */
  157. +#define NR_AC97      2  
  158. +
  159. +/* minor number of /dev/swmodem (temporary, experimental) */
  160. +#define SND_DEV_SWMODEM   7
  161. +
  162. +static const unsigned ali_multi_channels_5_1[] = { /*ALI_SURR_LEFT_CHANNEL, ALI_SURR_RIGHT_CHANNEL,*/ ALI_CENTER_CHANNEL, ALI_LEF_C+
  163. HANNEL, ALI_SURR_LEFT_CHANNEL, ALI_SURR_RIGHT_CHANNEL};
  164. +
  165. +static const unsigned sample_size[] = { 1, 2, 2, 4 };
  166. +static const unsigned sample_shift[] = { 0, 1, 1, 2 };
  167. +
  168. +static const char invalid_magic[] = KERN_CRIT "trident: invalid magic value in %s\n";
  169. +
  170. +enum {
  171. +   TRIDENT_4D_DX = 0,
  172. +   TRIDENT_4D_NX,
  173. +   SIS_7018,
  174. +   ALI_5451
  175. +};
  176. +
  177. +static char * card_names[] = {
  178. +   "Trident 4DWave DX",
  179. +   "Trident 4DWave NX",
  180. +   "SiS 7018 PCI Audio",
  181. +   "ALi Audio Accelerator"
  182. +};
  183. +
  184. +static struct pci_device_id trident_pci_tbl [] __devinitdata = {
  185. +   {PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX,
  186. +    PCI_ANY_ID, PCI_ANY_ID, 0, 0, TRIDENT_4D_DX},
  187. +   {PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX,
  188. +    PCI_ANY_ID, PCI_ANY_ID, 0, 0, TRIDENT_4D_NX},
  189. +   {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7018,
  190. +    PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_7018},
  191. +   {PCI_VENDOR_ID_ALI, PCI_DEVICE_ID_ALI_5451,
  192. +    PCI_ANY_ID, PCI_ANY_ID, 0, 0, ALI_5451},
  193. +   {0,}
  194. +};
  195. +
  196. +MODULE_DEVICE_TABLE (pci, trident_pci_tbl);
  197. +
  198. +/* "software" or virtual channel, an instance of opened /dev/dsp */
  199. +struct trident_state {
  200. +   unsigned int magic;
  201. +   struct trident_card *card;   /* Card info */
  202. +
  203. +   /* file mode */
  204. +   mode_t open_mode;
  205. +
  206. +   /* virtual channel number */
  207. +   int virt;
  208. +
  209. +   struct dmabuf {
  210. +      /* wave sample stuff */
  211. +      unsigned int rate;
  212. +      unsigned char fmt, enable;
  213. +
  214. +      /* hardware channel */
  215. +      struct trident_channel *channel;
  216. +
  217. +      /* OSS buffer management stuff */
  218. +      void *rawbuf;
  219. +      dma_addr_t dma_handle;
  220. +      unsigned buforder;
  221. +      unsigned numfrag;
  222. +      unsigned fragshift;
  223. +
  224. +      /* our buffer acts like a circular ring */
  225. +      unsigned hwptr;      /* where dma last started, updated by update_ptr */
  226. +      unsigned swptr;      /* where driver last clear/filled, updated by read/write */
  227. +      int count;      /* bytes to be comsumed or been generated by dma machine */
  228. +      unsigned total_bytes;   /* total bytes dmaed by hardware */
  229. +
  230. +      unsigned error;      /* number of over/underruns */
  231. +      wait_queue_head_t wait;   /* put process on wait queue when no more space in buffer */
  232. +
  233. +      /* redundant, but makes calculations easier */
  234. +      unsigned fragsize;
  235. +      unsigned dmasize;
  236. +      unsigned fragsamples;
  237. +
  238. +      /* OSS stuff */
  239. +      unsigned mapped:1;
  240. +      unsigned ready:1;
  241. +      unsigned endcleared:1;
  242. +      unsigned update_flag;
  243. +      unsigned ossfragshift;
  244. +      int ossmaxfrags;
  245. +      unsigned subdivision;
  246. +      
  247. +   } dmabuf;
  248. +
  249. +   /* 5.1channels */  
  250. +   struct trident_state *other_states[4];
  251. +   int multi_channels_adjust_count;
  252. +   unsigned chans_num;
  253. +   unsigned fmt_flag:1;
  254. +};
  255. +
  256. +/* hardware channels */
  257. +struct trident_channel {
  258. +   int  num;   /* channel number */
  259. +   u32 lba;   /* Loop Begine Address, where dma buffer starts */
  260. +   u32 eso;   /* End Sample Offset, wehre dma buffer ends (in the unit of samples) */
  261. +   u32 delta;   /* delta value, sample rate / 48k for playback, 48k/sample rate for recording */
  262. +   u16 attribute;   /* control where PCM data go and come  */
  263. +   u16 fm_vol;
  264. +   u32 control;   /* signed/unsigned, 8/16 bits, mono/stereo */
  265. +};
  266. +
  267. +struct trident_pcm_bank_address {
  268. +   u32 start;
  269. +   u32 stop;
  270. +   u32 aint;
  271. +   u32 aint_en;
  272. +};
  273. +static struct trident_pcm_bank_address bank_a_addrs =
  274. +{
  275. +   T4D_START_A,
  276. +   T4D_STOP_A,
  277. +   T4D_AINT_A,
  278. +   T4D_AINTEN_A
  279. +};
  280. +static struct trident_pcm_bank_address bank_b_addrs =
  281. +{
  282. +   T4D_START_B,
  283. +   T4D_STOP_B,
  284. +   T4D_AINT_B,
  285. +   T4D_AINTEN_B
  286. +};
  287. +struct trident_pcm_bank {
  288. +   /* register addresses to control bank operations */
  289. +   struct trident_pcm_bank_address *addresses;
  290. +   /* each bank has 32 channels */
  291. +   u32 bitmap; /* channel allocation bitmap */
  292. +   struct trident_channel channels[32];
  293. +};
  294. +
  295. +struct trident_card {
  296. +   unsigned int magic;
  297. +
  298. +   /* We keep trident cards in a linked list */
  299. +   struct trident_card *next;
  300. +
  301. +   /* single open lock mechanism, only used for recording */
  302. +   struct semaphore open_sem;
  303. +
  304. +   /* The trident has a certain amount of cross channel interaction
  305. +      so we use a single per card lock */
  306. +   spinlock_t lock;
  307. +
  308. +   /* PCI device stuff */
  309. +   struct pci_dev * pci_dev;
  310. +   u16 pci_id;
  311. +   u8 revision;
  312. +
  313. +   /* soundcore stuff */
  314. +   int dev_audio;
  315. +
  316. +   /* structures for abstraction of hardware facilities, codecs, banks and channels*/
  317. +   struct ac97_codec *ac97_codec[NR_AC97];
  318. +   struct trident_pcm_bank banks[NR_BANKS];
  319. +   struct trident_state *states[NR_HW_CH];
  320. +
  321. +   /* hardware resources */
  322. +   unsigned long iobase;
  323. +   u32 irq;
  324. +  
  325. +   /* Function support */
  326. +   struct trident_channel *(*alloc_pcm_channel)(struct trident_card *);
  327. +   struct trident_channel *(*alloc_rec_pcm_channel)(struct trident_card *);
  328. +   void (*free_pcm_channel)(struct trident_card *, unsigned int chan);
  329. +   void (*address_interrupt)(struct trident_card *);
  330. +
  331. +  
  332. +   //Add by Matt Wu 01-05-2001 for spdif in
  333. +   int   multi_channel_use_count;
  334. +   int   rec_channel_use_count;
  335. +   //End add
  336. +};
  337. +
  338. +/* table to map from CHANNELMASK to channel attribute for SiS 7018 */
  339. +static u16 mask2attr [] =
  340. +{
  341. +   PCM_LR, PCM_LR, SURR_LR, CENTER_LFE,
  342. +   HSET, MIC, MODEM_LINE1, MODEM_LINE2,
  343. +   I2S_LR, SPDIF_LR
  344. +};
  345. +/* table to map from channel attribute to CHANNELMASK for SiS 7018 */
  346. +static int attr2mask [] = {
  347. +   DSP_BIND_MODEM1, DSP_BIND_MODEM2, DSP_BIND_FRONT, DSP_BIND_HANDSET,
  348. +   DSP_BIND_I2S, DSP_BIND_CENTER_LFE, DSP_BIND_SURR, DSP_BIND_SPDIF
  349. +};
  350. +
  351. +
  352. +//Add by Matt Wu 01-05-2001 for spdif in
  353. +static int ali_close_multi_channels(void);
  354. +void ali_delay(struct trident_card *card,int interval);
  355. +void ali_detect_spdif_rate(struct trident_card *card);
  356. +//End add
  357. +
  358. +static struct trident_card *devs;
  359. +
  360. +static void trident_ac97_set(struct ac97_codec *codec, u8 reg, u16 val);
  361. +static u16 trident_ac97_get(struct ac97_codec *codec, u8 reg);
  362. +
  363. +static int trident_open_mixdev(struct inode *inode, struct file *file);
  364. +static int trident_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd,
  365. +            unsigned long arg);
  366. +static loff_t trident_llseek(struct file *file, loff_t offset, int origin);
  367. +
  368. +static void ali_ac97_set(struct ac97_codec *codec, u8 reg, u16 val);
  369. +static u16 ali_ac97_get(struct ac97_codec *codec, u8 reg);
  370. +static void ali_set_spdif_out_rate(struct trident_card *card, unsigned int rate);
  371. +static void ali_enable_special_channel(struct trident_state *stat);
  372. +static struct trident_channel *ali_alloc_rec_pcm_channel(struct trident_card *card);
  373. +static struct trident_channel *ali_alloc_pcm_channel(struct trident_card *card);
  374. +static int ali_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data);
  375. +static void ali_restore_regs(struct trident_card *card);
  376. +static void ali_save_regs(struct trident_card *card);
  377. +static void ali_free_pcm_channel(struct trident_card *card, unsigned int channel);
  378. +static int ali_setup_multi_channels(struct trident_card *card, int chan_nums);
  379. +static unsigned int ali_get_spdif_in_rate(struct trident_card *card);
  380. +static void ali_setup_spdif_in(struct trident_card *card);
  381. +static void ali_disable_spdif_in(struct trident_card *card);
  382. +static void ali_disable_special_channel(struct trident_card *card, int ch);
  383. +static void ali_setup_spdif_out(struct trident_card *card, int flag);
  384. +static int ali_write_5_1(struct trident_state *state, const char *buffer,int cnt_for_multi_channel, unsigned int *copy_count, unsig+
  385. ned int *state_cnt);
  386. +static int ali_allocate_other_states_resources(struct trident_state *state, int chan_nums);
  387. +static void ali_free_other_states_resources(struct trident_state *state);
  388. +
  389. +
  390. +/* save registers for ALi Power Management */
  391. +static struct ali_saved_registers {
  392. +   unsigned long global_regs[ALI_GLOBAL_REGS];
  393. +   unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS];
  394. +   unsigned mixer_regs[ALI_MIXER_REGS];
  395. +} ali_registers;
  396. +
  397. +#define seek_offset(dma_ptr, buffer, cnt, offset, copy_count)   (dma_ptr) += (offset);   \
  398. +                     (buffer) += (offset);   \
  399. +                     (cnt) -= (offset);   \
  400. +                     (copy_count) += (offset);
  401. +
  402. +#define lock_set_fmt(state)   {spin_lock_irqsave(&state->card->lock, flags);         \
  403. +            if (state->fmt_flag) {                  \
  404. +               spin_unlock_irqrestore(&state->card->lock, flags);   \
  405. +               return -EFAULT;                  \
  406. +            }                        \
  407. +            state->fmt_flag = 1;                  \
  408. +            spin_unlock_irqrestore(&state->card->lock, flags);}
  409. +            
  410. +#define unlock_set_fmt(state)   {spin_lock_irqsave(&state->card->lock, flags);      \
  411. +            state->fmt_flag = 0;               \
  412. +            spin_unlock_irqrestore(&state->card->lock, flags);}
  413. +
  414. +static int trident_enable_loop_interrupts(struct trident_card * card)
  415. +{
  416. +   u32 global_control;
  417. +
  418. +   global_control = inl(TRID_REG(card, T4D_LFO_GC_CIR));
  419. +
  420. +   switch (card->pci_id)
  421. +   {
  422. +   case PCI_DEVICE_ID_SI_7018:
  423. +      global_control |= (ENDLP_IE | MIDLP_IE| BANK_B_EN);
  424. +      break;
  425. +   case PCI_DEVICE_ID_ALI_5451:
  426. +   case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
  427. +   case PCI_DEVICE_ID_TRIDENT_4DWAVE_NX:
  428. +      global_control |= (ENDLP_IE | MIDLP_IE);
  429. +      break;
  430. +   default:
  431. +      return FALSE;
  432. +   }
  433. +
  434. +   outl(global_control, TRID_REG(card, T4D_LFO_GC_CIR));
  435. +
  436. +#ifdef DEBUG
  437. +   printk("trident: Enable Loop Interrupts, globctl = 0x%08X\n",
  438. +          global_control);
  439. +#endif
  440. +   return (TRUE);
  441. +}
  442. +
  443. +static int trident_disable_loop_interrupts(struct trident_card * card)
  444. +{
  445. +   u32 global_control;
  446. +
  447. +   global_control = inl(TRID_REG(card, T4D_LFO_GC_CIR));
  448. +   global_control &= ~(ENDLP_IE | MIDLP_IE);
  449. +   outl(global_control, TRID_REG(card, T4D_LFO_GC_CIR));
  450. +
  451. +#ifdef DEBUG
  452. +   printk("trident: Disabled Loop Interrupts, globctl = 0x%08X\n",
  453. +          global_control);
  454. +#endif
  455. +   return (TRUE);
  456. +}
  457. +
  458. +static void trident_enable_voice_irq(struct trident_card * card, unsigned int channel)
  459. +{
  460. +   unsigned int mask = 1 << (channel & 0x1f);
  461. +   struct trident_pcm_bank *bank = &card->banks[channel >> 5];
  462. +   u32 reg, addr = bank->addresses->aint_en;
  463. +
  464. +   reg = inl(TRID_REG(card, addr));
  465. +   reg |= mask;
  466. +   outl(reg, TRID_REG(card, addr));
  467. +
  468. +#ifdef DEBUG
  469. +   reg = inl(TRID_REG(card, T4D_AINTEN_B));
  470. +   printk("trident: enabled IRQ on channel %d, AINTEN_B = 0x%08x\n",
  471. +          channel, reg);
  472. +#endif
  473. +}
  474. +
  475. +static void trident_disable_voice_irq(struct trident_card * card, unsigned int channel)
  476. +{
  477. +   unsigned int mask = 1 << (channel & 0x1f);
  478. +   struct trident_pcm_bank *bank = &card->banks[channel >> 5];
  479. +   u32 reg, addr = bank->addresses->aint_en;
  480. +  
  481. +   reg = inl(TRID_REG(card, addr));
  482. +   reg &= ~mask;
  483. +   outl(reg, TRID_REG(card, addr));
  484. +  
  485. +   /* Ack the channel in case the interrupt was set before we disable it. */
  486. +   outl(mask, TRID_REG(card, bank->addresses->aint));
  487. +
  488. +#ifdef DEBUG
  489. +   reg = inl(TRID_REG(card, T4D_AINTEN_B));
  490. +   printk("trident: disabled IRQ on channel %d, AINTEN_B = 0x%08x\n",
  491. +          channel, reg);
  492. +#endif
  493. +}
  494. +
  495. +static void trident_start_voice(struct trident_card * card, unsigned int channel)
  496. +{
  497. +   unsigned int mask = 1 << (channel & 0x1f);
  498. +   struct trident_pcm_bank *bank = &card->banks[channel >> 5];
  499. +   u32 addr = bank->addresses->start;
  500. +
  501. +#ifdef DEBUG
  502. +   u32 reg;
  503. +#endif
  504. +
  505. +   outl(mask, TRID_REG(card, addr));
  506. +
  507. +#ifdef DEBUG
  508. +   reg = inl(TRID_REG(card, T4D_START_B));
  509. +   printk("trident: start voice on channel %d, START_B  = 0x%08x\n",
  510. +          channel, reg);
  511. +#endif
  512. +}
  513. +
  514. +static void trident_stop_voice(struct trident_card * card, unsigned int channel)
  515. +{
  516. +   unsigned int mask = 1 << (channel & 0x1f);
  517. +   struct trident_pcm_bank *bank = &card->banks[channel >> 5];
  518. +   u32 addr = bank->addresses->stop;
  519. +
  520. +#ifdef DEBUG
  521. +   u32 reg;
  522. +#endif
  523. +
  524. +   outl(mask, TRID_REG(card, addr));
  525. +
  526. +#ifdef DEBUG
  527. +   reg = inl(TRID_REG(card, T4D_STOP_B));
  528. +   printk("trident: stop voice on channel %d,  STOP_B  = 0x%08x\n",
  529. +          channel, reg);
  530. +#endif
  531. +}
  532. +
  533. +static u32 trident_get_interrupt_mask (struct trident_card * card, unsigned int channel)
  534. +{
  535. +   struct trident_pcm_bank *bank = &card->banks[channel];
  536. +   u32 addr = bank->addresses->aint;
  537. +   return inl(TRID_REG(card, addr));
  538. +}
  539. +
  540. +static int trident_check_channel_interrupt(struct trident_card * card, unsigned int channel)
  541. +{
  542. +   unsigned int mask = 1 << (channel & 0x1f);
  543. +   u32 reg = trident_get_interrupt_mask (card, channel >> 5);
  544. +
  545. +#ifdef DEBUG
  546. +   if (reg & mask)
  547. +      printk("trident: channel %d has interrupt, AINT_B = 0x%08x\n",
  548. +             channel, reg);
  549. +#endif
  550. +   return (reg & mask) ? TRUE : FALSE;
  551. +}
  552. +
  553. +static void trident_ack_channel_interrupt(struct trident_card * card, unsigned int channel)
  554. +{
  555. +   unsigned int mask = 1 << (channel & 0x1f);
  556. +   struct trident_pcm_bank *bank = &card->banks[channel >> 5];
  557. +   u32 reg, addr = bank->addresses->aint;
  558. +
  559. +   reg = inl(TRID_REG(card, addr));
  560. +   reg &= mask;
  561. +   outl(reg, TRID_REG(card, addr));
  562. +
  563. +#ifdef DEBUG
  564. +   reg = inl(TRID_REG(card, T4D_AINT_B));
  565. +   printk("trident: Ack channel %d interrupt, AINT_B = 0x%08x\n",
  566. +          channel, reg);
  567. +#endif
  568. +}
  569. +
  570. +static struct trident_channel * trident_alloc_pcm_channel(struct trident_card *card)
  571. +{
  572. +   struct trident_pcm_bank *bank;
  573. +   int idx;
  574. +
  575. +   bank = &card->banks[BANK_B];
  576. +
  577. +   for (idx = 31; idx >= 0; idx--) {
  578. +      if (!(bank->bitmap & (1 << idx))) {
  579. +         struct trident_channel *channel = &bank->channels[idx];
  580. +         bank->bitmap |= 1 << idx;
  581. +         channel->num = idx + 32;
  582. +         return channel;
  583. +      }
  584. +   }
  585. +
  586. +   /* no more free channels avaliable */
  587. +   printk(KERN_ERR "trident: no more channels available on Bank B.\n");
  588. +   return NULL;
  589. +}
  590. +
  591. +static void trident_free_pcm_channel(struct trident_card *card, unsigned int channel)
  592. +{
  593. +   int bank;
  594. +
  595. +   if (channel < 31 || channel > 63)
  596. +      return;
  597. +
  598. +   bank = channel >> 5;
  599. +   channel = channel & 0x1f;
  600. +
  601. +   card->banks[bank].bitmap &= ~(1 << (channel));
  602. +}
  603. +
  604. +/* called with spin lock held */
  605. +
  606. +static int trident_load_channel_registers(struct trident_card *card, u32 *data, unsigned int channel)
  607. +{
  608. +   int i;
  609. +
  610. +   if (channel > 63)
  611. +      return FALSE;
  612. +
  613. +   /* select hardware channel to write */
  614. +   outb(channel, TRID_REG(card, T4D_LFO_GC_CIR));
  615. +#ifdef DEBUG
  616. +   printk("GC_CIR=%xh\n", inb(TRID_REG(card, T4D_LFO_GC_CIR)));
  617. +#endif
  618. +
  619. +   /* Output the channel registers, but don't write register
  620. +      three to an ALI chip. */
  621. +   for (i = 0; i < CHANNEL_REGS; i++) {
  622. +      if (i == 3 && card->pci_id == PCI_DEVICE_ID_ALI_5451)
  623. +         continue;
  624. +      outl(data[i], TRID_REG(card, CHANNEL_START + 4*i));
  625. +   }
  626. +   return TRUE;
  627. +}
  628. +
  629. +/* called with spin lock held */
  630. +static int trident_write_voice_regs(struct trident_state *state)
  631. +{
  632. +   unsigned int data[CHANNEL_REGS + 1];
  633. +   struct trident_channel *channel;
  634. +
  635. +   channel = state->dmabuf.channel;
  636. +
  637. +   data[1] = channel->lba;
  638. +   data[4] = channel->control;
  639. +
  640. +   switch (state->card->pci_id)
  641. +   {
  642. +   case PCI_DEVICE_ID_ALI_5451:
  643. +      data[0] = 0; /* Current Sample Offset */
  644. +      data[2] = (channel->eso << 16) | (channel->delta & 0xffff);
  645. +      data[3] = 0;
  646. +      break;  
  647. +   case PCI_DEVICE_ID_SI_7018:
  648. +      data[0] = 0; /* Current Sample Offset */
  649. +      data[2] = (channel->eso << 16) | (channel->delta & 0xffff);
  650. +      data[3] = (channel->attribute << 16) | (channel->fm_vol & 0xffff);
  651. +      break;
  652. +   case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
  653. +      data[0] = 0; /* Current Sample Offset */
  654. +      data[2] = (channel->eso << 16) | (channel->delta & 0xffff);
  655. +      data[3] = channel->fm_vol & 0xffff;
  656. +      break;
  657. +   case PCI_DEVICE_ID_TRIDENT_4DWAVE_NX:
  658. +      data[0] = (channel->delta << 24);
  659. +      data[2] = ((channel->delta << 16) & 0xff000000) | (channel->eso & 0x00ffffff);
  660. +      data[3] = channel->fm_vol & 0xffff;
  661. +      break;
  662. +   default:
  663. +      return FALSE;
  664. +   }
  665. +
  666. +   return trident_load_channel_registers(state->card, data, channel->num);
  667. +}
  668. +
  669. +static int compute_rate_play(u32 rate)
  670. +{
  671. +   int delta;
  672. +   /* We special case 44100 and 8000 since rounding with the equation
  673. +      does not give us an accurate enough value. For 11025 and 22050
  674. +      the equation gives us the best answer. All other frequencies will
  675. +      also use the equation. JDW */
  676. +   if (rate == 44100)
  677. +      delta = 0xeb3;
  678. +   else if (rate == 8000)
  679. +      delta = 0x2ab;
  680. +   else if (rate == 48000)
  681. +      delta = 0x1000;
  682. +   else
  683. +      delta = (((rate << 12) + rate) / 48000) & 0x0000ffff;
  684. +   return delta;
  685. +}
  686. +
  687. +static int compute_rate_rec(u32 rate)
  688. +{
  689. +   int delta;
  690. +
  691. +   if (rate == 44100)
  692. +      delta = 0x116a;
  693. +   else if (rate == 8000)
  694. +      delta = 0x6000;
  695. +   else if (rate == 48000)
  696. +      delta = 0x1000;
  697. +   else
  698. +      delta = ((48000 << 12) / rate) & 0x0000ffff;
  699. +
  700. +   return delta;
  701. +}
  702. +/* set playback sample rate */
  703. +static unsigned int trident_set_dac_rate(struct trident_state * state, unsigned int rate)
  704. +{  
  705. +   struct dmabuf *dmabuf = &state->dmabuf;
  706. +
  707. +   if (rate > 48000)
  708. +      rate = 48000;
  709. +   if (rate < 4000)
  710. +      rate = 4000;
  711. +
  712. +   dmabuf->rate = rate;
  713. +#ifdef DEBUG
  714. +   printk("ch=%d rate=%xh\n", state->dmabuf.channel->num, rate);
  715. +#endif
  716. +   dmabuf->channel->delta = compute_rate_play(rate);
  717. +
  718. +   trident_write_voice_regs(state);
  719. +
  720. +#ifdef DEBUG
  721. +   printk("trident: called trident_set_dac_rate : rate = %d\n", rate);
  722. +#endif
  723. +
  724. +   return rate;
  725. +}
  726. +
  727. +/* set recording sample rate */
  728. +static unsigned int trident_set_adc_rate(struct trident_state * state, unsigned int rate)
  729. +{
  730. +   struct dmabuf *dmabuf = &state->dmabuf;
  731. +
  732. +   if (rate > 48000)
  733. +      rate = 48000;
  734. +   if (rate < 4000)
  735. +      rate = 4000;
  736. +
  737. +   dmabuf->rate = rate;
  738. +   dmabuf->channel->delta = compute_rate_rec(rate);
  739. +
  740. +   trident_write_voice_regs(state);
  741. +
  742. +#ifdef DEBUG
  743. +   printk("trident: called trident_set_adc_rate : rate = %d\n", rate);
  744. +#endif
  745. +   return rate;
  746. +}
  747. +
  748. +/* prepare channel attributes for playback */
  749. +static void trident_play_setup(struct trident_state *state)
  750. +{
  751. +   struct dmabuf *dmabuf = &state->dmabuf;
  752. +   struct trident_channel *channel = dmabuf->channel;
  753. +
  754. +   channel->lba = virt_to_bus(dmabuf->rawbuf);
  755. +   channel->delta = compute_rate_play(dmabuf->rate);
  756. +
  757. +   channel->eso = dmabuf->dmasize >> sample_shift[dmabuf->fmt];
  758. +   channel->eso -= 1;
  759. +
  760. +   if (state->card->pci_id != PCI_DEVICE_ID_SI_7018) {
  761. +      channel->attribute = 0;
  762. +      if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451) {
  763. +         if ((channel->num == ALI_SPDIF_IN_CHANNEL) || (channel->num == ALI_PCM_IN_CHANNEL))
  764. +            ali_disable_special_channel(state->card, channel->num);
  765. +         else if ((inl(TRID_REG(state->card, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)
  766. +                        && (channel->num == ALI_SPDIF_OUT_CHANNEL))
  767. +         {
  768. +            ali_set_spdif_out_rate(state->card, state->dmabuf.rate);
  769. +            state->dmabuf.channel->delta = 0x1000;
  770. +         }
  771. +      }
  772. +   }
  773. +
  774. +   channel->fm_vol = 0x0;
  775. +  
  776. +   channel->control = CHANNEL_LOOP;
  777. +   if (dmabuf->fmt & TRIDENT_FMT_16BIT) {
  778. +      /* 16-bits */
  779. +      channel->control |= CHANNEL_16BITS;
  780. +      /* signed */
  781. +      channel->control |= CHANNEL_SIGNED;
  782. +   }
  783. +   if (dmabuf->fmt & TRIDENT_FMT_STEREO)
  784. +      /* stereo */
  785. +      channel->control |= CHANNEL_STEREO;
  786. +#ifdef DEBUG
  787. +   printk("trident: trident_play_setup, LBA = 0x%08x, "
  788. +          "Delat = 0x%08x, ESO = 0x%08x, Control = 0x%08x\n",
  789. +          channel->lba, channel->delta, channel->eso, channel->control);
  790. +#endif
  791. +   trident_write_voice_regs(state);
  792. +}
  793. +
  794. +/* prepare channel attributes for recording */
  795. +static void trident_rec_setup(struct trident_state *state)
  796. +{
  797. +   u16 w;
  798. +   u8  bval;
  799. +
  800. +   struct trident_card *card = state->card;
  801. +   struct dmabuf *dmabuf = &state->dmabuf;
  802. +   struct trident_channel *channel = dmabuf->channel;
  803. +   unsigned int rate;
  804. +
  805. +   /* Enable AC-97 ADC (capture) */
  806. +   switch (card->pci_id)
  807. +   {
  808. +   case PCI_DEVICE_ID_ALI_5451:
  809. +      ali_enable_special_channel(state);
  810. +      break;
  811. +   case PCI_DEVICE_ID_SI_7018:
  812. +      /* for 7018, the ac97 is always in playback/record (duplex) mode */
  813. +      break;
  814. +   case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
  815. +      w = inb(TRID_REG(card, DX_ACR2_AC97_COM_STAT));
  816. +      outb(w | 0x48, TRID_REG(card, DX_ACR2_AC97_COM_STAT));
  817. +      /* enable and set record channel */
  818. +      outb(0x80 | channel->num, TRID_REG(card, T4D_REC_CH));
  819. +      break;
  820. +   case PCI_DEVICE_ID_TRIDENT_4DWAVE_NX:
  821. +      w = inw(TRID_REG(card, T4D_MISCINT));
  822. +      outw(w | 0x1000, TRID_REG(card, T4D_MISCINT));
  823. +      /* enable and set record channel */
  824. +      outb(0x80 | channel->num, TRID_REG(card, T4D_REC_CH));
  825. +      break;
  826. +   default:
  827. +      return;
  828. +   }
  829. +
  830. +   channel->lba = virt_to_bus(dmabuf->rawbuf);
  831. +   channel->delta = compute_rate_rec(dmabuf->rate);
  832. +   if ((card->pci_id == PCI_DEVICE_ID_ALI_5451) && (channel->num == ALI_SPDIF_IN_CHANNEL)) {
  833. +      rate = ali_get_spdif_in_rate(card);
  834. +      if (rate == 0)
  835. +      {
  836. +         printk("Err: spdif-in setup error!\n");
  837. +         rate = 48000;
  838. +      }
  839. +      bval = inb(TRID_REG(card,ALI_SPDIF_CTRL));
  840. +      if (bval & 0x10)
  841. +      {
  842. +         outb(bval,TRID_REG(card,ALI_SPDIF_CTRL));
  843. +         printk("clear SPDIF parity error flag.\n");
  844. +      }
  845. +
  846. +      if (rate != 48000)
  847. +         channel->delta = ((rate << 12) / dmabuf->rate) & 0x0000ffff;
  848. +   }
  849. +  
  850. +   channel->eso = dmabuf->dmasize >> sample_shift[dmabuf->fmt];
  851. +   channel->eso -= 1;
  852. +
  853. +   if (state->card->pci_id != PCI_DEVICE_ID_SI_7018) {
  854. +      channel->attribute = 0;
  855. +   }
  856. +
  857. +   channel->fm_vol = 0x0;
  858. +  
  859. +   channel->control = CHANNEL_LOOP;
  860. +   if (dmabuf->fmt & TRIDENT_FMT_16BIT) {
  861. +      /* 16-bits */
  862. +      channel->control |= CHANNEL_16BITS;
  863. +      /* signed */
  864. +      channel->control |= CHANNEL_SIGNED;
  865. +   }
  866. +   if (dmabuf->fmt & TRIDENT_FMT_STEREO)
  867. +      /* stereo */
  868. +      channel->control |= CHANNEL_STEREO;
  869. +#ifdef DEBUG
  870. +   printk("trident: trident_rec_setup, LBA = 0x%08x, "
  871. +          "Delat = 0x%08x, ESO = 0x%08x, Control = 0x%08x\n",
  872. +          channel->lba, channel->delta, channel->eso, channel->control);
  873. +#endif
  874. +   trident_write_voice_regs(state);
  875. +}
  876. +
  877. +/* get current playback/recording dma buffer pointer (byte offset from LBA),
  878. +   called with spinlock held! */
  879. +extern __inline__ unsigned trident_get_dma_addr(struct trident_state *state)
  880. +{
  881. +   struct dmabuf *dmabuf = &state->dmabuf;
  882. +   u32 cso;
  883. +
  884. +   if (!dmabuf->enable)
  885. +      return 0;
  886. +
  887. +   outb(dmabuf->channel->num, TRID_REG(state->card, T4D_LFO_GC_CIR));
  888. +
  889. +   switch (state->card->pci_id)
  890. +   {
  891. +   case PCI_DEVICE_ID_ALI_5451:
  892. +   case PCI_DEVICE_ID_SI_7018:
  893. +   case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
  894. +      /* 16 bits ESO, CSO for 7018 and DX */
  895. +      cso = inw(TRID_REG(state->card, CH_DX_CSO_ALPHA_FMS + 2));
  896. +      break;
  897. +   case PCI_DEVICE_ID_TRIDENT_4DWAVE_NX:
  898. +      /* 24 bits ESO, CSO for NX */
  899. +      cso = inl(TRID_REG(state->card, CH_NX_DELTA_CSO)) & 0x00ffffff;
  900. +      break;
  901. +   default:
  902. +      return 0;
  903. +   }
  904. +
  905. +#ifdef DEBUG
  906. +   printk("trident: trident_get_dma_addr: chip reported channel: %d, "
  907. +          "cso = 0x%04x\n",
  908. +          dmabuf->channel->num, cso);
  909. +#endif
  910. +   /* ESO and CSO are in units of Samples, convert to byte offset */
  911. +   cso <<= sample_shift[dmabuf->fmt];
  912. +
  913. +   return (cso % dmabuf->dmasize);
  914. +}
  915. +
  916. +/* Stop recording (lock held) */
  917. +extern __inline__ void __stop_adc(struct trident_state *state)
  918. +{
  919. +   struct dmabuf *dmabuf = &state->dmabuf;
  920. +   unsigned int chan_num = dmabuf->channel->num;
  921. +   struct trident_card *card = state->card;
  922. +
  923. +   dmabuf->enable &= ~ADC_RUNNING;
  924. +   trident_stop_voice(card, chan_num);
  925. +   trident_disable_voice_irq(card, chan_num);
  926. +}
  927. +
  928. +static void stop_adc(struct trident_state *state)
  929. +{
  930. +   struct trident_card *card = state->card;
  931. +   unsigned long flags;
  932. +
  933. +   spin_lock_irqsave(&card->lock, flags);
  934. +   __stop_adc(state);
  935. +   spin_unlock_irqrestore(&card->lock, flags);
  936. +}
  937. +
  938. +static void start_adc(struct trident_state *state)
  939. +{
  940. +   struct dmabuf *dmabuf = &state->dmabuf;
  941. +   unsigned int chan_num = dmabuf->channel->num;
  942. +   struct trident_card *card = state->card;
  943. +   unsigned long flags;
  944. +
  945. +   spin_lock_irqsave(&card->lock, flags);
  946. +   if ((dmabuf->mapped || dmabuf->count < (signed)dmabuf->dmasize) && dmabuf->ready) {
  947. +      dmabuf->enable |= ADC_RUNNING;
  948. +      trident_enable_voice_irq(card, chan_num);
  949. +      trident_start_voice(card, chan_num);
  950. +   }
  951. +   spin_unlock_irqrestore(&card->lock, flags);
  952. +}
  953. +
  954. +/* stop playback (lock held) */
  955. +extern __inline__ void __stop_dac(struct trident_state *state)
  956. +{
  957. +   struct dmabuf *dmabuf = &state->dmabuf;
  958. +   unsigned int chan_num = dmabuf->channel->num;
  959. +   struct trident_card *card = state->card;
  960. +
  961. +   dmabuf->enable &= ~DAC_RUNNING;
  962. +   trident_stop_voice(card, chan_num);
  963. +   if (state->chans_num == 6) {
  964. +      trident_stop_voice(card, state->other_states[0]->dmabuf.channel->num);
  965. +      trident_stop_voice(card, state->other_states[1]->dmabuf.channel->num);
  966. +      trident_stop_voice(card, state->other_states[2]->dmabuf.channel->num);
  967. +      trident_stop_voice(card, state->other_states[3]->dmabuf.channel->num);
  968. +   }
  969. +   trident_disable_voice_irq(card, chan_num);
  970. +}
  971. +
  972. +
  973. +static void stop_dac(struct trident_state *state)
  974. +{
  975. +   struct trident_card *card = state->card;
  976. +   unsigned long flags;
  977. +
  978. +   spin_lock_irqsave(&card->lock, flags);
  979. +   __stop_dac(state);
  980. +   spin_unlock_irqrestore(&card->lock, flags);
  981. +}  
  982. +
  983. +static void start_dac(struct trident_state *state)
  984. +{
  985. +   struct dmabuf *dmabuf = &state->dmabuf;
  986. +   unsigned int chan_num = dmabuf->channel->num;
  987. +   struct trident_card *card = state->card;
  988. +   unsigned long flags;
  989. +
  990. +   spin_lock_irqsave(&card->lock, flags);
  991. +   if ((dmabuf->mapped || dmabuf->count > 0) && dmabuf->ready) {
  992. +      dmabuf->enable |= DAC_RUNNING;
  993. +      trident_enable_voice_irq(card, chan_num);
  994. +      trident_start_voice(card, chan_num);
  995. +      if (state->chans_num == 6) {
  996. +         trident_start_voice(card, state->other_states[0]->dmabuf.channel->num);
  997. +         trident_start_voice(card, state->other_states[1]->dmabuf.channel->num);
  998. +         trident_start_voice(card, state->other_states[2]->dmabuf.channel->num);
  999. +         trident_start_voice(card, state->other_states[3]->dmabuf.channel->num);
  1000. +      }
  1001. +   }
  1002. +   spin_unlock_irqrestore(&card->lock, flags);
  1003. +}
  1004. +
  1005. +#define DMABUF_DEFAULTORDER (15-PAGE_SHIFT)
  1006. +#define DMABUF_MINORDER 1
  1007. +
  1008. +/* allocate DMA buffer, playback and recording buffer should be allocated seperately */
  1009. +static int alloc_dmabuf(struct trident_state *state)
  1010. +{
  1011. +   struct dmabuf *dmabuf = &state->dmabuf;
  1012. +   void *rawbuf = NULL;
  1013. +   int order;
  1014. +   struct page *page, *pend;
  1015. +
  1016. +   /* alloc as big a chunk as we can, FIXME: is this necessary ?? */
  1017. +   for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
  1018. +      if ((rawbuf = pci_alloc_consistent(state->card->pci_dev,
  1019. +                     PAGE_SIZE << order,
  1020. +                     &dmabuf->dma_handle)))
  1021. +         break;
  1022. +   if (!rawbuf)
  1023. +      return -ENOMEM;
  1024. +
  1025. +#ifdef DEBUG
  1026. +   printk("trident: allocated %ld (order = %d) bytes at %p\n",
  1027. +          PAGE_SIZE << order, order, rawbuf);
  1028. +#endif
  1029. +
  1030. +   dmabuf->ready  = dmabuf->mapped = 0;
  1031. +   dmabuf->rawbuf = rawbuf;
  1032. +   dmabuf->buforder = order;
  1033. +  
  1034. +   /* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */
  1035. +   pend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1);
  1036. +   for (page = virt_to_page(rawbuf); page <= pend; page++)
  1037. +      mem_map_reserve(page);
  1038. +
  1039. +   return 0;
  1040. +}
  1041. +
  1042. +/* free DMA buffer */
  1043. +static void dealloc_dmabuf(struct trident_state *state)
  1044. +{
  1045. +   struct dmabuf *dmabuf = &state->dmabuf;
  1046. +   struct page *page, *pend;
  1047. +
  1048. +   if (dmabuf->rawbuf) {
  1049. +      /* undo marking the pages as reserved */
  1050. +      pend = virt_to_page(dmabuf->rawbuf + (PAGE_SIZE << dmabuf->buforder) - 1);
  1051. +      for (page = virt_to_page(dmabuf->rawbuf); page <= pend; page++)
  1052. +         mem_map_unreserve(page);
  1053. +      pci_free_consistent(state->card->pci_dev, PAGE_SIZE << dmabuf->buforder,
  1054. +                dmabuf->rawbuf, dmabuf->dma_handle);
  1055. +   }
  1056. +   dmabuf->rawbuf = NULL;
  1057. +   dmabuf->mapped = dmabuf->ready = 0;
  1058. +}
  1059. +
  1060. +static int prog_dmabuf(struct trident_state *state, unsigned rec)
  1061. +{
  1062. +   struct dmabuf *dmabuf = &state->dmabuf;
  1063. +   unsigned bytepersec;
  1064. +   struct trident_state *s = state;
  1065. +   unsigned bufsize, dma_nums;
  1066. +   unsigned long flags;
  1067. +   int ret, i, order;
  1068. +   struct page *page, *pend;
  1069. +  
  1070. +   lock_set_fmt(state);
  1071. +   if (state->chans_num == 6)
  1072. +      dma_nums = 5;
  1073. +   else    dma_nums = 1;
  1074. +  
  1075. +   for (i = 0; i < dma_nums; i++) {
  1076. +      if (i > 0) {
  1077. +         s = state->other_states[i - 1];        
  1078. +         dmabuf = &s->dmabuf;
  1079. +         dmabuf->fmt = state->dmabuf.fmt;
  1080. +         dmabuf->rate = state->dmabuf.rate;
  1081. +      }
  1082. +
  1083. +      spin_lock_irqsave(&s->card->lock, flags);
  1084. +      dmabuf->hwptr = dmabuf->swptr = dmabuf->total_bytes = 0;
  1085. +      dmabuf->count = dmabuf->error = 0;
  1086. +      spin_unlock_irqrestore(&s->card->lock, flags);
  1087. +
  1088. +      /* allocate DMA buffer if not allocated yet */
  1089. +      if (!dmabuf->rawbuf) {
  1090. +         if (i == 0) {
  1091. +            if ((ret = alloc_dmabuf(state))) {
  1092. +               unlock_set_fmt(state);
  1093. +               return ret;
  1094. +            }
  1095. +         }
  1096. +         else {
  1097. +            if ((order = state->dmabuf.buforder - 1) >= DMABUF_MINORDER)
  1098. +               dmabuf->rawbuf = (void *)__get_free_pages(GFP_KERNEL | GFP_DMA, order);
  1099. +            if (!dmabuf->rawbuf) {
  1100. +               free_pages((unsigned long)state->dmabuf.rawbuf, state->dmabuf.buforder);
  1101. +               state->dmabuf.rawbuf = NULL;
  1102. +               i-=2;
  1103. +               for (; i >= 0; i--)
  1104. +                  free_pages((unsigned long)state->other_states[i]->dmabuf.rawbuf, state->other_states[i]->dmabuf.bufor+
  1105. der);
  1106. +               unlock_set_fmt(state);
  1107. +               return -ENOMEM;
  1108. +            }
  1109. +            dmabuf->ready  = dmabuf->mapped = 0;
  1110. +            dmabuf->buforder = order;
  1111. +            pend = virt_to_page(dmabuf->rawbuf + (PAGE_SIZE << order) - 1);
  1112. +            for (page = virt_to_page(dmabuf->rawbuf); page <= pend; page++)
  1113. +               mem_map_reserve(page);
  1114. +         }
  1115. +      }
  1116. +      /* FIXME: figure out all this OSS fragment stuff */
  1117. +      bytepersec = dmabuf->rate << sample_shift[dmabuf->fmt];
  1118. +      bufsize = PAGE_SIZE << dmabuf->buforder;
  1119. +      if (dmabuf->ossfragshift) {
  1120. +         if ((1000 << dmabuf->ossfragshift) < bytepersec)
  1121. +            dmabuf->fragshift = ld2(bytepersec/1000);
  1122. +         else
  1123. +            dmabuf->fragshift = dmabuf->ossfragshift;
  1124. +      } else {
  1125. +         /* lets hand out reasonable big ass buffers by default */
  1126. +         dmabuf->fragshift = (dmabuf->buforder + PAGE_SHIFT -2);
  1127. +      }
  1128. +      dmabuf->numfrag = bufsize >> dmabuf->fragshift;
  1129. +      while (dmabuf->numfrag < 4 && dmabuf->fragshift > 3) {
  1130. +         dmabuf->fragshift--;
  1131. +         dmabuf->numfrag = bufsize >> dmabuf->fragshift;
  1132. +      }
  1133. +      dmabuf->fragsize = 1 << dmabuf->fragshift;
  1134. +      if (dmabuf->ossmaxfrags >= 4 && dmabuf->ossmaxfrags < dmabuf->numfrag)
  1135. +         dmabuf->numfrag = dmabuf->ossmaxfrags;
  1136. +      dmabuf->fragsamples = dmabuf->fragsize >> sample_shift[dmabuf->fmt];
  1137. +      dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift;
  1138. +
  1139. +      memset(dmabuf->rawbuf, (dmabuf->fmt & TRIDENT_FMT_16BIT) ? 0 : 0x80,
  1140. +             dmabuf->dmasize);
  1141. +
  1142. +      spin_lock_irqsave(&s->card->lock, flags);
  1143. +      if (rec) {
  1144. +         trident_rec_setup(s);
  1145. +      } else {
  1146. +         trident_play_setup(s);
  1147. +      }
  1148. +      spin_unlock_irqrestore(&s->card->lock, flags);
  1149. +
  1150. +      /* set the ready flag for the dma buffer */
  1151. +      dmabuf->ready = 1;
  1152. +
  1153. +#ifdef DEBUG
  1154. +   printk("trident: prog_dmabuf(%d), sample rate = %d, format = %d, numfrag = %d, "
  1155. +          "fragsize = %d dmasize = %d\n",
  1156. +          dmabuf->channel->num, dmabuf->rate, dmabuf->fmt, dmabuf->numfrag,
  1157. +          dmabuf->fragsize, dmabuf->dmasize);
  1158. +#endif
  1159. +   }
  1160. +   unlock_set_fmt(state);
  1161. +   return 0;
  1162. +}
  1163. +
  1164. +/* we are doing quantum mechanics here, the buffer can only be empty, half or full filled i.e.
  1165. +   |------------|------------|   or   |xxxxxxxxxxxx|------------|   or   |xxxxxxxxxxxx|xxxxxxxxxxxx|
  1166. +   but we almost always get this
  1167. +   |xxxxxx------|------------|   or   |xxxxxxxxxxxx|xxxxx-------|
  1168. +   so we have to clear the tail space to "silence"
  1169. +   |xxxxxx000000|------------|   or   |xxxxxxxxxxxx|xxxxxx000000|
  1170. +*/
  1171. +static void trident_clear_tail(struct trident_state *state)
  1172. +{
  1173. +   struct dmabuf *dmabuf = &state->dmabuf;
  1174. +   unsigned swptr;
  1175. +   unsigned char silence = (dmabuf->fmt & TRIDENT_FMT_16BIT) ? 0 : 0x80;
  1176. +   unsigned int len;
  1177. +   unsigned long flags;
  1178. +
  1179. +   spin_lock_irqsave(&state->card->lock, flags);
  1180. +   swptr = dmabuf->swptr;
  1181. +   spin_unlock_irqrestore(&state->card->lock, flags);
  1182. +
  1183. +   if (swptr == 0 || swptr == dmabuf->dmasize / 2 || swptr == dmabuf->dmasize)
  1184. +      return;
  1185. +
  1186. +   if (swptr < dmabuf->dmasize/2)
  1187. +      len = dmabuf->dmasize/2 - swptr;
  1188. +   else
  1189. +      len = dmabuf->dmasize - swptr;
  1190. +
  1191. +   memset(dmabuf->rawbuf + swptr, silence, len);
  1192. +   if(state->card->pci_id != PCI_DEVICE_ID_ALI_5451)
  1193. +   {
  1194. +      spin_lock_irqsave(&state->card->lock, flags);
  1195. +      dmabuf->swptr += len;
  1196. +      dmabuf->count += len;
  1197. +      spin_unlock_irqrestore(&state->card->lock, flags);
  1198. +   }
  1199. +
  1200. +   /* restart the dma machine in case it is halted */
  1201. +   start_dac(state);
  1202. +}
  1203. +
  1204. +static int drain_dac(struct trident_state *state, int nonblock)
  1205. +{
  1206. +   DECLARE_WAITQUEUE(wait, current);
  1207. +   struct dmabuf *dmabuf = &state->dmabuf;
  1208. +   unsigned long flags;
  1209. +   unsigned long tmo;
  1210. +   int count;
  1211. +   unsigned long diff = 0;
  1212. +
  1213. +   if (dmabuf->mapped || !dmabuf->ready)
  1214. +      return 0;
  1215. +
  1216. +   add_wait_queue(&dmabuf->wait, &wait);
  1217. +   for (;;) {
  1218. +      /* It seems that we have to set the current state to TASK_INTERRUPTIBLE
  1219. +         every time to make the process really go to sleep */
  1220. +      current->state = TASK_INTERRUPTIBLE;
  1221. +
  1222. +      spin_lock_irqsave(&state->card->lock, flags);
  1223. +      count = dmabuf->count;
  1224. +      spin_unlock_irqrestore(&state->card->lock, flags);
  1225. +
  1226. +      if (count <= 0)
  1227. +         break;
  1228. +
  1229. +      if (signal_pending(current))
  1230. +         break;
  1231. +
  1232. +      if (nonblock) {
  1233. +         remove_wait_queue(&dmabuf->wait, &wait);
  1234. +         current->state = TASK_RUNNING;
  1235. +         return -EBUSY;
  1236. +      }
  1237. +
  1238. +      /* No matter how much data left in the buffer, we have to wait untill
  1239. +         CSO == ESO/2 or CSO == ESO when address engine interrupts */
  1240. +       if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451)
  1241. +      {  
  1242. +         diff = dmabuf->swptr - trident_get_dma_addr(state) + dmabuf->dmasize ;
  1243. +         diff = diff % (dmabuf->dmasize);
  1244. +         tmo  = (diff * HZ) / dmabuf->rate;
  1245. +      }
  1246. +      else
  1247. +      {
  1248. +         tmo = (dmabuf->dmasize * HZ) / dmabuf->rate;
  1249. +      }
  1250. +      tmo >>= sample_shift[dmabuf->fmt];
  1251. +//      printk("trident: diff=%d count= %d/%d total=%d tmo=%d hwptr=%d swptr=%d curptr=%d\n",diff,dmabuf->count,dmabuf->dmasi+
  1252. ze,dmabuf->total_bytes,tmo,dmabuf->hwptr,dmabuf->swptr,trident_get_dma_addr(state));
  1253. +      if (!schedule_timeout(tmo ? tmo : 1) && tmo){
  1254. +         break;
  1255. +      }
  1256. +   }
  1257. +   remove_wait_queue(&dmabuf->wait, &wait);
  1258. +   current->state = TASK_RUNNING;
  1259. +   if (signal_pending(current))
  1260. +      return -ERESTARTSYS;
  1261. +
  1262. +   return 0;
  1263. +}
  1264. +
  1265. +/* update buffer manangement pointers, especially, dmabuf->count and dmabuf->hwptr */
  1266. +static void trident_update_ptr(struct trident_state *state)
  1267. +{
  1268. +   struct dmabuf *dmabuf = &state->dmabuf;
  1269. +   unsigned hwptr, swptr;
  1270. +   int clear_cnt = 0;
  1271. +   int diff;
  1272. +   unsigned char silence;
  1273. +   unsigned half_dmasize;
  1274. +
  1275. +   /* update hardware pointer */
  1276. +   hwptr = trident_get_dma_addr(state);
  1277. +   diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
  1278. +   dmabuf->hwptr = hwptr;
  1279. +   dmabuf->total_bytes += diff;
  1280. +
  1281. +   /* error handling and process wake up for ADC */
  1282. +   if (dmabuf->enable == ADC_RUNNING) {
  1283. +      if (dmabuf->mapped) {
  1284. +         dmabuf->count -= diff;
  1285. +         if (dmabuf->count >= (signed)dmabuf->fragsize)
  1286. +            wake_up(&dmabuf->wait);
  1287. +      } else {
  1288. +         dmabuf->count += diff;
  1289. +
  1290. +         if (dmabuf->count < 0 || dmabuf->count > dmabuf->dmasize) {
  1291. +            /* buffer underrun or buffer overrun, we have no way to recover
  1292. +               it here, just stop the machine and let the process force hwptr
  1293. +               and swptr to sync */
  1294. +            __stop_adc(state);
  1295. +            dmabuf->error++;
  1296. +         }
  1297. +         if (dmabuf->count < (signed)dmabuf->dmasize/2)
  1298. +            wake_up(&dmabuf->wait);
  1299. +      }
  1300. +   }
  1301. +
  1302. +   /* error handling and process wake up for DAC */
  1303. +   if (dmabuf->enable == DAC_RUNNING) {
  1304. +      if (dmabuf->mapped) {
  1305. +         dmabuf->count += diff;
  1306. +         if (dmabuf->count >= (signed)dmabuf->fragsize)
  1307. +            wake_up(&dmabuf->wait);
  1308. +      } else {
  1309. +         dmabuf->count -= diff;
  1310. +
  1311. +         if (dmabuf->count < 0 || dmabuf->count > dmabuf->dmasize) {
  1312. +            /* buffer underrun or buffer overrun, we have no way to recover
  1313. +               it here, just stop the machine and let the process force hwptr
  1314. +               and swptr to sync */
  1315. +            __stop_dac(state);
  1316. +            dmabuf->error++;
  1317. +         }
  1318. +         else if (!dmabuf->endcleared) {
  1319. +            swptr = dmabuf->swptr;
  1320. +            silence = (dmabuf->fmt & TRIDENT_FMT_16BIT ? 0 : 0x80);
  1321. +            if (dmabuf->update_flag & ALI_ADDRESS_INT_UPDATE) {
  1322. +               /* We must clear end data of 1/2 dmabuf if needed.
  1323. +                  According to 1/2 algorithm of Address Engine Interrupt,
  1324. +                  check the validation of the data of half dmasize. */
  1325. +               half_dmasize = dmabuf->dmasize / 2;
  1326. +               if ((diff = hwptr - half_dmasize) < 0 )
  1327. +                  diff = hwptr;
  1328. +               if ((dmabuf->count + diff) < half_dmasize) {
  1329. +                  //there is invalid data in the end of half buffer
  1330. +                  if ((clear_cnt = half_dmasize - swptr) < 0)
  1331. +                     clear_cnt += half_dmasize;
  1332. +                  //clear the invalid data
  1333. +                  memset (dmabuf->rawbuf + swptr,
  1334. +                     silence, clear_cnt);
  1335. +                  if (state->chans_num == 6) {
  1336. +                  clear_cnt = clear_cnt / 2;
  1337. +                  swptr = swptr / 2;
  1338. +                     memset (state->other_states[0]->dmabuf.rawbuf + swptr,
  1339. +                        silence, clear_cnt);
  1340. +                     memset (state->other_states[1]->dmabuf.rawbuf + swptr,
  1341. +                        silence, clear_cnt);
  1342. +                     memset (state->other_states[2]->dmabuf.rawbuf + swptr,
  1343. +                        silence, clear_cnt);
  1344. +                     memset (state->other_states[3]->dmabuf.rawbuf + swptr,
  1345. +                        silence, clear_cnt);
  1346. +                  }
  1347. +                  dmabuf->endcleared = 1;
  1348. +               }
  1349. +            } else if (dmabuf->count < (signed) dmabuf->fragsize) {
  1350. +               clear_cnt = dmabuf->fragsize;
  1351. +               if ((swptr + clear_cnt) > dmabuf->dmasize)
  1352. +                  clear_cnt = dmabuf->dmasize - swptr;
  1353. +               memset (dmabuf->rawbuf + swptr, silence, clear_cnt);
  1354. +               if (state->chans_num == 6) {
  1355. +                  clear_cnt = clear_cnt / 2;
  1356. +                  swptr = swptr / 2;
  1357. +                  memset (state->other_states[0]->dmabuf.rawbuf + swptr,
  1358. +                     silence, clear_cnt);
  1359. +                  memset (state->other_states[1]->dmabuf.rawbuf + swptr,
  1360. +                     silence, clear_cnt);
  1361. +                  memset (state->other_states[2]->dmabuf.rawbuf + swptr,
  1362. +                     silence, clear_cnt);
  1363. +                  memset (state->other_states[3]->dmabuf.rawbuf + swptr,
  1364. +                     silence, clear_cnt);
  1365. +               }
  1366. +               dmabuf->endcleared = 1;
  1367. +            }
  1368. +         }
  1369. +         /* trident_update_ptr is called by interrupt handler or by process via
  1370. +            ioctl/poll, we only wake up the waiting process when we have more
  1371. +            than 1/2 buffer free (always true for interrupt handler) */
  1372. +         if (dmabuf->count < (signed)dmabuf->dmasize/2)
  1373. +            wake_up(&dmabuf->wait);
  1374. +      }
  1375. +   }
  1376. +   dmabuf->update_flag &= ~ALI_ADDRESS_INT_UPDATE;
  1377. +}
  1378. +
  1379. +static void trident_address_interrupt(struct trident_card *card)
  1380. +{
  1381. +   int i;
  1382. +   struct trident_state *state;
  1383. +  
  1384. +   /* Update the pointers for all channels we are running. */
  1385. +   /* FIXME: should read interrupt status only once */
  1386. +   for (i = 0; i < NR_HW_CH; i++) {
  1387. +      if (trident_check_channel_interrupt(card, 63 - i)) {
  1388. +         trident_ack_channel_interrupt(card, 63 - i);
  1389. +         if ((state = card->states[i]) != NULL) {
  1390. +            trident_update_ptr(state);
  1391. +         } else {
  1392. +            printk("trident: spurious channel irq %d.\n",
  1393. +                   63 - i);
  1394. +            trident_stop_voice(card, 63 - i);
  1395. +            trident_disable_voice_irq(card, 63 - i);
  1396. +         }
  1397. +      }
  1398. +   }
  1399. +}
  1400. +
  1401. +static void trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  1402. +{
  1403. +   struct trident_card *card = (struct trident_card *)dev_id;
  1404. +   u32 event;
  1405. +
  1406. +   spin_lock(&card->lock);
  1407. +   event = inl(TRID_REG(card, T4D_MISCINT));
  1408. +
  1409. +#ifdef DEBUG
  1410. +   printk("trident: trident_interrupt called, MISCINT = 0x%08x\n", event);
  1411. +#endif
  1412. +
  1413. +   if (event & ADDRESS_IRQ) {
  1414. +      card->address_interrupt(card);
  1415. +   }
  1416. +
  1417. +   /* manually clear interrupt status, bad hardware design, blame T^2 */
  1418. +   outl((ST_TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW),
  1419. +        TRID_REG(card, T4D_MISCINT));
  1420. +   spin_unlock(&card->lock);
  1421. +}
  1422. +
  1423. +static loff_t trident_llseek(struct file *file, loff_t offset, int origin)
  1424. +{
  1425. +   return -ESPIPE;
  1426. +}
  1427. +
  1428. +/* in this loop, dmabuf.count signifies the amount of data that is waiting to be copied to
  1429. +   the user's buffer.  it is filled by the dma machine and drained by this loop. */
  1430. +static ssize_t trident_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
  1431. +{
  1432. +   struct trident_state *state = (struct trident_state *)file->private_data;
  1433. +   struct dmabuf *dmabuf = &state->dmabuf;
  1434. +   ssize_t ret;
  1435. +   unsigned long flags;
  1436. +   unsigned swptr;
  1437. +   int cnt;
  1438. +
  1439. +#ifdef DEBUG
  1440. +   printk("trident: trident_read called, count = %d\n", count);
  1441. +#endif
  1442. +
  1443. +   VALIDATE_STATE(state);
  1444. +   if (ppos != &file->f_pos)
  1445. +      return -ESPIPE;
  1446. +   if (dmabuf->mapped)
  1447. +      return -ENXIO;
  1448. +   if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
  1449. +      return ret;
  1450. +   if (!access_ok(VERIFY_WRITE, buffer, count))
  1451. +      return -EFAULT;
  1452. +   ret = 0;
  1453. +
  1454. +   while (count > 0) {
  1455. +      spin_lock_irqsave(&state->card->lock, flags);
  1456. +      if (dmabuf->count > (signed) dmabuf->dmasize) {
  1457. +         /* buffer overrun, we are recovering from sleep_on_timeout,
  1458. +            resync hwptr and swptr, make process flush the buffer */
  1459. +         dmabuf->count = dmabuf->dmasize;
  1460. +         dmabuf->swptr = dmabuf->hwptr;
  1461. +      }
  1462. +      swptr = dmabuf->swptr;
  1463. +      cnt = dmabuf->dmasize - swptr;
  1464. +      if (dmabuf->count < cnt)
  1465. +         cnt = dmabuf->count;
  1466. +      spin_unlock_irqrestore(&state->card->lock, flags);
  1467. +
  1468. +      if (cnt > count)
  1469. +         cnt = count;
  1470. +      if (cnt <= 0) {
  1471. +         unsigned long tmo;
  1472. +         /* buffer is empty, start the dma machine and wait for data to be
  1473. +            recorded */
  1474. +         start_adc(state);
  1475. +         if (file->f_flags & O_NONBLOCK) {
  1476. +            if (!ret) ret = -EAGAIN;
  1477. +            return ret;
  1478. +         }
  1479. +         /* No matter how much space left in the buffer, we have to wait untill
  1480. +            CSO == ESO/2 or CSO == ESO when address engine interrupts */
  1481. +         tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
  1482. +         tmo >>= sample_shift[dmabuf->fmt];
  1483. +         /* There are two situations when sleep_on_timeout returns, one is when
  1484. +            the interrupt is serviced correctly and the process is waked up by
  1485. +            ISR ON TIME. Another is when timeout is expired, which means that
  1486. +            either interrupt is NOT serviced correctly (pending interrupt) or it
  1487. +            is TOO LATE for the process to be scheduled to run (scheduler latency)
  1488. +            which results in a (potential) buffer overrun. And worse, there is
  1489. +            NOTHING we can do to prevent it. */
  1490. +         if (!interruptible_sleep_on_timeout(&dmabuf->wait, tmo)) {
  1491. +#ifdef DEBUG
  1492. +            printk(KERN_ERR "trident: recording schedule timeout, "
  1493. +                   "dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
  1494. +                   dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
  1495. +                   dmabuf->hwptr, dmabuf->swptr);
  1496. +#endif
  1497. +            /* a buffer overrun, we delay the recovery untill next time the
  1498. +               while loop begin and we REALLY have space to record */
  1499. +         }
  1500. +         if (signal_pending(current)) {
  1501. +            ret = ret ? ret : -ERESTARTSYS;
  1502. +            return ret;
  1503. +         }
  1504. +         continue;
  1505. +      }
  1506. +
  1507. +      if (copy_to_user(buffer, dmabuf->rawbuf + swptr, cnt)) {
  1508. +         if (!ret) ret = -EFAULT;
  1509. +         return ret;
  1510. +      }
  1511. +
  1512. +      swptr = (swptr + cnt) % dmabuf->dmasize;
  1513. +
  1514. +      spin_lock_irqsave(&state->card->lock, flags);
  1515. +      dmabuf->swptr = swptr;
  1516. +      dmabuf->count -= cnt;
  1517. +      spin_unlock_irqrestore(&state->card->lock, flags);
  1518. +
  1519. +      count -= cnt;
  1520. +      buffer += cnt;
  1521. +      ret += cnt;
  1522. +      start_adc(state);
  1523. +   }
  1524. +   return ret;
  1525. +}
  1526. +
  1527. +/* in this loop, dmabuf.count signifies the amount of data that is waiting to be dma to
  1528. +   the soundcard.  it is drained by the dma machine and filled by this loop. */
  1529. +static ssize_t trident_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
  1530. +{
  1531. +   struct trident_state *state = (struct trident_state *)file->private_data;
  1532. +   struct dmabuf *dmabuf = &state->dmabuf;
  1533. +   ssize_t ret;
  1534. +   unsigned long flags;
  1535. +   unsigned swptr;
  1536. +   int cnt;
  1537. +   unsigned int state_cnt;
  1538. +   unsigned int copy_count;
  1539. +
  1540. +#ifdef DEBUG
  1541. +   printk("trident: trident_write called, count = %d\n", count);
  1542. +#endif
  1543. +   VALIDATE_STATE(state);
  1544. +   if (ppos != &file->f_pos)
  1545. +      return -ESPIPE;
  1546. +   if (dmabuf->mapped)
  1547. +      return -ENXIO;
  1548. +   if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
  1549. +      return ret;
  1550. +   if (!access_ok(VERIFY_READ, buffer, count))
  1551. +      return -EFAULT;
  1552. +   ret = 0;
  1553. +
  1554. +   while (count > 0) {
  1555. +      spin_lock_irqsave(&state->card->lock, flags);
  1556. +      if (dmabuf->count < 0) {
  1557. +         /* buffer underrun, we are recovering from sleep_on_timeout,
  1558. +            resync hwptr and swptr */
  1559. +         dmabuf->count = 0;
  1560. +         dmabuf->swptr = dmabuf->hwptr;
  1561. +      }
  1562. +      swptr = dmabuf->swptr;
  1563. +      cnt = dmabuf->dmasize - swptr;
  1564. +      if (dmabuf->count + cnt > dmabuf->dmasize)
  1565. +         cnt = dmabuf->dmasize - dmabuf->count;
  1566. +      spin_unlock_irqrestore(&state->card->lock, flags);
  1567. +
  1568. +      if (cnt > count)
  1569. +         cnt = count;
  1570. +      if (cnt <= 0) {
  1571. +         unsigned long tmo;
  1572. +         /* buffer is full, start the dma machine and wait for data to be
  1573. +            played */
  1574. +         start_dac(state);
  1575. +         if (file->f_flags & O_NONBLOCK) {
  1576. +            if (!ret) ret = -EAGAIN;
  1577. +            return ret;
  1578. +         }
  1579. +         /* No matter how much data left in the buffer, we have to wait untill
  1580. +            CSO == ESO/2 or CSO == ESO when address engine interrupts */
  1581. +         lock_set_fmt(state);
  1582. +         tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
  1583. +         tmo >>= sample_shift[dmabuf->fmt];
  1584. +         unlock_set_fmt(state);
  1585. +         /* There are two situations when sleep_on_timeout returns, one is when
  1586. +            the interrupt is serviced correctly and the process is waked up by
  1587. +            ISR ON TIME. Another is when timeout is expired, which means that
  1588. +            either interrupt is NOT serviced correctly (pending interrupt) or it
  1589. +            is TOO LATE for the process to be scheduled to run (scheduler latency)
  1590. +            which results in a (potential) buffer underrun. And worse, there is
  1591. +            NOTHING we can do to prevent it. */
  1592. +         if (!interruptible_sleep_on_timeout(&dmabuf->wait, tmo)) {
  1593. +#ifdef DEBUG
  1594. +            printk(KERN_ERR "trident: playback schedule timeout, "
  1595. +                   "dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
  1596. +                   dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
  1597. +                   dmabuf->hwptr, dmabuf->swptr);
  1598. +#endif
  1599. +            /* a buffer underrun, we delay the recovery untill next time the
  1600. +               while loop begin and we REALLY have data to play */
  1601. +         }
  1602. +         if (signal_pending(current)) {
  1603. +            if (!ret) ret = -ERESTARTSYS;
  1604. +            return ret;
  1605. +         }
  1606. +         continue;
  1607. +      }
  1608. +      lock_set_fmt(state);
  1609. +      if (state->chans_num == 6) {
  1610. +         copy_count = 0;
  1611. +         state_cnt = 0;
  1612. +         if (ali_write_5_1(state, buffer, cnt, &copy_count, &state_cnt) == -EFAULT) {
  1613. +            if (state_cnt){
  1614. +               swptr = (swptr + state_cnt) % dmabuf->dmasize;
  1615. +               spin_lock_irqsave(&state->card->lock, flags);
  1616. +               dmabuf->swptr = swptr;
  1617. +               dmabuf->count += state_cnt;
  1618. +               dmabuf->endcleared = 0;
  1619. +               spin_unlock_irqrestore(&state->card->lock, flags);
  1620. +            }
  1621. +            ret += copy_count;
  1622. +            if (!ret) ret = -EFAULT;
  1623. +            unlock_set_fmt(state);
  1624. +            return ret;
  1625. +         }
  1626. +      }
  1627. +      else {
  1628. +         if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) {
  1629. +            if (!ret) ret = -EFAULT;
  1630. +            unlock_set_fmt(state);
  1631. +            return ret;
  1632. +         }
  1633. +         state_cnt = cnt;
  1634. +      }
  1635. +      unlock_set_fmt(state);
  1636. +      
  1637. +      swptr = (swptr + state_cnt) % dmabuf->dmasize;      
  1638. +      
  1639. +      spin_lock_irqsave(&state->card->lock, flags);
  1640. +      dmabuf->swptr = swptr;
  1641. +      dmabuf->count += state_cnt;
  1642. +      dmabuf->endcleared = 0;
  1643. +      spin_unlock_irqrestore(&state->card->lock, flags);
  1644. +
  1645. +      count -= cnt;
  1646. +      buffer += cnt;  
  1647. +      ret += cnt;
  1648. +      start_dac(state);
  1649. +   }
  1650. +   return ret;
  1651. +}
  1652. +
  1653. +/* No kernel lock - we have our own spinlock */
  1654. +static unsigned int trident_poll(struct file *file, struct poll_table_struct *wait)
  1655. +{
  1656. +   struct trident_state *state = (struct trident_state *)file->private_data;
  1657. +   struct dmabuf *dmabuf = &state->dmabuf;
  1658. +   unsigned long flags;
  1659. +   unsigned int mask = 0;
  1660. +
  1661. +   VALIDATE_STATE(state);
  1662. +   if (file->f_mode & FMODE_WRITE)
  1663. +      poll_wait(file, &dmabuf->wait, wait);
  1664. +   if (file->f_mode & FMODE_READ)
  1665. +      poll_wait(file, &dmabuf->wait, wait);
  1666. +
  1667. +   spin_lock_irqsave(&state->card->lock, flags);
  1668. +   trident_update_ptr(state);
  1669. +   if (file->f_mode & FMODE_READ) {
  1670. +      if (dmabuf->count >= (signed)dmabuf->fragsize)
  1671. +         mask |= POLLIN | POLLRDNORM;
  1672. +   }
  1673. +   if (file->f_mode & FMODE_WRITE) {
  1674. +      if (dmabuf->mapped) {
  1675. +         if (dmabuf->count >= (signed)dmabuf->fragsize)
  1676. +            mask |= POLLOUT | POLLWRNORM;
  1677. +      } else {
  1678. +         if ((signed)dmabuf->dmasize >= dmabuf->count + (signed)dmabuf->fragsize)
  1679. +            mask |= POLLOUT | POLLWRNORM;
  1680. +      }
  1681. +   }
  1682. +   spin_unlock_irqrestore(&state->card->lock, flags);
  1683. +
  1684. +   return mask;
  1685. +}
  1686. +
  1687. +static int trident_mmap(struct file *file, struct vm_area_struct *vma)
  1688. +{
  1689. +   struct trident_state *state = (struct trident_state *)file->private_data;
  1690. +   struct dmabuf *dmabuf = &state->dmabuf;
  1691. +   int ret = -EINVAL;
  1692. +   unsigned long size;
  1693. +
  1694. +   VALIDATE_STATE(state);
  1695. +   lock_kernel();
  1696. +   if (vma->vm_flags & VM_WRITE) {
  1697. +      if ((ret = prog_dmabuf(state, 0)) != 0)
  1698. +         goto out;
  1699. +   } else if (vma->vm_flags & VM_READ) {
  1700. +      if ((ret = prog_dmabuf(state, 1)) != 0)
  1701. +         goto out;
  1702. +   } else
  1703. +      goto out;
  1704. +
  1705. +   ret = -EINVAL;
  1706. +   if (vma->vm_pgoff != 0)
  1707. +      goto out;
  1708. +   size = vma->vm_end - vma->vm_start;
  1709. +   if (size > (PAGE_SIZE << dmabuf->buforder))
  1710. +      goto out;
  1711. +   ret = -EAGAIN;
  1712. +   if (remap_page_range(vma->vm_start, virt_to_phys(dmabuf->rawbuf),
  1713. +              size, vma->vm_page_prot))
  1714. +      goto out;
  1715. +   dmabuf->mapped = 1;
  1716. +   ret = 0;
  1717. +out:
  1718. +   unlock_kernel();
  1719. +   return ret;
  1720. +}
  1721. +
  1722. +static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  1723. +{
  1724. +   struct trident_state *state = (struct trident_state *)file->private_data;
  1725. +   struct dmabuf *dmabuf = &state->dmabuf;
  1726. +   unsigned long flags;
  1727. +   audio_buf_info abinfo;
  1728. +   count_info cinfo;
  1729. +   int val, mapped, ret;
  1730. +
  1731. +   struct trident_card *card = state->card;
  1732. +
  1733. +   VALIDATE_STATE(state);
  1734. +   mapped = ((file->f_mode & FMODE_WRITE) && dmabuf->mapped) ||
  1735. +      ((file->f_mode & FMODE_READ) && dmabuf->mapped);
  1736. +#ifdef DEBUG
  1737. +   printk("trident: trident_ioctl, command = %2d, arg = 0x%08x\n",
  1738. +          _IOC_NR(cmd), arg ? *(int *)arg : 0);
  1739. +#endif
  1740. +
  1741. +   switch (cmd)
  1742. +   {
  1743. +   case OSS_GETVERSION:
  1744. +      return put_user(SOUND_VERSION, (int *)arg);
  1745. +
  1746. +   case SNDCTL_DSP_RESET:
  1747. +      /* FIXME: spin_lock ? */
  1748. +      if (file->f_mode & FMODE_WRITE) {
  1749. +         stop_dac(state);
  1750. +         synchronize_irq();
  1751. +         dmabuf->ready = 0;
  1752. +         dmabuf->swptr = dmabuf->hwptr = 0;
  1753. +         dmabuf->count = dmabuf->total_bytes = 0;
  1754. +      }
  1755. +      if (file->f_mode & FMODE_READ) {
  1756. +         stop_adc(state);
  1757. +         synchronize_irq();
  1758. +         dmabuf->ready = 0;
  1759. +         dmabuf->swptr = dmabuf->hwptr = 0;
  1760. +         dmabuf->count = dmabuf->total_bytes = 0;
  1761. +      }
  1762. +      return 0;
  1763. +
  1764. +   case SNDCTL_DSP_SYNC:
  1765. +      if (file->f_mode & FMODE_WRITE)
  1766. +         return drain_dac(state, file->f_flags & O_NONBLOCK);
  1767. +      return 0;
  1768. +
  1769. +   case SNDCTL_DSP_SPEED: /* set smaple rate */
  1770. +      if (get_user(val, (int *)arg))
  1771. +         return -EFAULT;
  1772. +      if (val >= 0) {
  1773. +         if (file->f_mode & FMODE_WRITE) {
  1774. +            stop_dac(state);
  1775. +            dmabuf->ready = 0;
  1776. +            spin_lock_irqsave(&state->card->lock, flags);
  1777. +            trident_set_dac_rate(state, val);
  1778. +            spin_unlock_irqrestore(&state->card->lock, flags);
  1779. +         }
  1780. +         if (file->f_mode & FMODE_READ) {
  1781. +            stop_adc(state);
  1782. +            dmabuf->ready = 0;
  1783. +            spin_lock_irqsave(&state->card->lock, flags);
  1784. +            trident_set_adc_rate(state, val);
  1785. +            spin_unlock_irqrestore(&state->card->lock, flags);
  1786. +         }
  1787. +      }
  1788. +      return put_user(dmabuf->rate, (int *)arg);
  1789. +
  1790. +   case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
  1791. +      if (get_user(val, (int *)arg))
  1792. +         return -EFAULT;
  1793. +      lock_set_fmt(state);
  1794. +      if (file->f_mode & FMODE_WRITE) {
  1795. +         stop_dac(state);
  1796. +         dmabuf->ready = 0;
  1797. +         if (val)
  1798. +            dmabuf->fmt |= TRIDENT_FMT_STEREO;
  1799. +         else
  1800. +            dmabuf->fmt &= ~TRIDENT_FMT_STEREO;
  1801. +      }
  1802. +      if (file->f_mode & FMODE_READ) {
  1803. +         stop_adc(state);
  1804. +         dmabuf->ready = 0;
  1805. +         if (val)
  1806. +            dmabuf->fmt |= TRIDENT_FMT_STEREO;
  1807. +         else
  1808. +            dmabuf->fmt &= ~TRIDENT_FMT_STEREO;
  1809. +      }
  1810. +      unlock_set_fmt(state);
  1811. +      return 0;
  1812. +
  1813. +   case SNDCTL_DSP_GETBLKSIZE:
  1814. +      if (file->f_mode & FMODE_WRITE) {
  1815. +         if ((val = prog_dmabuf(state, 0)))
  1816. +            return val;
  1817. +         return put_user(dmabuf->fragsize, (int *)arg);
  1818. +      }
  1819. +      if (file->f_mode & FMODE_READ) {
  1820. +         if ((val = prog_dmabuf(state, 1)))
  1821. +            return val;
  1822. +         return put_user(dmabuf->fragsize, (int *)arg);
  1823. +      }
  1824. +
  1825. +   case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format*/
  1826. +      return put_user(AFMT_S16_LE|AFMT_U16_LE|AFMT_S8|AFMT_U8, (int *)arg);
  1827. +
  1828. +   case SNDCTL_DSP_SETFMT: /* Select sample format */
  1829. +      if (get_user(val, (int *)arg))
  1830. +         return -EFAULT;
  1831. +      lock_set_fmt(state);
  1832. +      if (val != AFMT_QUERY) {
  1833. +         if (file->f_mode & FMODE_WRITE) {
  1834. +            stop_dac(state);
  1835. +            dmabuf->ready = 0;
  1836. +            if (val == AFMT_S16_LE)
  1837. +               dmabuf->fmt |= TRIDENT_FMT_16BIT;
  1838. +            else
  1839. +               dmabuf->fmt &= ~TRIDENT_FMT_16BIT;
  1840. +         }
  1841. +         if (file->f_mode & FMODE_READ) {
  1842. +            stop_adc(state);
  1843. +            dmabuf->ready = 0;
  1844. +            if (val == AFMT_S16_LE)
  1845. +               dmabuf->fmt |= TRIDENT_FMT_16BIT;
  1846. +            else
  1847. +               dmabuf->fmt &= ~TRIDENT_FMT_16BIT;
  1848. +         }
  1849. +      }
  1850. +      unlock_set_fmt(state);
  1851. +      return put_user((dmabuf->fmt & TRIDENT_FMT_16BIT) ?
  1852. +            AFMT_S16_LE : AFMT_U8, (int *)arg);
  1853. +
  1854. +   case SNDCTL_DSP_CHANNELS:
  1855. +      if (get_user(val, (int *)arg))
  1856. +         return -EFAULT;
  1857. +      if (val != 0) {
  1858. +         lock_set_fmt(state);
  1859. +         if (file->f_mode & FMODE_WRITE) {
  1860. +            stop_dac(state);
  1861. +            dmabuf->ready = 0;
  1862. +                        
  1863. +            //prevent from memory leak
  1864. +            if ((state->chans_num > 2) && (state->chans_num != val)) {
  1865. +               ali_free_other_states_resources(state);
  1866. +               state->chans_num = 1;
  1867. +            }
  1868. +            
  1869. +            if (val >= 2)
  1870. +            {
  1871. +
  1872. +               dmabuf->fmt |= TRIDENT_FMT_STEREO;
  1873. +               if ((val == 6) && (state->card->pci_id == PCI_DEVICE_ID_ALI_5451)) {
  1874. +
  1875. +                  if( card->rec_channel_use_count > 0 )
  1876. +                  {
  1877. +                     printk("Err: Record is working on the card!\n");
  1878. +                     return -EBUSY;
  1879. +                  }
  1880. +
  1881. +                  ret = ali_setup_multi_channels(state->card, 6);
  1882. +                  if (ret < 0) {
  1883. +                     unlock_set_fmt(state);
  1884. +                     return ret;
  1885. +                  }
  1886. +                  down(&state->card->open_sem);
  1887. +                  ret = ali_allocate_other_states_resources(state, 6);
  1888. +                  up(&state->card->open_sem);
  1889. +                  if (ret < 0) {
  1890. +                     unlock_set_fmt(state);
  1891. +                     return ret;
  1892. +                  }
  1893. +                  //Added by Matt Wu
  1894. +                  state->card->multi_channel_use_count ++;
  1895. +                  //End add
  1896. +               }
  1897. +               else val = 2;   /*yield to 2-channels*/
  1898. +            }
  1899. +            else
  1900. +               dmabuf->fmt &= ~TRIDENT_FMT_STEREO;
  1901. +            state->chans_num = val;
  1902. +         }
  1903. +         if (file->f_mode & FMODE_READ) {
  1904. +            stop_adc(state);
  1905. +            dmabuf->ready = 0;
  1906. +            if (val >= 2) {
  1907. +               if (!((file->f_mode & FMODE_WRITE) && (val == 6)))
  1908. +                  val = 2;
  1909. +               dmabuf->fmt |= TRIDENT_FMT_STEREO;
  1910. +            }
  1911. +            else
  1912. +               dmabuf->fmt &= ~TRIDENT_FMT_STEREO;
  1913. +            state->chans_num = val;
  1914. +         }
  1915. +         unlock_set_fmt(state);
  1916. +      }
  1917. +      return put_user(val, (int *)arg);
  1918. +
  1919. +   case SNDCTL_DSP_POST:
  1920. +      /* FIXME: the same as RESET ?? */
  1921. +      return 0;
  1922. +
  1923. +   case SNDCTL_DSP_SUBDIVIDE:
  1924. +      if (dmabuf->subdivision)
  1925. +         return -EINVAL;
  1926. +      if (get_user(val, (int *)arg))
  1927. +         return -EFAULT;
  1928. +      if (val != 1 && val != 2 && val != 4)
  1929. +         return -EINVAL;
  1930. +      dmabuf->subdivision = val;
  1931. +      return 0;
  1932. +
  1933. +   case SNDCTL_DSP_SETFRAGMENT:
  1934. +      if (get_user(val, (int *)arg))
  1935. +         return -EFAULT;
  1936. +
  1937. +      dmabuf->ossfragshift = val & 0xffff;
  1938. +      dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
  1939. +      if (dmabuf->ossfragshift < 4)
  1940. +         dmabuf->ossfragshift = 4;
  1941. +      if (dmabuf->ossfragshift > 15)
  1942. +         dmabuf->ossfragshift = 15;
  1943. +      if (dmabuf->ossmaxfrags < 4)
  1944. +         dmabuf->ossmaxfrags = 4;
  1945. +
  1946. +      return 0;
  1947. +
  1948. +   case SNDCTL_DSP_GETOSPACE:
  1949. +      if (!(file->f_mode & FMODE_WRITE))
  1950. +         return -EINVAL;
  1951. +      if (!dmabuf->enable && (val = prog_dmabuf(state, 0)) != 0)
  1952. +         return val;
  1953. +      spin_lock_irqsave(&state->card->lock, flags);
  1954. +      trident_update_ptr(state);
  1955. +      abinfo.fragsize = dmabuf->fragsize;
  1956. +      abinfo.bytes = dmabuf->dmasize - dmabuf->count;
  1957. +      abinfo.fragstotal = dmabuf->numfrag;
  1958. +      abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
  1959. +      spin_unlock_irqrestore(&state->card->lock, flags);
  1960. +      return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
  1961. +
  1962. +   case SNDCTL_DSP_GETISPACE:
  1963. +      if (!(file->f_mode & FMODE_READ))
  1964. +         return -EINVAL;
  1965. +      if (!dmabuf->enable && (val = prog_dmabuf(state, 1)) != 0)
  1966. +         return val;
  1967. +      spin_lock_irqsave(&state->card->lock, flags);
  1968. +      trident_update_ptr(state);
  1969. +      abinfo.fragsize = dmabuf->fragsize;
  1970. +      abinfo.bytes = dmabuf->count;
  1971. +      abinfo.fragstotal = dmabuf->numfrag;
  1972. +      abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
  1973. +      spin_unlock_irqrestore(&state->card->lock, flags);
  1974. +      return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
  1975. +
  1976. +   case SNDCTL_DSP_NONBLOCK:
  1977. +      file->f_flags |= O_NONBLOCK;
  1978. +      return 0;
  1979. +
  1980. +   case SNDCTL_DSP_GETCAPS:
  1981. +       return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP|DSP_CAP_BIND,
  1982. +             (int *)arg);
  1983. +
  1984. +   case SNDCTL_DSP_GETTRIGGER:
  1985. +      val = 0;
  1986. +      if (file->f_mode & FMODE_READ && dmabuf->enable)
  1987. +         val |= PCM_ENABLE_INPUT;
  1988. +      if (file->f_mode & FMODE_WRITE && dmabuf->enable)
  1989. +         val |= PCM_ENABLE_OUTPUT;
  1990. +      return put_user(val, (int *)arg);
  1991. +
  1992. +   case SNDCTL_DSP_SETTRIGGER:
  1993. +      if (get_user(val, (int *)arg))
  1994. +         return -EFAULT;
  1995. +      if (file->f_mode & FMODE_READ) {
  1996. +         if (val & PCM_ENABLE_INPUT) {
  1997. +            if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
  1998. +               return ret;
  1999. +            start_adc(state);
  2000. +         } else
  2001. +            stop_adc(state);
  2002. +      }
  2003. +      if (file->f_mode & FMODE_WRITE) {
  2004. +         if (val & PCM_ENABLE_OUTPUT) {
  2005. +            if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
  2006. +               return ret;
  2007. +            start_dac(state);
  2008. +         } else
  2009. +            stop_dac(state);
  2010. +      }
  2011. +      return 0;
  2012. +
  2013. +   case SNDCTL_DSP_GETIPTR:
  2014. +      if (!(file->f_mode & FMODE_READ))
  2015. +         return -EINVAL;
  2016. +      spin_lock_irqsave(&state->card->lock, flags);
  2017. +      trident_update_ptr(state);
  2018. +      cinfo.bytes = dmabuf->total_bytes;
  2019. +      cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
  2020. +      cinfo.ptr = dmabuf->hwptr;
  2021. +      if (dmabuf->mapped)
  2022. +         dmabuf->count &= dmabuf->fragsize-1;
  2023. +      spin_unlock_irqrestore(&state->card->lock, flags);
  2024. +      return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
  2025. +
  2026. +   case SNDCTL_DSP_GETOPTR:
  2027. +      if (!(file->f_mode & FMODE_WRITE))
  2028. +         return -EINVAL;
  2029. +      spin_lock_irqsave(&state->card->lock, flags);
  2030. +      trident_update_ptr(state);
  2031. +      cinfo.bytes = dmabuf->total_bytes;
  2032. +      cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
  2033. +      cinfo.ptr = dmabuf->hwptr;
  2034. +      if (dmabuf->mapped)
  2035. +         dmabuf->count &= dmabuf->fragsize-1;
  2036. +      spin_unlock_irqrestore(&state->card->lock, flags);
  2037. +      return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
  2038. +
  2039. +   case SNDCTL_DSP_SETDUPLEX:
  2040. +      return -EINVAL;
  2041. +
  2042. +   case SNDCTL_DSP_GETODELAY:
  2043. +      if (!(file->f_mode & FMODE_WRITE))
  2044. +         return -EINVAL;
  2045. +      spin_lock_irqsave(&state->card->lock, flags);
  2046. +      trident_update_ptr(state);
  2047. +      val = dmabuf->count;
  2048. +      spin_unlock_irqrestore(&state->card->lock, flags);
  2049. +      return put_user(val, (int *)arg);
  2050. +
  2051. +   case SOUND_PCM_READ_RATE:
  2052. +      return put_user(dmabuf->rate, (int *)arg);
  2053. +
  2054. +   case SOUND_PCM_READ_CHANNELS:
  2055. +      return put_user((dmabuf->fmt & TRIDENT_FMT_STEREO) ? 2 : 1,
  2056. +            (int *)arg);
  2057. +
  2058. +   case SOUND_PCM_READ_BITS:
  2059. +      return put_user((dmabuf->fmt & TRIDENT_FMT_16BIT) ?
  2060. +            AFMT_S16_LE : AFMT_U8, (int *)arg);
  2061. +
  2062. +   case SNDCTL_DSP_GETCHANNELMASK:
  2063. +      return put_user(DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE,
  2064. +            (int *)arg);
  2065. +
  2066. +   case SNDCTL_DSP_BIND_CHANNEL:
  2067. +      if (state->card->pci_id != PCI_DEVICE_ID_SI_7018)
  2068. +         return -EINVAL;
  2069. +
  2070. +      if (get_user(val, (int *)arg))
  2071. +         return -EFAULT;
  2072. +      if (val == DSP_BIND_QUERY) {
  2073. +         val = dmabuf->channel->attribute | 0x3c00;
  2074. +         val = attr2mask[val >> 8];
  2075. +      } else {
  2076. +         dmabuf->ready = 0;
  2077. +         if (file->f_mode & FMODE_READ)
  2078. +            dmabuf->channel->attribute = (CHANNEL_REC|SRC_ENABLE);
  2079. +         if (file->f_mode & FMODE_WRITE)
  2080. +            dmabuf->channel->attribute = (CHANNEL_SPC_PB|SRC_ENABLE);
  2081. +         dmabuf->channel->attribute |= mask2attr[ffs(val)];
  2082. +      }
  2083. +      return put_user(val, (int *)arg);
  2084. +
  2085. +   case SNDCTL_DSP_MAPINBUF:
  2086. +   case SNDCTL_DSP_MAPOUTBUF:
  2087. +   case SNDCTL_DSP_SETSYNCRO:
  2088. +   case SOUND_PCM_WRITE_FILTER:
  2089. +   case SOUND_PCM_READ_FILTER:
  2090. +      return -EINVAL;
  2091. +      
  2092. +   }
  2093. +   return -EINVAL;
  2094. +}
  2095. +
  2096. +static int trident_open(struct inode *inode, struct file *file)
  2097. +{
  2098. +   int i = 0;
  2099. +   int minor = MINOR(inode->i_rdev);
  2100. +   struct trident_card *card = devs;
  2101. +   struct trident_state *state = NULL;
  2102. +   struct dmabuf *dmabuf = NULL;
  2103. +  
  2104. +   //Add by Matt Wu 01-05-2001
  2105. +   if(file->f_mode & FMODE_READ)
  2106. +   {
  2107. +      if (card->multi_channel_use_count > 0)
  2108. +      {
  2109. +         printk("Err: The card is now set as multi_channels mode!\n");
  2110. +         return -EBUSY;
  2111. +      }
  2112. +   }
  2113. +   //End add
  2114. +
  2115. +   /* find an avaiable virtual channel (instance of /dev/dsp) */
  2116. +   while (card != NULL) {
  2117. +      down(&card->open_sem);
  2118. +      for (i = 0; i < NR_HW_CH; i++) {
  2119. +         if (card->states[i] == NULL) {
  2120. +            state = card->states[i] = (struct trident_state *)
  2121. +               kmalloc(sizeof(struct trident_state), GFP_KERNEL);
  2122. +            if (state == NULL) {
  2123. +               return -ENOMEM;
  2124. +            }
  2125. +            memset(state, 0, sizeof(struct trident_state));
  2126. +            dmabuf = &state->dmabuf;
  2127. +            goto found_virt;
  2128. +         }
  2129. +      }
  2130. +      up(&card->open_sem);
  2131. +      card = card->next;
  2132. +   }
  2133. +   /* no more virtual channel avaiable */
  2134. +   if (!state) {
  2135. +      return -ENODEV;
  2136. +   }
  2137. + found_virt:
  2138. +   /* found a free virtual channel, allocate hardware channels */
  2139. +   if(file->f_mode & FMODE_READ)
  2140. +      dmabuf->channel = card->alloc_rec_pcm_channel(card);
  2141. +   else
  2142. +      dmabuf->channel = card->alloc_pcm_channel(card);
  2143. +      
  2144. +   if (dmabuf->channel == NULL) {
  2145. +      kfree (card->states[i]);
  2146. +      card->states[i] = NULL;
  2147. +      return -ENODEV;
  2148. +   }
  2149. +
  2150. +   /* initialize the virtual channel */
  2151. +   state->virt = i;
  2152. +   state->card = card;
  2153. +   state->magic = TRIDENT_STATE_MAGIC;
  2154. +   init_waitqueue_head(&dmabuf->wait);
  2155. +   file->private_data = state;
  2156. +
  2157. +   /* set default sample format. According to OSS Programmer's Guide  /dev/dsp
  2158. +      should be default to unsigned 8-bits, mono, with sample rate 8kHz and
  2159. +      /dev/dspW will accept 16-bits sample */
  2160. +   if (file->f_mode & FMODE_WRITE) {
  2161. +      dmabuf->fmt &= ~TRIDENT_FMT_MASK;
  2162. +      if ((minor & 0x0f) == SND_DEV_DSP16)
  2163. +         dmabuf->fmt |= TRIDENT_FMT_16BIT;
  2164. +      dmabuf->ossfragshift = 0;
  2165. +      dmabuf->ossmaxfrags  = 0;
  2166. +      dmabuf->subdivision  = 0;
  2167. +      if (card->pci_id == PCI_DEVICE_ID_SI_7018) {
  2168. +         /* set default channel attribute to normal playback */
  2169. +         dmabuf->channel->attribute = CHANNEL_PB;
  2170. +      }
  2171. +      trident_set_dac_rate(state, 8000);
  2172. +   }
  2173. +
  2174. +   if (file->f_mode & FMODE_READ) {
  2175. +      
  2176. +      /* FIXME: Trident 4d can only record in signed 16-bits stereo, 48kHz sample,
  2177. +         to be dealed with in trident_set_adc_rate() ?? */
  2178. +      dmabuf->fmt &= ~TRIDENT_FMT_MASK;
  2179. +      if ((minor & 0x0f) == SND_DEV_DSP16)
  2180. +         dmabuf->fmt |= TRIDENT_FMT_16BIT;
  2181. +      dmabuf->ossfragshift = 0;
  2182. +      dmabuf->ossmaxfrags  = 0;
  2183. +      dmabuf->subdivision  = 0;
  2184. +      if (card->pci_id == PCI_DEVICE_ID_SI_7018) {
  2185. +         /* set default channel attribute to 0x8a80, record from
  2186. +            PCM L/R FIFO and mono = (left + right + 1)/2*/
  2187. +         dmabuf->channel->attribute =
  2188. +            (CHANNEL_REC|PCM_LR|MONO_MIX);
  2189. +      }
  2190. +      trident_set_adc_rate(state, 8000);
  2191. +
  2192. +      //Add by Matt Wu 01-05-2001
  2193. +      card->rec_channel_use_count ++;
  2194. +      //End add
  2195. +
  2196. +   }
  2197. +
  2198. +   state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
  2199. +   up(&card->open_sem);
  2200. +
  2201. +#ifdef DEBUG
  2202. +       printk(KERN_ERR "trident: open virtual channel %d, hard channel %d\n",
  2203. +              state->virt, dmabuf->channel->num);
  2204. +#endif
  2205. +
  2206. +   return 0;
  2207. +}
  2208. +
  2209. +static int trident_release(struct inode *inode, struct file *file)
  2210. +{
  2211. +   struct trident_state *state = (struct trident_state *)file->private_data;
  2212. +   struct trident_card *card;
  2213. +   struct dmabuf *dmabuf;
  2214. +   unsigned long flags;
  2215. +
  2216. +   lock_kernel();
  2217. +   card = state->card;
  2218. +   dmabuf = &state->dmabuf;
  2219. +   VALIDATE_STATE(state);
  2220. +
  2221. +   if (file->f_mode & FMODE_WRITE) {
  2222. +      trident_clear_tail(state);
  2223. +      drain_dac(state, file->f_flags & O_NONBLOCK);
  2224. +   }
  2225. +
  2226. +   /* stop DMA state machine and free DMA buffers/channels */
  2227. +   down(&card->open_sem);
  2228. +
  2229. +   if (file->f_mode & FMODE_WRITE) {
  2230. +      stop_dac(state);
  2231. +      lock_set_fmt(state);
  2232. +
  2233. +      unlock_set_fmt(state);
  2234. +      dealloc_dmabuf(state);
  2235. +      state->card->free_pcm_channel(state->card, dmabuf->channel->num);
  2236. +
  2237. +      //Added by Matt Wu
  2238. +      if (state->chans_num > 2)
  2239. +      {
  2240. +         if( card->multi_channel_use_count-- < 0 )
  2241. +            card->multi_channel_use_count = 0;
  2242. +
  2243. +         if (card->multi_channel_use_count == 0)
  2244. +            ali_close_multi_channels();
  2245. +
  2246. +         ali_free_other_states_resources(state);
  2247. +      }
  2248. +      //End add
  2249. +
  2250. +   }
  2251. +   if (file->f_mode & FMODE_READ) {
  2252. +      stop_adc(state);
  2253. +      dealloc_dmabuf(state);
  2254. +      state->card->free_pcm_channel(state->card, dmabuf->channel->num);
  2255. +
  2256. +      //Added by Matt Wu
  2257. +      if( card->rec_channel_use_count-- < 0 )
  2258. +         card->rec_channel_use_count = 0;
  2259. +      //End add
  2260. +
  2261. +   }
  2262. +
  2263. +   card->states[state->virt] = NULL;
  2264. +   kfree(state);
  2265. +
  2266. +   /* we're covered by the open_sem */
  2267. +   up(&card->open_sem);
  2268. +   unlock_kernel();
  2269. +
  2270. +   return 0;
  2271. +}
  2272. +
  2273. +static /*const*/ struct file_operations trident_audio_fops = {
  2274. +   owner:      THIS_MODULE,
  2275. +   llseek:      trident_llseek,
  2276. +   read:      trident_read,
  2277. +   write:      trident_write,
  2278. +   poll:      trident_poll,
  2279. +   ioctl:      trident_ioctl,
  2280. +   mmap:      trident_mmap,
  2281. +   open:      trident_open,
  2282. +   release:   trident_release,
  2283. +};
  2284. +
  2285. +/* trident specific AC97 functions */
  2286. +/* Write AC97 codec registers */
  2287. +static void trident_ac97_set(struct ac97_codec *codec, u8 reg, u16 val)
  2288. +{
  2289. +   struct trident_card *card = (struct trident_card *)codec->private_data;
  2290. +   unsigned int address, mask, busy;
  2291. +   unsigned short count  = 0xffff;
  2292. +   unsigned long flags;
  2293. +   u32 data;
  2294. +
  2295. +   data = ((u32) val) << 16;
  2296. +
  2297. +   switch (card->pci_id)
  2298. +   {
  2299. +   default:
  2300. +   case PCI_DEVICE_ID_SI_7018:
  2301. +      address = SI_AC97_WRITE;
  2302. +      mask = SI_AC97_BUSY_WRITE | SI_AC97_AUDIO_BUSY;
  2303. +      if (codec->id)
  2304. +         mask |= SI_AC97_SECONDARY;
  2305. +      busy = SI_AC97_BUSY_WRITE;
  2306. +      break;
  2307. +   case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
  2308. +      address = DX_ACR0_AC97_W;
  2309. +      mask = busy = DX_AC97_BUSY_WRITE;
  2310. +      break;
  2311. +   case PCI_DEVICE_ID_TRIDENT_4DWAVE_NX:
  2312. +      address = NX_ACR1_AC97_W;
  2313. +      mask = NX_AC97_BUSY_WRITE;
  2314. +      if (codec->id)
  2315. +         mask |= NX_AC97_WRITE_SECONDARY;
  2316. +      busy = NX_AC97_BUSY_WRITE;
  2317. +      break;
  2318. +   }
  2319. +
  2320. +   spin_lock_irqsave(&card->lock, flags);
  2321. +   do {
  2322. +      if ((inw(TRID_REG(card, address)) & busy) == 0)
  2323. +         break;
  2324. +   } while (count--);
  2325. +
  2326. +
  2327. +   data |= (mask | (reg & AC97_REG_ADDR));
  2328. +
  2329. +   if (count == 0) {
  2330. +      printk(KERN_ERR "trident: AC97 CODEC write timed out.\n");
  2331. +      spin_unlock_irqrestore(&card->lock, flags);
  2332. +      return;
  2333. +   }
  2334. +
  2335. +   outl(data, TRID_REG(card, address));
  2336. +   spin_unlock_irqrestore(&card->lock, flags);
  2337. +}
  2338. +
  2339. +/* Read AC97 codec registers */
  2340. +static u16 trident_ac97_get(struct ac97_codec *codec, u8 reg)
  2341. +{
  2342. +   struct trident_card *card = (struct trident_card *)codec->private_data;
  2343. +   unsigned int address, mask, busy;
  2344. +   unsigned short count = 0xffff;
  2345. +   unsigned long flags;
  2346. +   u32 data;
  2347. +
  2348. +   switch (card->pci_id)
  2349. +   {
  2350. +   default:
  2351. +   case PCI_DEVICE_ID_SI_7018:
  2352. +      address = SI_AC97_READ;
  2353. +      mask = SI_AC97_BUSY_READ | SI_AC97_AUDIO_BUSY;
  2354. +      if (codec->id)
  2355. +         mask |= SI_AC97_SECONDARY;
  2356. +      busy = SI_AC97_BUSY_READ;
  2357. +      break;
  2358. +   case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
  2359. +      address = DX_ACR1_AC97_R;
  2360. +      mask = busy = DX_AC97_BUSY_READ;
  2361. +      break;
  2362. +   case PCI_DEVICE_ID_TRIDENT_4DWAVE_NX:
  2363. +      if (codec->id)
  2364. +         address = NX_ACR3_AC97_R_SECONDARY;
  2365. +      else
  2366. +         address = NX_ACR2_AC97_R_PRIMARY;
  2367. +      mask = NX_AC97_BUSY_READ;
  2368. +      busy = NX_AC97_BUSY_READ | NX_AC97_BUSY_DATA;
  2369. +      break;
  2370. +   }
  2371. +
  2372. +   data = (mask | (reg & AC97_REG_ADDR));
  2373. +
  2374. +   spin_lock_irqsave(&card->lock, flags);
  2375. +   outl(data, TRID_REG(card, address));
  2376. +   do {
  2377. +      data = inl(TRID_REG(card, address));
  2378. +      if ((data & busy) == 0)
  2379. +         break;
  2380. +   } while (count--);
  2381. +   spin_unlock_irqrestore(&card->lock, flags);
  2382. +
  2383. +   if (count == 0) {
  2384. +      printk(KERN_ERR "trident: AC97 CODEC read timed out.\n");
  2385. +      data = 0;
  2386. +   }
  2387. +   return ((u16) (data >> 16));
  2388. +}
  2389. +
  2390. +/* Write AC97 codec registers for ALi*/
  2391. +static void ali_ac97_set(struct ac97_codec *codec, u8 reg, u16 val)
  2392. +{
  2393. +   struct trident_card *card = NULL;
  2394. +   unsigned int address, mask;
  2395. +   unsigned int wCount1 = 0xffff;
  2396. +   unsigned int wCount2= 0xffff;
  2397. +   unsigned long chk1, chk2;
  2398. +   unsigned long flags;
  2399. +   u32 data;
  2400. +
  2401. +   //Added by Matt Wu
  2402. +   if (!codec)
  2403. +      return;
  2404. +
  2405. +   card = (struct trident_card *)(codec->private_data);
  2406. +
  2407. +   if(!card)
  2408. +      return;
  2409. +   //End add
  2410. +
  2411. +   data = ((u32) val) << 16;
  2412. +   address = ALI_AC97_WRITE;
  2413. +   mask = ALI_AC97_WRITE_ACTION | ALI_AC97_AUDIO_BUSY;
  2414. +
  2415. +   if (codec->id)
  2416. +      mask |= ALI_AC97_SECONDARY;
  2417. +   if (card->revision == ALI_5451_V02)
  2418. +      mask |= ALI_AC97_WRITE_MIXER_REGISTER;
  2419. +      
  2420. +   spin_lock_irqsave(&card->lock, flags);
  2421. +   while (wCount1--) {
  2422. +      if ((inw(TRID_REG(card, address)) & ALI_AC97_BUSY_WRITE) == 0) {
  2423. +         data |= (mask | (reg & AC97_REG_ADDR));
  2424. +        
  2425. +         chk1 = inl(TRID_REG(card,  ALI_STIMER));
  2426. +         chk2 = inl(TRID_REG(card,  ALI_STIMER));
  2427. +         while (wCount2-- && (chk1 == chk2))
  2428. +            chk2 = inl(TRID_REG(card,  ALI_STIMER));
  2429. +         if (wCount2 == 0) {
  2430. +            spin_unlock_irqrestore(&card->lock, flags);
  2431. +            return;
  2432. +         }
  2433. +         outl(data, TRID_REG(card, address));   //write!
  2434. +         spin_unlock_irqrestore(&card->lock, flags);
  2435. +         return;   //success
  2436. +      }
  2437. +      inw(TRID_REG(card, address));   //wait for a read cycle
  2438. +   }
  2439. +
  2440. +   printk(KERN_ERR "ali: AC97 CODEC write timed out.\n");
  2441. +   spin_unlock_irqrestore(&card->lock, flags);
  2442. +   return;
  2443. +}
  2444. +
  2445. +/* Read AC97 codec registers for ALi*/
  2446. +static u16 ali_ac97_get(struct ac97_codec *codec, u8 reg)
  2447. +{
  2448. +   struct trident_card *card = NULL;
  2449. +   unsigned int address, mask;
  2450. +        unsigned int wCount1 = 0xffff;
  2451. +        unsigned int wCount2= 0xffff;
  2452. +        unsigned long chk1, chk2;
  2453. +   unsigned long flags;
  2454. +   u32 data;
  2455. +
  2456. +   //Added by Matt Wu
  2457. +   if (!codec)
  2458. +      return 0;
  2459. +
  2460. +   card = (struct trident_card *)(codec->private_data);
  2461. +
  2462. +   if(!card)
  2463. +      return 0;
  2464. +   //End add
  2465. +
  2466. +   address = ALI_AC97_READ;
  2467. +   if (card->revision == ALI_5451_V02) {
  2468. +      address = ALI_AC97_WRITE;
  2469. +      mask &= ALI_AC97_READ_MIXER_REGISTER;
  2470. +   }
  2471. +   mask = ALI_AC97_READ_ACTION | ALI_AC97_AUDIO_BUSY;
  2472. +   if (codec->id)
  2473. +      mask |= ALI_AC97_SECONDARY;
  2474. +
  2475. +   spin_lock_irqsave(&card->lock, flags);
  2476. +   data = (mask | (reg & AC97_REG_ADDR));
  2477. +   while (wCount1--) {
  2478. +      if ((inw(TRID_REG(card, address)) & ALI_AC97_BUSY_READ) == 0) {
  2479. +         chk1 = inl(TRID_REG(card,  ALI_STIMER));
  2480. +         chk2 = inl(TRID_REG(card,  ALI_STIMER));
  2481. +         while (wCount2-- && (chk1 == chk2))
  2482. +            chk2 = inl(TRID_REG(card,  ALI_STIMER));
  2483. +         if (wCount2 == 0) {
  2484. +            printk(KERN_ERR "ali: AC97 CODEC read timed out.\n");
  2485. +            spin_unlock_irqrestore(&card->lock, flags);
  2486. +            return 0;
  2487. +         }
  2488. +         outl(data, TRID_REG(card, address));   //read!
  2489. +         wCount2 = 0xffff;
  2490. +         while (wCount2--) {
  2491. +            if ((inw(TRID_REG(card, address)) & ALI_AC97_BUSY_READ) == 0) {
  2492. +               data = inl(TRID_REG(card, address));
  2493. +               spin_unlock_irqrestore(&card->lock, flags);
  2494. +               return ((u16) (data >> 16));
  2495. +            }
  2496. +         }
  2497. +      }
  2498. +      inw(TRID_REG(card, address));   //wait a read cycle
  2499. +   }
  2500. +   spin_unlock_irqrestore(&card->lock, flags);
  2501. +   printk(KERN_ERR "ali: AC97 CODEC read timed out.\n");
  2502. +   return 0;
  2503. +}
  2504. +
  2505. +static void ali_enable_special_channel(struct trident_state *stat)
  2506. +{
  2507. +   struct trident_card *card = stat->card;
  2508. +   unsigned long s_channels;
  2509. +  
  2510. +   s_channels = inl(TRID_REG(card, ALI_GLOBAL_CONTROL));
  2511. +   s_channels |= (1<<stat->dmabuf.channel->num);
  2512. +   outl(s_channels, TRID_REG(card, ALI_GLOBAL_CONTROL));
  2513. +#ifdef DEBUG
  2514. +   printk("D4h=%lxh\n", inl(TRID_REG(card, ALI_GLOBAL_CONTROL)));
  2515. +#endif
  2516. +}
  2517. +
  2518. +/*
  2519. +flag:   ALI_SPDIF_OUT_TO_SPDIF_OUT
  2520. +   ALI_PCM_TO_SPDIF_OUT
  2521. +*/
  2522. +static void ali_setup_spdif_out(struct trident_card *card, int flag)
  2523. +{
  2524. +   unsigned long spdif;
  2525. +   unsigned char ch;
  2526. +
  2527. +        char temp;
  2528. +        struct pci_dev *pci_dev = NULL;
  2529. +
  2530. +        pci_dev = pci_find_device(0x10b9,0x1533, pci_dev);
  2531. +        if (pci_dev == NULL)
  2532. +                return;
  2533. +        pci_read_config_byte(pci_dev, 0x61, &temp);
  2534. +        temp |= 0x40;
  2535. +        pci_write_config_byte(pci_dev, 0x61, temp);
  2536. +        pci_read_config_byte(pci_dev, 0x7d, &temp);
  2537. +        temp |= 0x01;
  2538. +        pci_write_config_byte(pci_dev, 0x7d, temp);
  2539. +        pci_read_config_byte(pci_dev, 0x7e, &temp);
  2540. +        temp &= (~0x20);
  2541. +        temp |= 0x10;
  2542. +        pci_write_config_byte(pci_dev, 0x7e, temp);
  2543. +
  2544. +
  2545. +   ch = inb(TRID_REG(card, ALI_SCTRL));
  2546. +   outb(ch | ALI_SPDIF_OUT_ENABLE, TRID_REG(card, ALI_SCTRL));
  2547. +   ch = inb(TRID_REG(card, ALI_SPDIF_CTRL));
  2548. +   outb(ch & ALI_SPDIF_OUT_CH_STATUS, TRID_REG(card, ALI_SPDIF_CTRL));
  2549. +  
  2550. +   if (flag & ALI_SPDIF_OUT_TO_SPDIF_OUT) {
  2551. +        spdif = inw(TRID_REG(card, ALI_GLOBAL_CONTROL));
  2552. +         spdif |= ALI_SPDIF_OUT_CH_ENABLE;
  2553. +         spdif &= ALI_SPDIF_OUT_SEL_SPDIF;
  2554. +         outw(spdif, TRID_REG(card, ALI_GLOBAL_CONTROL));
  2555. +      spdif = inw(TRID_REG(card, ALI_SPDIF_CS));
  2556. +      if (flag & ALI_SPDIF_OUT_NON_PCM)
  2557. +            spdif |= 0x0002;
  2558. +      else   spdif &= (~0x0002);
  2559. +         outw(spdif, TRID_REG(card, ALI_SPDIF_CS));
  2560. +      }
  2561. +      else {
  2562. +         spdif = inw(TRID_REG(card, ALI_GLOBAL_CONTROL));
  2563. +         spdif |= ALI_SPDIF_OUT_SEL_PCM;
  2564. +         outw(spdif, TRID_REG(card, ALI_GLOBAL_CONTROL));
  2565. +      }
  2566. +}
  2567. +
  2568. +static void ali_disable_special_channel(struct trident_card *card, int ch)
  2569. +{
  2570. +   unsigned long sc;
  2571. +  
  2572. +   sc = inl(TRID_REG(card, ALI_GLOBAL_CONTROL));
  2573. +   sc &= ~(1 << ch);
  2574. +   outl(sc, TRID_REG(card, ALI_GLOBAL_CONTROL));
  2575. +}
  2576. +
  2577. +static void ali_disable_spdif_in(struct trident_card *card)
  2578. +{
  2579. +   unsigned long spdif;
  2580. +  
  2581. +   spdif = inl(TRID_REG(card, ALI_GLOBAL_CONTROL));
  2582. +   spdif &= (~ALI_SPDIF_IN_SUPPORT);
  2583. +   outl(spdif, TRID_REG(card, ALI_GLOBAL_CONTROL));
  2584. +  
  2585. +   ali_disable_special_channel(card, ALI_SPDIF_IN_CHANNEL);  
  2586. +}
  2587. +
  2588. +static void ali_setup_spdif_in(struct trident_card *card)
  2589. +{  
  2590. +   unsigned long spdif;
  2591. +
  2592. +   //Set SPDIF IN Supported
  2593. +   spdif = inl(TRID_REG(card, ALI_GLOBAL_CONTROL));
  2594. +   spdif |= ALI_SPDIF_IN_SUPPORT;
  2595. +   outl(spdif, TRID_REG(card, ALI_GLOBAL_CONTROL));
  2596. +
  2597. +   //Set SPDIF IN Rec
  2598. +   spdif = inl(TRID_REG(card, ALI_GLOBAL_CONTROL));
  2599. +   spdif |= ALI_SPDIF_IN_CH_ENABLE;
  2600. +   outl(spdif, TRID_REG(card, ALI_GLOBAL_CONTROL));
  2601. +
  2602. +   spdif = inb(TRID_REG(card, ALI_SPDIF_CTRL));
  2603. +   spdif |= ALI_SPDIF_IN_CH_STATUS;
  2604. +   outb(spdif, TRID_REG(card, ALI_SPDIF_CTRL));
  2605. +/*
  2606. +   spdif = inb(TRID_REG(card, ALI_SPDIF_CTRL));
  2607. +   spdif |= ALI_SPDIF_IN_FUNC_ENABLE;
  2608. +   outb(spdif, TRID_REG(card, ALI_SPDIF_CTRL));
  2609. +*/
  2610. +}
  2611. +
  2612. +void ali_delay(struct trident_card *card,int interval)
  2613. +{
  2614. +   unsigned long  begintimer,currenttimer;
  2615. +
  2616. +   begintimer   = inl(TRID_REG(card,  ALI_STIMER));
  2617. +   currenttimer = inl(TRID_REG(card,  ALI_STIMER));
  2618. +
  2619. +   while (currenttimer < begintimer + interval)
  2620. +      currenttimer = inl(TRID_REG(card,  ALI_STIMER));
  2621. +}
  2622. +
  2623. +void ali_detect_spdif_rate(struct trident_card *card)
  2624. +{
  2625. +   u16 wval  = 0;
  2626. +   u16 count = 0;
  2627. +   u8  bval = 0, R1 = 0, R2 = 0;
  2628. +
  2629. +   bval  = inb(TRID_REG(card,ALI_SPDIF_CTRL));
  2630. +   bval |= 0x02;
  2631. +   outb(bval,TRID_REG(card,ALI_SPDIF_CTRL));
  2632. +
  2633. +   bval  = inb(TRID_REG(card,ALI_SPDIF_CTRL + 1));
  2634. +   bval |= 0x1F;
  2635. +   outb(bval,TRID_REG(card,ALI_SPDIF_CTRL + 1));
  2636. +
  2637. +   while (((R1 < 0x0B )||(R1 > 0x0E)) && (R1 != 0x12) && count <= 50000)
  2638. +   {
  2639. +      count ++;
  2640. +
  2641. +      ali_delay(card, 6);
  2642. +
  2643. +      bval = inb(TRID_REG(card,ALI_SPDIF_CTRL + 1));
  2644. +      R1 = bval & 0x1F;
  2645. +   }
  2646. +
  2647. +   if (count > 50000)
  2648. +   {
  2649. +      printk("Error in ali_detect_spdif_rate!\n");
  2650. +      return;
  2651. +   }
  2652. +
  2653. +   count = 0;
  2654. +
  2655. +   while (count <= 50000)
  2656. +   {
  2657. +      count ++;
  2658. +
  2659. +      ali_delay(card, 6);
  2660. +
  2661. +      bval = inb(TRID_REG(card,ALI_SPDIF_CTRL + 1));
  2662. +      R2 = bval & 0x1F;
  2663. +
  2664. +      if(R2 != R1)
  2665. +         R1 = R2;
  2666. +      else
  2667. +         break;
  2668. +   }
  2669. +
  2670. +   if (count > 50000)
  2671. +   {
  2672. +      printk("Error in ali_detect_spdif_rate!\n");
  2673. +      return;
  2674. +   }
  2675. +
  2676. +   switch (R2)
  2677. +   {
  2678. +   case 0x0b:
  2679. +   case 0x0c:
  2680. +   case 0x0d:
  2681. +   case 0x0e:
  2682. +      wval  = inw(TRID_REG(card,ALI_SPDIF_CTRL + 2));
  2683. +      wval &= 0xE0F0;
  2684. +      wval |= (u16)0x09 << 8 | (u16)0x05;
  2685. +      outw(wval,TRID_REG(card,ALI_SPDIF_CTRL + 2));
  2686. +
  2687. +      bval  = inb(TRID_REG(card,ALI_SPDIF_CS +3)) & 0xF0;
  2688. +      outb(bval|0x02,TRID_REG(card,ALI_SPDIF_CS + 3));
  2689. +      break;
  2690. +
  2691. +   case 0x12:
  2692. +      wval  = inw(TRID_REG(card,ALI_SPDIF_CTRL + 2));
  2693. +      wval &= 0xE0F0;
  2694. +      wval |= (u16)0x0E << 8 | (u16)0x08;
  2695. +      outw(wval,TRID_REG(card,ALI_SPDIF_CTRL + 2));
  2696. +
  2697. +      bval  = inb(TRID_REG(card,ALI_SPDIF_CS +3)) & 0xF0;
  2698. +      outb(bval|0x03,TRID_REG(card,ALI_SPDIF_CS + 3));
  2699. +      break;
  2700. +
  2701. +   default:
  2702. +      break;
  2703. +   }
  2704. +
  2705. +}
  2706. +
  2707. +static unsigned int ali_get_spdif_in_rate(struct trident_card *card)
  2708. +{
  2709. +   u32   dwRate = 0;
  2710. +   u8   bval = 0;
  2711. +
  2712. +   ali_detect_spdif_rate(card);
  2713. +
  2714. +   bval  = inb(TRID_REG(card,ALI_SPDIF_CTRL));
  2715. +   bval &= 0x7F;
  2716. +   bval |= 0x40;
  2717. +   outb(bval,TRID_REG(card,ALI_SPDIF_CTRL));
  2718. +
  2719. +   bval  = inb(TRID_REG(card,ALI_SPDIF_CS + 3));
  2720. +   bval &= 0x0F;
  2721. +
  2722. +   switch (bval)
  2723. +   {
  2724. +   case 0:
  2725. +      dwRate = 44100;
  2726. +      break;
  2727. +   case 1:
  2728. +      dwRate = 48000;
  2729. +      break;
  2730. +   case 2:
  2731. +      dwRate = 32000;
  2732. +      break;
  2733. +   default:
  2734. +      // Error occurs
  2735. +      break;
  2736. +   }
  2737. +
  2738. +   return dwRate;
  2739. +  
  2740. +}
  2741. +
  2742. +static int ali_close_multi_channels()
  2743. +{
  2744. +   char temp = 0;
  2745. +   struct pci_dev *pci_dev = NULL;
  2746. +
  2747. +        pci_dev = pci_find_device(0x10b9,0x1533, pci_dev);
  2748. +        if (pci_dev == NULL)
  2749. +                return -1;
  2750. +   temp = 0x80;
  2751. +   pci_write_config_byte(pci_dev, 0x59, ~temp);
  2752. +  
  2753. +   pci_dev = pci_find_device(0x10b9,0x7101, pci_dev);
  2754. +   if (pci_dev == NULL)
  2755. +                return -1;
  2756. +
  2757. +   temp = 0x20;
  2758. +   pci_write_config_byte(pci_dev, 0xB8, ~temp);
  2759. +
  2760. +   return 0;
  2761. +}
  2762. +
  2763. +static int ali_setup_multi_channels(struct trident_card *card, int chan_nums)
  2764. +{
  2765. +   unsigned long dwValue;
  2766. +   char temp = 0;
  2767. +   struct pci_dev *pci_dev = NULL;
  2768. +
  2769. +   pci_dev = pci_find_device(0x10b9,0x1533, pci_dev);
  2770. +   if (pci_dev == NULL)
  2771. +                return -1;
  2772. +#ifdef DEBUG  
  2773. +   pci_read_config_byte(pci_dev, 0x59, &temp);
  2774. +   printk("Old value of 1533 59h=%xh\n", temp);
  2775. +#endif
  2776. +   temp = 0x80;
  2777. +   pci_write_config_byte(pci_dev, 0x59, temp);
  2778. +#ifdef DEBUG  
  2779. +   printk("1533 59h=%xh\n", temp);
  2780. +#endif
  2781. +  
  2782. +   pci_dev = pci_find_device(0x10b9,0x7101, pci_dev);
  2783. +    if (pci_dev == NULL)
  2784. +                return -1;
  2785. +#ifdef DEBUG
  2786. +   pci_read_config_byte(pci_dev, 0xB8, &temp);
  2787. +   printk("Old value of 7101 B8h=%xh\n", temp);
  2788. +#endif
  2789. +   temp = 0x20;
  2790. +   pci_write_config_byte(pci_dev, (int)0xB8,(u8) temp);
  2791. +#ifdef DEBUG
  2792. +        printk("7101 b8h=%xh\n", temp);
  2793. +#endif
  2794. +   if (chan_nums == 6) {
  2795. +      dwValue = inl(TRID_REG(card, ALI_SCTRL)) | 0x000f0000;
  2796. +      outl(dwValue, TRID_REG(card, ALI_SCTRL));
  2797. +#ifdef DEBUG
  2798. +      printk("SCTRL=%lxh\n", inl(TRID_REG(card, ALI_SCTRL)));
  2799. +#endif
  2800. +      udelay(4000);
  2801. +      //while(--wCount) {
  2802. +         dwValue = inl(TRID_REG(card, ALI_SCTRL));
  2803. +         if (dwValue & 0x2000000) {
  2804. +#ifdef DEBUG
  2805. +            printk("codec0 28h= %xh\n", ali_ac97_get(card->ac97_codec[0], 0x28));
  2806. +            printk("codec0 2ch= %xh\n", ali_ac97_get(card->ac97_codec[0], 0x2c));
  2807. +            printk("codec0 2eh= %xh\n", ali_ac97_get(card->ac97_codec[0], 0x2E));
  2808. +            printk("codec0 30h= %xh\n", ali_ac97_get(card->ac97_codec[0], 0x30));
  2809. +            printk("codec1 28h= %xh\n", ali_ac97_get(card->ac97_codec[1], 0x28));
  2810. +                                printk("codec1 2ch= %xh\n", ali_ac97_get(card->ac97_codec[1], 0x2c));
  2811. +                                printk("codec1 2eh= %xh\n", ali_ac97_get(card->ac97_codec[1], 0x2E));
  2812. +                                printk("codec1 30h= %xh\n", ali_ac97_get(card->ac97_codec[1], 0x30));
  2813. +            //printk("codec0 2ch= %xh\n", ali_ac97_get(card->ac97_codec[0], 0x32));
  2814. +            printk("codec0 02h= %xh\n", ali_ac97_get(card->ac97_codec[0], 0x02));
  2815. +#endif
  2816. +            ali_ac97_set(card->ac97_codec[0], 0x02, 8080);
  2817. +#ifdef DEBUG
  2818. +            printk("codec0 02h= %xh\n", ali_ac97_get(card->ac97_codec[0], 0x02));
  2819. +#endif
  2820. +            ali_ac97_set(card->ac97_codec[0], 0x36, 0);
  2821. +#ifdef DEBUG
  2822. +            printk("after set codec 0 36h, codec0 02h= %xh\n", ali_ac97_get(card->ac97_codec[0], 0x02));
  2823. +#endif
  2824. +            ali_ac97_set(card->ac97_codec[0], 0x38, 0);
  2825. +#ifdef DEBUG
  2826. +            printk("after set codec0 38h, codec0 02h= %xh\n", ali_ac97_get(card->ac97_codec[0], 0x02));
  2827. +#endif
  2828. +            ali_ac97_set(card->ac97_codec[1], 0x36, 0);
  2829. +#ifdef DEBUG
  2830. +            printk("after set codec 1 36h, codec0 02h= %xh\n", ali_ac97_get(card->ac97_codec[0], 0x02));
  2831. +#endif
  2832. +                                ali_ac97_set(card->ac97_codec[1], 0x38, 0);
  2833. +#ifdef DEBUG
  2834. +            printk("after set codec 1 38h, codec0 02h= %xh\n", ali_ac97_get(card->ac97_codec[0], 0x02));
  2835. +#endif
  2836. +            ali_ac97_set(card->ac97_codec[1], 0x02, 0);
  2837. +            ali_ac97_set(card->ac97_codec[1], 0x18, 0x0808);
  2838. +            ali_ac97_set(card->ac97_codec[1], 0x74, 0x3);
  2839. +#ifdef DEBUG
  2840. +            printk("codec1 02h= %xh\n", ali_ac97_get(card->ac97_codec[1], 0x02));
  2841. +             printk("codec1 18h= %xh\n", ali_ac97_get(card->ac97_codec[1], 0x18));
  2842. +             printk("codec1 74h= %xh\n", ali_ac97_get(card->ac97_codec[1], 0x74));
  2843. +#endif
  2844. +            return 1;
  2845. +         }
  2846. +      //}
  2847. +   }
  2848. +   return -EINVAL;
  2849. +}
  2850. +
  2851. +static void ali_free_pcm_channel(struct trident_card *card, unsigned int channel)
  2852. +{
  2853. +   int bank;
  2854. +
  2855. +   if (channel > 31)
  2856. +      return;
  2857. +
  2858. +   bank = channel >> 5;
  2859. +   channel = channel & 0x1f;
  2860. +
  2861. +   card->banks[bank].bitmap &= ~(1 << (channel));
  2862. +}
  2863. +
  2864. +static int ali_allocate_other_states_resources(struct trident_state *state, int chan_nums)
  2865. +{
  2866. +   struct trident_card *card = state->card;
  2867. +   struct trident_state *s;
  2868. +   int i, state_count = 0;
  2869. +   struct trident_pcm_bank *bank;
  2870. +   struct trident_channel *channel;
  2871. +  
  2872. +   bank = &card->banks[BANK_A];
  2873. +  
  2874. +   if (chan_nums == 6) {
  2875. +      for(i = 0;(i < ALI_CHANNELS) && (state_count != 4); i++) {
  2876. +         if (!card->states[i]) {
  2877. +            if (!(bank->bitmap & (1 << ali_multi_channels_5_1[state_count]))) {
  2878. +               bank->bitmap |= (1 << ali_multi_channels_5_1[state_count]);
  2879. +               channel = &bank->channels[ali_multi_channels_5_1[state_count]];
  2880. +               channel->num = ali_multi_channels_5_1[state_count];
  2881. +            }
  2882. +            else {
  2883. +               state_count--;
  2884. +               for (; state_count >= 0; state_count--) {
  2885. +                  kfree(state->other_states[state_count]);
  2886. +                  ali_free_pcm_channel(card, ali_multi_channels_5_1[state_count]);
  2887. +               }
  2888. +               return -EBUSY;
  2889. +            }
  2890. +            s = card->states[i] = (struct trident_state *)
  2891. +                  kmalloc(sizeof(struct trident_state), GFP_KERNEL);
  2892. +            if (!s) {
  2893. +               ali_free_pcm_channel(card, ali_multi_channels_5_1[state_count]);
  2894. +               state_count--;
  2895. +               for (; state_count >= 0; state_count--) {                  
  2896. +                  ali_free_pcm_channel(card, ali_multi_channels_5_1[state_count]);
  2897. +                  kfree(state->other_states[state_count]);
  2898. +               }
  2899. +               return -ENOMEM;
  2900. +            }
  2901. +            memset(s, 0, sizeof(struct trident_state));
  2902. +            
  2903. +            s->dmabuf.channel = channel;
  2904. +            s->dmabuf.ossfragshift = s->dmabuf.ossmaxfrags = s->dmabuf.subdivision = 0;
  2905. +            init_waitqueue_head(&s->dmabuf.wait);
  2906. +            s->magic = card->magic;
  2907. +            s->card = card;
  2908. +            s->virt = i;
  2909. +            ali_enable_special_channel(s);
  2910. +            state->other_states[state_count++] = s;
  2911. +         }
  2912. +      }
  2913. +      
  2914. +      if (state_count != 4) {
  2915. +         state_count--;
  2916. +         for (; state_count >= 0; state_count--) {
  2917. +            kfree(state->other_states[state_count]);
  2918. +            ali_free_pcm_channel(card, ali_multi_channels_5_1[state_count]);
  2919. +         }
  2920. +         return -EBUSY;
  2921. +      }
  2922. +   }
  2923. +   return 0;
  2924. +}
  2925. +
  2926. +static void ali_save_regs(struct trident_card *card)
  2927. +{
  2928. +   unsigned long flags;
  2929. +   int i, j;
  2930. +
  2931. +   save_flags(flags);
  2932. +   cli();
  2933. +  
  2934. +   ali_registers.global_regs[0x2c] = inl(TRID_REG(card,T4D_MISCINT));
  2935. +   //ali_registers.global_regs[0x20] = inl(TRID_REG(card,T4D_START_A));  
  2936. +   ali_registers.global_regs[0x21] = inl(TRID_REG(card,T4D_STOP_A));
  2937. +  
  2938. +   //disable all IRQ bits
  2939. +   outl(ALI_DISABLE_ALL_IRQ, TRID_REG(card, T4D_MISCINT));
  2940. +  
  2941. +   for (i = 1; i < ALI_MIXER_REGS; i++)
  2942. +      ali_registers.mixer_regs[i] = ali_ac97_get (card->ac97_codec[0], i*2);
  2943. +  
  2944. +   for (i = 0; i < ALI_GLOBAL_REGS; i++)
  2945. +   {  
  2946. +      if ((i*4 == T4D_MISCINT) || (i*4 == T4D_STOP_A))
  2947. +         continue;
  2948. +      ali_registers.global_regs[i] = inl(TRID_REG(card, i*4));
  2949. +   }
  2950. +  
  2951. +   for (i = 0; i < ALI_CHANNELS; i++)
  2952. +   {
  2953. +      outb(i,TRID_REG(card, T4D_LFO_GC_CIR));
  2954. +      for (j = 0; j < ALI_CHANNEL_REGS; j++)
  2955. +         ali_registers.channel_regs[i][j] = inl(TRID_REG(card, j*4 + 0xe0));
  2956. +   }
  2957. +
  2958. +   //Stop all HW channel
  2959. +   outl(ALI_STOP_ALL_CHANNELS, TRID_REG(card, T4D_STOP_A));
  2960. +
  2961. +   restore_flags(flags);
  2962. +}
  2963. +
  2964. +static void ali_restore_regs(struct trident_card *card)
  2965. +{
  2966. +   unsigned long flags;
  2967. +   int i, j;
  2968. +
  2969. +   save_flags(flags);
  2970. +   cli();
  2971. +  
  2972. +   for (i = 1; i < ALI_MIXER_REGS; i++)
  2973. +      ali_ac97_set(card->ac97_codec[0], i*2, ali_registers.mixer_regs[i]);
  2974. +  
  2975. +   for (i = 0; i < ALI_CHANNELS; i++)
  2976. +   {
  2977. +      outb(i,TRID_REG(card, T4D_LFO_GC_CIR));
  2978. +      for (j = 0; j < ALI_CHANNEL_REGS; j++)
  2979. +         outl(ali_registers.channel_regs[i][j], TRID_REG(card, j*4 + 0xe0));
  2980. +   }
  2981. +  
  2982. +   for (i = 0; i < ALI_GLOBAL_REGS; i++)
  2983. +   {  
  2984. +      if ((i*4 == T4D_MISCINT) || (i*4 == T4D_STOP_A) || (i*4 == T4D_START_A))
  2985. +         continue;
  2986. +      ali_registers.global_regs[i] = inl(TRID_REG(card, i*4));
  2987. +   }
  2988. +  
  2989. +   //start HW channel
  2990. +   outl(ali_registers.global_regs[0x20], TRID_REG(card,T4D_START_A));
  2991. +   //restore IRQ enable bits
  2992. +   outl(ali_registers.global_regs[0x2c], TRID_REG(card,T4D_MISCINT));
  2993. +  
  2994. +   restore_flags(flags);
  2995. +}
  2996. +
  2997. +static int ali_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
  2998. +{
  2999. +   struct trident_card *card = (struct trident_card *)dev->data;
  3000. +  
  3001. +   if (card) {
  3002. +      switch (rqst) {
  3003. +         case PM_SUSPEND:
  3004. +            ali_save_regs(card);
  3005. +            break;
  3006. +         case PM_RESUME:
  3007. +            ali_restore_regs(card);
  3008. +            break;
  3009. +      }
  3010. +   }
  3011. +   return 0;
  3012. +}
  3013. +
  3014. +static struct trident_channel *ali_alloc_pcm_channel(struct trident_card *card)
  3015. +{
  3016. +   struct trident_pcm_bank *bank;
  3017. +   int idx;
  3018. +
  3019. +   bank = &card->banks[BANK_A];
  3020. +  
  3021. +   if (inl(TRID_REG(card, ALI_GLOBAL_CONTROL)) & (ALI_SPDIF_OUT_CH_ENABLE)) {
  3022. +      idx = ALI_SPDIF_OUT_CHANNEL;
  3023. +      if (!(bank->bitmap & (1 << idx))) {
  3024. +         struct trident_channel *channel = &bank->channels[idx];
  3025. +         bank->bitmap |= 1 << idx;
  3026. +         channel->num = idx;
  3027. +         return channel;
  3028. +      }
  3029. +   }
  3030. +  
  3031. +   for (idx = ALI_PCM_OUT_CHANNEL_FIRST; idx <= ALI_PCM_OUT_CHANNEL_LAST ; idx++) {
  3032. +      if (!(bank->bitmap & (1 << idx))) {
  3033. +         struct trident_channel *channel = &bank->channels[idx];
  3034. +         bank->bitmap |= 1 << idx;
  3035. +         channel->num = idx;
  3036. +         return channel;
  3037. +      }
  3038. +   }
  3039. +
  3040. +   /* no more free channels avaliable */
  3041. +   printk(KERN_ERR "ali: no more channels available on Bank A.\n");
  3042. +   return NULL;
  3043. +}
  3044. +
  3045. +static struct trident_channel *ali_alloc_rec_pcm_channel(struct trident_card *card)
  3046. +{
  3047. +   struct trident_pcm_bank *bank;
  3048. +   int idx;
  3049. +  
  3050. +   if (inl(TRID_REG(card, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_IN_SUPPORT)
  3051. +      idx = ALI_SPDIF_IN_CHANNEL;
  3052. +   else   idx = ALI_PCM_IN_CHANNEL;
  3053. +
  3054. +   bank = &card->banks[BANK_A];
  3055. +  
  3056. +   if (!(bank->bitmap & (1 << idx))) {
  3057. +      struct trident_channel *channel = &bank->channels[idx];
  3058. +      bank->bitmap |= 1 << idx;
  3059. +      channel->num = idx;
  3060. +      return channel;
  3061. +   }
  3062. +  
  3063. +   /* no free recordable channels avaliable */
  3064. +   printk(KERN_ERR "ali: no recordable channels available on Bank A.\n");
  3065. +   return NULL;
  3066. +}
  3067. +
  3068. +static void ali_set_spdif_out_rate(struct trident_card *card, unsigned int rate)
  3069. +{
  3070. +   unsigned char ch_st_sel;
  3071. +   unsigned short status_rate;
  3072. +  
  3073. +#ifdef DEBUG
  3074. +   printk("ali: spdif out rate =%d\n", rate);
  3075. +#endif
  3076. +   switch(rate) {
  3077. +   case 44100:
  3078. +      status_rate = 0;
  3079. +      break;
  3080. +   case 32000:
  3081. +      status_rate = 0x300;
  3082. +      break;
  3083. +   case 48000:
  3084. +   default:
  3085. +      status_rate = 0x200;
  3086. +      break;
  3087. +   }
  3088. +  
  3089. +   ch_st_sel = inb(TRID_REG(card, ALI_SPDIF_CTRL)) & ALI_SPDIF_OUT_CH_STATUS;   //select spdif_out
  3090. +  
  3091. +   ch_st_sel |= 0x80;   //select right
  3092. +   outb(ch_st_sel, TRID_REG(card, ALI_SPDIF_CTRL));
  3093. +   outb(status_rate | 0x20, TRID_REG(card, ALI_SPDIF_CS + 2));
  3094. +  
  3095. +   ch_st_sel &= (~0x80);   //select left
  3096. +   outb(ch_st_sel, TRID_REG(card, ALI_SPDIF_CTRL));
  3097. +   outw(status_rate | 0x10, TRID_REG(card, ALI_SPDIF_CS + 2));
  3098. +#ifdef DEBUG
  3099. +   printk("ali: SPDIF_CS=%lxh\n", inl(TRID_REG(card, ALI_SPDIF_CS)));
  3100. +#endif
  3101. +}
  3102. +
  3103. +static void ali_address_interrupt(struct trident_card *card)
  3104. +{
  3105. +   int i, channel;
  3106. +   struct trident_state *state;
  3107. +   u32 mask, channel_mask;
  3108. +  
  3109. +   mask = trident_get_interrupt_mask (card, 0);
  3110. +   for (i = 0; i < NR_HW_CH; i++) {
  3111. +      if ((state = card->states[i]) == NULL)
  3112. +         continue;      
  3113. +      channel = state->dmabuf.channel->num;
  3114. +      if ((channel_mask = 1 << channel) & mask) {
  3115. +         mask &= ~channel_mask;
  3116. +         trident_ack_channel_interrupt(card, channel);
  3117. +         udelay(100);
  3118. +         state->dmabuf.update_flag |= ALI_ADDRESS_INT_UPDATE;
  3119. +         trident_update_ptr(state);
  3120. +      }
  3121. +   }
  3122. +   if (mask) {
  3123. +      for (i = 0; i < NR_HW_CH; i++) {
  3124. +         if (mask & (1 << i)) {
  3125. +            printk("ali: spurious channel irq %d.\n", i);
  3126. +            trident_ack_channel_interrupt(card, i);
  3127. +            trident_stop_voice(card, i);
  3128. +            trident_disable_voice_irq(card, i);
  3129. +         }
  3130. +      }
  3131. +   }
  3132. +}
  3133. +
  3134. +/* Updating the values of counters of other_states' DMAs without lock
  3135. +protection is no harm because all DMAs of multi-channels and interrupt
  3136. +depend on a master state's DMA, and changing the counters of the master
  3137. +state DMA is protected by a spinlock.
  3138. +*/
  3139. +static int ali_write_5_1(struct trident_state *state,  const char *buf, int cnt_for_multi_channel, unsigned int *copy_count, unsign+
  3140. ed int *state_cnt)
  3141. +{
  3142. +  
  3143. +   struct dmabuf *dmabuf = &state->dmabuf;
  3144. +   struct dmabuf *dmabuf_temp;
  3145. +   const char *buffer = buf;
  3146. +   unsigned swptr, other_dma_nums, sample_s;
  3147. +   unsigned int i, loop;
  3148. +  
  3149. +   other_dma_nums = 4;
  3150. +   sample_s = sample_size[dmabuf->fmt] >> 1;
  3151. +   swptr = dmabuf->swptr;
  3152. +
  3153. +   if ((i = state->multi_channels_adjust_count) > 0) {
  3154. +      if (i == 1) {
  3155. +         if (copy_from_user(dmabuf->rawbuf + swptr, buffer, sample_s))
  3156. +            return -EFAULT;
  3157. +         seek_offset(swptr, buffer, cnt_for_multi_channel, sample_s, *copy_count);
  3158. +         i--;
  3159. +         (*state_cnt) += sample_s;
  3160. +         state->multi_channels_adjust_count++;
  3161. +      }
  3162. +      else   i = i - (state->chans_num - other_dma_nums);
  3163. +      for (; (i < other_dma_nums) && (cnt_for_multi_channel > 0); i++) {
  3164. +         dmabuf_temp = &state->other_states[i]->dmabuf;
  3165. +         if (copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s))
  3166. +            return -EFAULT;
  3167. +         seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s, *copy_count);
  3168. +      }
  3169. +      if (cnt_for_multi_channel == 0)
  3170. +         state->multi_channels_adjust_count += i;
  3171. +   }
  3172. +   if (cnt_for_multi_channel > 0) {
  3173. +      loop = cnt_for_multi_channel / (state->chans_num * sample_s);
  3174. +      for (i = 0; i < loop; i++) {
  3175. +         if (copy_from_user(dmabuf->rawbuf + swptr, buffer, sample_s * 2))
  3176. +            return -EFAULT;
  3177. +         seek_offset(swptr, buffer, cnt_for_multi_channel, sample_s * 2, *copy_count);
  3178. +         (*state_cnt) += (sample_s * 2);
  3179. +      
  3180. +         dmabuf_temp = &state->other_states[0]->dmabuf;
  3181. +         if (copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s))
  3182. +            return -EFAULT;
  3183. +         seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s, *copy_count);
  3184. +      
  3185. +         dmabuf_temp = &state->other_states[1]->dmabuf;
  3186. +         if (copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s))
  3187. +            return -EFAULT;
  3188. +         seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s, *copy_count);
  3189. +      
  3190. +         dmabuf_temp = &state->other_states[2]->dmabuf;
  3191. +         if (copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s))
  3192. +            return -EFAULT;
  3193. +         seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s, *copy_count);
  3194. +            
  3195. +         dmabuf_temp = &state->other_states[3]->dmabuf;
  3196. +         if (copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s))
  3197. +            return -EFAULT;
  3198. +         seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s, *copy_count);
  3199. +      }
  3200. +      
  3201. +      if (cnt_for_multi_channel > 0) {
  3202. +         state->multi_channels_adjust_count = cnt_for_multi_channel / sample_s;
  3203. +        
  3204. +         if (copy_from_user(dmabuf->rawbuf + swptr, buffer, sample_s))
  3205. +            return -EFAULT;
  3206. +         seek_offset(swptr, buffer, cnt_for_multi_channel, sample_s, *copy_count);        
  3207. +         (*state_cnt) += sample_s;
  3208. +        
  3209. +         if (cnt_for_multi_channel > 0) {
  3210. +            if (copy_from_user(dmabuf->rawbuf + swptr, buffer, sample_s))
  3211. +               return -EFAULT;
  3212. +            seek_offset(swptr, buffer, cnt_for_multi_channel, sample_s, *copy_count);
  3213. +            (*state_cnt) += sample_s;
  3214. +        
  3215. +            if (cnt_for_multi_channel > 0) {
  3216. +               loop = state->multi_channels_adjust_count - (state->chans_num - other_dma_nums);
  3217. +               for (i = 0; i < loop; i++) {
  3218. +                  dmabuf_temp = &state->other_states[i]->dmabuf;
  3219. +                  if (copy_from_user(dmabuf_temp->rawbuf + dmabuf_temp->swptr, buffer, sample_s))
  3220. +                     return -EFAULT;
  3221. +                  seek_offset(dmabuf_temp->swptr, buffer, cnt_for_multi_channel, sample_s, *copy_count);
  3222. +               }
  3223. +            }
  3224. +         }
  3225. +      }
  3226. +      else
  3227. +         state->multi_channels_adjust_count = 0;
  3228. +   }
  3229. +   for (i = 0; i < other_dma_nums; i++) {
  3230. +      dmabuf_temp = &state->other_states[i]->dmabuf;
  3231. +      dmabuf_temp->swptr = dmabuf_temp->swptr % dmabuf_temp->dmasize;
  3232. +   }
  3233. +   return *state_cnt;
  3234. +}
  3235. +
  3236. +static void ali_free_other_states_resources(struct trident_state *state)
  3237. +{
  3238. +   int i;
  3239. +   struct trident_card *card = state->card;
  3240. +   struct trident_state *s;
  3241. +   unsigned other_states_count;
  3242. +  
  3243. +   other_states_count = state->chans_num - 2;   /* except PCM L/R channels*/
  3244. +   for ( i = 0; i < other_states_count; i++) {
  3245. +      s = state->other_states[i];
  3246. +      dealloc_dmabuf(s);
  3247. +      ali_disable_special_channel(s->card, s->dmabuf.channel->num);
  3248. +      state->card->free_pcm_channel(s->card, s->dmabuf.channel->num);
  3249. +      card->states[s->virt] = NULL;
  3250. +      kfree(s);
  3251. +   }
  3252. +}
  3253. +
  3254. +#ifdef CONFIG_PROC_FS
  3255. +struct proc_dir_entry *res = NULL;
  3256. +static int ali_write_proc(struct file *file, const char *buffer, unsigned long count, void *data)
  3257. +{
  3258. +   struct trident_card *card = (struct trident_card *)data;
  3259. +   unsigned long flags;
  3260. +  
  3261. +   spin_lock_irqsave(&card->lock, flags);
  3262. +   if (*buffer == '0') {   //default
  3263. +      ali_setup_spdif_out(card, ALI_PCM_TO_SPDIF_OUT);
  3264. +      ali_disable_special_channel(card, ALI_SPDIF_OUT_CHANNEL);
  3265. +   }  
  3266. +   else if (*buffer == '1')
  3267. +      ali_setup_spdif_out(card, ALI_SPDIF_OUT_TO_SPDIF_OUT|ALI_SPDIF_OUT_PCM);
  3268. +   else if (*buffer == '2')   //AC3 data
  3269. +      ali_setup_spdif_out(card, ALI_SPDIF_OUT_TO_SPDIF_OUT|ALI_SPDIF_OUT_NON_PCM);
  3270. +   else if (*buffer == '3')
  3271. +      ali_disable_spdif_in(card);   //default
  3272. +   else if (*buffer == '4')
  3273. +      ali_setup_spdif_in(card);
  3274. +   spin_unlock_irqrestore(&card->lock, flags);
  3275. +
  3276. +   return count;
  3277. +}
  3278. +#endif
  3279. +
  3280. +/* OSS /dev/mixer file operation methods */
  3281. +static int trident_open_mixdev(struct inode *inode, struct file *file)
  3282. +{
  3283. +   int i = 0;
  3284. +   int minor = MINOR(inode->i_rdev);
  3285. +   struct trident_card *card = devs;
  3286. +
  3287. +   for (card = devs; card != NULL; card = card->next)
  3288. +      for (i = 0; i < NR_AC97; i++)
  3289. +         if (card->ac97_codec[i] != NULL &&
  3290. +             card->ac97_codec[i]->dev_mixer == minor)
  3291. +            goto match;
  3292. +
  3293. +   if (!card) {
  3294. +      return -ENODEV;
  3295. +   }
  3296. + match:
  3297. +   file->private_data = card->ac97_codec[i];
  3298. +
  3299. +
  3300. +   return 0;
  3301. +}
  3302. +
  3303. +static int trident_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd,
  3304. +            unsigned long arg)
  3305. +{
  3306. +   struct ac97_codec *codec = (struct ac97_codec *)file->private_data;
  3307. +
  3308. +   return codec->mixer_ioctl(codec, cmd, arg);
  3309. +}
  3310. +
  3311. +static /*const*/ struct file_operations trident_mixer_fops = {
  3312. +   owner:      THIS_MODULE,
  3313. +   llseek:      trident_llseek,
  3314. +   ioctl:      trident_ioctl_mixdev,
  3315. +   open:      trident_open_mixdev,
  3316. +};
  3317. +
  3318. +/* AC97 codec initialisation. */
  3319. +static int __init trident_ac97_init(struct trident_card *card)
  3320. +{
  3321. +   int num_ac97 = 0;
  3322. +   unsigned long ready_2nd = 0;
  3323. +   struct ac97_codec *codec;
  3324. +
  3325. +   /* initialize controller side of AC link, and find out if secondary codes
  3326. +      really exist */
  3327. +   switch (card->pci_id)
  3328. +   {
  3329. +   case PCI_DEVICE_ID_ALI_5451:
  3330. +      outl(0x80000000,TRID_REG(card, ALI_GLOBAL_CONTROL));
  3331. +      outl(0x00000000,TRID_REG(card, 0xa4));
  3332. +      outl(0xffffffff,TRID_REG(card, 0x98));
  3333. +      outl(0x00000000,TRID_REG(card, 0xa8));
  3334. +      outb(0x10,    TRID_REG(card, 0x22));
  3335. +      ready_2nd = inl(TRID_REG(card, ALI_SCTRL));
  3336. +      ready_2nd &= 0x3fff;
  3337. +      outl(ready_2nd | PCMOUT | 0x8000, TRID_REG(card, ALI_SCTRL));
  3338. +      ready_2nd = inl(TRID_REG(card, ALI_SCTRL));
  3339. +      ready_2nd &= SI_AC97_SECONDARY_READY;
  3340. +      printk("codec 2 ready flag= %lx\n", ready_2nd);
  3341. +      break;
  3342. +   case PCI_DEVICE_ID_SI_7018:
  3343. +      /* disable AC97 GPIO interrupt */
  3344. +      outl(0x00, TRID_REG(card, SI_AC97_GPIO));
  3345. +      /* when power up the AC link is in cold reset mode so stop it */
  3346. +      outl(PCMOUT|SURROUT|CENTEROUT|LFEOUT|SECONDARY_ID,
  3347. +           TRID_REG(card, SI_SERIAL_INTF_CTRL));
  3348. +      /* it take a long time to recover from a cold reset (especially when you have
  3349. +         more than one codec) */
  3350. +      udelay(2000);
  3351. +      ready_2nd = inl(TRID_REG(card, SI_SERIAL_INTF_CTRL));
  3352. +      ready_2nd &= SI_AC97_SECONDARY_READY;
  3353. +      break;
  3354. +   case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
  3355. +      /* playback on */
  3356. +      outl(DX_AC97_PLAYBACK, TRID_REG(card, DX_ACR2_AC97_COM_STAT));
  3357. +      break;
  3358. +   case PCI_DEVICE_ID_TRIDENT_4DWAVE_NX:
  3359. +      /* enable AC97 Output Slot 3,4 (PCM Left/Right Playback) */
  3360. +      outl(NX_AC97_PCM_OUTPUT, TRID_REG(card, NX_ACR0_AC97_COM_STAT));
  3361. +      ready_2nd = inl(TRID_REG(card, NX_ACR0_AC97_COM_STAT));
  3362. +      ready_2nd &= NX_AC97_SECONDARY_READY;
  3363. +      break;
  3364. +   }
  3365. +
  3366. +   for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
  3367. +      if ((codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL)
  3368. +         return -ENOMEM;
  3369. +      memset(codec, 0, sizeof(struct ac97_codec));
  3370. +
  3371. +      /* initialize some basic codec information, other fields will be filled
  3372. +         in ac97_probe_codec */
  3373. +      codec->private_data = card;
  3374. +      codec->id = num_ac97;
  3375. +
  3376. +      if (card->pci_id == PCI_DEVICE_ID_ALI_5451) {
  3377. +         codec->codec_read = ali_ac97_get;
  3378. +         codec->codec_write = ali_ac97_set;
  3379. +      }
  3380. +      else {
  3381. +         codec->codec_read = trident_ac97_get;
  3382. +         codec->codec_write = trident_ac97_set;
  3383. +      }
  3384. +  
  3385. +      if (ac97_probe_codec(codec) == 0)
  3386. +         break;
  3387. +
  3388. +      if ((codec->dev_mixer = register_sound_mixer(&trident_mixer_fops, -1)) < 0) {
  3389. +         printk(KERN_ERR "trident: couldn't register mixer!\n");
  3390. +         kfree(codec);
  3391. +         break;
  3392. +      }
  3393. +
  3394. +      card->ac97_codec[num_ac97] = codec;
  3395. +
  3396. +      /* if there is no secondary codec at all, don't probe any more */
  3397. +      if (!ready_2nd)
  3398. +         return num_ac97+1;
  3399. +   }
  3400. +
  3401. +   return 1/*num_ac97*/;
  3402. +}
  3403. +
  3404. +/* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered
  3405. +   untill "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */
  3406. +static int __init trident_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
  3407. +{
  3408. +   unsigned long iobase;
  3409. +   struct trident_card *card;
  3410. +   u8 revision;
  3411. +
  3412. +   if (!pci_dma_supported(pci_dev, TRIDENT_DMA_MASK)) {
  3413. +      printk(KERN_ERR "trident: architecture does not support"
  3414. +             " 30bit PCI busmaster DMA\n");
  3415. +      return -ENODEV;
  3416. +   }
  3417. +   pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
  3418. +
  3419. +   iobase = pci_resource_start(pci_dev, 0);
  3420. +   if (check_region(iobase, 256)) {
  3421. +      printk(KERN_ERR "trident: can't allocate I/O space at 0x%4.4lx\n",
  3422. +             iobase);
  3423. +      return -ENODEV;
  3424. +   }
  3425. +
  3426. +   if (pci_enable_device(pci_dev))
  3427. +       return -ENODEV;
  3428. +
  3429. +   if ((card = kmalloc(sizeof(struct trident_card), GFP_KERNEL)) == NULL) {
  3430. +      printk(KERN_ERR "trident: out of memory\n");
  3431. +      return -ENOMEM;
  3432. +   }
  3433. +   memset(card, 0, sizeof(*card));
  3434. +
  3435. +   card->iobase = iobase;
  3436. +   card->pci_dev = pci_dev;
  3437. +   card->pci_id = pci_id->device;
  3438. +   card->revision = revision;
  3439. +   card->irq = pci_dev->irq;
  3440. +   card->next = devs;
  3441. +   card->magic = TRIDENT_CARD_MAGIC;
  3442. +   card->banks[BANK_A].addresses = &bank_a_addrs;
  3443. +   card->banks[BANK_A].bitmap = 0UL;
  3444. +   card->banks[BANK_B].addresses = &bank_b_addrs;
  3445. +   card->banks[BANK_B].bitmap = 0UL;
  3446. +   init_MUTEX(&card->open_sem);
  3447. +   spin_lock_init(&card->lock);
  3448. +   devs = card;
  3449. +
  3450. +   pci_set_master(pci_dev);
  3451. +
  3452. +   printk(KERN_INFO "trident: %s found at IO 0x%04lx, IRQ %d\n",
  3453. +          card_names[pci_id->driver_data], card->iobase, card->irq);
  3454. +
  3455. +   if(card->pci_id == PCI_DEVICE_ID_ALI_5451) {
  3456. +      /* ALi Power Management */
  3457. +      struct pm_dev *pmdev;
  3458. +      
  3459. +      pmdev = pm_register(PM_PCI_DEV, PM_PCI_ID(pci_dev),
  3460. +            ali_pm_callback);
  3461. +      if (pmdev)
  3462. +         pmdev->data = card;
  3463. +      
  3464. +      /* ALi channel Management */  
  3465. +      card->alloc_pcm_channel = ali_alloc_pcm_channel;
  3466. +      card->alloc_rec_pcm_channel = ali_alloc_rec_pcm_channel;
  3467. +      card->free_pcm_channel = ali_free_pcm_channel;
  3468. +      
  3469. +      card->address_interrupt = ali_address_interrupt;
  3470. +
  3471. +      //Add by Matt Wu 01-05-2001 for spdif in
  3472. +      card->multi_channel_use_count = 0;
  3473. +      card->rec_channel_use_count = 0;
  3474. +      //End add
  3475. +
  3476. +
  3477. +      /* ALi SPDIF OUT function */
  3478. +      if(card->revision == ALI_5451_V02) {
  3479. +         ali_setup_spdif_out(card, ALI_PCM_TO_SPDIF_OUT);      
  3480. +#ifdef CONFIG_PROC_FS
  3481. +         res = create_proc_entry("ALi5451", 0, NULL);
  3482. +         if (res) {
  3483. +            res->write_proc = ali_write_proc;
  3484. +            res->data = card;
  3485. +         }
  3486. +#endif
  3487. +      }
  3488. +   }
  3489. +   else {
  3490. +      card->alloc_pcm_channel = trident_alloc_pcm_channel;
  3491. +      card->alloc_rec_pcm_channel = trident_alloc_pcm_channel;
  3492. +      card->free_pcm_channel = trident_free_pcm_channel;
  3493. +      card->address_interrupt = trident_address_interrupt;
  3494. +   }
  3495. +
  3496. +   /* claim our iospace and irq */
  3497. +   request_region(card->iobase, 256, card_names[pci_id->driver_data]);
  3498. +   if (request_irq(card->irq, &trident_interrupt, SA_SHIRQ,
  3499. +         card_names[pci_id->driver_data], card)) {
  3500. +      printk(KERN_ERR "trident: unable to allocate irq %d\n", card->irq);
  3501. +      release_region(card->iobase, 256);
  3502. +      kfree(card);
  3503. +      return -ENODEV;
  3504. +   }
  3505. +   /* register /dev/dsp */
  3506. +   if ((card->dev_audio = register_sound_dsp(&trident_audio_fops, -1)) < 0) {
  3507. +      printk(KERN_ERR "trident: couldn't register DSP device!\n");
  3508. +      release_region(iobase, 256);
  3509. +      free_irq(card->irq, card);
  3510. +      kfree(card);
  3511. +      return -ENODEV;
  3512. +   }
  3513. +   /* initilize AC97 codec and register /dev/mixer */
  3514. +   if (trident_ac97_init(card) <= 0) {
  3515. +      unregister_sound_dsp(card->dev_audio);
  3516. +      release_region(iobase, 256);
  3517. +      free_irq(card->irq, card);
  3518. +      kfree(card);
  3519. +      return -ENODEV;
  3520. +   }
  3521. +   outl(0x00, TRID_REG(card, T4D_MUSICVOL_WAVEVOL));
  3522. +
  3523. +   if (card->pci_id == PCI_DEVICE_ID_ALI_5451) {
  3524. +      /* edited by HMSEO for GT sound */
  3525. +#ifdef CONFIG_ALPHA_NAUTILUS
  3526. +      u16 ac97_data;
  3527. +      ac97_data = ali_ac97_get (card->ac97_codec[0], AC97_POWER_CONTROL);
  3528. +      ali_ac97_set (card->ac97_codec[0], AC97_POWER_CONTROL, ac97_data | ALI_EAPD_POWER_DOWN);
  3529. +#endif
  3530. +      /* edited by HMSEO for GT sound*/
  3531. +   }
  3532. +
  3533. +   pci_set_drvdata(pci_dev, card);
  3534. +   pci_dev->dma_mask = TRIDENT_DMA_MASK;
  3535. +
  3536. +   /* Enable Address Engine Interrupts */
  3537. +   trident_enable_loop_interrupts(card);
  3538. +
  3539. +   return 0;
  3540. +}
  3541. +
  3542. +static void __exit trident_remove(struct pci_dev *pci_dev)
  3543. +{
  3544. +   int i;
  3545. +   struct trident_card *card = pci_get_drvdata(pci_dev);
  3546. +
  3547. +   /* ALi S/PDIF and Power Management */
  3548. +   if(card->pci_id == PCI_DEVICE_ID_ALI_5451) {
  3549. +      ali_setup_spdif_out(card, ALI_PCM_TO_SPDIF_OUT);
  3550. +                ali_disable_special_channel(card, ALI_SPDIF_OUT_CHANNEL);
  3551. +                ali_disable_spdif_in(card);
  3552. +#ifdef CONFIG_PROC_FS
  3553. +      remove_proc_entry("ALi5451", NULL);
  3554. +#endif
  3555. +      pm_unregister_all(ali_pm_callback);
  3556. +   }
  3557. +
  3558. +   /* Kill interrupts, and SP/DIF */
  3559. +   trident_disable_loop_interrupts(card);
  3560. +
  3561. +   /* free hardware resources */
  3562. +   free_irq(card->irq, card);
  3563. +   release_region(card->iobase, 256);
  3564. +
  3565. +   /* unregister audio devices */
  3566. +   for (i = 0; i < NR_AC97; i++)
  3567. +      if (card->ac97_codec[i] != NULL) {
  3568. +         unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
  3569. +         kfree (card->ac97_codec[i]);
  3570. +      }
  3571. +   unregister_sound_dsp(card->dev_audio);
  3572. +
  3573. +   kfree(card);
  3574. +
  3575. +   pci_set_drvdata(pci_dev, NULL);
  3576. +}
  3577. +
  3578. +MODULE_AUTHOR("Alan Cox, Aaron Holtzman, Ollie Lho, Ching Ling Lee");
  3579. +MODULE_DESCRIPTION("Trident 4DWave/SiS 7018/ALi 5451 PCI Audio Driver");
  3580. +
  3581. +#define TRIDENT_MODULE_NAME "trident"
  3582. +
  3583. +static struct pci_driver trident_pci_driver = {
  3584. +   name:      TRIDENT_MODULE_NAME,
  3585. +   id_table:   trident_pci_tbl,
  3586. +   probe:      trident_probe,
  3587. +   remove:      trident_remove,
  3588. +};
  3589. +
  3590. +static int __init trident_init_module (void)
  3591. +{
  3592. +   if (!pci_present())   /* No PCI bus in this machine! */
  3593. +      return -ENODEV;
  3594. +
  3595. +   printk(KERN_INFO "Trident 4DWave/SiS 7018/ALi 5451 PCI Audio, version "
  3596. +          DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
  3597. +
  3598. +   if (!pci_register_driver(&trident_pci_driver)) {
  3599. +      pci_unregister_driver(&trident_pci_driver);
  3600. +                return -ENODEV;
  3601. +   }
  3602. +   return 0;
  3603. +}
  3604. +
  3605. +static void __exit trident_cleanup_module (void)
  3606. +{
  3607. +   pci_unregister_driver(&trident_pci_driver);
  3608. +}
  3609. +
  3610. +module_init(trident_init_module);
  3611. +module_exit(trident_cleanup_module);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement