/* Original macro does not contain enough null pointer checks for our need */ #define V4L2_SUBDEV_HAS_OP(sd, o, f) \
((sd) && (sd)->ops && (sd)->ops->o && (sd)->ops->o->f)
/* intermediate buffers with raw data from the USB device */ struct rtl2832_sdr_frame_buf { /* common v4l buffer stuff -- must be first */ struct vb2_v4l2_buffer vb; struct list_head list;
};
/* Note if taking both locks v4l2_lock must always be locked first! */ struct mutex v4l2_lock; /* Protects everything else */ struct mutex vb_queue_lock; /* Protects vb_queue and capt_file */
/* Pointer to our usb_device, will be NULL after unplug */ struct usb_device *udev; /* Both mutexes most be hold when setting! */
unsignedint vb_full; /* vb is full and packets dropped */
struct urb *urb_list[MAX_BULK_BUFS]; int buf_num; unsignedlong buf_size;
u8 *buf_list[MAX_BULK_BUFS];
dma_addr_t dma_addr[MAX_BULK_BUFS]; int urbs_initialized; int urbs_submitted;
for (i = dev->urbs_submitted - 1; i >= 0; i--) {
dev_dbg(&pdev->dev, "kill urb=%d\n", i); /* stop the URB */
usb_kill_urb(dev->urb_list[i]);
}
dev->urbs_submitted = 0;
return0;
}
staticint rtl2832_sdr_submit_urbs(struct rtl2832_sdr_dev *dev)
{ struct platform_device *pdev = dev->pdev; int i, ret;
for (i = 0; i < dev->urbs_initialized; i++) {
dev_dbg(&pdev->dev, "submit urb=%d\n", i);
ret = usb_submit_urb(dev->urb_list[i], GFP_KERNEL); if (ret) {
dev_err(&pdev->dev, "Could not submit urb no. %d - get them all back\n",
i);
rtl2832_sdr_kill_urbs(dev); return ret;
}
dev->urbs_submitted++;
}
for (i = dev->urbs_initialized - 1; i >= 0; i--) { if (dev->urb_list[i]) {
dev_dbg(&pdev->dev, "free urb=%d\n", i); /* free the URBs */
usb_free_urb(dev->urb_list[i]);
}
}
dev->urbs_initialized = 0;
return0;
}
staticint rtl2832_sdr_alloc_urbs(struct rtl2832_sdr_dev *dev)
{ struct platform_device *pdev = dev->pdev; int i, j;
/* allocate the URBs */ for (i = 0; i < MAX_BULK_BUFS; i++) {
dev_dbg(&pdev->dev, "alloc urb=%d\n", i);
dev->urb_list[i] = usb_alloc_urb(0, GFP_KERNEL); if (!dev->urb_list[i]) { for (j = 0; j < i; j++) {
usb_free_urb(dev->urb_list[j]);
dev->urb_list[j] = NULL;
}
dev->urbs_initialized = 0; return -ENOMEM;
}
usb_fill_bulk_urb(dev->urb_list[i],
dev->udev,
usb_rcvbulkpipe(dev->udev, 0x81),
dev->buf_list[i],
BULK_BUFFER_SIZE,
rtl2832_sdr_urb_complete, dev);
/* Must be called with vb_queue_lock hold */ staticvoid rtl2832_sdr_cleanup_queued_bufs(struct rtl2832_sdr_dev *dev)
{ struct platform_device *pdev = dev->pdev; unsignedlong flags;
dev_dbg(&pdev->dev, "\n");
spin_lock_irqsave(&dev->queued_bufs_lock, flags); while (!list_empty(&dev->queued_bufs)) { struct rtl2832_sdr_frame_buf *buf;
/* Check the device has not disconnected between prep and queuing */ if (!dev->udev) {
vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); return;
}
/* low-pass filter */
ret = regmap_bulk_write(dev->regmap, 0x11c, "\xca\xdc\xd7\xd8\xe0\xf2\x0e\x35\x06\x50\x9c\x0d\x71\x11\x14\x71\x74\x19\x41\xa5", 20); if (ret) goto err;
ret = regmap_bulk_write(dev->regmap, 0x017, "\x11\x10", 2); if (ret) goto err;
/* mode */
ret = regmap_write(dev->regmap, 0x019, 0x05); if (ret) goto err;
ret = regmap_bulk_write(dev->regmap, 0x01a, "\x1b\x16\x0d\x06\x01\xff", 6); if (ret) goto err;
/* FSM */
ret = regmap_bulk_write(dev->regmap, 0x192, "\x00\xf0\x0f", 3); if (ret) goto err;
/* PID filter */
ret = regmap_write(dev->regmap, 0x061, 0x60); if (ret) goto err;
/* used RF tuner based settings */ switch (pdata->tuner) { case RTL2832_SDR_TUNER_E4000:
ret = regmap_write(dev->regmap, 0x112, 0x5a);
ret = regmap_write(dev->regmap, 0x102, 0x40);
ret = regmap_write(dev->regmap, 0x103, 0x5a);
ret = regmap_write(dev->regmap, 0x1c7, 0x30);
ret = regmap_write(dev->regmap, 0x104, 0xd0);
ret = regmap_write(dev->regmap, 0x105, 0xbe);
ret = regmap_write(dev->regmap, 0x1c8, 0x18);
ret = regmap_write(dev->regmap, 0x106, 0x35);
ret = regmap_write(dev->regmap, 0x1c9, 0x21);
ret = regmap_write(dev->regmap, 0x1ca, 0x21);
ret = regmap_write(dev->regmap, 0x1cb, 0x00);
ret = regmap_write(dev->regmap, 0x107, 0x40);
ret = regmap_write(dev->regmap, 0x1cd, 0x10);
ret = regmap_write(dev->regmap, 0x1ce, 0x10);
ret = regmap_write(dev->regmap, 0x108, 0x80);
ret = regmap_write(dev->regmap, 0x109, 0x7f);
ret = regmap_write(dev->regmap, 0x10a, 0x80);
ret = regmap_write(dev->regmap, 0x10b, 0x7f);
ret = regmap_write(dev->regmap, 0x00e, 0xfc);
ret = regmap_write(dev->regmap, 0x00e, 0xfc);
ret = regmap_write(dev->regmap, 0x011, 0xd4);
ret = regmap_write(dev->regmap, 0x1e5, 0xf0);
ret = regmap_write(dev->regmap, 0x1d9, 0x00);
ret = regmap_write(dev->regmap, 0x1db, 0x00);
ret = regmap_write(dev->regmap, 0x1dd, 0x14);
ret = regmap_write(dev->regmap, 0x1de, 0xec);
ret = regmap_write(dev->regmap, 0x1d8, 0x0c);
ret = regmap_write(dev->regmap, 0x1e6, 0x02);
ret = regmap_write(dev->regmap, 0x1d7, 0x09);
ret = regmap_write(dev->regmap, 0x00d, 0x83);
ret = regmap_write(dev->regmap, 0x010, 0x49);
ret = regmap_write(dev->regmap, 0x00d, 0x87);
ret = regmap_write(dev->regmap, 0x00d, 0x85);
ret = regmap_write(dev->regmap, 0x013, 0x02); break; case RTL2832_SDR_TUNER_FC0012: case RTL2832_SDR_TUNER_FC0013:
ret = regmap_write(dev->regmap, 0x112, 0x5a);
ret = regmap_write(dev->regmap, 0x102, 0x40);
ret = regmap_write(dev->regmap, 0x103, 0x5a);
ret = regmap_write(dev->regmap, 0x1c7, 0x2c);
ret = regmap_write(dev->regmap, 0x104, 0xcc);
ret = regmap_write(dev->regmap, 0x105, 0xbe);
ret = regmap_write(dev->regmap, 0x1c8, 0x16);
ret = regmap_write(dev->regmap, 0x106, 0x35);
ret = regmap_write(dev->regmap, 0x1c9, 0x21);
ret = regmap_write(dev->regmap, 0x1ca, 0x21);
ret = regmap_write(dev->regmap, 0x1cb, 0x00);
ret = regmap_write(dev->regmap, 0x107, 0x40);
ret = regmap_write(dev->regmap, 0x1cd, 0x10);
ret = regmap_write(dev->regmap, 0x1ce, 0x10);
ret = regmap_write(dev->regmap, 0x108, 0x80);
ret = regmap_write(dev->regmap, 0x109, 0x7f);
ret = regmap_write(dev->regmap, 0x10a, 0x80);
ret = regmap_write(dev->regmap, 0x10b, 0x7f);
ret = regmap_write(dev->regmap, 0x00e, 0xfc);
ret = regmap_write(dev->regmap, 0x00e, 0xfc);
ret = regmap_bulk_write(dev->regmap, 0x011, "\xe9\xbf", 2);
ret = regmap_write(dev->regmap, 0x1e5, 0xf0);
ret = regmap_write(dev->regmap, 0x1d9, 0x00);
ret = regmap_write(dev->regmap, 0x1db, 0x00);
ret = regmap_write(dev->regmap, 0x1dd, 0x11);
ret = regmap_write(dev->regmap, 0x1de, 0xef);
ret = regmap_write(dev->regmap, 0x1d8, 0x0c);
ret = regmap_write(dev->regmap, 0x1e6, 0x02);
ret = regmap_write(dev->regmap, 0x1d7, 0x09); break; case RTL2832_SDR_TUNER_R820T: case RTL2832_SDR_TUNER_R828D:
ret = regmap_write(dev->regmap, 0x112, 0x5a);
ret = regmap_write(dev->regmap, 0x102, 0x40);
ret = regmap_write(dev->regmap, 0x115, 0x01);
ret = regmap_write(dev->regmap, 0x103, 0x80);
ret = regmap_write(dev->regmap, 0x1c7, 0x24);
ret = regmap_write(dev->regmap, 0x104, 0xcc);
ret = regmap_write(dev->regmap, 0x105, 0xbe);
ret = regmap_write(dev->regmap, 0x1c8, 0x14);
ret = regmap_write(dev->regmap, 0x106, 0x35);
ret = regmap_write(dev->regmap, 0x1c9, 0x21);
ret = regmap_write(dev->regmap, 0x1ca, 0x21);
ret = regmap_write(dev->regmap, 0x1cb, 0x00);
ret = regmap_write(dev->regmap, 0x107, 0x40);
ret = regmap_write(dev->regmap, 0x1cd, 0x10);
ret = regmap_write(dev->regmap, 0x1ce, 0x10);
ret = regmap_write(dev->regmap, 0x108, 0x80);
ret = regmap_write(dev->regmap, 0x109, 0x7f);
ret = regmap_write(dev->regmap, 0x10a, 0x80);
ret = regmap_write(dev->regmap, 0x10b, 0x7f);
ret = regmap_write(dev->regmap, 0x00e, 0xfc);
ret = regmap_write(dev->regmap, 0x00e, 0xfc);
ret = regmap_write(dev->regmap, 0x011, 0xf4); break; case RTL2832_SDR_TUNER_FC2580:
ret = regmap_write(dev->regmap, 0x112, 0x39);
ret = regmap_write(dev->regmap, 0x102, 0x40);
ret = regmap_write(dev->regmap, 0x103, 0x5a);
ret = regmap_write(dev->regmap, 0x1c7, 0x2c);
ret = regmap_write(dev->regmap, 0x104, 0xcc);
ret = regmap_write(dev->regmap, 0x105, 0xbe);
ret = regmap_write(dev->regmap, 0x1c8, 0x16);
ret = regmap_write(dev->regmap, 0x106, 0x35);
ret = regmap_write(dev->regmap, 0x1c9, 0x21);
ret = regmap_write(dev->regmap, 0x1ca, 0x21);
ret = regmap_write(dev->regmap, 0x1cb, 0x00);
ret = regmap_write(dev->regmap, 0x107, 0x40);
ret = regmap_write(dev->regmap, 0x1cd, 0x10);
ret = regmap_write(dev->regmap, 0x1ce, 0x10);
ret = regmap_write(dev->regmap, 0x108, 0x80);
ret = regmap_write(dev->regmap, 0x109, 0x7f);
ret = regmap_write(dev->regmap, 0x10a, 0x9c);
ret = regmap_write(dev->regmap, 0x10b, 0x7f);
ret = regmap_write(dev->regmap, 0x00e, 0xfc);
ret = regmap_write(dev->regmap, 0x00e, 0xfc);
ret = regmap_bulk_write(dev->regmap, 0x011, "\xe9\xf4", 2); break; default:
dev_notice(&pdev->dev, "Unsupported tuner\n");
}
/* software reset */
ret = regmap_update_bits(dev->regmap, 0x101, 0x04, 0x04); if (ret) goto err;
ret = regmap_update_bits(dev->regmap, 0x101, 0x04, 0x00); if (ret) goto err;
err: return ret;
};
for (i = 0; i < dev->num_formats; i++) { if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
f->fmt.sdr.buffersize = formats[i].buffersize; return0;
}
}
switch (ctrl->id) { case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: case V4L2_CID_RF_TUNER_BANDWIDTH: /* TODO: these controls should be moved to tuner drivers */ if (dev->bandwidth_auto->val) { /* Round towards the closest legal value */
s32 val = dev->f_adc + div_u64(dev->bandwidth->step, 2);
u32 offset;
if (!pdata) {
dev_err(&pdev->dev, "Cannot proceed without platform data\n");
ret = -EINVAL; goto err;
} if (!pdev->dev.parent->driver) {
dev_dbg(&pdev->dev, "No parent device\n");
ret = -EINVAL; goto err;
} /* try to refcount host drv since we are the consumer */ if (!try_module_get(pdev->dev.parent->driver->owner)) {
dev_err(&pdev->dev, "Refcount fail");
ret = -EINVAL; goto err;
}
dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) {
ret = -ENOMEM; goto err_module_put;
}
mutex_lock(&dev->vb_queue_lock);
mutex_lock(&dev->v4l2_lock); /* No need to keep the urbs around after disconnection */
dev->udev = NULL;
v4l2_device_disconnect(&dev->v4l2_dev);
video_unregister_device(&dev->vdev);
mutex_unlock(&dev->v4l2_lock);
mutex_unlock(&dev->vb_queue_lock);
v4l2_device_put(&dev->v4l2_dev);
module_put(pdev->dev.parent->driver->owner);
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.52Bemerkung:
(vorverarbeitet am 2026-10-01)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.