Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 92791
b: refs/heads/master
c: 1cb03b7
h: refs/heads/master
i:
  92789: 064a6e6
  92787: 7ee26f1
  92783: 13dc86b
v: v3
  • Loading branch information
Mike Isely authored and Mauro Carvalho Chehab committed Apr 24, 2008
1 parent c07b191 commit 7ed8f43
Show file tree
Hide file tree
Showing 8 changed files with 247 additions and 75 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d3f8d8fb304a8b9a81eae16ff7b50f5379f2437e
refs/heads/master: 1cb03b76d09d20accfa5c1664c16ba6566f539a0
69 changes: 69 additions & 0 deletions trunk/drivers/media/video/pvrusb2/pvrusb2-context.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,22 @@ struct pvr2_context *pvr2_context_create(
}


static void pvr2_context_reset_input_limits(struct pvr2_context *mp)
{
unsigned int tmsk,mmsk;
struct pvr2_channel *cp;
struct pvr2_hdw *hdw = mp->hdw;
mmsk = pvr2_hdw_get_input_available(hdw);
tmsk = mmsk;
for (cp = mp->mc_first; cp; cp = cp->mc_next) {
if (!cp->input_mask) continue;
tmsk &= cp->input_mask;
}
pvr2_hdw_set_input_allowed(hdw,mmsk,tmsk);
pvr2_hdw_commit_ctl(hdw);
}


static void pvr2_context_enter(struct pvr2_context *mp)
{
mutex_lock(&mp->mutex);
Expand Down Expand Up @@ -300,7 +316,9 @@ void pvr2_channel_done(struct pvr2_channel *cp)
{
struct pvr2_context *mp = cp->mc_head;
pvr2_context_enter(mp);
cp->input_mask = 0;
pvr2_channel_disclaim_stream(cp);
pvr2_context_reset_input_limits(mp);
if (cp->mc_next) {
cp->mc_next->mc_prev = cp->mc_prev;
} else {
Expand All @@ -316,6 +334,57 @@ void pvr2_channel_done(struct pvr2_channel *cp)
}


int pvr2_channel_limit_inputs(struct pvr2_channel *cp,unsigned int cmsk)
{
unsigned int tmsk,mmsk;
int ret = 0;
struct pvr2_channel *p2;
struct pvr2_hdw *hdw = cp->hdw;

mmsk = pvr2_hdw_get_input_available(hdw);
cmsk &= mmsk;
if (cmsk == cp->input_mask) {
/* No change; nothing to do */
return 0;
}

pvr2_context_enter(cp->mc_head);
do {
if (!cmsk) {
cp->input_mask = 0;
pvr2_context_reset_input_limits(cp->mc_head);
break;
}
tmsk = mmsk;
for (p2 = cp->mc_head->mc_first; p2; p2 = p2->mc_next) {
if (p2 == cp) continue;
if (!p2->input_mask) continue;
tmsk &= p2->input_mask;
}
if (!(tmsk & cmsk)) {
ret = -EPERM;
break;
}
tmsk &= cmsk;
if ((ret = pvr2_hdw_set_input_allowed(hdw,mmsk,tmsk)) != 0) {
/* Internal failure changing allowed list; probably
should not happen, but react if it does. */
break;
}
cp->input_mask = cmsk;
pvr2_hdw_commit_ctl(hdw);
} while (0);
pvr2_context_exit(cp->mc_head);
return ret;
}


unsigned int pvr2_channel_get_limited_inputs(struct pvr2_channel *cp)
{
return cp->input_mask;
}


int pvr2_channel_claim_stream(struct pvr2_channel *cp,
struct pvr2_context_stream *sp)
{
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/media/video/pvrusb2/pvrusb2-context.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ struct pvr2_channel {
struct pvr2_channel *mc_prev;
struct pvr2_context_stream *stream;
struct pvr2_hdw *hdw;
unsigned int input_mask;
void (*check_func)(struct pvr2_channel *);
};

Expand All @@ -72,6 +73,8 @@ void pvr2_context_disconnect(struct pvr2_context *);

void pvr2_channel_init(struct pvr2_channel *,struct pvr2_context *);
void pvr2_channel_done(struct pvr2_channel *);
int pvr2_channel_limit_inputs(struct pvr2_channel *,unsigned int);
unsigned int pvr2_channel_get_limited_inputs(struct pvr2_channel *);
int pvr2_channel_claim_stream(struct pvr2_channel *,
struct pvr2_context_stream *);
struct pvr2_ioread *pvr2_channel_create_mpeg_stream(
Expand Down
47 changes: 21 additions & 26 deletions trunk/drivers/media/video/pvrusb2/pvrusb2-dvb.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,13 +244,10 @@ static int pvr2_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)

static int pvr2_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire)
{
/* TO DO: This function will call into the core and request for
* input to be set to 'dtv' if (acquire) and if it isn't set already.
*
* If (!acquire) then we should do nothing -- don't switch inputs
* again unless the analog side of the driver requests the bus.
*/
return 0;
struct pvr2_dvb_adapter *adap = fe->dvb->priv;
return pvr2_channel_limit_inputs(
&adap->channel,
(acquire ? (1 << PVR2_CVAL_INPUT_DTV) : 0));
}

static int pvr2_dvb_adapter_init(struct pvr2_dvb_adapter *adap)
Expand Down Expand Up @@ -320,32 +317,26 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
{
struct pvr2_hdw *hdw = adap->channel.hdw;
struct pvr2_dvb_props *dvb_props = hdw->hdw_desc->dvb_props;
int ret;
int ret = 0;

if (dvb_props == NULL) {
err("fe_props not defined!");
return -EINVAL;
}

/* FIXME: This code should be moved into the core,
* and should only be called if we don't already have
* control of the bus.
*
* We can't call "pvr2_dvb_bus_ctrl(adap->fe, 1)" from here,
* because adap->fe isn't defined yet.
*/
ret = pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_by_id(hdw,
PVR2_CID_INPUT),
PVR2_CVAL_INPUT_DTV);
if (ret != 0)
ret = pvr2_channel_limit_inputs(
&adap->channel,
(1 << PVR2_CVAL_INPUT_DTV));
if (ret) {
err("failed to grab control of dtv input (code=%d)",
ret);
return ret;

pvr2_hdw_commit_ctl(hdw);

}

if (dvb_props->frontend_attach == NULL) {
err("frontend_attach not defined!");
return -EINVAL;
ret = -EINVAL;
goto done;
}

if ((dvb_props->frontend_attach(adap) == 0) && (adap->fe)) {
Expand All @@ -354,7 +345,8 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
err("frontend registration failed!");
dvb_frontend_detach(adap->fe);
adap->fe = NULL;
return -ENODEV;
ret = -ENODEV;
goto done;
}

if (dvb_props->tuner_attach)
Expand All @@ -368,10 +360,13 @@ static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)

} else {
err("no frontend was attached!");
return -ENODEV;
ret = -ENODEV;
return ret;
}

