Commit ce18a223 authored by Wolfgang Rohdewald's avatar Wolfgang Rohdewald Committed by Linus Torvalds

[PATCH] dvb: ttpci: more error handling for firmware communication

o propagate more errors back to caller or log them, mainly in
  av7110.c and av7110_av.c
o fix error message in StartHWFilter
o do not StopHWFilter for handle 0xffff
Signed-off-by: default avatarWolfgang Rohdewald <wolfgang@rohdewald.de>
Signed-off-by: default avatarJohannes Stezenbach <js@linuxtv.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent eef5764d
...@@ -116,13 +116,18 @@ static int av7110_num = 0; ...@@ -116,13 +116,18 @@ static int av7110_num = 0;
static void init_av7110_av(struct av7110 *av7110) static void init_av7110_av(struct av7110 *av7110)
{ {
int ret;
struct saa7146_dev *dev = av7110->dev; struct saa7146_dev *dev = av7110->dev;
/* set internal volume control to maximum */ /* set internal volume control to maximum */
av7110->adac_type = DVB_ADAC_TI; av7110->adac_type = DVB_ADAC_TI;
av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
if (ret<0)
printk("dvb-ttpci:cannot set internal volume to maximum:%d\n",ret);
av7710_set_video_mode(av7110, vidmode); ret = av7710_set_video_mode(av7110, vidmode);
if (ret<0)
printk("dvb-ttpci:cannot set video mode:%d\n",ret);
/* handle different card types */ /* handle different card types */
/* remaining inits according to card and frontend type */ /* remaining inits according to card and frontend type */
...@@ -156,8 +161,12 @@ static void init_av7110_av(struct av7110 *av7110) ...@@ -156,8 +161,12 @@ static void init_av7110_av(struct av7110 *av7110)
if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) { if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
// switch DVB SCART on // switch DVB SCART on
av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0); ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1); if (ret<0)
printk("dvb-ttpci:cannot switch on SCART(Main):%d\n",ret);
ret = av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
if (ret<0)
printk("dvb-ttpci:cannot switch on SCART(AD):%d\n",ret);
if (rgb_on && if (rgb_on &&
(av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) { (av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
...@@ -165,8 +174,12 @@ static void init_av7110_av(struct av7110 *av7110) ...@@ -165,8 +174,12 @@ static void init_av7110_av(struct av7110 *av7110)
} }
} }
av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); ret = av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
av7110_setup_irc_config(av7110, 0); if (ret<0)
printk("dvb-ttpci:cannot set volume :%d\n",ret);
ret = av7110_setup_irc_config(av7110, 0);
if (ret<0)
printk("dvb-ttpci:cannot setup irc config :%d\n",ret);
} }
static void recover_arm(struct av7110 *av7110) static void recover_arm(struct av7110 *av7110)
...@@ -258,8 +271,9 @@ static int arm_thread(void *data) ...@@ -258,8 +271,9 @@ static int arm_thread(void *data)
* *
* If we want to support multiple controls we would have to do much more... * If we want to support multiple controls we would have to do much more...
*/ */
void av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config) int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
{ {
int ret = 0;
static struct av7110 *last; static struct av7110 *last;
dprintk(4, "%p\n", av7110); dprintk(4, "%p\n", av7110);
...@@ -270,9 +284,10 @@ void av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config) ...@@ -270,9 +284,10 @@ void av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config)
last = av7110; last = av7110;
if (av7110) { if (av7110) {
av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config); ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config);
av7110->ir_config = ir_config; av7110->ir_config = ir_config;
} }
return ret;
} }
static void (*irc_handler)(u32); static void (*irc_handler)(u32);
...@@ -765,13 +780,14 @@ static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, ...@@ -765,13 +780,14 @@ static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
pcrpid, vpid, apid, ttpid, subpid); pcrpid, vpid, apid, ttpid, subpid);
} }
void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
u16 subpid, u16 pcrpid) u16 subpid, u16 pcrpid)
{ {
int ret = 0;
dprintk(4, "%p\n", av7110); dprintk(4, "%p\n", av7110);
if (down_interruptible(&av7110->pid_mutex)) if (down_interruptible(&av7110->pid_mutex))
return; return -ERESTARTSYS;
if (!(vpid & 0x8000)) if (!(vpid & 0x8000))
av7110->pids[DMX_PES_VIDEO] = vpid; av7110->pids[DMX_PES_VIDEO] = vpid;
...@@ -786,10 +802,11 @@ void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, ...@@ -786,10 +802,11 @@ void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
if (av7110->fe_synced) { if (av7110->fe_synced) {
pcrpid = av7110->pids[DMX_PES_PCR]; pcrpid = av7110->pids[DMX_PES_PCR];
SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid); ret = SetPIDs(av7110, vpid, apid, ttpid, subpid, pcrpid);
} }
up(&av7110->pid_mutex); up(&av7110->pid_mutex);
return ret;
} }
...@@ -832,11 +849,13 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter) ...@@ -832,11 +849,13 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
ret = av7110_fw_request(av7110, buf, 20, &handle, 1); ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
if (ret != 0 || handle >= 32) { if (ret != 0 || handle >= 32) {
printk("dvb-ttpci: %s error buf %04x %04x %04x %04x " printk("dvb-ttpci: %s error buf %04x %04x %04x %04x "
"ret %x handle %04x\n", "ret %d handle %04x\n",
__FUNCTION__, buf[0], buf[1], buf[2], buf[3], __FUNCTION__, buf[0], buf[1], buf[2], buf[3],
ret, handle); ret, handle);
dvbdmxfilter->hw_handle = 0xffff; dvbdmxfilter->hw_handle = 0xffff;
return -1; if (!ret)
ret = -1;
return ret;
} }
av7110->handle2filter[handle] = dvbdmxfilter; av7110->handle2filter[handle] = dvbdmxfilter;
...@@ -859,7 +878,7 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) ...@@ -859,7 +878,7 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
if (handle >= 32) { if (handle >= 32) {
printk("%s tried to stop invalid filter %04x, filter type = %x\n", printk("%s tried to stop invalid filter %04x, filter type = %x\n",
__FUNCTION__, handle, dvbdmxfilter->type); __FUNCTION__, handle, dvbdmxfilter->type);
return 0; return -EINVAL;
} }
av7110->handle2filter[handle] = NULL; av7110->handle2filter[handle] = NULL;
...@@ -873,18 +892,20 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) ...@@ -873,18 +892,20 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
"resp %04x %04x pid %d\n", "resp %04x %04x pid %d\n",
__FUNCTION__, buf[0], buf[1], buf[2], ret, __FUNCTION__, buf[0], buf[1], buf[2], ret,
answ[0], answ[1], dvbdmxfilter->feed->pid); answ[0], answ[1], dvbdmxfilter->feed->pid);
ret = -1; if (!ret)
ret = -1;
} }
return ret; return ret;
} }
static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed) static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
{ {
struct dvb_demux *dvbdmx = dvbdmxfeed->demux; struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv; struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
u16 *pid = dvbdmx->pids, npids[5]; u16 *pid = dvbdmx->pids, npids[5];
int i; int i;
int ret = 0;
dprintk(4, "%p\n", av7110); dprintk(4, "%p\n", av7110);
...@@ -893,36 +914,49 @@ static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed) ...@@ -893,36 +914,49 @@ static void dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
npids[i] = (pid[i]&0x8000) ? 0 : pid[i]; npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) { if ((i == 2) && npids[i] && (dvbdmxfeed->ts_type & TS_PACKET)) {
npids[i] = 0; npids[i] = 0;
ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
StartHWFilter(dvbdmxfeed->filter); if (!ret)
return; ret = StartHWFilter(dvbdmxfeed->filter);
return ret;
}
if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4) {
ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
if (ret)
return ret;
} }
if (dvbdmxfeed->pes_type <= 2 || dvbdmxfeed->pes_type == 4)
ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
if (dvbdmxfeed->pes_type < 2 && npids[0]) if (dvbdmxfeed->pes_type < 2 && npids[0])
if (av7110->fe_synced) if (av7110->fe_synced)
av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); {
ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
if (ret)
return ret;
}
if ((dvbdmxfeed->ts_type & TS_PACKET)) { if ((dvbdmxfeed->ts_type & TS_PACKET)) {
if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000)) if (dvbdmxfeed->pes_type == 0 && !(dvbdmx->pids[0] & 0x8000))
av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed); ret = av7110_av_start_record(av7110, RP_AUDIO, dvbdmxfeed);
if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000)) if (dvbdmxfeed->pes_type == 1 && !(dvbdmx->pids[1] & 0x8000))
av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed); ret = av7110_av_start_record(av7110, RP_VIDEO, dvbdmxfeed);
} }
return ret;
} }
static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed) static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
{ {
struct dvb_demux *dvbdmx = dvbdmxfeed->demux; struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv; struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv;
u16 *pid = dvbdmx->pids, npids[5]; u16 *pid = dvbdmx->pids, npids[5];
int i; int i;
int ret = 0;
dprintk(4, "%p\n", av7110); dprintk(4, "%p\n", av7110);
if (dvbdmxfeed->pes_type <= 1) { if (dvbdmxfeed->pes_type <= 1) {
av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO); ret = av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO);
if (ret)
return ret;
if (!av7110->rec_mode) if (!av7110->rec_mode)
dvbdmx->recording = 0; dvbdmx->recording = 0;
if (!av7110->playing) if (!av7110->playing)
...@@ -933,24 +967,27 @@ static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed) ...@@ -933,24 +967,27 @@ static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
switch (i) { switch (i) {
case 2: //teletext case 2: //teletext
if (dvbdmxfeed->ts_type & TS_PACKET) if (dvbdmxfeed->ts_type & TS_PACKET)
StopHWFilter(dvbdmxfeed->filter); ret = StopHWFilter(dvbdmxfeed->filter);
npids[2] = 0; npids[2] = 0;
break; break;
case 0: case 0:
case 1: case 1:
case 4: case 4:
if (!pids_off) if (!pids_off)
return; return 0;
npids[i] = (pid[i]&0x8000) ? 0 : pid[i]; npids[i] = (pid[i]&0x8000) ? 0 : pid[i];
break; break;
} }
ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]); if (!ret)
ret = ChangePIDs(av7110, npids[1], npids[0], npids[2], npids[3], npids[4]);
return ret;
} }
static int av7110_start_feed(struct dvb_demux_feed *feed) static int av7110_start_feed(struct dvb_demux_feed *feed)
{ {
struct dvb_demux *demux = feed->demux; struct dvb_demux *demux = feed->demux;
struct av7110 *av7110 = demux->priv; struct av7110 *av7110 = demux->priv;
int ret = 0;
dprintk(4, "%p\n", av7110); dprintk(4, "%p\n", av7110);
...@@ -971,21 +1008,22 @@ static int av7110_start_feed(struct dvb_demux_feed *feed) ...@@ -971,21 +1008,22 @@ static int av7110_start_feed(struct dvb_demux_feed *feed)
!(demux->pids[1] & 0x8000)) { !(demux->pids[1] & 0x8000)) {
dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout); dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
av7110_av_start_play(av7110,RP_AV); ret = av7110_av_start_play(av7110,RP_AV);
demux->playing = 1; if (!ret)
demux->playing = 1;
} }
break; break;
default: default:
dvb_feed_start_pid(feed); ret = dvb_feed_start_pid(feed);
break; break;
} }
} else if ((feed->ts_type & TS_PACKET) && } else if ((feed->ts_type & TS_PACKET) &&
(demux->dmx.frontend->source != DMX_MEMORY_FE)) { (demux->dmx.frontend->source != DMX_MEMORY_FE)) {
StartHWFilter(feed->filter); ret = StartHWFilter(feed->filter);
} }
} }
if (feed->type == DMX_TYPE_SEC) { else if (feed->type == DMX_TYPE_SEC) {
int i; int i;
for (i = 0; i < demux->filternum; i++) { for (i = 0; i < demux->filternum; i++) {
...@@ -996,12 +1034,15 @@ static int av7110_start_feed(struct dvb_demux_feed *feed) ...@@ -996,12 +1034,15 @@ static int av7110_start_feed(struct dvb_demux_feed *feed)
if (demux->filter[i].filter.parent != &feed->feed.sec) if (demux->filter[i].filter.parent != &feed->feed.sec)
continue; continue;
demux->filter[i].state = DMX_STATE_GO; demux->filter[i].state = DMX_STATE_GO;
if (demux->dmx.frontend->source != DMX_MEMORY_FE) if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
StartHWFilter(&demux->filter[i]); ret = StartHWFilter(&demux->filter[i]);
if (ret)
break;
}
} }
} }
return 0; return ret;
} }
...@@ -1010,6 +1051,7 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed) ...@@ -1010,6 +1051,7 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed)
struct dvb_demux *demux = feed->demux; struct dvb_demux *demux = feed->demux;
struct av7110 *av7110 = demux->priv; struct av7110 *av7110 = demux->priv;
int ret = 0;
dprintk(4, "%p\n", av7110); dprintk(4, "%p\n", av7110);
if (feed->type == DMX_TYPE_TS) { if (feed->type == DMX_TYPE_TS) {
...@@ -1022,26 +1064,29 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed) ...@@ -1022,26 +1064,29 @@ static int av7110_stop_feed(struct dvb_demux_feed *feed)
} }
if (feed->ts_type & TS_DECODER && if (feed->ts_type & TS_DECODER &&
feed->pes_type < DMX_TS_PES_OTHER) { feed->pes_type < DMX_TS_PES_OTHER) {
dvb_feed_stop_pid(feed); ret = dvb_feed_stop_pid(feed);
} else } else
if ((feed->ts_type & TS_PACKET) && if ((feed->ts_type & TS_PACKET) &&
(demux->dmx.frontend->source != DMX_MEMORY_FE)) (demux->dmx.frontend->source != DMX_MEMORY_FE))
StopHWFilter(feed->filter); ret = StopHWFilter(feed->filter);
} }
if (feed->type == DMX_TYPE_SEC) { if (!ret && feed->type == DMX_TYPE_SEC) {
int i; int i;
for (i = 0; i<demux->filternum; i++) for (i = 0; i<demux->filternum; i++)
if (demux->filter[i].state == DMX_STATE_GO && if (demux->filter[i].state == DMX_STATE_GO &&
demux->filter[i].filter.parent == &feed->feed.sec) { demux->filter[i].filter.parent == &feed->feed.sec) {
demux->filter[i].state = DMX_STATE_READY; demux->filter[i].state = DMX_STATE_READY;
if (demux->dmx.frontend->source != DMX_MEMORY_FE) if (demux->dmx.frontend->source != DMX_MEMORY_FE) {
StopHWFilter(&demux->filter[i]); ret = StopHWFilter(&demux->filter[i]);
if (ret)
break;
}
} }
} }
return 0; return ret;
} }
...@@ -1093,7 +1138,7 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, ...@@ -1093,7 +1138,7 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4); ret = av7110_fw_request(av7110, &tag, 0, fwstc, 4);
if (ret) { if (ret) {
printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__); printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__);
return -EIO; return ret;
} }
dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n", dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
fwstc[0], fwstc[1], fwstc[2], fwstc[3]); fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
...@@ -1119,18 +1164,14 @@ static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) ...@@ -1119,18 +1164,14 @@ static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
switch (tone) { switch (tone) {
case SEC_TONE_ON: case SEC_TONE_ON:
Set22K(av7110, 1); return Set22K(av7110, 1);
break;
case SEC_TONE_OFF: case SEC_TONE_OFF:
Set22K(av7110, 0); return Set22K(av7110, 0);
break;
default: default:
return -EINVAL; return -EINVAL;
} }
return 0;
} }
static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe, static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
...@@ -1138,9 +1179,7 @@ static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe, ...@@ -1138,9 +1179,7 @@ static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
{ {
struct av7110* av7110 = fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1); return av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
return 0;
} }
static int av7110_diseqc_send_burst(struct dvb_frontend* fe, static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
...@@ -1148,9 +1187,7 @@ static int av7110_diseqc_send_burst(struct dvb_frontend* fe, ...@@ -1148,9 +1187,7 @@ static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
{ {
struct av7110* av7110 = fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_diseqc_send(av7110, 0, NULL, minicmd); return av7110_diseqc_send(av7110, 0, NULL, minicmd);
return 0;
} }
/* simplified code from budget-core.c */ /* simplified code from budget-core.c */
...@@ -1992,76 +2029,84 @@ static struct l64781_config grundig_29504_401_config = { ...@@ -1992,76 +2029,84 @@ static struct l64781_config grundig_29504_401_config = {
static void av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) static int av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
{ {
int ret = 0;
int synced = (status & FE_HAS_LOCK) ? 1 : 0; int synced = (status & FE_HAS_LOCK) ? 1 : 0;
av7110->fe_status = status; av7110->fe_status = status;
if (av7110->fe_synced == synced) if (av7110->fe_synced == synced)
return; return 0;
av7110->fe_synced = synced; av7110->fe_synced = synced;
if (av7110->playing) if (av7110->playing)
return; return 0;
if (down_interruptible(&av7110->pid_mutex)) if (down_interruptible(&av7110->pid_mutex))
return; return -ERESTARTSYS;
if (av7110->fe_synced) { if (av7110->fe_synced) {
SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO], ret = SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
av7110->pids[DMX_PES_AUDIO], av7110->pids[DMX_PES_AUDIO],
av7110->pids[DMX_PES_TELETEXT], 0, av7110->pids[DMX_PES_TELETEXT], 0,
av7110->pids[DMX_PES_PCR]); av7110->pids[DMX_PES_PCR]);
av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); if (!ret)
ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
} else { } else {
SetPIDs(av7110, 0, 0, 0, 0, 0); ret = SetPIDs(av7110, 0, 0, 0, 0, 0);
av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0); if (!ret) {
av7110_wait_msgstate(av7110, GPMQBusy); ret = av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
if (!ret)
ret = av7110_wait_msgstate(av7110, GPMQBusy);
}
} }
up(&av7110->pid_mutex); up(&av7110->pid_mutex);
return ret;
} }
static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{ {
struct av7110* av7110 = fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0);
return av7110->fe_set_frontend(fe, params); int ret = av7110_fe_lock_fix(av7110, 0);
if (!ret)
ret = av7110->fe_set_frontend(fe, params);
return ret;
} }
static int av7110_fe_init(struct dvb_frontend* fe) static int av7110_fe_init(struct dvb_frontend* fe)
{ {
struct av7110* av7110 = fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0); int ret = av7110_fe_lock_fix(av7110, 0);
return av7110->fe_init(fe); if (!ret)
ret = av7110->fe_init(fe);
return ret;
} }
static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status) static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
{ {
struct av7110* av7110 = fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
int ret;
/* call the real implementation */ /* call the real implementation */
ret = av7110->fe_read_status(fe, status); int ret = av7110->fe_read_status(fe, status);
if (ret) if (!ret)
return ret; if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK))
ret = av7110_fe_lock_fix(av7110, *status);
if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK)) { return ret;
av7110_fe_lock_fix(av7110, *status);
}
return 0;
} }
static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe) static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
{ {
struct av7110* av7110 = fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0); int ret = av7110_fe_lock_fix(av7110, 0);
return av7110->fe_diseqc_reset_overload(fe); if (!ret)
ret = av7110->fe_diseqc_reset_overload(fe);
return ret;
} }
static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
...@@ -2069,40 +2114,50 @@ static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, ...@@ -2069,40 +2114,50 @@ static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
{ {
struct av7110* av7110 = fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0); int ret = av7110_fe_lock_fix(av7110, 0);
return av7110->fe_diseqc_send_master_cmd(fe, cmd); if (!ret)
ret = av7110->fe_diseqc_send_master_cmd(fe, cmd);
return ret;
} }
static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
{ {
struct av7110* av7110 = fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0); int ret = av7110_fe_lock_fix(av7110, 0);
return av7110->fe_diseqc_send_burst(fe, minicmd); if (!ret)
ret = av7110->fe_diseqc_send_burst(fe, minicmd);
return ret;
} }
static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
{ {
struct av7110* av7110 = fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0); int ret = av7110_fe_lock_fix(av7110, 0);
return av7110->fe_set_tone(fe, tone); if (!ret)
ret = av7110->fe_set_tone(fe, tone);
return ret;
} }
static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
{ {
struct av7110* av7110 = fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0); int ret = av7110_fe_lock_fix(av7110, 0);
return av7110->fe_set_voltage(fe, voltage); if (!ret)
ret = av7110->fe_set_voltage(fe, voltage);
return ret;
} }
static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd) static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd)
{ {
struct av7110* av7110 = fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0); int ret = av7110_fe_lock_fix(av7110, 0);
return av7110->fe_dishnetwork_send_legacy_command(fe, cmd); if (!ret)
ret = av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
return ret;
} }
static u8 read_pwm(struct av7110* av7110) static u8 read_pwm(struct av7110* av7110)
......
...@@ -254,12 +254,12 @@ struct av7110 { ...@@ -254,12 +254,12 @@ struct av7110 {
}; };
extern void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
u16 subpid, u16 pcrpid); u16 subpid, u16 pcrpid);
extern void av7110_register_irc_handler(void (*func)(u32)); extern void av7110_register_irc_handler(void (*func)(u32));
extern void av7110_unregister_irc_handler(void (*func)(u32)); extern void av7110_unregister_irc_handler(void (*func)(u32));
extern void av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config); extern int av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config);
extern int av7110_ir_init (void); extern int av7110_ir_init (void);
extern void av7110_ir_exit (void); extern void av7110_ir_exit (void);
......
...@@ -121,6 +121,7 @@ static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data) ...@@ -121,6 +121,7 @@ static int dvb_filter_pes2ts_cb(void *priv, unsigned char *data)
int av7110_av_start_record(struct av7110 *av7110, int av, int av7110_av_start_record(struct av7110 *av7110, int av,
struct dvb_demux_feed *dvbdmxfeed) struct dvb_demux_feed *dvbdmxfeed)
{ {
int ret = 0;
struct dvb_demux *dvbdmx = dvbdmxfeed->demux; struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed); dprintk(2, "av7110:%p, , dvb_demux_feed:%p\n", av7110, dvbdmxfeed);
...@@ -137,7 +138,7 @@ int av7110_av_start_record(struct av7110 *av7110, int av, ...@@ -137,7 +138,7 @@ int av7110_av_start_record(struct av7110 *av7110, int av,
dvbdmx->pesfilter[0]->pid, dvbdmx->pesfilter[0]->pid,
dvb_filter_pes2ts_cb, dvb_filter_pes2ts_cb,
(void *) dvbdmx->pesfilter[0]); (void *) dvbdmx->pesfilter[0]);
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
break; break;
case RP_VIDEO: case RP_VIDEO:
...@@ -145,7 +146,7 @@ int av7110_av_start_record(struct av7110 *av7110, int av, ...@@ -145,7 +146,7 @@ int av7110_av_start_record(struct av7110 *av7110, int av,
dvbdmx->pesfilter[1]->pid, dvbdmx->pesfilter[1]->pid,
dvb_filter_pes2ts_cb, dvb_filter_pes2ts_cb,
(void *) dvbdmx->pesfilter[1]); (void *) dvbdmx->pesfilter[1]);
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
break; break;
case RP_AV: case RP_AV:
...@@ -157,14 +158,15 @@ int av7110_av_start_record(struct av7110 *av7110, int av, ...@@ -157,14 +158,15 @@ int av7110_av_start_record(struct av7110 *av7110, int av,
dvbdmx->pesfilter[1]->pid, dvbdmx->pesfilter[1]->pid,
dvb_filter_pes2ts_cb, dvb_filter_pes2ts_cb,
(void *) dvbdmx->pesfilter[1]); (void *) dvbdmx->pesfilter[1]);
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AV_PES, 0);
break; break;
} }
return 0; return ret;
} }
int av7110_av_start_play(struct av7110 *av7110, int av) int av7110_av_start_play(struct av7110 *av7110, int av)
{ {
int ret = 0;
dprintk(2, "av7110:%p, \n", av7110); dprintk(2, "av7110:%p, \n", av7110);
if (av7110->rec_mode) if (av7110->rec_mode)
...@@ -182,54 +184,57 @@ int av7110_av_start_play(struct av7110 *av7110, int av) ...@@ -182,54 +184,57 @@ int av7110_av_start_play(struct av7110 *av7110, int av)
av7110->playing |= av; av7110->playing |= av;
switch (av7110->playing) { switch (av7110->playing) {
case RP_AUDIO: case RP_AUDIO:
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
break; break;
case RP_VIDEO: case RP_VIDEO:
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
av7110->sinfo = 0; av7110->sinfo = 0;
break; break;
case RP_AV: case RP_AV:
av7110->sinfo = 0; av7110->sinfo = 0;
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AV_PES, 0);
break; break;
} }
return av7110->playing; if (!ret)
ret = av7110->playing;
return ret;
} }
void av7110_av_stop(struct av7110 *av7110, int av) int av7110_av_stop(struct av7110 *av7110, int av)
{ {
int ret = 0;
dprintk(2, "av7110:%p, \n", av7110); dprintk(2, "av7110:%p, \n", av7110);
if (!(av7110->playing & av) && !(av7110->rec_mode & av)) if (!(av7110->playing & av) && !(av7110->rec_mode & av))
return; return 0;
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
if (av7110->playing) { if (av7110->playing) {
av7110->playing &= ~av; av7110->playing &= ~av;
switch (av7110->playing) { switch (av7110->playing) {
case RP_AUDIO: case RP_AUDIO:
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, AudioPES, 0);
break; break;
case RP_VIDEO: case RP_VIDEO:
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Play, 2, VideoPES, 0);
break; break;
case RP_NONE: case RP_NONE:
av7110_set_vidmode(av7110, av7110->vidmode); ret = av7110_set_vidmode(av7110, av7110->vidmode);
break; break;
} }
} else { } else {
av7110->rec_mode &= ~av; av7110->rec_mode &= ~av;
switch (av7110->rec_mode) { switch (av7110->rec_mode) {
case RP_AUDIO: case RP_AUDIO:
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, AudioPES, 0);
break; break;
case RP_VIDEO: case RP_VIDEO:
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Record, 2, VideoPES, 0);
break; break;
case RP_NONE: case RP_NONE:
break; break;
} }
} }
return ret;
} }
...@@ -317,19 +322,22 @@ int av7110_set_volume(struct av7110 *av7110, int volleft, int volright) ...@@ -317,19 +322,22 @@ int av7110_set_volume(struct av7110 *av7110, int volleft, int volright)
return 0; return 0;
} }
void av7110_set_vidmode(struct av7110 *av7110, int mode) int av7110_set_vidmode(struct av7110 *av7110, int mode)
{ {
int ret;
dprintk(2, "av7110:%p, \n", av7110); dprintk(2, "av7110:%p, \n", av7110);
av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode); ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, LoadVidCode, 1, mode);
if (!av7110->playing) { if (!ret && !av7110->playing) {
ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO], ret = ChangePIDs(av7110, av7110->pids[DMX_PES_VIDEO],
av7110->pids[DMX_PES_AUDIO], av7110->pids[DMX_PES_AUDIO],
av7110->pids[DMX_PES_TELETEXT], av7110->pids[DMX_PES_TELETEXT],
0, av7110->pids[DMX_PES_PCR]); 0, av7110->pids[DMX_PES_PCR]);
av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); if (!ret)
ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
} }
return ret;
} }
...@@ -340,17 +348,18 @@ static int sw2mode[16] = { ...@@ -340,17 +348,18 @@ static int sw2mode[16] = {
VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL, VIDEO_MODE_PAL,
}; };
static void get_video_format(struct av7110 *av7110, u8 *buf, int count) static int get_video_format(struct av7110 *av7110, u8 *buf, int count)
{ {
int i; int i;
int hsize, vsize; int hsize, vsize;
int sw; int sw;
u8 *p; u8 *p;
int ret = 0;
dprintk(2, "av7110:%p, \n", av7110); dprintk(2, "av7110:%p, \n", av7110);
if (av7110->sinfo) if (av7110->sinfo)
return; return 0;
for (i = 7; i < count - 10; i++) { for (i = 7; i < count - 10; i++) {
p = buf + i; p = buf + i;
if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3) if (p[0] || p[1] || p[2] != 0x01 || p[3] != 0xb3)
...@@ -359,11 +368,14 @@ static void get_video_format(struct av7110 *av7110, u8 *buf, int count) ...@@ -359,11 +368,14 @@ static void get_video_format(struct av7110 *av7110, u8 *buf, int count)
hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4); hsize = ((p[1] &0xF0) >> 4) | (p[0] << 4);
vsize = ((p[1] &0x0F) << 8) | (p[2]); vsize = ((p[1] &0x0F) << 8) | (p[2]);
sw = (p[3] & 0x0F); sw = (p[3] & 0x0F);
av7110_set_vidmode(av7110, sw2mode[sw]); ret = av7110_set_vidmode(av7110, sw2mode[sw]);
dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw); if (!ret) {
av7110->sinfo = 1; dprintk(2, "playback %dx%d fr=%d\n", hsize, vsize, sw);
av7110->sinfo = 1;
}
break; break;
} }
return ret;
} }
...@@ -974,7 +986,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, ...@@ -974,7 +986,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
unsigned long arg = (unsigned long) parg; unsigned long arg = (unsigned long) parg;
int ret = 0; int ret = 0;
dprintk(2, "av7110:%p, \n", av7110); dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
if ((file->f_flags & O_ACCMODE) == O_RDONLY) { if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT && if ( cmd != VIDEO_GET_STATUS && cmd != VIDEO_GET_EVENT &&
...@@ -987,49 +999,57 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, ...@@ -987,49 +999,57 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
case VIDEO_STOP: case VIDEO_STOP:
av7110->videostate.play_state = VIDEO_STOPPED; av7110->videostate.play_state = VIDEO_STOPPED;
if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY)
av7110_av_stop(av7110, RP_VIDEO); ret = av7110_av_stop(av7110, RP_VIDEO);
else else
vidcom(av7110, VIDEO_CMD_STOP, ret = vidcom(av7110, VIDEO_CMD_STOP,
av7110->videostate.video_blank ? 0 : 1); av7110->videostate.video_blank ? 0 : 1);
av7110->trickmode = TRICK_NONE; if (!ret)
av7110->trickmode = TRICK_NONE;
break; break;
case VIDEO_PLAY: case VIDEO_PLAY:
av7110->trickmode = TRICK_NONE; av7110->trickmode = TRICK_NONE;
if (av7110->videostate.play_state == VIDEO_FREEZED) { if (av7110->videostate.play_state == VIDEO_FREEZED) {
av7110->videostate.play_state = VIDEO_PLAYING; av7110->videostate.play_state = VIDEO_PLAYING;
vidcom(av7110, VIDEO_CMD_PLAY, 0); ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
if (ret)
break;
} }
if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) { if (av7110->videostate.stream_source == VIDEO_SOURCE_MEMORY) {
if (av7110->playing == RP_AV) { if (av7110->playing == RP_AV) {
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Stop, 0);
if (ret)
break;
av7110->playing &= ~RP_VIDEO; av7110->playing &= ~RP_VIDEO;
} }
av7110_av_start_play(av7110, RP_VIDEO); ret = av7110_av_start_play(av7110, RP_VIDEO);
vidcom(av7110, VIDEO_CMD_PLAY, 0);
} else {
//av7110_av_stop(av7110, RP_VIDEO);
vidcom(av7110, VIDEO_CMD_PLAY, 0);
} }
av7110->videostate.play_state = VIDEO_PLAYING; if (!ret)
ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
if (!ret)
av7110->videostate.play_state = VIDEO_PLAYING;
break; break;
case VIDEO_FREEZE: case VIDEO_FREEZE:
av7110->videostate.play_state = VIDEO_FREEZED; av7110->videostate.play_state = VIDEO_FREEZED;
if (av7110->playing & RP_VIDEO) if (av7110->playing & RP_VIDEO)
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Pause, 0);
else else
vidcom(av7110, VIDEO_CMD_FREEZE, 1); ret = vidcom(av7110, VIDEO_CMD_FREEZE, 1);
av7110->trickmode = TRICK_FREEZE; if (!ret)
av7110->trickmode = TRICK_FREEZE;
break; break;
case VIDEO_CONTINUE: case VIDEO_CONTINUE:
if (av7110->playing & RP_VIDEO) if (av7110->playing & RP_VIDEO)
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Continue, 0);
vidcom(av7110, VIDEO_CMD_PLAY, 0); if (!ret)
av7110->videostate.play_state = VIDEO_PLAYING; ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
av7110->trickmode = TRICK_NONE; if (!ret) {
av7110->videostate.play_state = VIDEO_PLAYING;
av7110->trickmode = TRICK_NONE;
}
break; break;
case VIDEO_SELECT_SOURCE: case VIDEO_SELECT_SOURCE:
...@@ -1045,7 +1065,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, ...@@ -1045,7 +1065,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
break; break;
case VIDEO_GET_EVENT: case VIDEO_GET_EVENT:
ret=dvb_video_get_event(av7110, parg, file->f_flags); ret = dvb_video_get_event(av7110, parg, file->f_flags);
break; break;
case VIDEO_GET_SIZE: case VIDEO_GET_SIZE:
...@@ -1105,25 +1125,32 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, ...@@ -1105,25 +1125,32 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
case VIDEO_FAST_FORWARD: case VIDEO_FAST_FORWARD:
//note: arg is ignored by firmware //note: arg is ignored by firmware
if (av7110->playing & RP_VIDEO) if (av7110->playing & RP_VIDEO)
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
__Scan_I, 2, AV_PES, 0); __Scan_I, 2, AV_PES, 0);
else else
vidcom(av7110, VIDEO_CMD_FFWD, arg); ret = vidcom(av7110, VIDEO_CMD_FFWD, arg);
av7110->trickmode = TRICK_FAST; if (!ret) {
av7110->videostate.play_state = VIDEO_PLAYING; av7110->trickmode = TRICK_FAST;
av7110->videostate.play_state = VIDEO_PLAYING;
}
break; break;
case VIDEO_SLOWMOTION: case VIDEO_SLOWMOTION:
if (av7110->playing&RP_VIDEO) { if (av7110->playing&RP_VIDEO) {
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0); ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, __Slow, 2, 0, 0);
vidcom(av7110, VIDEO_CMD_SLOW, arg); if (!ret)
ret = vidcom(av7110, VIDEO_CMD_SLOW, arg);
} else { } else {
vidcom(av7110, VIDEO_CMD_PLAY, 0); ret = vidcom(av7110, VIDEO_CMD_PLAY, 0);
vidcom(av7110, VIDEO_CMD_STOP, 0); if (!ret)
vidcom(av7110, VIDEO_CMD_SLOW, arg); ret = vidcom(av7110, VIDEO_CMD_STOP, 0);
if (!ret)
ret = vidcom(av7110, VIDEO_CMD_SLOW, arg);
}
if (!ret) {
av7110->trickmode = TRICK_SLOW;
av7110->videostate.play_state = VIDEO_PLAYING;
} }
av7110->trickmode = TRICK_SLOW;
av7110->videostate.play_state = VIDEO_PLAYING;
break; break;
case VIDEO_GET_CAPABILITIES: case VIDEO_GET_CAPABILITIES:
...@@ -1136,18 +1163,21 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, ...@@ -1136,18 +1163,21 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
av7110_ipack_reset(&av7110->ipack[1]); av7110_ipack_reset(&av7110->ipack[1]);
if (av7110->playing == RP_AV) { if (av7110->playing == RP_AV) {
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
__Play, 2, AV_PES, 0); __Play, 2, AV_PES, 0);
if (ret)
break;
if (av7110->trickmode == TRICK_FAST) if (av7110->trickmode == TRICK_FAST)
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
__Scan_I, 2, AV_PES, 0); __Scan_I, 2, AV_PES, 0);
if (av7110->trickmode == TRICK_SLOW) { if (av7110->trickmode == TRICK_SLOW) {
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
__Slow, 2, 0, 0); __Slow, 2, 0, 0);
vidcom(av7110, VIDEO_CMD_SLOW, arg); if (!ret)
ret = vidcom(av7110, VIDEO_CMD_SLOW, arg);
} }
if (av7110->trickmode == TRICK_FREEZE) if (av7110->trickmode == TRICK_FREEZE)
vidcom(av7110, VIDEO_CMD_STOP, 1); ret = vidcom(av7110, VIDEO_CMD_STOP, 1);
} }
break; break;
...@@ -1170,7 +1200,7 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, ...@@ -1170,7 +1200,7 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
unsigned long arg = (unsigned long) parg; unsigned long arg = (unsigned long) parg;
int ret = 0; int ret = 0;
dprintk(2, "av7110:%p, \n", av7110); dprintk(1, "av7110:%p, cmd=%04x\n", av7110,cmd);
if (((file->f_flags & O_ACCMODE) == O_RDONLY) && if (((file->f_flags & O_ACCMODE) == O_RDONLY) &&
(cmd != AUDIO_GET_STATUS)) (cmd != AUDIO_GET_STATUS))
...@@ -1179,28 +1209,32 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, ...@@ -1179,28 +1209,32 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
switch (cmd) { switch (cmd) {
case AUDIO_STOP: case AUDIO_STOP:
if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
av7110_av_stop(av7110, RP_AUDIO); ret = av7110_av_stop(av7110, RP_AUDIO);
else else
audcom(av7110, AUDIO_CMD_MUTE); ret = audcom(av7110, AUDIO_CMD_MUTE);
av7110->audiostate.play_state = AUDIO_STOPPED; if (!ret)
av7110->audiostate.play_state = AUDIO_STOPPED;
break; break;
case AUDIO_PLAY: case AUDIO_PLAY:
if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY) if (av7110->audiostate.stream_source == AUDIO_SOURCE_MEMORY)
av7110_av_start_play(av7110, RP_AUDIO); ret = av7110_av_start_play(av7110, RP_AUDIO);
audcom(av7110, AUDIO_CMD_UNMUTE); if (!ret)
av7110->audiostate.play_state = AUDIO_PLAYING; ret = audcom(av7110, AUDIO_CMD_UNMUTE);
if (!ret)
av7110->audiostate.play_state = AUDIO_PLAYING;
break; break;
case AUDIO_PAUSE: case AUDIO_PAUSE:
audcom(av7110, AUDIO_CMD_MUTE); ret = audcom(av7110, AUDIO_CMD_MUTE);
av7110->audiostate.play_state = AUDIO_PAUSED; if (!ret)
av7110->audiostate.play_state = AUDIO_PAUSED;
break; break;
case AUDIO_CONTINUE: case AUDIO_CONTINUE:
if (av7110->audiostate.play_state == AUDIO_PAUSED) { if (av7110->audiostate.play_state == AUDIO_PAUSED) {
av7110->audiostate.play_state = AUDIO_PLAYING; av7110->audiostate.play_state = AUDIO_PLAYING;
audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16); ret = audcom(av7110, AUDIO_CMD_UNMUTE | AUDIO_CMD_PCM16);
} }
break; break;
...@@ -1210,14 +1244,15 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, ...@@ -1210,14 +1244,15 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
case AUDIO_SET_MUTE: case AUDIO_SET_MUTE:
{ {
audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE); ret = audcom(av7110, arg ? AUDIO_CMD_MUTE : AUDIO_CMD_UNMUTE);
av7110->audiostate.mute_state = (int) arg; if (!ret)
av7110->audiostate.mute_state = (int) arg;
break; break;
} }
case AUDIO_SET_AV_SYNC: case AUDIO_SET_AV_SYNC:
av7110->audiostate.AV_sync_state = (int) arg; av7110->audiostate.AV_sync_state = (int) arg;
audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF); ret = audcom(av7110, arg ? AUDIO_CMD_SYNC_ON : AUDIO_CMD_SYNC_OFF);
break; break;
case AUDIO_SET_BYPASS_MODE: case AUDIO_SET_BYPASS_MODE:
...@@ -1229,21 +1264,24 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, ...@@ -1229,21 +1264,24 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
switch(av7110->audiostate.channel_select) { switch(av7110->audiostate.channel_select) {
case AUDIO_STEREO: case AUDIO_STEREO:
audcom(av7110, AUDIO_CMD_STEREO); ret = audcom(av7110, AUDIO_CMD_STEREO);
if (av7110->adac_type == DVB_ADAC_CRYSTAL) if (!ret)
i2c_writereg(av7110, 0x20, 0x02, 0x49); if (av7110->adac_type == DVB_ADAC_CRYSTAL)
i2c_writereg(av7110, 0x20, 0x02, 0x49);
break; break;
case AUDIO_MONO_LEFT: case AUDIO_MONO_LEFT:
audcom(av7110, AUDIO_CMD_MONO_L); ret = audcom(av7110, AUDIO_CMD_MONO_L);
if (av7110->adac_type == DVB_ADAC_CRYSTAL) if (!ret)
i2c_writereg(av7110, 0x20, 0x02, 0x4a); if (av7110->adac_type == DVB_ADAC_CRYSTAL)
i2c_writereg(av7110, 0x20, 0x02, 0x4a);
break; break;
case AUDIO_MONO_RIGHT: case AUDIO_MONO_RIGHT:
audcom(av7110, AUDIO_CMD_MONO_R); ret = audcom(av7110, AUDIO_CMD_MONO_R);
if (av7110->adac_type == DVB_ADAC_CRYSTAL) if (!ret)
i2c_writereg(av7110, 0x20, 0x02, 0x45); if (av7110->adac_type == DVB_ADAC_CRYSTAL)
i2c_writereg(av7110, 0x20, 0x02, 0x45);
break; break;
default: default:
...@@ -1264,7 +1302,7 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, ...@@ -1264,7 +1302,7 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout); dvb_ringbuffer_flush_spinlock_wakeup(&av7110->aout);
av7110_ipack_reset(&av7110->ipack[0]); av7110_ipack_reset(&av7110->ipack[0]);
if (av7110->playing == RP_AV) if (av7110->playing == RP_AV)
av7110_fw_cmd(av7110, COMTYPE_REC_PLAY, ret = av7110_fw_cmd(av7110, COMTYPE_REC_PLAY,
__Play, 2, AV_PES, 0); __Play, 2, AV_PES, 0);
break; break;
case AUDIO_SET_ID: case AUDIO_SET_ID:
...@@ -1274,7 +1312,7 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, ...@@ -1274,7 +1312,7 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
{ {
struct audio_mixer *amix = (struct audio_mixer *)parg; struct audio_mixer *amix = (struct audio_mixer *)parg;
av7110_set_volume(av7110, amix->volume_left, amix->volume_right); ret = av7110_set_volume(av7110, amix->volume_left, amix->volume_right);
break; break;
} }
case AUDIO_SET_STREAMTYPE: case AUDIO_SET_STREAMTYPE:
......
...@@ -3,14 +3,14 @@ ...@@ -3,14 +3,14 @@
struct av7110; struct av7110;
extern void av7110_set_vidmode(struct av7110 *av7110, int mode); extern int av7110_set_vidmode(struct av7110 *av7110, int mode);
extern int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len); extern int av7110_record_cb(struct dvb_filter_pes2ts *p2t, u8 *buf, size_t len);
extern int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen); extern int av7110_pes_play(void *dest, struct dvb_ringbuffer *buf, int dlen);
extern int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len); extern int av7110_write_to_decoder(struct dvb_demux_feed *feed, const u8 *buf, size_t len);
extern int av7110_set_volume(struct av7110 *av7110, int volleft, int volright); extern int av7110_set_volume(struct av7110 *av7110, int volleft, int volright);
extern void av7110_av_stop(struct av7110 *av7110, int av); extern int av7110_av_stop(struct av7110 *av7110, int av);
extern int av7110_av_start_record(struct av7110 *av7110, int av, extern int av7110_av_start_record(struct av7110 *av7110, int av,
struct dvb_demux_feed *dvbdmxfeed); struct dvb_demux_feed *dvbdmxfeed);
extern int av7110_av_start_play(struct av7110 *av7110, int av); extern int av7110_av_start_play(struct av7110 *av7110, int av);
......
...@@ -458,27 +458,27 @@ static inline int SendDAC(struct av7110 *av7110, u8 addr, u8 data) ...@@ -458,27 +458,27 @@ static inline int SendDAC(struct av7110 *av7110, u8 addr, u8 data)
return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data); return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, AudioDAC, 2, addr, data);
} }
static inline void av7710_set_video_mode(struct av7110 *av7110, int mode) static inline int av7710_set_video_mode(struct av7110 *av7110, int mode)
{ {
av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode); return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetVidMode, 1, mode);
} }
static int inline vidcom(struct av7110 *av7110, u32 com, u32 arg) static inline int vidcom(struct av7110 *av7110, u32 com, u32 arg)
{ {
return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_VIDEO_COMMAND, 4, return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_VIDEO_COMMAND, 4,
(com>>16), (com&0xffff), (com>>16), (com&0xffff),
(arg>>16), (arg&0xffff)); (arg>>16), (arg&0xffff));
} }
static int inline audcom(struct av7110 *av7110, u32 com) static inline int audcom(struct av7110 *av7110, u32 com)
{ {
return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_AUDIO_COMMAND, 2, return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_AUDIO_COMMAND, 2,
(com>>16), (com&0xffff)); (com>>16), (com&0xffff));
} }
static inline void Set22K(struct av7110 *av7110, int state) static inline int Set22K(struct av7110 *av7110, int state)
{ {
av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0); return av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, (state ? ON22K : OFF22K), 0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment