V4L/DVB (5692): M920x: attempt to fix hw pid filters on second endpoint
Signed-off-by: Aapo Tahkola <aet@rasterburn.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
parent
7cb47a1460
commit
47f8df0fc0
|
@ -22,6 +22,8 @@ static int dvb_usb_m920x_debug;
|
||||||
module_param_named(debug,dvb_usb_m920x_debug, int, 0644);
|
module_param_named(debug,dvb_usb_m920x_debug, int, 0644);
|
||||||
MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
|
MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
|
||||||
|
|
||||||
|
static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid);
|
||||||
|
|
||||||
static inline int m920x_read(struct usb_device *udev, u8 request, u16 value,
|
static inline int m920x_read(struct usb_device *udev, u8 request, u16 value,
|
||||||
u16 index, void *data, int size)
|
u16 index, void *data, int size)
|
||||||
{
|
{
|
||||||
|
@ -57,7 +59,8 @@ static inline int m920x_write(struct usb_device *udev, u8 request,
|
||||||
|
|
||||||
static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq)
|
static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0, i, epi;
|
||||||
|
int adap_enabled[M9206_MAX_ADAPTERS] = { 0 };
|
||||||
|
|
||||||
/* Remote controller init. */
|
/* Remote controller init. */
|
||||||
if (d->props.rc_query) {
|
if (d->props.rc_query) {
|
||||||
|
@ -76,6 +79,28 @@ static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq)
|
||||||
deb("Initialising remote control success\n");
|
deb("Initialising remote control success\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < d->props.num_adapters; i++) {
|
||||||
|
epi = d->adapter[i].props.stream.endpoint - 0x81;
|
||||||
|
|
||||||
|
if (epi < 0 || epi >= M9206_MAX_ADAPTERS) {
|
||||||
|
printk(KERN_INFO "m920x: Unexpected adapter endpoint!\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
adap_enabled[epi] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < M9206_MAX_ADAPTERS; i++) {
|
||||||
|
if (adap_enabled[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x0)) != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if ((ret = m920x_set_filter(d, 0x81 + i, 0, 0x02f5)) != 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,8 +236,7 @@ static struct i2c_algorithm m920x_i2c_algo = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* pid filter */
|
/* pid filter */
|
||||||
static int m920x_set_filter(struct dvb_usb_adapter *adap,
|
static int m920x_set_filter(struct dvb_usb_device *d, int type, int idx, int pid)
|
||||||
int type, int idx, int pid)
|
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -221,10 +245,10 @@ static int m920x_set_filter(struct dvb_usb_adapter *adap,
|
||||||
|
|
||||||
pid |= 0x8000;
|
pid |= 0x8000;
|
||||||
|
|
||||||
if ((ret = m920x_write(adap->dev->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0)
|
if ((ret = m920x_write(d->udev, M9206_FILTER, pid, (type << 8) | (idx * 4) )) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if ((ret = m920x_write(adap->dev->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0)
|
if ((ret = m920x_write(d->udev, M9206_FILTER, 0, (type << 8) | (idx * 4) )) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -233,40 +257,35 @@ static int m920x_set_filter(struct dvb_usb_adapter *adap,
|
||||||
static int m920x_update_filters(struct dvb_usb_adapter *adap)
|
static int m920x_update_filters(struct dvb_usb_adapter *adap)
|
||||||
{
|
{
|
||||||
struct m920x_state *m = adap->dev->priv;
|
struct m920x_state *m = adap->dev->priv;
|
||||||
int enabled = m->filtering_enabled;
|
int enabled = m->filtering_enabled[adap->id];
|
||||||
int i, ret = 0, filter = 0;
|
int i, ret = 0, filter = 0;
|
||||||
|
int ep = adap->props.stream.endpoint;
|
||||||
|
|
||||||
for (i = 0; i < M9206_MAX_FILTERS; i++)
|
for (i = 0; i < M9206_MAX_FILTERS; i++)
|
||||||
if (m->filters[i] == 8192)
|
if (m->filters[adap->id][i] == 8192)
|
||||||
enabled = 0;
|
enabled = 0;
|
||||||
|
|
||||||
/* Disable all filters */
|
/* Disable all filters */
|
||||||
if ((ret = m920x_set_filter(adap, 0x81, 1, enabled)) != 0)
|
if ((ret = m920x_set_filter(adap->dev, ep, 1, enabled)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
for (i = 0; i < M9206_MAX_FILTERS; i++)
|
for (i = 0; i < M9206_MAX_FILTERS; i++)
|
||||||
if ((ret = m920x_set_filter(adap, 0x81, i + 2, 0)) != 0)
|
if ((ret = m920x_set_filter(adap->dev, ep, i + 2, 0)) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if ((ret = m920x_set_filter(adap, 0x82, 0, 0x0)) != 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/* Set */
|
/* Set */
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
for (i = 0; i < M9206_MAX_FILTERS; i++) {
|
for (i = 0; i < M9206_MAX_FILTERS; i++) {
|
||||||
if (m->filters[i] == 0)
|
if (m->filters[adap->id][i] == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((ret = m920x_set_filter(adap, 0x81, filter + 2, m->filters[i])) != 0)
|
if ((ret = m920x_set_filter(adap->dev, ep, filter + 2, m->filters[adap->id][i])) != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
filter++;
|
filter++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = m920x_set_filter(adap, 0x82, 0, 0x02f5)) != 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +293,7 @@ static int m920x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
|
||||||
{
|
{
|
||||||
struct m920x_state *m = adap->dev->priv;
|
struct m920x_state *m = adap->dev->priv;
|
||||||
|
|
||||||
m->filtering_enabled = onoff ? 1 : 0;
|
m->filtering_enabled[adap->id] = onoff ? 1 : 0;
|
||||||
|
|
||||||
return m920x_update_filters(adap);
|
return m920x_update_filters(adap);
|
||||||
}
|
}
|
||||||
|
@ -283,7 +302,7 @@ static int m920x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, in
|
||||||
{
|
{
|
||||||
struct m920x_state *m = adap->dev->priv;
|
struct m920x_state *m = adap->dev->priv;
|
||||||
|
|
||||||
m->filters[index] = onoff ? pid : 0;
|
m->filters[adap->id][index] = onoff ? pid : 0;
|
||||||
|
|
||||||
return m920x_update_filters(adap);
|
return m920x_update_filters(adap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#define M9206_FW 0x30
|
#define M9206_FW 0x30
|
||||||
|
|
||||||
#define M9206_MAX_FILTERS 8
|
#define M9206_MAX_FILTERS 8
|
||||||
|
#define M9206_MAX_ADAPTERS 2
|
||||||
|
|
||||||
/*
|
/*
|
||||||
sequences found in logs:
|
sequences found in logs:
|
||||||
|
@ -60,8 +61,8 @@ response to a write, is unknown.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct m920x_state {
|
struct m920x_state {
|
||||||
u16 filters[M9206_MAX_FILTERS];
|
u16 filters[M9206_MAX_ADAPTERS][M9206_MAX_FILTERS];
|
||||||
int filtering_enabled;
|
int filtering_enabled[M9206_MAX_ADAPTERS];
|
||||||
int rep_count;
|
int rep_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue