diff options
Diffstat (limited to 'drivers/media/usb/dvb-usb-v2')
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/Kconfig | 1 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/dvb_usb_core.c | 6 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/gl861.c | 3 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/lmedm04.c | 102 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 40 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/rtl28xxu.h | 4 | ||||
-rw-r--r-- | drivers/media/usb/dvb-usb-v2/usb_urb.c | 5 |
7 files changed, 70 insertions, 91 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig index df4412245a8a..511e3f270308 100644 --- a/drivers/media/usb/dvb-usb-v2/Kconfig +++ b/drivers/media/usb/dvb-usb-v2/Kconfig @@ -133,6 +133,7 @@ config DVB_USB_RTL28XXU depends on DVB_USB_V2 && I2C_MUX select DVB_MN88472 if MEDIA_SUBDRV_AUTOSELECT select DVB_MN88473 if MEDIA_SUBDRV_AUTOSELECT + select DVB_CXD2841ER if MEDIA_SUBDRV_AUTOSELECT select DVB_RTL2830 select DVB_RTL2832 select DVB_RTL2832_SDR if (MEDIA_SUBDRV_AUTOSELECT && MEDIA_SDR_SUPPORT) diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index 3b8f7931b730..d55ef016d418 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -957,9 +957,7 @@ int dvb_usbv2_probe(struct usb_interface *intf, if (d->props->identify_state) { const char *name = NULL; ret = d->props->identify_state(d, &name); - if (ret == 0) { - ; - } else if (ret == COLD) { + if (ret == COLD) { dev_info(&d->udev->dev, "%s: found a '%s' in cold state\n", KBUILD_MODNAME, d->name); @@ -984,7 +982,7 @@ int dvb_usbv2_probe(struct usb_interface *intf, } else { goto err_free_all; } - } else { + } else if (ret != WARM) { goto err_free_all; } } diff --git a/drivers/media/usb/dvb-usb-v2/gl861.c b/drivers/media/usb/dvb-usb-v2/gl861.c index 0559417c8af4..80fed4494736 100644 --- a/drivers/media/usb/dvb-usb-v2/gl861.c +++ b/drivers/media/usb/dvb-usb-v2/gl861.c @@ -200,11 +200,10 @@ gl861_i2c_write_ex(struct dvb_usb_device *d, u8 addr, u8 *wbuf, u16 wlen) u8 *buf; int ret; - buf = kmalloc(wlen, GFP_KERNEL); + buf = kmemdup(wbuf, wlen, GFP_KERNEL); if (!buf) return -ENOMEM; - memcpy(buf, wbuf, wlen); ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0), GL861_REQ_I2C_RAW, GL861_WRITE, addr << (8 + 1), 0x0100, buf, wlen, 2000); diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c index f109c04f05ae..602013cf3e69 100644 --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -134,9 +134,9 @@ struct lme2510_state { u8 stream_on; u8 pid_size; u8 pid_off; - void *buffer; + u8 int_buffer[128]; struct urb *lme_urb; - void *usb_buffer; + u8 usb_buffer[64]; /* Frontend original calls */ int (*fe_read_status)(struct dvb_frontend *, enum fe_status *); int (*fe_read_signal_strength)(struct dvb_frontend *, u16 *); @@ -147,59 +147,30 @@ struct lme2510_state { u8 dvb_usb_lme2510_firmware; }; -static int lme2510_bulk_write(struct usb_device *dev, - u8 *snd, int len, u8 pipe) -{ - int actual_l; - - return usb_bulk_msg(dev, usb_sndbulkpipe(dev, pipe), - snd, len, &actual_l, 100); -} - -static int lme2510_bulk_read(struct usb_device *dev, - u8 *rev, int len, u8 pipe) -{ - int actual_l; - - return usb_bulk_msg(dev, usb_rcvbulkpipe(dev, pipe), - rev, len, &actual_l, 200); -} - static int lme2510_usb_talk(struct dvb_usb_device *d, - u8 *wbuf, int wlen, u8 *rbuf, int rlen) + u8 *wbuf, int wlen, u8 *rbuf, int rlen) { struct lme2510_state *st = d->priv; - u8 *buff; int ret = 0; - if (st->usb_buffer == NULL) { - st->usb_buffer = kmalloc(64, GFP_KERNEL); - if (st->usb_buffer == NULL) { - info("MEM Error no memory"); - return -ENOMEM; - } - } - buff = st->usb_buffer; + if (max(wlen, rlen) > sizeof(st->usb_buffer)) + return -EINVAL; ret = mutex_lock_interruptible(&d->usb_mutex); - if (ret < 0) return -EAGAIN; - /* the read/write capped at 64 */ - memcpy(buff, wbuf, (wlen < 64) ? wlen : 64); + memcpy(st->usb_buffer, wbuf, wlen); - ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01); + ret = dvb_usbv2_generic_rw_locked(d, st->usb_buffer, wlen, + st->usb_buffer, rlen); - ret |= lme2510_bulk_read(d->udev, buff, (rlen < 64) ? - rlen : 64 , 0x01); - - if (rlen > 0) - memcpy(rbuf, buff, rlen); + if (rlen) + memcpy(rbuf, st->usb_buffer, rlen); mutex_unlock(&d->usb_mutex); - return (ret < 0) ? -ENODEV : 0; + return ret; } static int lme2510_stream_restart(struct dvb_usb_device *d) @@ -417,20 +388,14 @@ static int lme2510_int_read(struct dvb_usb_adapter *adap) if (lme_int->lme_urb == NULL) return -ENOMEM; - lme_int->buffer = usb_alloc_coherent(d->udev, 128, GFP_ATOMIC, - &lme_int->lme_urb->transfer_dma); - - if (lme_int->buffer == NULL) - return -ENOMEM; - usb_fill_int_urb(lme_int->lme_urb, - d->udev, - usb_rcvintpipe(d->udev, 0xa), - lme_int->buffer, - 128, - lme2510_int_response, - adap, - 8); + d->udev, + usb_rcvintpipe(d->udev, 0xa), + lme_int->int_buffer, + sizeof(lme_int->int_buffer), + lme2510_int_response, + adap, + 8); /* Quirk of pipe reporting PIPE_BULK but behaves as interrupt */ ep = usb_pipe_endpoint(d->udev, lme_int->lme_urb->pipe); @@ -438,8 +403,6 @@ static int lme2510_int_read(struct dvb_usb_adapter *adap) if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_BULK) lme_int->lme_urb->pipe = usb_rcvbulkpipe(d->udev, 0xa), - lme_int->lme_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - usb_submit_urb(lme_int->lme_urb, GFP_ATOMIC); info("INT Interrupt Service Started"); @@ -1245,41 +1208,20 @@ static int lme2510_get_rc_config(struct dvb_usb_device *d, return 0; } -static void *lme2510_exit_int(struct dvb_usb_device *d) +static void lme2510_exit(struct dvb_usb_device *d) { struct lme2510_state *st = d->priv; struct dvb_usb_adapter *adap = &d->adapter[0]; - void *buffer = NULL; if (adap != NULL) { lme2510_kill_urb(&adap->stream); } - if (st->usb_buffer != NULL) { - st->i2c_talk_onoff = 1; - st->signal_level = 0; - st->signal_sn = 0; - buffer = st->usb_buffer; - } - - if (st->lme_urb != NULL) { + if (st->lme_urb) { usb_kill_urb(st->lme_urb); - usb_free_coherent(d->udev, 128, st->buffer, - st->lme_urb->transfer_dma); + usb_free_urb(st->lme_urb); info("Interrupt Service Stopped"); } - - return buffer; -} - -static void lme2510_exit(struct dvb_usb_device *d) -{ - void *usb_buffer; - - if (d != NULL) { - usb_buffer = lme2510_exit_int(d); - kfree(usb_buffer); - } } static struct dvb_usb_device_properties lme2510_props = { @@ -1288,6 +1230,8 @@ static struct dvb_usb_device_properties lme2510_props = { .bInterfaceNumber = 0, .adapter_nr = adapter_nr, .size_of_priv = sizeof(struct lme2510_state), + .generic_bulk_ctrl_endpoint = 0x01, + .generic_bulk_ctrl_endpoint_response = 0x01, .download_firmware = lme2510_download_firmware, diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 8a83b10e50e0..d0075cb743b2 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -384,6 +384,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) struct rtl28xxu_req req_r828d = {0x0074, CMD_I2C_RD, 1, buf}; struct rtl28xxu_req req_mn88472 = {0xff38, CMD_I2C_RD, 1, buf}; struct rtl28xxu_req req_mn88473 = {0xff38, CMD_I2C_RD, 1, buf}; + struct rtl28xxu_req req_cxd2837er = {0xfdd8, CMD_I2C_RD, 1, buf}; struct rtl28xxu_req req_si2157 = {0x00c0, CMD_I2C_RD, 1, buf}; struct rtl28xxu_req req_si2168 = {0x00c8, CMD_I2C_RD, 1, buf}; @@ -540,7 +541,18 @@ tuner_found: /* probe slave demod */ if (dev->tuner == TUNER_RTL2832_R828D) { - /* power on MN88472 demod on GPIO0 */ + /* power off slave demod on GPIO0 to reset CXD2837ER */ + ret = rtl28xxu_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x00, 0x01); + if (ret) + goto err; + + ret = rtl28xxu_wr_reg_mask(d, SYS_GPIO_OUT_EN, 0x00, 0x01); + if (ret) + goto err; + + msleep(50); + + /* power on slave demod on GPIO0 */ ret = rtl28xxu_wr_reg_mask(d, SYS_GPIO_OUT_VAL, 0x01, 0x01); if (ret) goto err; @@ -553,7 +565,7 @@ tuner_found: if (ret) goto err; - /* check MN88472 answers */ + /* check slave answers */ ret = rtl28xxu_ctrl_msg(d, &req_mn88472); if (ret == 0 && buf[0] == 0x02) { dev_dbg(&d->intf->dev, "MN88472 found\n"); @@ -567,6 +579,13 @@ tuner_found: dev->slave_demod = SLAVE_DEMOD_MN88473; goto demod_found; } + + ret = rtl28xxu_ctrl_msg(d, &req_cxd2837er); + if (ret == 0 && buf[0] == 0xb1) { + dev_dbg(&d->intf->dev, "CXD2837ER found\n"); + dev->slave_demod = SLAVE_DEMOD_CXD2837ER; + goto demod_found; + } } if (dev->tuner == TUNER_RTL2832_SI2157) { /* check Si2168 ID register; reg=c8 val=80 */ @@ -989,6 +1008,23 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) } dev->i2c_client_slave_demod = client; + } else if (dev->slave_demod == SLAVE_DEMOD_CXD2837ER) { + struct cxd2841er_config cxd2837er_config = {}; + + cxd2837er_config.i2c_addr = 0xd8; + cxd2837er_config.xtal = SONY_XTAL_20500; + cxd2837er_config.flags = (CXD2841ER_AUTO_IFHZ | + CXD2841ER_NO_AGCNEG | CXD2841ER_TSBITS | + CXD2841ER_EARLY_TUNE | CXD2841ER_TS_SERIAL); + adap->fe[1] = dvb_attach(cxd2841er_attach_t_c, + &cxd2837er_config, + &d->i2c_adap); + if (!adap->fe[1]) { + dev->slave_demod = SLAVE_DEMOD_NONE; + goto err_slave_demod_failed; + } + adap->fe[1]->id = 1; + dev->i2c_client_slave_demod = NULL; } else { struct si2168_config si2168_config = {}; struct i2c_adapter *adapter; diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h index 138062960a73..197f4e339605 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h @@ -31,6 +31,7 @@ #include "rtl2832_sdr.h" #include "mn88472.h" #include "mn88473.h" +#include "cxd2841er.h" #include "qt1010.h" #include "mt2060.h" @@ -87,7 +88,8 @@ struct rtl28xxu_dev { #define SLAVE_DEMOD_MN88472 1 #define SLAVE_DEMOD_MN88473 2 #define SLAVE_DEMOD_SI2168 3 - unsigned int slave_demod:2; + #define SLAVE_DEMOD_CXD2837ER 4 + unsigned int slave_demod:3; union { struct rtl2830_platform_data rtl2830_platform_data; struct rtl2832_platform_data rtl2832_platform_data; diff --git a/drivers/media/usb/dvb-usb-v2/usb_urb.c b/drivers/media/usb/dvb-usb-v2/usb_urb.c index 024c751eb165..2ad2ddeaff51 100644 --- a/drivers/media/usb/dvb-usb-v2/usb_urb.c +++ b/drivers/media/usb/dvb-usb-v2/usb_urb.c @@ -155,7 +155,6 @@ static int usb_urb_alloc_bulk_urbs(struct usb_data_stream *stream) stream->props.u.bulk.buffersize, usb_urb_complete, stream); - stream->urb_list[i]->transfer_flags = URB_FREE_BUFFER; stream->urbs_initialized++; } return 0; @@ -186,7 +185,7 @@ static int usb_urb_alloc_isoc_urbs(struct usb_data_stream *stream) urb->complete = usb_urb_complete; urb->pipe = usb_rcvisocpipe(stream->udev, stream->props.endpoint); - urb->transfer_flags = URB_ISO_ASAP | URB_FREE_BUFFER; + urb->transfer_flags = URB_ISO_ASAP; urb->interval = stream->props.u.isoc.interval; urb->number_of_packets = stream->props.u.isoc.framesperurb; urb->transfer_buffer_length = stream->props.u.isoc.framesize * @@ -210,7 +209,7 @@ static int usb_free_stream_buffers(struct usb_data_stream *stream) if (stream->state & USB_STATE_URB_BUF) { while (stream->buf_num) { stream->buf_num--; - stream->buf_list[stream->buf_num] = NULL; + kfree(stream->buf_list[stream->buf_num]); } } |