|
@@ -132,13 +132,15 @@ static int pcxhr_check_reg_bit(struct pcxhr_mgr *mgr, unsigned int reg,
|
|
|
*read = PCXHR_INPB(mgr, reg);
|
|
|
if ((*read & mask) == bit) {
|
|
|
if (i > 100)
|
|
|
- snd_printdd("ATTENTION! check_reg(%x) loopcount=%d\n",
|
|
|
+ snd_printdd("ATTENTION! check_reg(%x) "
|
|
|
+ "loopcount=%d\n",
|
|
|
reg, i);
|
|
|
return 0;
|
|
|
}
|
|
|
i++;
|
|
|
} while (time_after_eq(end_time, jiffies));
|
|
|
- snd_printk(KERN_ERR "pcxhr_check_reg_bit: timeout, reg=%x, mask=0x%x, val=0x%x\n",
|
|
|
+ snd_printk(KERN_ERR
|
|
|
+ "pcxhr_check_reg_bit: timeout, reg=%x, mask=0x%x, val=%x\n",
|
|
|
reg, mask, *read);
|
|
|
return -EIO;
|
|
|
}
|
|
@@ -159,18 +161,22 @@ static int pcxhr_check_reg_bit(struct pcxhr_mgr *mgr, unsigned int reg,
|
|
|
#define PCXHR_IT_TEST_XILINX (0x0000003C | PCXHR_MASK_IT_HF1 | \
|
|
|
PCXHR_MASK_IT_MANAGE_HF5)
|
|
|
#define PCXHR_IT_DOWNLOAD_BOOT (0x0000000C | PCXHR_MASK_IT_HF1 | \
|
|
|
- PCXHR_MASK_IT_MANAGE_HF5 | PCXHR_MASK_IT_WAIT)
|
|
|
+ PCXHR_MASK_IT_MANAGE_HF5 | \
|
|
|
+ PCXHR_MASK_IT_WAIT)
|
|
|
#define PCXHR_IT_RESET_BOARD_FUNC (0x0000000C | PCXHR_MASK_IT_HF0 | \
|
|
|
- PCXHR_MASK_IT_MANAGE_HF5 | PCXHR_MASK_IT_WAIT_EXTRA)
|
|
|
+ PCXHR_MASK_IT_MANAGE_HF5 | \
|
|
|
+ PCXHR_MASK_IT_WAIT_EXTRA)
|
|
|
#define PCXHR_IT_DOWNLOAD_DSP (0x0000000C | \
|
|
|
- PCXHR_MASK_IT_MANAGE_HF5 | PCXHR_MASK_IT_WAIT)
|
|
|
+ PCXHR_MASK_IT_MANAGE_HF5 | \
|
|
|
+ PCXHR_MASK_IT_WAIT)
|
|
|
#define PCXHR_IT_DEBUG (0x0000005A | PCXHR_MASK_IT_NO_HF0_HF1)
|
|
|
#define PCXHR_IT_RESET_SEMAPHORE (0x0000005C | PCXHR_MASK_IT_NO_HF0_HF1)
|
|
|
#define PCXHR_IT_MESSAGE (0x00000074 | PCXHR_MASK_IT_NO_HF0_HF1)
|
|
|
#define PCXHR_IT_RESET_CHK (0x00000076 | PCXHR_MASK_IT_NO_HF0_HF1)
|
|
|
#define PCXHR_IT_UPDATE_RBUFFER (0x00000078 | PCXHR_MASK_IT_NO_HF0_HF1)
|
|
|
|
|
|
-static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr, unsigned int itdsp, int atomic)
|
|
|
+static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr,
|
|
|
+ unsigned int itdsp, int atomic)
|
|
|
{
|
|
|
int err;
|
|
|
unsigned char reg;
|
|
@@ -178,17 +184,21 @@ static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr, unsigned int itdsp, int atom
|
|
|
if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) {
|
|
|
/* clear hf5 bit */
|
|
|
PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX0,
|
|
|
- PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & ~PCXHR_MBOX0_HF5);
|
|
|
+ PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) &
|
|
|
+ ~PCXHR_MBOX0_HF5);
|
|
|
}
|
|
|
if ((itdsp & PCXHR_MASK_IT_NO_HF0_HF1) == 0) {
|
|
|
- reg = PCXHR_ICR_HI08_RREQ | PCXHR_ICR_HI08_TREQ | PCXHR_ICR_HI08_HDRQ;
|
|
|
+ reg = (PCXHR_ICR_HI08_RREQ |
|
|
|
+ PCXHR_ICR_HI08_TREQ |
|
|
|
+ PCXHR_ICR_HI08_HDRQ);
|
|
|
if (itdsp & PCXHR_MASK_IT_HF0)
|
|
|
reg |= PCXHR_ICR_HI08_HF0;
|
|
|
if (itdsp & PCXHR_MASK_IT_HF1)
|
|
|
reg |= PCXHR_ICR_HI08_HF1;
|
|
|
PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg);
|
|
|
}
|
|
|
- reg = (unsigned char)(((itdsp & PCXHR_MASK_EXTRA_INFO) >> 1) | PCXHR_CVR_HI08_HC);
|
|
|
+ reg = (unsigned char)(((itdsp & PCXHR_MASK_EXTRA_INFO) >> 1) |
|
|
|
+ PCXHR_CVR_HI08_HC);
|
|
|
PCXHR_OUTPB(mgr, PCXHR_DSP_CVR, reg);
|
|
|
if (itdsp & PCXHR_MASK_IT_WAIT) {
|
|
|
if (atomic)
|
|
@@ -211,10 +221,14 @@ static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr, unsigned int itdsp, int atom
|
|
|
}
|
|
|
if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) {
|
|
|
/* wait for hf5 bit */
|
|
|
- err = pcxhr_check_reg_bit(mgr, PCXHR_PLX_MBOX0, PCXHR_MBOX0_HF5,
|
|
|
- PCXHR_MBOX0_HF5, PCXHR_TIMEOUT_DSP, ®);
|
|
|
+ err = pcxhr_check_reg_bit(mgr, PCXHR_PLX_MBOX0,
|
|
|
+ PCXHR_MBOX0_HF5,
|
|
|
+ PCXHR_MBOX0_HF5,
|
|
|
+ PCXHR_TIMEOUT_DSP,
|
|
|
+ ®);
|
|
|
if (err) {
|
|
|
- snd_printk(KERN_ERR "pcxhr_send_it_dsp : TIMEOUT HF5\n");
|
|
|
+ snd_printk(KERN_ERR
|
|
|
+ "pcxhr_send_it_dsp : TIMEOUT HF5\n");
|
|
|
return err;
|
|
|
}
|
|
|
}
|
|
@@ -263,7 +277,8 @@ void pcxhr_enable_dsp(struct pcxhr_mgr *mgr)
|
|
|
/*
|
|
|
* load the xilinx image
|
|
|
*/
|
|
|
-int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilinx, int second)
|
|
|
+int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr,
|
|
|
+ const struct firmware *xilinx, int second)
|
|
|
{
|
|
|
unsigned int i;
|
|
|
unsigned int chipsc;
|
|
@@ -274,7 +289,9 @@ int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilin
|
|
|
/* test first xilinx */
|
|
|
chipsc = PCXHR_INPL(mgr, PCXHR_PLX_CHIPSC);
|
|
|
/* REV01 cards do not support the PCXHR_CHIPSC_GPI_USERI bit anymore */
|
|
|
- /* this bit will always be 1; no possibility to test presence of first xilinx */
|
|
|
+ /* this bit will always be 1;
|
|
|
+ * no possibility to test presence of first xilinx
|
|
|
+ */
|
|
|
if(second) {
|
|
|
if ((chipsc & PCXHR_CHIPSC_GPI_USERI) == 0) {
|
|
|
snd_printk(KERN_ERR "error loading first xilinx\n");
|
|
@@ -290,7 +307,8 @@ int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilin
|
|
|
data = *image;
|
|
|
mask = 0x80;
|
|
|
while (mask) {
|
|
|
- chipsc &= ~(PCXHR_CHIPSC_DATA_CLK | PCXHR_CHIPSC_DATA_IN);
|
|
|
+ chipsc &= ~(PCXHR_CHIPSC_DATA_CLK |
|
|
|
+ PCXHR_CHIPSC_DATA_IN);
|
|
|
if (data & mask)
|
|
|
chipsc |= PCXHR_CHIPSC_DATA_IN;
|
|
|
PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC, chipsc);
|
|
@@ -330,15 +348,20 @@ static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp)
|
|
|
data = dsp->data + i;
|
|
|
if (i == 0) {
|
|
|
/* test data header consistency */
|
|
|
- len = (unsigned int)((data[0]<<16) + (data[1]<<8) + data[2]);
|
|
|
- if (len && dsp->size != (len + 2) * 3)
|
|
|
+ len = (unsigned int)((data[0]<<16) +
|
|
|
+ (data[1]<<8) +
|
|
|
+ data[2]);
|
|
|
+ if (len && (dsp->size != (len + 2) * 3))
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
/* wait DSP ready for new transfer */
|
|
|
- err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY,
|
|
|
- PCXHR_ISR_HI08_TRDY, PCXHR_TIMEOUT_DSP, &dummy);
|
|
|
+ err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
|
|
|
+ PCXHR_ISR_HI08_TRDY,
|
|
|
+ PCXHR_ISR_HI08_TRDY,
|
|
|
+ PCXHR_TIMEOUT_DSP, &dummy);
|
|
|
if (err) {
|
|
|
- snd_printk(KERN_ERR "dsp loading error at position %d\n", i);
|
|
|
+ snd_printk(KERN_ERR
|
|
|
+ "dsp loading error at position %d\n", i);
|
|
|
return err;
|
|
|
}
|
|
|
/* send host data */
|
|
@@ -357,7 +380,8 @@ static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp)
|
|
|
/*
|
|
|
* load the eeprom image
|
|
|
*/
|
|
|
-int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr, const struct firmware *eeprom)
|
|
|
+int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr,
|
|
|
+ const struct firmware *eeprom)
|
|
|
{
|
|
|
int err;
|
|
|
unsigned char reg;
|
|
@@ -365,7 +389,9 @@ int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr, const struct firmware *eepro
|
|
|
/* init value of the ICR register */
|
|
|
reg = PCXHR_ICR_HI08_RREQ | PCXHR_ICR_HI08_TREQ | PCXHR_ICR_HI08_HDRQ;
|
|
|
if (PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & PCXHR_MBOX0_BOOT_HERE) {
|
|
|
- /* no need to load the eeprom binary, but init the HI08 interface */
|
|
|
+ /* no need to load the eeprom binary,
|
|
|
+ * but init the HI08 interface
|
|
|
+ */
|
|
|
PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg | PCXHR_ICR_HI08_INIT);
|
|
|
msleep(PCXHR_WAIT_DEFAULT);
|
|
|
PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg);
|
|
@@ -429,8 +455,10 @@ int pcxhr_load_dsp_binary(struct pcxhr_mgr *mgr, const struct firmware *dsp)
|
|
|
if (err)
|
|
|
return err;
|
|
|
/* wait for chk bit */
|
|
|
- return pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_CHK,
|
|
|
- PCXHR_ISR_HI08_CHK, PCXHR_TIMEOUT_DSP, &dummy);
|
|
|
+ return pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
|
|
|
+ PCXHR_ISR_HI08_CHK,
|
|
|
+ PCXHR_ISR_HI08_CHK,
|
|
|
+ PCXHR_TIMEOUT_DSP, &dummy);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -443,8 +471,8 @@ struct pcxhr_cmd_info {
|
|
|
/* RMH status type */
|
|
|
enum {
|
|
|
RMH_SSIZE_FIXED = 0, /* status size fix (st_length = 0..x) */
|
|
|
- RMH_SSIZE_ARG = 1, /* status size given in the LSB byte (used with st_length = 1) */
|
|
|
- RMH_SSIZE_MASK = 2, /* status size given in bitmask (used with st_length = 1) */
|
|
|
+ RMH_SSIZE_ARG = 1, /* status size given in the LSB byte */
|
|
|
+ RMH_SSIZE_MASK = 2, /* status size given in bitmask */
|
|
|
};
|
|
|
|
|
|
/*
|
|
@@ -474,7 +502,7 @@ static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = {
|
|
|
[CMD_UPDATE_R_BUFFERS] = { 0x840000, 0, RMH_SSIZE_FIXED },
|
|
|
[CMD_FORMAT_STREAM_OUT] = { 0x860000, 0, RMH_SSIZE_FIXED },
|
|
|
[CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED },
|
|
|
-[CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED }, /* stat_len = nb_streams * 2 */
|
|
|
+[CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED },
|
|
|
[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED },
|
|
|
};
|
|
|
|
|
@@ -524,10 +552,13 @@ static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
|
|
|
|
|
|
for (i = 0; i < rmh->stat_len; i++) {
|
|
|
/* wait for receiver full */
|
|
|
- err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_RXDF,
|
|
|
- PCXHR_ISR_HI08_RXDF, PCXHR_TIMEOUT_DSP, ®);
|
|
|
+ err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
|
|
|
+ PCXHR_ISR_HI08_RXDF,
|
|
|
+ PCXHR_ISR_HI08_RXDF,
|
|
|
+ PCXHR_TIMEOUT_DSP, ®);
|
|
|
if (err) {
|
|
|
- snd_printk(KERN_ERR "ERROR RMH stat: ISR:RXDF=1 (ISR = %x; i=%d )\n",
|
|
|
+ snd_printk(KERN_ERR "ERROR RMH stat: "
|
|
|
+ "ISR:RXDF=1 (ISR = %x; i=%d )\n",
|
|
|
reg, i);
|
|
|
return err;
|
|
|
}
|
|
@@ -537,10 +568,10 @@ static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
|
|
|
data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL);
|
|
|
|
|
|
/* need to update rmh->stat_len on the fly ?? */
|
|
|
- if (i==0) {
|
|
|
+ if (!i) {
|
|
|
if (rmh->dsp_stat != RMH_SSIZE_FIXED) {
|
|
|
if (rmh->dsp_stat == RMH_SSIZE_ARG) {
|
|
|
- rmh->stat_len = (u16)(data & 0x0000ff) + 1;
|
|
|
+ rmh->stat_len = (data & 0x0000ff) + 1;
|
|
|
data &= 0xffff00;
|
|
|
} else {
|
|
|
/* rmh->dsp_stat == RMH_SSIZE_MASK */
|
|
@@ -562,7 +593,8 @@ static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
|
|
|
rmh->stat[i] = data;
|
|
|
}
|
|
|
if (rmh->stat_len > max_stat_len) {
|
|
|
- snd_printdd("PCXHR : rmh->stat_len=%x too big\n", rmh->stat_len);
|
|
|
+ snd_printdd("PCXHR : rmh->stat_len=%x too big\n",
|
|
|
+ rmh->stat_len);
|
|
|
rmh->stat_len = max_stat_len;
|
|
|
}
|
|
|
return 0;
|
|
@@ -605,7 +637,8 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
|
|
|
data &= 0xff7fff; /* MASK_1_WORD_COMMAND */
|
|
|
#ifdef CONFIG_SND_DEBUG_VERBOSE
|
|
|
if (rmh->cmd_idx < CMD_LAST_INDEX)
|
|
|
- snd_printdd("MSG cmd[0]=%x (%s)\n", data, cmd_names[rmh->cmd_idx]);
|
|
|
+ snd_printdd("MSG cmd[0]=%x (%s)\n",
|
|
|
+ data, cmd_names[rmh->cmd_idx]);
|
|
|
#endif
|
|
|
|
|
|
err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY,
|
|
@@ -619,8 +652,10 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
|
|
|
if (rmh->cmd_len > 1) {
|
|
|
/* send length */
|
|
|
data = rmh->cmd_len - 1;
|
|
|
- err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY,
|
|
|
- PCXHR_ISR_HI08_TRDY, PCXHR_TIMEOUT_DSP, ®);
|
|
|
+ err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
|
|
|
+ PCXHR_ISR_HI08_TRDY,
|
|
|
+ PCXHR_ISR_HI08_TRDY,
|
|
|
+ PCXHR_TIMEOUT_DSP, ®);
|
|
|
if (err)
|
|
|
return err;
|
|
|
PCXHR_OUTPB(mgr, PCXHR_DSP_TXH, (data>>16)&0xFF);
|
|
@@ -653,8 +688,10 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
|
|
|
/* test status ISR */
|
|
|
if (reg & PCXHR_ISR_HI08_ERR) {
|
|
|
/* ERROR, wait for receiver full */
|
|
|
- err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_RXDF,
|
|
|
- PCXHR_ISR_HI08_RXDF, PCXHR_TIMEOUT_DSP, ®);
|
|
|
+ err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
|
|
|
+ PCXHR_ISR_HI08_RXDF,
|
|
|
+ PCXHR_ISR_HI08_RXDF,
|
|
|
+ PCXHR_TIMEOUT_DSP, ®);
|
|
|
if (err) {
|
|
|
snd_printk(KERN_ERR "ERROR RMH: ISR:RXDF=1 (ISR = %x)\n", reg);
|
|
|
return err;
|
|
@@ -663,7 +700,8 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
|
|
|
data = PCXHR_INPB(mgr, PCXHR_DSP_TXH) << 16;
|
|
|
data |= PCXHR_INPB(mgr, PCXHR_DSP_TXM) << 8;
|
|
|
data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL);
|
|
|
- snd_printk(KERN_ERR "ERROR RMH(%d): 0x%x\n", rmh->cmd_idx, data);
|
|
|
+ snd_printk(KERN_ERR "ERROR RMH(%d): 0x%x\n",
|
|
|
+ rmh->cmd_idx, data);
|
|
|
err = -EINVAL;
|
|
|
} else {
|
|
|
/* read the response data */
|
|
@@ -732,8 +770,9 @@ int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
|
|
|
static inline int pcxhr_pipes_running(struct pcxhr_mgr *mgr)
|
|
|
{
|
|
|
int start_mask = PCXHR_INPL(mgr, PCXHR_PLX_MBOX2);
|
|
|
- /* least segnificant 12 bits are the pipe states for the playback audios */
|
|
|
- /* next 12 bits are the pipe states for the capture audios
|
|
|
+ /* least segnificant 12 bits are the pipe states
|
|
|
+ * for the playback audios
|
|
|
+ * next 12 bits are the pipe states for the capture audios
|
|
|
* (PCXHR_PIPE_STATE_CAPTURE_OFFSET)
|
|
|
*/
|
|
|
start_mask &= 0xffffff;
|
|
@@ -744,7 +783,8 @@ static inline int pcxhr_pipes_running(struct pcxhr_mgr *mgr)
|
|
|
#define PCXHR_PIPE_STATE_CAPTURE_OFFSET 12
|
|
|
#define MAX_WAIT_FOR_DSP 20
|
|
|
|
|
|
-static int pcxhr_prepair_pipe_start(struct pcxhr_mgr *mgr, int audio_mask, int *retry)
|
|
|
+static int pcxhr_prepair_pipe_start(struct pcxhr_mgr *mgr,
|
|
|
+ int audio_mask, int *retry)
|
|
|
{
|
|
|
struct pcxhr_rmh rmh;
|
|
|
int err;
|
|
@@ -760,17 +800,20 @@ static int pcxhr_prepair_pipe_start(struct pcxhr_mgr *mgr, int audio_mask, int *
|
|
|
} else {
|
|
|
/* can start capture pipe */
|
|
|
pcxhr_set_pipe_cmd_params(&rmh, 1, audio -
|
|
|
- PCXHR_PIPE_STATE_CAPTURE_OFFSET,
|
|
|
- 0, 0);
|
|
|
+ PCXHR_PIPE_STATE_CAPTURE_OFFSET,
|
|
|
+ 0, 0);
|
|
|
}
|
|
|
err = pcxhr_send_msg(mgr, &rmh);
|
|
|
if (err) {
|
|
|
snd_printk(KERN_ERR
|
|
|
- "error pipe start (CMD_CAN_START_PIPE) err=%x!\n",
|
|
|
+ "error pipe start "
|
|
|
+ "(CMD_CAN_START_PIPE) err=%x!\n",
|
|
|
err);
|
|
|
return err;
|
|
|
}
|
|
|
- /* if the pipe couldn't be prepaired for start, retry it later */
|
|
|
+ /* if the pipe couldn't be prepaired for start,
|
|
|
+ * retry it later
|
|
|
+ */
|
|
|
if (rmh.stat[0] == 0)
|
|
|
*retry |= (1<<audio);
|
|
|
}
|
|
@@ -795,14 +838,14 @@ static int pcxhr_stop_pipes(struct pcxhr_mgr *mgr, int audio_mask)
|
|
|
} else {
|
|
|
/* stop capture pipe */
|
|
|
pcxhr_set_pipe_cmd_params(&rmh, 1, audio -
|
|
|
- PCXHR_PIPE_STATE_CAPTURE_OFFSET,
|
|
|
- 0, 0);
|
|
|
+ PCXHR_PIPE_STATE_CAPTURE_OFFSET,
|
|
|
+ 0, 0);
|
|
|
}
|
|
|
err = pcxhr_send_msg(mgr, &rmh);
|
|
|
if (err) {
|
|
|
snd_printk(KERN_ERR
|
|
|
- "error pipe stop (CMD_STOP_PIPE) err=%x!\n",
|
|
|
- err);
|
|
|
+ "error pipe stop "
|
|
|
+ "(CMD_STOP_PIPE) err=%x!\n", err);
|
|
|
return err;
|
|
|
}
|
|
|
}
|
|
@@ -822,15 +865,16 @@ static int pcxhr_toggle_pipes(struct pcxhr_mgr *mgr, int audio_mask)
|
|
|
if (audio_mask & 1) {
|
|
|
pcxhr_init_rmh(&rmh, CMD_CONF_PIPE);
|
|
|
if (audio < PCXHR_PIPE_STATE_CAPTURE_OFFSET)
|
|
|
- pcxhr_set_pipe_cmd_params(&rmh, 0, 0, 0, 1 << audio);
|
|
|
+ pcxhr_set_pipe_cmd_params(&rmh, 0, 0, 0,
|
|
|
+ 1 << audio);
|
|
|
else
|
|
|
pcxhr_set_pipe_cmd_params(&rmh, 1, 0, 0,
|
|
|
1 << (audio - PCXHR_PIPE_STATE_CAPTURE_OFFSET));
|
|
|
err = pcxhr_send_msg(mgr, &rmh);
|
|
|
if (err) {
|
|
|
snd_printk(KERN_ERR
|
|
|
- "error pipe start (CMD_CONF_PIPE) err=%x!\n",
|
|
|
- err);
|
|
|
+ "error pipe start "
|
|
|
+ "(CMD_CONF_PIPE) err=%x!\n", err);
|
|
|
return err;
|
|
|
}
|
|
|
}
|
|
@@ -841,7 +885,9 @@ static int pcxhr_toggle_pipes(struct pcxhr_mgr *mgr, int audio_mask)
|
|
|
pcxhr_init_rmh(&rmh, CMD_SEND_IRQA);
|
|
|
err = pcxhr_send_msg(mgr, &rmh);
|
|
|
if (err) {
|
|
|
- snd_printk(KERN_ERR "error pipe start (CMD_SEND_IRQA) err=%x!\n", err );
|
|
|
+ snd_printk(KERN_ERR
|
|
|
+ "error pipe start (CMD_SEND_IRQA) err=%x!\n",
|
|
|
+ err);
|
|
|
return err;
|
|
|
}
|
|
|
return 0;
|
|
@@ -849,7 +895,8 @@ static int pcxhr_toggle_pipes(struct pcxhr_mgr *mgr, int audio_mask)
|
|
|
|
|
|
|
|
|
|
|
|
-int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_mask, int start)
|
|
|
+int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask,
|
|
|
+ int capture_mask, int start)
|
|
|
{
|
|
|
int state, i, err;
|
|
|
int audio_mask;
|
|
@@ -858,21 +905,23 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_m
|
|
|
struct timeval my_tv1, my_tv2;
|
|
|
do_gettimeofday(&my_tv1);
|
|
|
#endif
|
|
|
- audio_mask = (playback_mask | (capture_mask << PCXHR_PIPE_STATE_CAPTURE_OFFSET));
|
|
|
+ audio_mask = (playback_mask |
|
|
|
+ (capture_mask << PCXHR_PIPE_STATE_CAPTURE_OFFSET));
|
|
|
/* current pipe state (playback + record) */
|
|
|
state = pcxhr_pipes_running(mgr);
|
|
|
snd_printdd("pcxhr_set_pipe_state %s (mask %x current %x)\n",
|
|
|
start ? "START" : "STOP", audio_mask, state);
|
|
|
if (start) {
|
|
|
- audio_mask &= ~state; /* start only pipes that are not yet started */
|
|
|
+ /* start only pipes that are not yet started */
|
|
|
+ audio_mask &= ~state;
|
|
|
state = audio_mask;
|
|
|
for (i = 0; i < MAX_WAIT_FOR_DSP; i++) {
|
|
|
err = pcxhr_prepair_pipe_start(mgr, state, &state);
|
|
|
if (err)
|
|
|
return err;
|
|
|
if (state == 0)
|
|
|
- break; /* success, all pipes prepaired for start */
|
|
|
- mdelay(1); /* otherwise wait 1 millisecond and retry */
|
|
|
+ break; /* success, all pipes prepaired */
|
|
|
+ mdelay(1); /* wait 1 millisecond and retry */
|
|
|
}
|
|
|
} else {
|
|
|
audio_mask &= state; /* stop only pipes that are started */
|
|
@@ -891,7 +940,7 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_m
|
|
|
if ((state & audio_mask) == (start ? audio_mask : 0))
|
|
|
break;
|
|
|
if (++i >= MAX_WAIT_FOR_DSP * 100) {
|
|
|
- snd_printk(KERN_ERR "error pipe start/stop (ED_NO_RESPONSE_AT_IRQA)\n");
|
|
|
+ snd_printk(KERN_ERR "error pipe start/stop\n");
|
|
|
return -EBUSY;
|
|
|
}
|
|
|
udelay(10); /* wait 10 microseconds */
|
|
@@ -918,7 +967,8 @@ int pcxhr_write_io_num_reg_cont(struct pcxhr_mgr *mgr, unsigned int mask,
|
|
|
|
|
|
spin_lock_irqsave(&mgr->msg_lock, flags);
|
|
|
if ((mgr->io_num_reg_cont & mask) == value) {
|
|
|
- snd_printdd("IO_NUM_REG_CONT mask %x already is set to %x\n", mask, value);
|
|
|
+ snd_printdd("IO_NUM_REG_CONT mask %x already is set to %x\n",
|
|
|
+ mask, value);
|
|
|
if (changed)
|
|
|
*changed = 0;
|
|
|
spin_unlock_irqrestore(&mgr->msg_lock, flags);
|
|
@@ -971,7 +1021,8 @@ static int pcxhr_handle_async_err(struct pcxhr_mgr *mgr, u32 err,
|
|
|
err = ((err >> 12) & 0xfff);
|
|
|
if (!err)
|
|
|
return 0;
|
|
|
- snd_printdd("CMD_ASYNC : Error %s %s Pipe %d err=%x\n", err_src_name[err_src],
|
|
|
+ snd_printdd("CMD_ASYNC : Error %s %s Pipe %d err=%x\n",
|
|
|
+ err_src_name[err_src],
|
|
|
is_capture ? "Record" : "Play", pipe, err);
|
|
|
if (err == 0xe01)
|
|
|
mgr->async_err_stream_xrun++;
|
|
@@ -996,6 +1047,13 @@ void pcxhr_msg_tasklet(unsigned long arg)
|
|
|
snd_printdd("TASKLET : PCXHR_IRQ_TIME_CODE event occured\n");
|
|
|
if (mgr->src_it_dsp & PCXHR_IRQ_NOTIFY)
|
|
|
snd_printdd("TASKLET : PCXHR_IRQ_NOTIFY event occured\n");
|
|
|
+ if (mgr->src_it_dsp & (PCXHR_IRQ_FREQ_CHANGE | PCXHR_IRQ_TIME_CODE)) {
|
|
|
+ /* clear events FREQ_CHANGE and TIME_CODE */
|
|
|
+ pcxhr_init_rmh(prmh, CMD_TEST_IT);
|
|
|
+ err = pcxhr_send_msg(mgr, prmh);
|
|
|
+ snd_printdd("CMD_TEST_IT : err=%x, stat=%x\n",
|
|
|
+ err, prmh->stat[0]);
|
|
|
+ }
|
|
|
if (mgr->src_it_dsp & PCXHR_IRQ_ASYNC) {
|
|
|
snd_printdd("TASKLET : PCXHR_IRQ_ASYNC event occured\n");
|
|
|
|
|
@@ -1005,18 +1063,22 @@ void pcxhr_msg_tasklet(unsigned long arg)
|
|
|
prmh->stat_len = PCXHR_SIZE_MAX_LONG_STATUS;
|
|
|
err = pcxhr_send_msg(mgr, prmh);
|
|
|
if (err)
|
|
|
- snd_printk(KERN_ERR "ERROR pcxhr_msg_tasklet=%x;\n", err);
|
|
|
+ snd_printk(KERN_ERR "ERROR pcxhr_msg_tasklet=%x;\n",
|
|
|
+ err);
|
|
|
i = 1;
|
|
|
while (i < prmh->stat_len) {
|
|
|
- int nb_audio = (prmh->stat[i] >> FIELD_SIZE) & MASK_FIRST_FIELD;
|
|
|
- int nb_stream = (prmh->stat[i] >> (2*FIELD_SIZE)) & MASK_FIRST_FIELD;
|
|
|
+ int nb_audio = ((prmh->stat[i] >> FIELD_SIZE) &
|
|
|
+ MASK_FIRST_FIELD);
|
|
|
+ int nb_stream = ((prmh->stat[i] >> (2*FIELD_SIZE)) &
|
|
|
+ MASK_FIRST_FIELD);
|
|
|
int pipe = prmh->stat[i] & MASK_FIRST_FIELD;
|
|
|
int is_capture = prmh->stat[i] & 0x400000;
|
|
|
u32 err2;
|
|
|
|
|
|
if (prmh->stat[i] & 0x800000) { /* if BIT_END */
|
|
|
snd_printdd("TASKLET : End%sPipe %d\n",
|
|
|
- is_capture ? "Record" : "Play", pipe);
|
|
|
+ is_capture ? "Record" : "Play",
|
|
|
+ pipe);
|
|
|
}
|
|
|
i++;
|
|
|
err2 = prmh->stat[i] ? prmh->stat[i] : prmh->stat[i+1];
|
|
@@ -1062,7 +1124,7 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr,
|
|
|
pcxhr_init_rmh(&rmh, CMD_STREAM_SAMPLE_COUNT);
|
|
|
pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture,
|
|
|
stream->pipe->first_audio, 0, stream_mask);
|
|
|
- /* rmh.stat_len = 2; */ /* 2 resp data for each stream of the pipe */
|
|
|
+ /* rmh.stat_len = 2; */ /* 2 resp data for each stream of the pipe */
|
|
|
|
|
|
err = pcxhr_send_msg(mgr, &rmh);
|
|
|
if (err)
|
|
@@ -1072,18 +1134,21 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr,
|
|
|
hw_sample_count += (u_int64_t)rmh.stat[1];
|
|
|
|
|
|
snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n",
|
|
|
- stream->pipe->is_capture ? 'C':'P', stream->substream->number,
|
|
|
+ stream->pipe->is_capture ? 'C' : 'P',
|
|
|
+ stream->substream->number,
|
|
|
(long unsigned int)hw_sample_count,
|
|
|
(long unsigned int)(stream->timer_abs_periods +
|
|
|
- stream->timer_period_frag + PCXHR_GRANULARITY));
|
|
|
-
|
|
|
+ stream->timer_period_frag +
|
|
|
+ mgr->granularity));
|
|
|
return hw_sample_count;
|
|
|
}
|
|
|
|
|
|
static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
|
|
|
- struct pcxhr_stream *stream, int samples_to_add)
|
|
|
+ struct pcxhr_stream *stream,
|
|
|
+ int samples_to_add)
|
|
|
{
|
|
|
- if (stream->substream && (stream->status == PCXHR_STREAM_STATUS_RUNNING)) {
|
|
|
+ if (stream->substream &&
|
|
|
+ (stream->status == PCXHR_STREAM_STATUS_RUNNING)) {
|
|
|
u_int64_t new_sample_count;
|
|
|
int elapsed = 0;
|
|
|
int hardware_read = 0;
|
|
@@ -1092,20 +1157,22 @@ static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
|
|
|
if (samples_to_add < 0) {
|
|
|
stream->timer_is_synced = 0;
|
|
|
/* add default if no hardware_read possible */
|
|
|
- samples_to_add = PCXHR_GRANULARITY;
|
|
|
+ samples_to_add = mgr->granularity;
|
|
|
}
|
|
|
|
|
|
if (!stream->timer_is_synced) {
|
|
|
- if (stream->timer_abs_periods != 0 ||
|
|
|
- stream->timer_period_frag + PCXHR_GRANULARITY >=
|
|
|
- runtime->period_size) {
|
|
|
- new_sample_count = pcxhr_stream_read_position(mgr, stream);
|
|
|
+ if ((stream->timer_abs_periods != 0) ||
|
|
|
+ ((stream->timer_period_frag + samples_to_add) >=
|
|
|
+ runtime->period_size)) {
|
|
|
+ new_sample_count =
|
|
|
+ pcxhr_stream_read_position(mgr, stream);
|
|
|
hardware_read = 1;
|
|
|
- if (new_sample_count >= PCXHR_GRANULARITY_MIN) {
|
|
|
- /* sub security offset because of jitter and
|
|
|
- * finer granularity of dsp time (MBOX4)
|
|
|
+ if (new_sample_count >= mgr->granularity) {
|
|
|
+ /* sub security offset because of
|
|
|
+ * jitter and finer granularity of
|
|
|
+ * dsp time (MBOX4)
|
|
|
*/
|
|
|
- new_sample_count -= PCXHR_GRANULARITY_MIN;
|
|
|
+ new_sample_count -= mgr->granularity;
|
|
|
stream->timer_is_synced = 1;
|
|
|
}
|
|
|
}
|
|
@@ -1128,12 +1195,15 @@ static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
|
|
|
stream->timer_buf_periods = 0;
|
|
|
stream->timer_abs_periods = new_elapse_pos;
|
|
|
}
|
|
|
- if (new_sample_count >= stream->timer_abs_periods)
|
|
|
- stream->timer_period_frag = (u_int32_t)(new_sample_count -
|
|
|
- stream->timer_abs_periods);
|
|
|
- else
|
|
|
- snd_printk(KERN_ERR "ERROR new_sample_count too small ??? %lx\n",
|
|
|
+ if (new_sample_count >= stream->timer_abs_periods) {
|
|
|
+ stream->timer_period_frag =
|
|
|
+ (u_int32_t)(new_sample_count -
|
|
|
+ stream->timer_abs_periods);
|
|
|
+ } else {
|
|
|
+ snd_printk(KERN_ERR
|
|
|
+ "ERROR new_sample_count too small ??? %ld\n",
|
|
|
(long unsigned int)new_sample_count);
|
|
|
+ }
|
|
|
|
|
|
if (elapsed) {
|
|
|
spin_unlock(&mgr->lock);
|
|
@@ -1143,7 +1213,6 @@ static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
|
|
|
{
|
|
|
struct pcxhr_mgr *mgr = dev_id;
|
|
@@ -1156,7 +1225,8 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
|
|
|
reg = PCXHR_INPL(mgr, PCXHR_PLX_IRQCS);
|
|
|
if (! (reg & PCXHR_IRQCS_ACTIVE_PCIDB)) {
|
|
|
spin_unlock(&mgr->lock);
|
|
|
- return IRQ_NONE; /* this device did not cause the interrupt */
|
|
|
+ /* this device did not cause the interrupt */
|
|
|
+ return IRQ_NONE;
|
|
|
}
|
|
|
|
|
|
/* clear interrupt */
|
|
@@ -1167,10 +1237,12 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
|
|
|
if (reg & PCXHR_IRQ_TIMER) {
|
|
|
int timer_toggle = reg & PCXHR_IRQ_TIMER;
|
|
|
/* is a 24 bit counter */
|
|
|
- int dsp_time_new = PCXHR_INPL(mgr, PCXHR_PLX_MBOX4) & PCXHR_DSP_TIME_MASK;
|
|
|
+ int dsp_time_new =
|
|
|
+ PCXHR_INPL(mgr, PCXHR_PLX_MBOX4) & PCXHR_DSP_TIME_MASK;
|
|
|
int dsp_time_diff = dsp_time_new - mgr->dsp_time_last;
|
|
|
|
|
|
- if (dsp_time_diff < 0 && mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID) {
|
|
|
+ if ((dsp_time_diff < 0) &&
|
|
|
+ (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) {
|
|
|
snd_printdd("ERROR DSP TIME old(%d) new(%d) -> "
|
|
|
"resynchronize all streams\n",
|
|
|
mgr->dsp_time_last, dsp_time_new);
|
|
@@ -1178,40 +1250,49 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
|
|
|
}
|
|
|
#ifdef CONFIG_SND_DEBUG_VERBOSE
|
|
|
if (dsp_time_diff == 0)
|
|
|
- snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n", dsp_time_new);
|
|
|
- else if (dsp_time_diff >= (2*PCXHR_GRANULARITY))
|
|
|
+ snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n",
|
|
|
+ dsp_time_new);
|
|
|
+ else if (dsp_time_diff >= (2*mgr->granularity))
|
|
|
snd_printdd("ERROR DSP TIME TOO BIG old(%d) add(%d)\n",
|
|
|
- mgr->dsp_time_last, dsp_time_new - mgr->dsp_time_last);
|
|
|
+ mgr->dsp_time_last,
|
|
|
+ dsp_time_new - mgr->dsp_time_last);
|
|
|
+ else if (dsp_time_diff % mgr->granularity)
|
|
|
+ snd_printdd("ERROR DSP TIME increased by %d\n",
|
|
|
+ dsp_time_diff);
|
|
|
#endif
|
|
|
mgr->dsp_time_last = dsp_time_new;
|
|
|
|
|
|
- if (timer_toggle == mgr->timer_toggle)
|
|
|
+ if (timer_toggle == mgr->timer_toggle) {
|
|
|
snd_printdd("ERROR TIMER TOGGLE\n");
|
|
|
+ mgr->dsp_time_err++;
|
|
|
+ }
|
|
|
mgr->timer_toggle = timer_toggle;
|
|
|
|
|
|
reg &= ~PCXHR_IRQ_TIMER;
|
|
|
for (i = 0; i < mgr->num_cards; i++) {
|
|
|
chip = mgr->chip[i];
|
|
|
for (j = 0; j < chip->nb_streams_capt; j++)
|
|
|
- pcxhr_update_timer_pos(mgr, &chip->capture_stream[j],
|
|
|
- dsp_time_diff);
|
|
|
+ pcxhr_update_timer_pos(mgr,
|
|
|
+ &chip->capture_stream[j],
|
|
|
+ dsp_time_diff);
|
|
|
}
|
|
|
for (i = 0; i < mgr->num_cards; i++) {
|
|
|
chip = mgr->chip[i];
|
|
|
for (j = 0; j < chip->nb_streams_play; j++)
|
|
|
- pcxhr_update_timer_pos(mgr, &chip->playback_stream[j],
|
|
|
- dsp_time_diff);
|
|
|
+ pcxhr_update_timer_pos(mgr,
|
|
|
+ &chip->playback_stream[j],
|
|
|
+ dsp_time_diff);
|
|
|
}
|
|
|
}
|
|
|
/* other irq's handled in the tasklet */
|
|
|
if (reg & PCXHR_IRQ_MASK) {
|
|
|
-
|
|
|
- /* as we didn't request any notifications, some kind of xrun error
|
|
|
- * will probably occured
|
|
|
- */
|
|
|
- /* better resynchronize all streams next interrupt : */
|
|
|
- mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID;
|
|
|
-
|
|
|
+ if (reg & PCXHR_IRQ_ASYNC) {
|
|
|
+ /* as we didn't request any async notifications,
|
|
|
+ * some kind of xrun error will probably occured
|
|
|
+ */
|
|
|
+ /* better resynchronize all streams next interrupt : */
|
|
|
+ mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID;
|
|
|
+ }
|
|
|
mgr->src_it_dsp = reg;
|
|
|
tasklet_hi_schedule(&mgr->msg_taskq);
|
|
|
}
|