return 0;
done:
pvr2_channel_limit_inputs(&adap->channel, 0);
return ret;
}

static int pvr2_dvb_frontend_exit(struct pvr2_dvb_adapter *adap)
Expand Down
4 changes: 3 additions & 1 deletion trunk/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,10 @@ struct pvr2_hdw {
int v4l_minor_number_vbi;
int v4l_minor_number_radio;

/* Bit mask of PVR2_CVAL_INPUT choices which are valid */
/* Bit mask of PVR2_CVAL_INPUT choices which are valid for the hardware */
unsigned int input_avail_mask;
/* Bit mask of PVR2_CVAL_INPUT choices which are currenly allowed */
unsigned int input_allowed_mask;

/* Location of eeprom or a negative number if none */
int eeprom_addr;
Expand Down
132 changes: 112 additions & 20 deletions trunk/drivers/media/video/pvrusb2/pvrusb2-hdw.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ static const struct pvr2_fx2cmd_descdef pvr2_fx2cmd_desc[] = {
};


static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v);
static void pvr2_hdw_state_sched(struct pvr2_hdw *);
static int pvr2_hdw_state_eval(struct pvr2_hdw *);
static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long);
Expand Down Expand Up @@ -404,30 +405,12 @@ static int ctrl_get_input(struct pvr2_ctrl *cptr,int *vp)

static int ctrl_check_input(struct pvr2_ctrl *cptr,int v)
{
return ((1 << v) & cptr->hdw->input_avail_mask) != 0;
return ((1 << v) & cptr->hdw->input_allowed_mask) != 0;
}

static int ctrl_set_input(struct pvr2_ctrl *cptr,int m,int v)
{
struct pvr2_hdw *hdw = cptr->hdw;

if (hdw->input_val != v) {
hdw->input_val = v;
hdw->input_dirty = !0;
}

/* Handle side effects - if we switch to a mode that needs the RF
tuner, then select the right frequency choice as well and mark
it dirty. */
if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
hdw->freqSelector = 0;
hdw->freqDirty = !0;
} else if ((hdw->input_val == PVR2_CVAL_INPUT_TV) ||
(hdw->input_val == PVR2_CVAL_INPUT_DTV)) {
hdw->freqSelector = 1;
hdw->freqDirty = !0;
}
return 0;
return pvr2_hdw_set_input(cptr->hdw,v);
}

static int ctrl_isdirty_input(struct pvr2_ctrl *cptr)
Expand Down Expand Up @@ -1916,6 +1899,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
if (hdw_desc->flag_has_composite) m |= 1 << PVR2_CVAL_INPUT_COMPOSITE;
if (hdw_desc->flag_has_fmradio) m |= 1 << PVR2_CVAL_INPUT_RADIO;
hdw->input_avail_mask = m;
hdw->input_allowed_mask = hdw->input_avail_mask;

/* If not a hybrid device, pathway_state never changes. So
initialize it here to what it should forever be. */
Expand Down Expand Up @@ -3948,6 +3932,24 @@ static int pvr2_hdw_state_update(struct pvr2_hdw *hdw)
}


static unsigned int print_input_mask(unsigned int msk,
char *buf,unsigned int acnt)
{
unsigned int idx,ccnt;
unsigned int tcnt = 0;
for (idx = 0; idx < ARRAY_SIZE(control_values_input); idx++) {
if (!((1 << idx) & msk)) continue;
ccnt = scnprintf(buf+tcnt,
acnt-tcnt,
"%s%s",
(tcnt ? ", " : ""),
control_values_input[idx]);
tcnt += ccnt;
}
return tcnt;
}


static const char *pvr2_pathway_state_name(int id)
{
switch (id) {
Expand Down Expand Up @@ -4016,6 +4018,28 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which,
"state: %s",
pvr2_get_state_name(hdw->master_state));
case 4: {
unsigned int tcnt = 0;
unsigned int ccnt;

ccnt = scnprintf(buf,
acnt,
"Hardware supported inputs: ");
tcnt += ccnt;
tcnt += print_input_mask(hdw->input_avail_mask,
buf+tcnt,
acnt-tcnt);
if (hdw->input_avail_mask != hdw->input_allowed_mask) {
ccnt = scnprintf(buf+tcnt,
acnt-tcnt,
"; allowed inputs: ");
tcnt += ccnt;
tcnt += print_input_mask(hdw->input_allowed_mask,
buf+tcnt,
acnt-tcnt);
}
return tcnt;
}
case 5: {
struct pvr2_stream_stats stats;
if (!hdw->vid_stream) break;
pvr2_stream_get_stats(hdw->vid_stream,
Expand Down Expand Up @@ -4210,6 +4234,74 @@ unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *hdw)
}


unsigned int pvr2_hdw_get_input_allowed(struct pvr2_hdw *hdw)
{
return hdw->input_allowed_mask;
}


static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v)
{
if (hdw->input_val != v) {
hdw->input_val = v;
hdw->input_dirty = !0;
}

/* Handle side effects - if we switch to a mode that needs the RF
tuner, then select the right frequency choice as well and mark
it dirty. */
if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
hdw->freqSelector = 0;
hdw->freqDirty = !0;
} else if ((hdw->input_val == PVR2_CVAL_INPUT_TV) ||
(hdw->input_val == PVR2_CVAL_INPUT_DTV)) {
hdw->freqSelector = 1;
hdw->freqDirty = !0;
}
return 0;
}


int pvr2_hdw_set_input_allowed(struct pvr2_hdw *hdw,
unsigned int change_mask,
unsigned int change_val)
{
int ret = 0;
unsigned int nv,m,idx;
LOCK_TAKE(hdw->big_lock);
do {
nv = hdw->input_allowed_mask & ~change_mask;
nv |= (change_val & change_mask);
nv &= hdw->input_avail_mask;
if (!nv) {
/* No legal modes left; return error instead. */
ret = -EPERM;
break;
}
hdw->input_allowed_mask = nv;
if ((1 << hdw->input_val) & hdw->input_allowed_mask) {
/* Current mode is still in the allowed mask, so
we're done. */
break;
}
/* Select and switch to a mode that is still in the allowed
mask */
if (!hdw->input_allowed_mask) {
/* Nothing legal; give up */
break;
}
m = hdw->input_allowed_mask;
for (idx = 0; idx < (sizeof(m) << 3); idx++) {
if (!((1 << idx) & m)) continue;
pvr2_hdw_set_input(hdw,idx);
break;
}
} while (0);
LOCK_GIVE(hdw->big_lock);
return ret;
}


/* Find I2C address of eeprom */
static int pvr2_hdw_get_eeprom_addr(struct pvr2_hdw *hdw)
{
Expand Down
Loading

0 comments on commit 7ed8f43

Please sign in to comment.