ALSA: lx6464es - command buffer API cleanup
[linux-2.6.git] / sound / pci / lx6464es / lx_core.c
1 /* -*- linux-c -*- *
2  *
3  * ALSA driver for the digigram lx6464es interface
4  * low-level interface
5  *
6  * Copyright (c) 2009 Tim Blechmann <tim@klingt.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; see the file COPYING.  If not, write to
20  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  *
23  */
24
25 /* #define RMH_DEBUG 1 */
26
27 #include <linux/module.h>
28 #include <linux/pci.h>
29 #include <linux/delay.h>
30
31 #include "lx6464es.h"
32 #include "lx_core.h"
33
34 /* low-level register access */
35
36 static const unsigned long dsp_port_offsets[] = {
37         0,
38         0x400,
39         0x401,
40         0x402,
41         0x403,
42         0x404,
43         0x405,
44         0x406,
45         0x407,
46         0x408,
47         0x409,
48         0x40a,
49         0x40b,
50         0x40c,
51
52         0x410,
53         0x411,
54         0x412,
55         0x413,
56         0x414,
57         0x415,
58         0x416,
59
60         0x420,
61         0x430,
62         0x431,
63         0x432,
64         0x433,
65         0x434,
66         0x440
67 };
68
69 static void __iomem *lx_dsp_register(struct lx6464es *chip, int port)
70 {
71         void __iomem *base_address = chip->port_dsp_bar;
72         return base_address + dsp_port_offsets[port]*4;
73 }
74
75 unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port)
76 {
77         void __iomem *address = lx_dsp_register(chip, port);
78         return ioread32(address);
79 }
80
81 static void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data,
82                                u32 len)
83 {
84         void __iomem *address = lx_dsp_register(chip, port);
85         memcpy_fromio(data, address, len*sizeof(u32));
86 }
87
88
89 void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data)
90 {
91         void __iomem *address = lx_dsp_register(chip, port);
92         iowrite32(data, address);
93 }
94
95 static void lx_dsp_reg_writebuf(struct lx6464es *chip, int port,
96                                 const u32 *data, u32 len)
97 {
98         void __iomem *address = lx_dsp_register(chip, port);
99         memcpy_toio(address, data, len*sizeof(u32));
100 }
101
102
103 static const unsigned long plx_port_offsets[] = {
104         0x04,
105         0x40,
106         0x44,
107         0x48,
108         0x4c,
109         0x50,
110         0x54,
111         0x58,
112         0x5c,
113         0x64,
114         0x68,
115         0x6C
116 };
117
118 static void __iomem *lx_plx_register(struct lx6464es *chip, int port)
119 {
120         void __iomem *base_address = chip->port_plx_remapped;
121         return base_address + plx_port_offsets[port];
122 }
123
124 unsigned long lx_plx_reg_read(struct lx6464es *chip, int port)
125 {
126         void __iomem *address = lx_plx_register(chip, port);
127         return ioread32(address);
128 }
129
130 void lx_plx_reg_write(struct lx6464es *chip, int port, u32 data)
131 {
132         void __iomem *address = lx_plx_register(chip, port);
133         iowrite32(data, address);
134 }
135
136 u32 lx_plx_mbox_read(struct lx6464es *chip, int mbox_nr)
137 {
138         int index;
139
140         switch (mbox_nr) {
141         case 1:
142                 index = ePLX_MBOX1;    break;
143         case 2:
144                 index = ePLX_MBOX2;    break;
145         case 3:
146                 index = ePLX_MBOX3;    break;
147         case 4:
148                 index = ePLX_MBOX4;    break;
149         case 5:
150                 index = ePLX_MBOX5;    break;
151         case 6:
152                 index = ePLX_MBOX6;    break;
153         case 7:
154                 index = ePLX_MBOX7;    break;
155         case 0:                 /* reserved for HF flags */
156                 snd_BUG();
157         default:
158                 return 0xdeadbeef;
159         }
160
161         return lx_plx_reg_read(chip, index);
162 }
163
164 int lx_plx_mbox_write(struct lx6464es *chip, int mbox_nr, u32 value)
165 {
166         int index = -1;
167
168         switch (mbox_nr) {
169         case 1:
170                 index = ePLX_MBOX1;    break;
171         case 3:
172                 index = ePLX_MBOX3;    break;
173         case 4:
174                 index = ePLX_MBOX4;    break;
175         case 5:
176                 index = ePLX_MBOX5;    break;
177         case 6:
178                 index = ePLX_MBOX6;    break;
179         case 7:
180                 index = ePLX_MBOX7;    break;
181         case 0:                 /* reserved for HF flags */
182         case 2:                 /* reserved for Pipe States
183                                  * the DSP keeps an image of it */
184                 snd_BUG();
185                 return -EBADRQC;
186         }
187
188         lx_plx_reg_write(chip, index, value);
189         return 0;
190 }
191
192
193 /* rmh */
194
195 #ifdef CONFIG_SND_DEBUG
196 #define CMD_NAME(a) a
197 #else
198 #define CMD_NAME(a) NULL
199 #endif
200
201 #define Reg_CSM_MR                      0x00000002
202 #define Reg_CSM_MC                      0x00000001
203
204 struct dsp_cmd_info {
205         u32    dcCodeOp;        /* Op Code of the command (usually 1st 24-bits
206                                  * word).*/
207         u16    dcCmdLength;     /* Command length in words of 24 bits.*/
208         u16    dcStatusType;    /* Status type: 0 for fixed length, 1 for
209                                  * random. */
210         u16    dcStatusLength;  /* Status length (if fixed).*/
211         char  *dcOpName;
212 };
213
214 /*
215   Initialization and control data for the Microblaze interface
216   - OpCode:
217     the opcode field of the command set at the proper offset
218   - CmdLength
219     the number of command words
220   - StatusType
221     offset in the status registers: 0 means that the return value may be
222     different from 0, and must be read
223   - StatusLength
224     the number of status words (in addition to the return value)
225 */
226
227 static struct dsp_cmd_info dsp_commands[] =
228 {
229         { (CMD_00_INFO_DEBUG << OPCODE_OFFSET)                  , 1 /*custom*/
230           , 1   , 0 /**/                    , CMD_NAME("INFO_DEBUG") },
231         { (CMD_01_GET_SYS_CFG << OPCODE_OFFSET)                 , 1 /**/
232           , 1      , 2 /**/                 , CMD_NAME("GET_SYS_CFG") },
233         { (CMD_02_SET_GRANULARITY << OPCODE_OFFSET)             , 1 /**/
234           , 1      , 0 /**/                 , CMD_NAME("SET_GRANULARITY") },
235         { (CMD_03_SET_TIMER_IRQ << OPCODE_OFFSET)               , 1 /**/
236           , 1      , 0 /**/                 , CMD_NAME("SET_TIMER_IRQ") },
237         { (CMD_04_GET_EVENT << OPCODE_OFFSET)                   , 1 /**/
238           , 1      , 0 /*up to 10*/     , CMD_NAME("GET_EVENT") },
239         { (CMD_05_GET_PIPES << OPCODE_OFFSET)                   , 1 /**/
240           , 1      , 2 /*up to 4*/      , CMD_NAME("GET_PIPES") },
241         { (CMD_06_ALLOCATE_PIPE << OPCODE_OFFSET)               , 1 /**/
242           , 0      , 0 /**/                 , CMD_NAME("ALLOCATE_PIPE") },
243         { (CMD_07_RELEASE_PIPE << OPCODE_OFFSET)                , 1 /**/
244           , 0      , 0 /**/                 , CMD_NAME("RELEASE_PIPE") },
245         { (CMD_08_ASK_BUFFERS << OPCODE_OFFSET)                 , 1 /**/
246           , 1      , MAX_STREAM_BUFFER  , CMD_NAME("ASK_BUFFERS") },
247         { (CMD_09_STOP_PIPE << OPCODE_OFFSET)                   , 1 /**/
248           , 0      , 0 /*up to 2*/      , CMD_NAME("STOP_PIPE") },
249         { (CMD_0A_GET_PIPE_SPL_COUNT << OPCODE_OFFSET)          , 1 /**/
250           , 1      , 1 /*up to 2*/      , CMD_NAME("GET_PIPE_SPL_COUNT") },
251         { (CMD_0B_TOGGLE_PIPE_STATE << OPCODE_OFFSET)           , 1 /*up to 5*/
252           , 1      , 0 /**/                 , CMD_NAME("TOGGLE_PIPE_STATE") },
253         { (CMD_0C_DEF_STREAM << OPCODE_OFFSET)                  , 1 /*up to 4*/
254           , 1      , 0 /**/                 , CMD_NAME("DEF_STREAM") },
255         { (CMD_0D_SET_MUTE  << OPCODE_OFFSET)                   , 3 /**/
256           , 1      , 0 /**/                 , CMD_NAME("SET_MUTE") },
257         { (CMD_0E_GET_STREAM_SPL_COUNT << OPCODE_OFFSET)        , 1/**/
258           , 1      , 2 /**/                 , CMD_NAME("GET_STREAM_SPL_COUNT") },
259         { (CMD_0F_UPDATE_BUFFER << OPCODE_OFFSET)               , 3 /*up to 4*/
260           , 0      , 1 /**/                 , CMD_NAME("UPDATE_BUFFER") },
261         { (CMD_10_GET_BUFFER << OPCODE_OFFSET)                  , 1 /**/
262           , 1      , 4 /**/                 , CMD_NAME("GET_BUFFER") },
263         { (CMD_11_CANCEL_BUFFER << OPCODE_OFFSET)               , 1 /**/
264           , 1      , 1 /*up to 4*/      , CMD_NAME("CANCEL_BUFFER") },
265         { (CMD_12_GET_PEAK << OPCODE_OFFSET)                    , 1 /**/
266           , 1      , 1 /**/                 , CMD_NAME("GET_PEAK") },
267         { (CMD_13_SET_STREAM_STATE << OPCODE_OFFSET)            , 1 /**/
268           , 1      , 0 /**/                 , CMD_NAME("SET_STREAM_STATE") },
269 };
270
271 static void lx_message_init(struct lx_rmh *rmh, enum cmd_mb_opcodes cmd)
272 {
273         snd_BUG_ON(cmd >= CMD_14_INVALID);
274
275         rmh->cmd[0] = dsp_commands[cmd].dcCodeOp;
276         rmh->cmd_len = dsp_commands[cmd].dcCmdLength;
277         rmh->stat_len = dsp_commands[cmd].dcStatusLength;
278         rmh->dsp_stat = dsp_commands[cmd].dcStatusType;
279         rmh->cmd_idx = cmd;
280         memset(&rmh->cmd[1], 0, (REG_CRM_NUMBER - 1) * sizeof(u32));
281
282 #ifdef CONFIG_SND_DEBUG
283         memset(rmh->stat, 0, REG_CRM_NUMBER * sizeof(u32));
284 #endif
285 #ifdef RMH_DEBUG
286         rmh->cmd_idx = cmd;
287 #endif
288 }
289
290 #ifdef RMH_DEBUG
291 #define LXRMH "lx6464es rmh: "
292 static void lx_message_dump(struct lx_rmh *rmh)
293 {
294         u8 idx = rmh->cmd_idx;
295         int i;
296
297         snd_printk(LXRMH "command %s\n", dsp_commands[idx].dcOpName);
298
299         for (i = 0; i != rmh->cmd_len; ++i)
300                 snd_printk(LXRMH "\tcmd[%d] %08x\n", i, rmh->cmd[i]);
301
302         for (i = 0; i != rmh->stat_len; ++i)
303                 snd_printk(LXRMH "\tstat[%d]: %08x\n", i, rmh->stat[i]);
304         snd_printk("\n");
305 }
306 #else
307 static inline void lx_message_dump(struct lx_rmh *rmh)
308 {}
309 #endif
310
311
312
313 /* sleep 500 - 100 = 400 times 100us -> the timeout is >= 40 ms */
314 #define XILINX_TIMEOUT_MS       40
315 #define XILINX_POLL_NO_SLEEP    100
316 #define XILINX_POLL_ITERATIONS  150
317
318
319 static int lx_message_send_atomic(struct lx6464es *chip, struct lx_rmh *rmh)
320 {
321         u32 reg = ED_DSP_TIMED_OUT;
322         int dwloop;
323
324         if (lx_dsp_reg_read(chip, eReg_CSM) & (Reg_CSM_MC | Reg_CSM_MR)) {
325                 snd_printk(KERN_ERR LXP "PIOSendMessage eReg_CSM %x\n", reg);
326                 return -EBUSY;
327         }
328
329         /* write command */
330         lx_dsp_reg_writebuf(chip, eReg_CRM1, rmh->cmd, rmh->cmd_len);
331
332         /* MicoBlaze gogogo */
333         lx_dsp_reg_write(chip, eReg_CSM, Reg_CSM_MC);
334
335         /* wait for device to answer */
336         for (dwloop = 0; dwloop != XILINX_TIMEOUT_MS * 1000; ++dwloop) {
337                 if (lx_dsp_reg_read(chip, eReg_CSM) & Reg_CSM_MR) {
338                         if (rmh->dsp_stat == 0)
339                                 reg = lx_dsp_reg_read(chip, eReg_CRM1);
340                         else
341                                 reg = 0;
342                         goto polling_successful;
343                 } else
344                         udelay(1);
345         }
346         snd_printk(KERN_WARNING LXP "TIMEOUT lx_message_send_atomic! "
347                    "polling failed\n");
348
349 polling_successful:
350         if ((reg & ERROR_VALUE) == 0) {
351                 /* read response */
352                 if (rmh->stat_len) {
353                         snd_BUG_ON(rmh->stat_len >= (REG_CRM_NUMBER-1));
354                         lx_dsp_reg_readbuf(chip, eReg_CRM2, rmh->stat,
355                                            rmh->stat_len);
356                 }
357         } else
358                 snd_printk(LXP "rmh error: %08x\n", reg);
359
360         /* clear Reg_CSM_MR */
361         lx_dsp_reg_write(chip, eReg_CSM, 0);
362
363         switch (reg) {
364         case ED_DSP_TIMED_OUT:
365                 snd_printk(KERN_WARNING LXP "lx_message_send: dsp timeout\n");
366                 return -ETIMEDOUT;
367
368         case ED_DSP_CRASHED:
369                 snd_printk(KERN_WARNING LXP "lx_message_send: dsp crashed\n");
370                 return -EAGAIN;
371         }
372
373         lx_message_dump(rmh);
374
375         return reg;
376 }
377
378
379 /* low-level dsp access */
380 int __devinit lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version)
381 {
382         u16 ret;
383         unsigned long flags;
384
385         spin_lock_irqsave(&chip->msg_lock, flags);
386
387         lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG);
388         ret = lx_message_send_atomic(chip, &chip->rmh);
389
390         *rdsp_version = chip->rmh.stat[1];
391         spin_unlock_irqrestore(&chip->msg_lock, flags);
392         return ret;
393 }
394
395 int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq)
396 {
397         u16 ret = 0;
398         unsigned long flags;
399         u32 freq_raw = 0;
400         u32 freq = 0;
401         u32 frequency = 0;
402
403         spin_lock_irqsave(&chip->msg_lock, flags);
404
405         lx_message_init(&chip->rmh, CMD_01_GET_SYS_CFG);
406         ret = lx_message_send_atomic(chip, &chip->rmh);
407
408         if (ret == 0) {
409                 freq_raw = chip->rmh.stat[0] >> FREQ_FIELD_OFFSET;
410                 freq = freq_raw & XES_FREQ_COUNT8_MASK;
411
412                 if ((freq < XES_FREQ_COUNT8_48_MAX) ||
413                     (freq > XES_FREQ_COUNT8_44_MIN))
414                         frequency = 0; /* unknown */
415                 else if (freq >= XES_FREQ_COUNT8_44_MAX)
416                         frequency = 44100;
417                 else
418                         frequency = 48000;
419         }
420
421         spin_unlock_irqrestore(&chip->msg_lock, flags);
422
423         *rfreq = frequency * chip->freq_ratio;
424
425         return ret;
426 }
427
428 int lx_dsp_get_mac(struct lx6464es *chip)
429 {
430         u32 macmsb, maclsb;
431
432         macmsb = lx_dsp_reg_read(chip, eReg_ADMACESMSB) & 0x00FFFFFF;
433         maclsb = lx_dsp_reg_read(chip, eReg_ADMACESLSB) & 0x00FFFFFF;
434
435         /* todo: endianess handling */
436         chip->mac_address[5] = ((u8 *)(&maclsb))[0];
437         chip->mac_address[4] = ((u8 *)(&maclsb))[1];
438         chip->mac_address[3] = ((u8 *)(&maclsb))[2];
439         chip->mac_address[2] = ((u8 *)(&macmsb))[0];
440         chip->mac_address[1] = ((u8 *)(&macmsb))[1];
441         chip->mac_address[0] = ((u8 *)(&macmsb))[2];
442
443         return 0;
444 }
445
446
447 int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran)
448 {
449         unsigned long flags;
450         int ret;
451
452         spin_lock_irqsave(&chip->msg_lock, flags);
453
454         lx_message_init(&chip->rmh, CMD_02_SET_GRANULARITY);
455         chip->rmh.cmd[0] |= gran;
456
457         ret = lx_message_send_atomic(chip, &chip->rmh);
458         spin_unlock_irqrestore(&chip->msg_lock, flags);
459         return ret;
460 }
461
462 int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data)
463 {
464         unsigned long flags;
465         int ret;
466
467         spin_lock_irqsave(&chip->msg_lock, flags);
468
469         lx_message_init(&chip->rmh, CMD_04_GET_EVENT);
470         chip->rmh.stat_len = 9; /* we don't necessarily need the full length */
471
472         ret = lx_message_send_atomic(chip, &chip->rmh);
473
474         if (!ret)
475                 memcpy(data, chip->rmh.stat, chip->rmh.stat_len * sizeof(u32));
476
477         spin_unlock_irqrestore(&chip->msg_lock, flags);
478         return ret;
479 }
480
481 #define CSES_TIMEOUT        100     /* microseconds */
482 #define CSES_CE             0x0001
483 #define CSES_BROADCAST      0x0002
484 #define CSES_UPDATE_LDSV    0x0004
485
486 int lx_dsp_es_check_pipeline(struct lx6464es *chip)
487 {
488         int i;
489
490         for (i = 0; i != CSES_TIMEOUT; ++i) {
491                 /*
492                  * le bit CSES_UPDATE_LDSV est Ã  1 dés que le macprog
493                  * est pret. il re-passe Ã  0 lorsque le premier read a
494                  * Ã©té fait. pour l'instant on retire le test car ce bit
495                  * passe a 1 environ 200 Ã  400 ms aprés que le registre
496                  * confES Ã  Ã©té Ã©crit (kick du xilinx ES).
497                  *
498                  * On ne teste que le bit CE.
499                  * */
500
501                 u32 cses = lx_dsp_reg_read(chip, eReg_CSES);
502
503                 if ((cses & CSES_CE) == 0)
504                         return 0;
505
506                 udelay(1);
507         }
508
509         return -ETIMEDOUT;
510 }
511
512
513 #define PIPE_INFO_TO_CMD(capture, pipe)                                 \
514         ((u32)((u32)(pipe) | ((capture) ? ID_IS_CAPTURE : 0L)) << ID_OFFSET)
515
516
517
518 /* low-level pipe handling */
519 int lx_pipe_allocate(struct lx6464es *chip, u32 pipe, int is_capture,
520                      int channels)
521 {
522         int err;
523         unsigned long flags;
524
525         u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
526
527         spin_lock_irqsave(&chip->msg_lock, flags);
528         lx_message_init(&chip->rmh, CMD_06_ALLOCATE_PIPE);
529
530         chip->rmh.cmd[0] |= pipe_cmd;
531         chip->rmh.cmd[0] |= channels;
532
533         err = lx_message_send_atomic(chip, &chip->rmh);
534         spin_unlock_irqrestore(&chip->msg_lock, flags);
535
536         if (err != 0)
537                 snd_printk(KERN_ERR "lx6464es: could not allocate pipe\n");
538
539         return err;
540 }
541
542 int lx_pipe_release(struct lx6464es *chip, u32 pipe, int is_capture)
543 {
544         int err;
545         unsigned long flags;
546
547         u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
548
549         spin_lock_irqsave(&chip->msg_lock, flags);
550         lx_message_init(&chip->rmh, CMD_07_RELEASE_PIPE);
551
552         chip->rmh.cmd[0] |= pipe_cmd;
553
554         err = lx_message_send_atomic(chip, &chip->rmh);
555         spin_unlock_irqrestore(&chip->msg_lock, flags);
556
557         return err;
558 }
559
560 int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture,
561                   u32 *r_needed, u32 *r_freed, u32 *size_array)
562 {
563         int err;
564         unsigned long flags;
565
566         u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
567
568 #ifdef CONFIG_SND_DEBUG
569         if (size_array)
570                 memset(size_array, 0, sizeof(u32)*MAX_STREAM_BUFFER);
571 #endif
572
573         *r_needed = 0;
574         *r_freed = 0;
575
576         spin_lock_irqsave(&chip->msg_lock, flags);
577         lx_message_init(&chip->rmh, CMD_08_ASK_BUFFERS);
578
579         chip->rmh.cmd[0] |= pipe_cmd;
580
581         err = lx_message_send_atomic(chip, &chip->rmh);
582
583         if (!err) {
584                 int i;
585                 for (i = 0; i < MAX_STREAM_BUFFER; ++i) {
586                         u32 stat = chip->rmh.stat[i];
587                         if (stat & (BF_EOB << BUFF_FLAGS_OFFSET)) {
588                                 /* finished */
589                                 *r_freed += 1;
590                                 if (size_array)
591                                         size_array[i] = stat & MASK_DATA_SIZE;
592                         } else if ((stat & (BF_VALID << BUFF_FLAGS_OFFSET))
593                                    == 0)
594                                 /* free */
595                                 *r_needed += 1;
596                 }
597
598 #if 0
599                 snd_printdd(LXP "CMD_08_ASK_BUFFERS: needed %d, freed %d\n",
600                             *r_needed, *r_freed);
601                 for (i = 0; i < MAX_STREAM_BUFFER; ++i) {
602                         for (i = 0; i != chip->rmh.stat_len; ++i)
603                                 snd_printdd("  stat[%d]: %x, %x\n", i,
604                                             chip->rmh.stat[i],
605                                             chip->rmh.stat[i] & MASK_DATA_SIZE);
606                 }
607 #endif
608         }
609
610         spin_unlock_irqrestore(&chip->msg_lock, flags);
611         return err;
612 }
613
614
615 int lx_pipe_stop(struct lx6464es *chip, u32 pipe, int is_capture)
616 {
617         int err;
618         unsigned long flags;
619
620         u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
621
622         spin_lock_irqsave(&chip->msg_lock, flags);
623         lx_message_init(&chip->rmh, CMD_09_STOP_PIPE);
624
625         chip->rmh.cmd[0] |= pipe_cmd;
626
627         err = lx_message_send_atomic(chip, &chip->rmh);
628
629         spin_unlock_irqrestore(&chip->msg_lock, flags);
630         return err;
631 }
632
633 static int lx_pipe_toggle_state(struct lx6464es *chip, u32 pipe, int is_capture)
634 {
635         int err;
636         unsigned long flags;
637
638         u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
639
640         spin_lock_irqsave(&chip->msg_lock, flags);
641         lx_message_init(&chip->rmh, CMD_0B_TOGGLE_PIPE_STATE);
642
643         chip->rmh.cmd[0] |= pipe_cmd;
644
645         err = lx_message_send_atomic(chip, &chip->rmh);
646
647         spin_unlock_irqrestore(&chip->msg_lock, flags);
648         return err;
649 }
650
651
652 int lx_pipe_start(struct lx6464es *chip, u32 pipe, int is_capture)
653 {
654         int err;
655
656         err = lx_pipe_wait_for_idle(chip, pipe, is_capture);
657         if (err < 0)
658                 return err;
659
660         err = lx_pipe_toggle_state(chip, pipe, is_capture);
661
662         return err;
663 }
664
665 int lx_pipe_pause(struct lx6464es *chip, u32 pipe, int is_capture)
666 {
667         int err = 0;
668
669         err = lx_pipe_wait_for_start(chip, pipe, is_capture);
670         if (err < 0)
671                 return err;
672
673         err = lx_pipe_toggle_state(chip, pipe, is_capture);
674
675         return err;
676 }
677
678
679 int lx_pipe_sample_count(struct lx6464es *chip, u32 pipe, int is_capture,
680                          u64 *rsample_count)
681 {
682         int err;
683         unsigned long flags;
684
685         u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
686
687         spin_lock_irqsave(&chip->msg_lock, flags);
688         lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT);
689
690         chip->rmh.cmd[0] |= pipe_cmd;
691         chip->rmh.stat_len = 2; /* need all words here! */
692
693         err = lx_message_send_atomic(chip, &chip->rmh); /* don't sleep! */
694
695         if (err != 0)
696                 snd_printk(KERN_ERR
697                            "lx6464es: could not query pipe's sample count\n");
698         else {
699                 *rsample_count = ((u64)(chip->rmh.stat[0] & MASK_SPL_COUNT_HI)
700                                   << 24)     /* hi part */
701                         + chip->rmh.stat[1]; /* lo part */
702         }
703
704         spin_unlock_irqrestore(&chip->msg_lock, flags);
705         return err;
706 }
707
708 int lx_pipe_state(struct lx6464es *chip, u32 pipe, int is_capture, u16 *rstate)
709 {
710         int err;
711         unsigned long flags;
712
713         u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
714
715         spin_lock_irqsave(&chip->msg_lock, flags);
716         lx_message_init(&chip->rmh, CMD_0A_GET_PIPE_SPL_COUNT);
717
718         chip->rmh.cmd[0] |= pipe_cmd;
719
720         err = lx_message_send_atomic(chip, &chip->rmh);
721
722         if (err != 0)
723                 snd_printk(KERN_ERR "lx6464es: could not query pipe's state\n");
724         else
725                 *rstate = (chip->rmh.stat[0] >> PSTATE_OFFSET) & 0x0F;
726
727         spin_unlock_irqrestore(&chip->msg_lock, flags);
728         return err;
729 }
730
731 static int lx_pipe_wait_for_state(struct lx6464es *chip, u32 pipe,
732                                   int is_capture, u16 state)
733 {
734         int i;
735
736         /* max 2*PCMOnlyGranularity = 2*1024 at 44100 = < 50 ms:
737          * timeout 50 ms */
738         for (i = 0; i != 50; ++i) {
739                 u16 current_state;
740                 int err = lx_pipe_state(chip, pipe, is_capture, &current_state);
741
742                 if (err < 0)
743                         return err;
744
745                 if (current_state == state)
746                         return 0;
747
748                 mdelay(1);
749         }
750
751         return -ETIMEDOUT;
752 }
753
754 int lx_pipe_wait_for_start(struct lx6464es *chip, u32 pipe, int is_capture)
755 {
756         return lx_pipe_wait_for_state(chip, pipe, is_capture, PSTATE_RUN);
757 }
758
759 int lx_pipe_wait_for_idle(struct lx6464es *chip, u32 pipe, int is_capture)
760 {
761         return lx_pipe_wait_for_state(chip, pipe, is_capture, PSTATE_IDLE);
762 }
763
764 /* low-level stream handling */
765 int lx_stream_set_state(struct lx6464es *chip, u32 pipe,
766                                int is_capture, enum stream_state_t state)
767 {
768         int err;
769         unsigned long flags;
770
771         u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
772
773         spin_lock_irqsave(&chip->msg_lock, flags);
774         lx_message_init(&chip->rmh, CMD_13_SET_STREAM_STATE);
775
776         chip->rmh.cmd[0] |= pipe_cmd;
777         chip->rmh.cmd[0] |= state;
778
779         err = lx_message_send_atomic(chip, &chip->rmh);
780         spin_unlock_irqrestore(&chip->msg_lock, flags);
781
782         return err;
783 }
784
785 int lx_stream_set_format(struct lx6464es *chip, struct snd_pcm_runtime *runtime,
786                          u32 pipe, int is_capture)
787 {
788         int err;
789         unsigned long flags;
790
791         u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
792
793         u32 channels = runtime->channels;
794
795         if (runtime->channels != channels)
796                 snd_printk(KERN_ERR LXP "channel count mismatch: %d vs %d",
797                            runtime->channels, channels);
798
799         spin_lock_irqsave(&chip->msg_lock, flags);
800         lx_message_init(&chip->rmh, CMD_0C_DEF_STREAM);
801
802         chip->rmh.cmd[0] |= pipe_cmd;
803
804         if (runtime->sample_bits == 16)
805                 /* 16 bit format */
806                 chip->rmh.cmd[0] |= (STREAM_FMT_16b << STREAM_FMT_OFFSET);
807
808         if (snd_pcm_format_little_endian(runtime->format))
809                 /* little endian/intel format */
810                 chip->rmh.cmd[0] |= (STREAM_FMT_intel << STREAM_FMT_OFFSET);
811
812         chip->rmh.cmd[0] |= channels-1;
813
814         err = lx_message_send_atomic(chip, &chip->rmh);
815         spin_unlock_irqrestore(&chip->msg_lock, flags);
816
817         return err;
818 }
819
820 int lx_stream_state(struct lx6464es *chip, u32 pipe, int is_capture,
821                     int *rstate)
822 {
823         int err;
824         unsigned long flags;
825
826         u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
827
828         spin_lock_irqsave(&chip->msg_lock, flags);
829         lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT);
830
831         chip->rmh.cmd[0] |= pipe_cmd;
832
833         err = lx_message_send_atomic(chip, &chip->rmh);
834
835         *rstate = (chip->rmh.stat[0] & SF_START) ? START_STATE : PAUSE_STATE;
836
837         spin_unlock_irqrestore(&chip->msg_lock, flags);
838         return err;
839 }
840
841 int lx_stream_sample_position(struct lx6464es *chip, u32 pipe, int is_capture,
842                               u64 *r_bytepos)
843 {
844         int err;
845         unsigned long flags;
846
847         u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
848
849         spin_lock_irqsave(&chip->msg_lock, flags);
850         lx_message_init(&chip->rmh, CMD_0E_GET_STREAM_SPL_COUNT);
851
852         chip->rmh.cmd[0] |= pipe_cmd;
853
854         err = lx_message_send_atomic(chip, &chip->rmh);
855
856         *r_bytepos = ((u64) (chip->rmh.stat[0] & MASK_SPL_COUNT_HI)
857                       << 32)         /* hi part */
858                 + chip->rmh.stat[1]; /* lo part */
859
860         spin_unlock_irqrestore(&chip->msg_lock, flags);
861         return err;
862 }
863
864 /* low-level buffer handling */
865 int lx_buffer_give(struct lx6464es *chip, u32 pipe, int is_capture,
866                    u32 buffer_size, u32 buf_address_lo, u32 buf_address_hi,
867                    u32 *r_buffer_index)
868 {
869         int err;
870         unsigned long flags;
871
872         u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
873
874         spin_lock_irqsave(&chip->msg_lock, flags);
875         lx_message_init(&chip->rmh, CMD_0F_UPDATE_BUFFER);
876
877         chip->rmh.cmd[0] |= pipe_cmd;
878         chip->rmh.cmd[0] |= BF_NOTIFY_EOB; /* request interrupt notification */
879
880         /* todo: pause request, circular buffer */
881
882         chip->rmh.cmd[1] = buffer_size & MASK_DATA_SIZE;
883         chip->rmh.cmd[2] = buf_address_lo;
884
885         if (buf_address_hi) {
886                 chip->rmh.cmd_len = 4;
887                 chip->rmh.cmd[3] = buf_address_hi;
888                 chip->rmh.cmd[0] |= BF_64BITS_ADR;
889         }
890
891         err = lx_message_send_atomic(chip, &chip->rmh);
892
893         if (err == 0) {
894                 *r_buffer_index = chip->rmh.stat[0];
895                 goto done;
896         }
897
898         if (err == EB_RBUFFERS_TABLE_OVERFLOW)
899                 snd_printk(LXP "lx_buffer_give EB_RBUFFERS_TABLE_OVERFLOW\n");
900
901         if (err == EB_INVALID_STREAM)
902                 snd_printk(LXP "lx_buffer_give EB_INVALID_STREAM\n");
903
904         if (err == EB_CMD_REFUSED)
905                 snd_printk(LXP "lx_buffer_give EB_CMD_REFUSED\n");
906
907  done:
908         spin_unlock_irqrestore(&chip->msg_lock, flags);
909         return err;
910 }
911
912 int lx_buffer_free(struct lx6464es *chip, u32 pipe, int is_capture,
913                    u32 *r_buffer_size)
914 {
915         int err;
916         unsigned long flags;
917
918         u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
919
920         spin_lock_irqsave(&chip->msg_lock, flags);
921         lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER);
922
923         chip->rmh.cmd[0] |= pipe_cmd;
924         chip->rmh.cmd[0] |= MASK_BUFFER_ID; /* ask for the current buffer: the
925                                              * microblaze will seek for it */
926
927         err = lx_message_send_atomic(chip, &chip->rmh);
928
929         if (err == 0)
930                 *r_buffer_size = chip->rmh.stat[0]  & MASK_DATA_SIZE;
931
932         spin_unlock_irqrestore(&chip->msg_lock, flags);
933         return err;
934 }
935
936 int lx_buffer_cancel(struct lx6464es *chip, u32 pipe, int is_capture,
937                      u32 buffer_index)
938 {
939         int err;
940         unsigned long flags;
941
942         u32 pipe_cmd = PIPE_INFO_TO_CMD(is_capture, pipe);
943
944         spin_lock_irqsave(&chip->msg_lock, flags);
945         lx_message_init(&chip->rmh, CMD_11_CANCEL_BUFFER);
946
947         chip->rmh.cmd[0] |= pipe_cmd;
948         chip->rmh.cmd[0] |= buffer_index;
949
950         err = lx_message_send_atomic(chip, &chip->rmh);
951
952         spin_unlock_irqrestore(&chip->msg_lock, flags);
953         return err;
954 }
955
956
957 /* low-level gain/peak handling
958  *
959  * \todo: can we unmute capture/playback channels independently?
960  *
961  * */
962 int lx_level_unmute(struct lx6464es *chip, int is_capture, int unmute)
963 {
964         int err;
965         unsigned long flags;
966
967         /* bit set to 1: channel muted */
968         u64 mute_mask = unmute ? 0 : 0xFFFFFFFFFFFFFFFFLLU;
969
970         spin_lock_irqsave(&chip->msg_lock, flags);
971         lx_message_init(&chip->rmh, CMD_0D_SET_MUTE);
972
973         chip->rmh.cmd[0] |= PIPE_INFO_TO_CMD(is_capture, 0);
974
975         chip->rmh.cmd[1] = (u32)(mute_mask >> (u64)32);        /* hi part */
976         chip->rmh.cmd[2] = (u32)(mute_mask & (u64)0xFFFFFFFF); /* lo part */
977
978         snd_printk("mute %x %x %x\n", chip->rmh.cmd[0], chip->rmh.cmd[1],
979                    chip->rmh.cmd[2]);
980
981         err = lx_message_send_atomic(chip, &chip->rmh);
982
983         spin_unlock_irqrestore(&chip->msg_lock, flags);
984         return err;
985 }
986
987 static u32 peak_map[] = {
988         0x00000109, /* -90.308dB */
989         0x0000083B, /* -72.247dB */
990         0x000020C4, /* -60.205dB */
991         0x00008273, /* -48.030dB */
992         0x00020756, /* -36.005dB */
993         0x00040C37, /* -30.001dB */
994         0x00081385, /* -24.002dB */
995         0x00101D3F, /* -18.000dB */
996         0x0016C310, /* -15.000dB */
997         0x002026F2, /* -12.001dB */
998         0x002D6A86, /* -9.000dB */
999         0x004026E6, /* -6.004dB */
1000         0x005A9DF6, /* -3.000dB */
1001         0x0065AC8B, /* -2.000dB */
1002         0x00721481, /* -1.000dB */
1003         0x007FFFFF, /* FS */
1004 };
1005
1006 int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels,
1007                    u32 *r_levels)
1008 {
1009         int err = 0;
1010         unsigned long flags;
1011         int i;
1012         spin_lock_irqsave(&chip->msg_lock, flags);
1013
1014         for (i = 0; i < channels; i += 4) {
1015                 u32 s0, s1, s2, s3;
1016
1017                 lx_message_init(&chip->rmh, CMD_12_GET_PEAK);
1018                 chip->rmh.cmd[0] |= PIPE_INFO_TO_CMD(is_capture, i);
1019
1020                 err = lx_message_send_atomic(chip, &chip->rmh);
1021
1022                 if (err == 0) {
1023                         s0 = peak_map[chip->rmh.stat[0] & 0x0F];
1024                         s1 = peak_map[(chip->rmh.stat[0] >>  4) & 0xf];
1025                         s2 = peak_map[(chip->rmh.stat[0] >>  8) & 0xf];
1026                         s3 = peak_map[(chip->rmh.stat[0] >>  12) & 0xf];
1027                 } else
1028                         s0 = s1 = s2 = s3 = 0;
1029
1030                 r_levels[0] = s0;
1031                 r_levels[1] = s1;
1032                 r_levels[2] = s2;
1033                 r_levels[3] = s3;
1034
1035                 r_levels += 4;
1036         }
1037
1038         spin_unlock_irqrestore(&chip->msg_lock, flags);
1039         return err;
1040 }
1041
1042 /* interrupt handling */
1043 #define PCX_IRQ_NONE 0
1044 #define IRQCS_ACTIVE_PCIDB  0x00002000L         /* Bit nÃ\203¸ 13 */
1045 #define IRQCS_ENABLE_PCIIRQ 0x00000100L         /* Bit nÃ\203¸ 08 */
1046 #define IRQCS_ENABLE_PCIDB  0x00000200L         /* Bit nÃ\203¸ 09 */
1047
1048 static u32 lx_interrupt_test_ack(struct lx6464es *chip)
1049 {
1050         u32 irqcs = lx_plx_reg_read(chip, ePLX_IRQCS);
1051
1052         /* Test if PCI Doorbell interrupt is active */
1053         if (irqcs & IRQCS_ACTIVE_PCIDB) {
1054                 u32 temp;
1055                 irqcs = PCX_IRQ_NONE;
1056
1057                 while ((temp = lx_plx_reg_read(chip, ePLX_L2PCIDB))) {
1058                         /* RAZ interrupt */
1059                         irqcs |= temp;
1060                         lx_plx_reg_write(chip, ePLX_L2PCIDB, temp);
1061                 }
1062
1063                 return irqcs;
1064         }
1065         return PCX_IRQ_NONE;
1066 }
1067
1068 static int lx_interrupt_ack(struct lx6464es *chip, u32 *r_irqsrc,
1069                             int *r_async_pending, int *r_async_escmd)
1070 {
1071         u32 irq_async;
1072         u32 irqsrc = lx_interrupt_test_ack(chip);
1073
1074         if (irqsrc == PCX_IRQ_NONE)
1075                 return 0;
1076
1077         *r_irqsrc = irqsrc;
1078
1079         irq_async = irqsrc & MASK_SYS_ASYNC_EVENTS; /* + EtherSound response
1080                                                      * (set by xilinx) + EOB */
1081
1082         if (irq_async & MASK_SYS_STATUS_ESA) {
1083                 irq_async &= ~MASK_SYS_STATUS_ESA;
1084                 *r_async_escmd = 1;
1085         }
1086
1087         if (irq_async) {
1088                 /* snd_printd("interrupt: async event pending\n"); */
1089                 *r_async_pending = 1;
1090         }
1091
1092         return 1;
1093 }
1094
1095 static int lx_interrupt_handle_async_events(struct lx6464es *chip, u32 irqsrc,
1096                                             int *r_freq_changed,
1097                                             u64 *r_notified_in_pipe_mask,
1098                                             u64 *r_notified_out_pipe_mask)
1099 {
1100         int err;
1101         u32 stat[9];            /* answer from CMD_04_GET_EVENT */
1102
1103         /* On peut optimiser pour ne pas lire les evenements vides
1104          * les mots de rÃ\203©ponse sont dans l'ordre suivant :
1105          * Stat[0]      mot de status gÃ\203©nÃ\203©ral
1106          * Stat[1]      fin de buffer OUT pF
1107          * Stat[2]      fin de buffer OUT pf
1108          * Stat[3]      fin de buffer IN pF
1109          * Stat[4]      fin de buffer IN pf
1110          * Stat[5]      underrun poid fort
1111          * Stat[6]      underrun poid faible
1112          * Stat[7]      overrun poid fort
1113          * Stat[8]      overrun poid faible
1114          * */
1115
1116         u64 orun_mask;
1117         u64 urun_mask;
1118 #if 0
1119         int has_underrun   = (irqsrc & MASK_SYS_STATUS_URUN) ? 1 : 0;
1120         int has_overrun    = (irqsrc & MASK_SYS_STATUS_ORUN) ? 1 : 0;
1121 #endif
1122         int eb_pending_out = (irqsrc & MASK_SYS_STATUS_EOBO) ? 1 : 0;
1123         int eb_pending_in  = (irqsrc & MASK_SYS_STATUS_EOBI) ? 1 : 0;
1124
1125         *r_freq_changed = (irqsrc & MASK_SYS_STATUS_FREQ) ? 1 : 0;
1126
1127         err = lx_dsp_read_async_events(chip, stat);
1128         if (err < 0)
1129                 return err;
1130
1131         if (eb_pending_in) {
1132                 *r_notified_in_pipe_mask = ((u64)stat[3] << 32)
1133                         + stat[4];
1134                 snd_printdd(LXP "interrupt: EOBI pending %llx\n",
1135                             *r_notified_in_pipe_mask);
1136         }
1137         if (eb_pending_out) {
1138                 *r_notified_out_pipe_mask = ((u64)stat[1] << 32)
1139                         + stat[2];
1140                 snd_printdd(LXP "interrupt: EOBO pending %llx\n",
1141                             *r_notified_out_pipe_mask);
1142         }
1143
1144         orun_mask = ((u64)stat[7] << 32) + stat[8];
1145         urun_mask = ((u64)stat[5] << 32) + stat[6];
1146
1147         /* todo: handle xrun notification */
1148
1149         return err;
1150 }
1151
1152 static int lx_interrupt_request_new_buffer(struct lx6464es *chip,
1153                                            struct lx_stream *lx_stream)
1154 {
1155         struct snd_pcm_substream *substream = lx_stream->stream;
1156         const unsigned int is_capture = lx_stream->is_capture;
1157         int err;
1158         unsigned long flags;
1159
1160         const u32 channels = substream->runtime->channels;
1161         const u32 bytes_per_frame = channels * 3;
1162         const u32 period_size = substream->runtime->period_size;
1163         const u32 period_bytes = period_size * bytes_per_frame;
1164         const u32 pos = lx_stream->frame_pos;
1165         const u32 next_pos = ((pos+1) == substream->runtime->periods) ?
1166                 0 : pos + 1;
1167
1168         dma_addr_t buf = substream->dma_buffer.addr + pos * period_bytes;
1169         u32 buf_hi = 0;
1170         u32 buf_lo = 0;
1171         u32 buffer_index = 0;
1172
1173         u32 needed, freed;
1174         u32 size_array[MAX_STREAM_BUFFER];
1175
1176         snd_printdd("->lx_interrupt_request_new_buffer\n");
1177
1178         spin_lock_irqsave(&chip->lock, flags);
1179
1180         err = lx_buffer_ask(chip, 0, is_capture, &needed, &freed, size_array);
1181         snd_printdd(LXP "interrupt: needed %d, freed %d\n", needed, freed);
1182
1183         unpack_pointer(buf, &buf_lo, &buf_hi);
1184         err = lx_buffer_give(chip, 0, is_capture, period_bytes, buf_lo, buf_hi,
1185                              &buffer_index);
1186         snd_printdd(LXP "interrupt: gave buffer index %x on %p (%d bytes)\n",
1187                     buffer_index, (void *)buf, period_bytes);
1188
1189         lx_stream->frame_pos = next_pos;
1190         spin_unlock_irqrestore(&chip->lock, flags);
1191
1192         return err;
1193 }
1194
1195 void lx_tasklet_playback(unsigned long data)
1196 {
1197         struct lx6464es *chip = (struct lx6464es *)data;
1198         struct lx_stream *lx_stream = &chip->playback_stream;
1199         int err;
1200
1201         snd_printdd("->lx_tasklet_playback\n");
1202
1203         err = lx_interrupt_request_new_buffer(chip, lx_stream);
1204         if (err < 0)
1205                 snd_printk(KERN_ERR LXP
1206                            "cannot request new buffer for playback\n");
1207
1208         snd_pcm_period_elapsed(lx_stream->stream);
1209 }
1210
1211 void lx_tasklet_capture(unsigned long data)
1212 {
1213         struct lx6464es *chip = (struct lx6464es *)data;
1214         struct lx_stream *lx_stream = &chip->capture_stream;
1215         int err;
1216
1217         snd_printdd("->lx_tasklet_capture\n");
1218         err = lx_interrupt_request_new_buffer(chip, lx_stream);
1219         if (err < 0)
1220                 snd_printk(KERN_ERR LXP
1221                            "cannot request new buffer for capture\n");
1222
1223         snd_pcm_period_elapsed(lx_stream->stream);
1224 }
1225
1226
1227
1228 static int lx_interrupt_handle_audio_transfer(struct lx6464es *chip,
1229                                               u64 notified_in_pipe_mask,
1230                                               u64 notified_out_pipe_mask)
1231 {
1232         int err = 0;
1233
1234         if (notified_in_pipe_mask) {
1235                 snd_printdd(LXP "requesting audio transfer for capture\n");
1236                 tasklet_hi_schedule(&chip->tasklet_capture);
1237         }
1238
1239         if (notified_out_pipe_mask) {
1240                 snd_printdd(LXP "requesting audio transfer for playback\n");
1241                 tasklet_hi_schedule(&chip->tasklet_playback);
1242         }
1243
1244         return err;
1245 }
1246
1247
1248 irqreturn_t lx_interrupt(int irq, void *dev_id)
1249 {
1250         struct lx6464es *chip = dev_id;
1251         int async_pending, async_escmd;
1252         u32 irqsrc;
1253
1254         spin_lock(&chip->lock);
1255
1256         snd_printdd("**************************************************\n");
1257
1258         if (!lx_interrupt_ack(chip, &irqsrc, &async_pending, &async_escmd)) {
1259                 spin_unlock(&chip->lock);
1260                 snd_printdd("IRQ_NONE\n");
1261                 return IRQ_NONE; /* this device did not cause the interrupt */
1262         }
1263
1264         if (irqsrc & MASK_SYS_STATUS_CMD_DONE)
1265                 goto exit;
1266
1267 #if 0
1268         if (irqsrc & MASK_SYS_STATUS_EOBI)
1269                 snd_printdd(LXP "interrupt: EOBI\n");
1270
1271         if (irqsrc & MASK_SYS_STATUS_EOBO)
1272                 snd_printdd(LXP "interrupt: EOBO\n");
1273
1274         if (irqsrc & MASK_SYS_STATUS_URUN)
1275                 snd_printdd(LXP "interrupt: URUN\n");
1276
1277         if (irqsrc & MASK_SYS_STATUS_ORUN)
1278                 snd_printdd(LXP "interrupt: ORUN\n");
1279 #endif
1280
1281         if (async_pending) {
1282                 u64 notified_in_pipe_mask = 0;
1283                 u64 notified_out_pipe_mask = 0;
1284                 int freq_changed;
1285                 int err;
1286
1287                 /* handle async events */
1288                 err = lx_interrupt_handle_async_events(chip, irqsrc,
1289                                                        &freq_changed,
1290                                                        &notified_in_pipe_mask,
1291                                                        &notified_out_pipe_mask);
1292                 if (err)
1293                         snd_printk(KERN_ERR LXP
1294                                    "error handling async events\n");
1295
1296                 err = lx_interrupt_handle_audio_transfer(chip,
1297                                                          notified_in_pipe_mask,
1298                                                          notified_out_pipe_mask
1299                         );
1300                 if (err)
1301                         snd_printk(KERN_ERR LXP
1302                                    "error during audio transfer\n");
1303         }
1304
1305         if (async_escmd) {
1306 #if 0
1307                 /* backdoor for ethersound commands
1308                  *
1309                  * for now, we do not need this
1310                  *
1311                  * */
1312
1313                 snd_printdd("lx6464es: interrupt requests escmd handling\n");
1314 #endif
1315         }
1316
1317 exit:
1318         spin_unlock(&chip->lock);
1319         return IRQ_HANDLED;     /* this device caused the interrupt */
1320 }
1321
1322
1323 static void lx_irq_set(struct lx6464es *chip, int enable)
1324 {
1325         u32 reg = lx_plx_reg_read(chip, ePLX_IRQCS);
1326
1327         /* enable/disable interrupts
1328          *
1329          * Set the Doorbell and PCI interrupt enable bits
1330          *
1331          * */
1332         if (enable)
1333                 reg |=  (IRQCS_ENABLE_PCIIRQ | IRQCS_ENABLE_PCIDB);
1334         else
1335                 reg &= ~(IRQCS_ENABLE_PCIIRQ | IRQCS_ENABLE_PCIDB);
1336         lx_plx_reg_write(chip, ePLX_IRQCS, reg);
1337 }
1338
1339 void lx_irq_enable(struct lx6464es *chip)
1340 {
1341         snd_printdd("->lx_irq_enable\n");
1342         lx_irq_set(chip, 1);
1343 }
1344
1345 void lx_irq_disable(struct lx6464es *chip)
1346 {
1347         snd_printdd("->lx_irq_disable\n");
1348         lx_irq_set(chip, 0);
1349 }