summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9015.c220
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9015.h14
2 files changed, 115 insertions, 119 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c
index 1f352307a00a..99e3b14d493e 100644
--- a/drivers/media/usb/dvb-usb-v2/af9015.c
+++ b/drivers/media/usb/dvb-usb-v2/af9015.c
@@ -607,11 +607,121 @@ static int af9015_get_stream_config(struct dvb_frontend *fe, u8 *ts_type,
dev_dbg(&intf->dev, "adap %u\n", fe_to_adap(fe)->id);
if (d->udev->speed == USB_SPEED_FULL)
- stream->u.bulk.buffersize = TS_USB11_FRAME_SIZE;
+ stream->u.bulk.buffersize = 5 * 188;
return 0;
}
+static int af9015_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+ struct dvb_usb_device *d = fe_to_d(fe);
+ struct af9015_state *state = d_to_priv(d);
+ struct usb_interface *intf = d->intf;
+ int ret;
+ unsigned int utmp1, utmp2, reg1, reg2;
+ u8 buf[2];
+ const unsigned int adap_id = fe_to_adap(fe)->id;
+
+ dev_dbg(&intf->dev, "adap id %d, onoff %d\n", adap_id, onoff);
+
+ if (state->usb_ts_if_configured[adap_id] == false) {
+ dev_dbg(&intf->dev, "set usb and ts interface\n");
+
+ /* USB IF stream settings */
+ utmp1 = (d->udev->speed == USB_SPEED_FULL ? 5 : 87) * 188 / 4;
+ utmp2 = (d->udev->speed == USB_SPEED_FULL ? 64 : 512) / 4;
+
+ buf[0] = (utmp1 >> 0) & 0xff;
+ buf[1] = (utmp1 >> 8) & 0xff;
+ if (adap_id == 0) {
+ /* 1st USB IF (EP4) stream settings */
+ reg1 = 0xdd88;
+ reg2 = 0xdd0c;
+ } else {
+ /* 2nd USB IF (EP5) stream settings */
+ reg1 = 0xdd8a;
+ reg2 = 0xdd0d;
+ }
+
+ ret = af9015_write_regs(d, reg1, buf, 2);
+ if (ret)
+ goto err;
+ ret = af9015_write_reg(d, reg2, utmp2);
+ if (ret)
+ goto err;
+
+ /* TS IF settings */
+ if (state->dual_mode) {
+ ret = af9015_set_reg_bit(d, 0xd50b, 0);
+ if (ret)
+ goto err;
+ ret = af9015_set_reg_bit(d, 0xd520, 4);
+ if (ret)
+ goto err;
+ } else {
+ ret = af9015_clear_reg_bit(d, 0xd50b, 0);
+ if (ret)
+ goto err;
+ ret = af9015_clear_reg_bit(d, 0xd520, 4);
+ if (ret)
+ goto err;
+ }
+
+ state->usb_ts_if_configured[adap_id] = true;
+ }
+
+ if (adap_id == 0 && onoff) {
+ /* Adapter 0 stream on. EP4: clear NAK, enable, clear reset */
+ ret = af9015_clear_reg_bit(d, 0xdd13, 5);
+ if (ret)
+ goto err;
+ ret = af9015_set_reg_bit(d, 0xdd11, 5);
+ if (ret)
+ goto err;
+ ret = af9015_clear_reg_bit(d, 0xd507, 2);
+ if (ret)
+ goto err;
+ } else if (adap_id == 1 && onoff) {
+ /* Adapter 1 stream on. EP5: clear NAK, enable, clear reset */
+ ret = af9015_clear_reg_bit(d, 0xdd13, 6);
+ if (ret)
+ goto err;
+ ret = af9015_set_reg_bit(d, 0xdd11, 6);
+ if (ret)
+ goto err;
+ ret = af9015_clear_reg_bit(d, 0xd50b, 1);
+ if (ret)
+ goto err;
+ } else if (adap_id == 0 && !onoff) {
+ /* Adapter 0 stream off. EP4: set reset, disable, set NAK */
+ ret = af9015_set_reg_bit(d, 0xd507, 2);
+ if (ret)
+ goto err;
+ ret = af9015_clear_reg_bit(d, 0xdd11, 5);
+ if (ret)
+ goto err;
+ ret = af9015_set_reg_bit(d, 0xdd13, 5);
+ if (ret)
+ goto err;
+ } else if (adap_id == 1 && !onoff) {
+ /* Adapter 1 stream off. EP5: set reset, disable, set NAK */
+ ret = af9015_set_reg_bit(d, 0xd50b, 1);
+ if (ret)
+ goto err;
+ ret = af9015_clear_reg_bit(d, 0xdd11, 6);
+ if (ret)
+ goto err;
+ ret = af9015_set_reg_bit(d, 0xdd13, 6);
+ if (ret)
+ goto err;
+ }
+
+ return 0;
+err:
+ dev_dbg(&intf->dev, "failed %d\n", ret);
+ return ret;
+}
+
static int af9015_get_adapter_count(struct dvb_usb_device *d)
{
struct af9015_state *state = d_to_priv(d);
@@ -1061,105 +1171,6 @@ static int af9015_pid_filter(struct dvb_usb_adapter *adap, int index,
return ret;
}
-static int af9015_init_endpoint(struct dvb_usb_device *d)
-{
- struct af9015_state *state = d_to_priv(d);
- struct usb_interface *intf = d->intf;
- int ret;
- u16 frame_size;
- u8 packet_size;
-
- dev_dbg(&intf->dev, "usb speed %u\n", d->udev->speed);
-
- if (d->udev->speed == USB_SPEED_FULL) {
- frame_size = TS_USB11_FRAME_SIZE/4;
- packet_size = TS_USB11_MAX_PACKET_SIZE/4;
- } else {
- frame_size = TS_USB20_FRAME_SIZE/4;
- packet_size = TS_USB20_MAX_PACKET_SIZE/4;
- }
-
- ret = af9015_set_reg_bit(d, 0xd507, 2); /* assert EP4 reset */
- if (ret)
- goto error;
- ret = af9015_set_reg_bit(d, 0xd50b, 1); /* assert EP5 reset */
- if (ret)
- goto error;
- ret = af9015_clear_reg_bit(d, 0xdd11, 5); /* disable EP4 */
- if (ret)
- goto error;
- ret = af9015_clear_reg_bit(d, 0xdd11, 6); /* disable EP5 */
- if (ret)
- goto error;
- ret = af9015_set_reg_bit(d, 0xdd11, 5); /* enable EP4 */
- if (ret)
- goto error;
- if (state->dual_mode) {
- ret = af9015_set_reg_bit(d, 0xdd11, 6); /* enable EP5 */
- if (ret)
- goto error;
- }
- ret = af9015_clear_reg_bit(d, 0xdd13, 5); /* disable EP4 NAK */
- if (ret)
- goto error;
- if (state->dual_mode) {
- ret = af9015_clear_reg_bit(d, 0xdd13, 6); /* disable EP5 NAK */
- if (ret)
- goto error;
- }
- /* EP4 xfer length */
- ret = af9015_write_reg(d, 0xdd88, frame_size & 0xff);
- if (ret)
- goto error;
- ret = af9015_write_reg(d, 0xdd89, frame_size >> 8);
- if (ret)
- goto error;
- /* EP5 xfer length */
- ret = af9015_write_reg(d, 0xdd8a, frame_size & 0xff);
- if (ret)
- goto error;
- ret = af9015_write_reg(d, 0xdd8b, frame_size >> 8);
- if (ret)
- goto error;
- ret = af9015_write_reg(d, 0xdd0c, packet_size); /* EP4 packet size */
- if (ret)
- goto error;
- ret = af9015_write_reg(d, 0xdd0d, packet_size); /* EP5 packet size */
- if (ret)
- goto error;
- ret = af9015_clear_reg_bit(d, 0xd507, 2); /* negate EP4 reset */
- if (ret)
- goto error;
- if (state->dual_mode) {
- ret = af9015_clear_reg_bit(d, 0xd50b, 1); /* negate EP5 reset */
- if (ret)
- goto error;
- }
-
- /* enable / disable mp2if2 */
- if (state->dual_mode) {
- ret = af9015_set_reg_bit(d, 0xd50b, 0);
- if (ret)
- goto error;
- ret = af9015_set_reg_bit(d, 0xd520, 4);
- if (ret)
- goto error;
- } else {
- ret = af9015_clear_reg_bit(d, 0xd50b, 0);
- if (ret)
- goto error;
- ret = af9015_clear_reg_bit(d, 0xd520, 4);
- if (ret)
- goto error;
- }
-
-error:
- if (ret)
- dev_err(&intf->dev, "endpoint init failed %d\n", ret);
-
- return ret;
-}
-
static int af9015_init(struct dvb_usb_device *d)
{
struct af9015_state *state = d_to_priv(d);
@@ -1175,10 +1186,6 @@ static int af9015_init(struct dvb_usb_device *d)
if (ret)
goto error;
- ret = af9015_init_endpoint(d);
- if (ret)
- goto error;
-
error:
return ret;
}
@@ -1412,6 +1419,7 @@ static struct dvb_usb_device_properties af9015_props = {
.init = af9015_init,
.get_rc_config = af9015_get_rc_config,
.get_stream_config = af9015_get_stream_config,
+ .streaming_ctrl = af9015_streaming_ctrl,
.get_adapter_count = af9015_get_adapter_count,
.adapter = {
@@ -1422,7 +1430,7 @@ static struct dvb_usb_device_properties af9015_props = {
.pid_filter = af9015_pid_filter,
.pid_filter_ctrl = af9015_pid_filter_ctrl,
- .stream = DVB_USB_STREAM_BULK(0x84, 8, TS_USB20_FRAME_SIZE),
+ .stream = DVB_USB_STREAM_BULK(0x84, 6, 87 * 188),
}, {
.caps = DVB_USB_ADAP_HAS_PID_FILTER |
DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
@@ -1430,7 +1438,7 @@ static struct dvb_usb_device_properties af9015_props = {
.pid_filter = af9015_pid_filter,
.pid_filter_ctrl = af9015_pid_filter_ctrl,
- .stream = DVB_USB_STREAM_BULK(0x85, 8, TS_USB20_FRAME_SIZE),
+ .stream = DVB_USB_STREAM_BULK(0x85, 6, 87 * 188),
},
},
};
diff --git a/drivers/media/usb/dvb-usb-v2/af9015.h b/drivers/media/usb/dvb-usb-v2/af9015.h
index 97339bf3749b..28710aaf058a 100644
--- a/drivers/media/usb/dvb-usb-v2/af9015.h
+++ b/drivers/media/usb/dvb-usb-v2/af9015.h
@@ -34,19 +34,6 @@
#define AF9015_FIRMWARE "dvb-usb-af9015.fw"
-/* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0.
- We use smaller - about 1/4 from the original, 5 and 87. */
-#define TS_PACKET_SIZE 188
-
-#define TS_USB20_PACKET_COUNT 87
-#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
-
-#define TS_USB11_PACKET_COUNT 5
-#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
-
-#define TS_USB20_MAX_PACKET_SIZE 512
-#define TS_USB11_MAX_PACKET_SIZE 64
-
#define AF9015_I2C_EEPROM 0x50
#define AF9015_I2C_DEMOD 0x1c
#define AF9015_USB_TIMEOUT 2000
@@ -128,6 +115,7 @@ struct af9015_state {
struct af9013_platform_data af9013_pdata[2];
struct i2c_client *demod_i2c_client[2];
u8 af9013_i2c_addr[2];
+ bool usb_ts_if_configured[2];
/* for demod callback override */
int (*set_frontend[2]) (struct dvb_frontend *fe);