Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 285419
b: refs/heads/master
c: e90ab84
h: refs/heads/master
i:
  285417: b3a8e6d
  285415: d8be7fe
v: v3
  • Loading branch information
Antti Palosaari authored and Mauro Carvalho Chehab committed Dec 30, 2011
1 parent f1fe5b5 commit ff2d28f
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6cf1056f0a7ecb543d4b523f6c55a5587fc455f2
refs/heads/master: e90ab840fb826621c8c01cc9e70ca3f0889fa416
97 changes: 97 additions & 0 deletions trunk/drivers/media/dvb/dvb-usb/af9015.c
Original file line number Diff line number Diff line change
Expand Up @@ -1093,9 +1093,80 @@ static int af9015_rc_query(struct dvb_usb_device *d)
return ret;
}

/* override demod callbacks for resource locking */
static int af9015_af9013_set_frontend(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
int ret;
struct dvb_usb_adapter *adap = fe->dvb->priv;
struct af9015_state *priv = adap->dev->priv;

if (mutex_lock_interruptible(&adap->dev->usb_mutex))
return -EAGAIN;

ret = priv->set_frontend[adap->id](fe, params);

mutex_unlock(&adap->dev->usb_mutex);

return ret;
}

/* override demod callbacks for resource locking */
static int af9015_af9013_read_status(struct dvb_frontend *fe,
fe_status_t *status)
{
int ret;
struct dvb_usb_adapter *adap = fe->dvb->priv;
struct af9015_state *priv = adap->dev->priv;

if (mutex_lock_interruptible(&adap->dev->usb_mutex))
return -EAGAIN;

ret = priv->read_status[adap->id](fe, status);

mutex_unlock(&adap->dev->usb_mutex);

return ret;
}

/* override demod callbacks for resource locking */
static int af9015_af9013_init(struct dvb_frontend *fe)
{
int ret;
struct dvb_usb_adapter *adap = fe->dvb->priv;
struct af9015_state *priv = adap->dev->priv;

if (mutex_lock_interruptible(&adap->dev->usb_mutex))
return -EAGAIN;

ret = priv->init[adap->id](fe);

mutex_unlock(&adap->dev->usb_mutex);

return ret;
}

/* override demod callbacks for resource locking */
static int af9015_af9013_sleep(struct dvb_frontend *fe)
{
int ret;
struct dvb_usb_adapter *adap = fe->dvb->priv;
struct af9015_state *priv = adap->dev->priv;

if (mutex_lock_interruptible(&adap->dev->usb_mutex))
return -EAGAIN;

ret = priv->init[adap->id](fe);

mutex_unlock(&adap->dev->usb_mutex);

return ret;
}

static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
{
int ret;
struct af9015_state *state = adap->dev->priv;

if (adap->id == 1) {
/* copy firmware to 2nd demodulator */
Expand All @@ -1116,6 +1187,32 @@ static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
adap->fe_adap[0].fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id],
&adap->dev->i2c_adap);

/*
* AF9015 firmware does not like if it gets interrupted by I2C adapter
* request on some critical phases. During normal operation I2C adapter
* is used only 2nd demodulator and tuner on dual tuner devices.
* Override demodulator callbacks and use mutex for limit access to
* those "critical" paths to keep AF9015 happy.
* Note: we abuse unused usb_mutex here.
*/
if (adap->fe_adap[0].fe) {
state->set_frontend[adap->id] =
adap->fe_adap[0].fe->ops.set_frontend;
adap->fe_adap[0].fe->ops.set_frontend =
af9015_af9013_set_frontend;

state->read_status[adap->id] =
adap->fe_adap[0].fe->ops.read_status;
adap->fe_adap[0].fe->ops.read_status =
af9015_af9013_read_status;

state->init[adap->id] = adap->fe_adap[0].fe->ops.init;
adap->fe_adap[0].fe->ops.init = af9015_af9013_init;

state->sleep[adap->id] = adap->fe_adap[0].fe->ops.sleep;
adap->fe_adap[0].fe->ops.sleep = af9015_af9013_sleep;
}

return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
}

Expand Down
7 changes: 7 additions & 0 deletions trunk/drivers/media/dvb/dvb-usb/af9015.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ struct af9015_state {
u8 rc_repeat;
u32 rc_keycode;
u8 rc_last[4];

/* for demod callback override */
int (*set_frontend[2]) (struct dvb_frontend *fe,
struct dvb_frontend_parameters *params);
int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status);
int (*init[2]) (struct dvb_frontend *fe);
int (*sleep[2]) (struct dvb_frontend *fe);
};

struct af9015_config {
Expand Down

0 comments on commit ff2d28f

Please sign in to comment.