^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for the Auvitek USB bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "au0828.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <media/v4l2-common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <media/tuner.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "au8522.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "xc5000.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "mxl5007t.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "tda18271.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static int preallocate_big_buffers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) module_param_named(preallocate_big_buffers, preallocate_big_buffers, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) MODULE_PARM_DESC(preallocate_big_buffers, "Preallocate the larger transfer buffers at module load time");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define _AU0828_BULKPIPE 0x83
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define _BULKPIPESIZE 0xe522
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static u8 hauppauge_hvr950q_led_states[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 0x00, /* off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 0x02, /* yellow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 0x04, /* green */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static struct au8522_led_config hauppauge_hvr950q_led_cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) .gpio_output = 0x00e0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .gpio_output_enable = 0x6006,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .gpio_output_disable = 0x0660,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .gpio_leds = 0x00e2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .led_states = hauppauge_hvr950q_led_states,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .num_led_states = sizeof(hauppauge_hvr950q_led_states),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) .vsb8_strong = 20 /* dB */ * 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .qam64_strong = 25 /* dB */ * 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .qam256_strong = 32 /* dB */ * 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static struct au8522_config hauppauge_hvr950q_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .demod_address = 0x8e >> 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .status_mode = AU8522_DEMODLOCKING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .qam_if = AU8522_IF_6MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .vsb_if = AU8522_IF_6MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .led_cfg = &hauppauge_hvr950q_led_cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static struct au8522_config fusionhdtv7usb_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .demod_address = 0x8e >> 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) .status_mode = AU8522_DEMODLOCKING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .qam_if = AU8522_IF_6MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .vsb_if = AU8522_IF_6MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static struct au8522_config hauppauge_woodbury_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .demod_address = 0x8e >> 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .status_mode = AU8522_DEMODLOCKING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .qam_if = AU8522_IF_4MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .vsb_if = AU8522_IF_3_25MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static struct xc5000_config hauppauge_xc5000a_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .i2c_address = 0x61,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) .if_khz = 6000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) .chip_id = XC5000A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) .output_amp = 0x8f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static struct xc5000_config hauppauge_xc5000c_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) .i2c_address = 0x61,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) .if_khz = 6000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) .chip_id = XC5000C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) .output_amp = 0x8f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static struct mxl5007t_config mxl5007t_hvr950q_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .xtal_freq_hz = MxL_XTAL_24_MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) .if_freq_hz = MxL_IF_6_MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static struct tda18271_config hauppauge_woodbury_tunerconfig = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) .gate = TDA18271_GATE_DIGITAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static void au0828_restart_dvb_streaming(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static void au0828_bulk_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct au0828_dev *dev = from_timer(dev, t, bulk_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) dprintk(1, "%s called\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) dev->bulk_timeout_running = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) schedule_work(&dev->restart_streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*-------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static void urb_completion(struct urb *purb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct au0828_dev *dev = purb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int ptype = usb_pipetype(purb->pipe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) unsigned char *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) dprintk(2, "%s: %d\n", __func__, purb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) dprintk(2, "%s: no dev!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (!dev->urb_streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) dprintk(2, "%s: not streaming!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (ptype != PIPE_BULK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) pr_err("%s: Unsupported URB type %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) __func__, ptype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* See if the stream is corrupted (to work around a hardware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) bug where the stream gets misaligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ptr = purb->transfer_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (purb->actual_length > 0 && ptr[0] != 0x47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) dprintk(1, "Need to restart streaming %02x len=%d!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) ptr[0], purb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) schedule_work(&dev->restart_streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) } else if (dev->bulk_timeout_running == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /* The URB handler has fired, so cancel timer which would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * restart endpoint if we hadn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) dprintk(1, "%s cancelling bulk timeout\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) dev->bulk_timeout_running = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) del_timer(&dev->bulk_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* Feed the transport payload into the kernel demux */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) dvb_dmx_swfilter_packets(&dev->dvb.demux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) purb->transfer_buffer, purb->actual_length / 188);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /* Clean the buffer before we requeue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) memset(purb->transfer_buffer, 0, URB_BUFSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* Requeue URB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) usb_submit_urb(purb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static int stop_urb_transfer(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) dprintk(2, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (!dev->urb_streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (dev->bulk_timeout_running == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) dev->bulk_timeout_running = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) del_timer(&dev->bulk_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) dev->urb_streaming = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) for (i = 0; i < URB_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (dev->urbs[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) usb_kill_urb(dev->urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (!preallocate_big_buffers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) kfree(dev->urbs[i]->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) usb_free_urb(dev->urbs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) static int start_urb_transfer(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct urb *purb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) dprintk(2, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (dev->urb_streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) dprintk(2, "%s: bulk xfer already running!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) for (i = 0; i < URB_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) dev->urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (!dev->urbs[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) purb = dev->urbs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (preallocate_big_buffers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) purb->transfer_buffer = dev->dig_transfer_buffer[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) purb->transfer_buffer = kzalloc(URB_BUFSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (!purb->transfer_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) usb_free_urb(purb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) dev->urbs[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) pr_err("%s: failed big buffer allocation, err = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) purb->status = -EINPROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) usb_fill_bulk_urb(purb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) dev->usbdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) usb_rcvbulkpipe(dev->usbdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) _AU0828_BULKPIPE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) purb->transfer_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) URB_BUFSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) urb_completion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) for (i = 0; i < URB_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) ret = usb_submit_urb(dev->urbs[i], GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) stop_urb_transfer(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) pr_err("%s: failed urb submission, err = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) dev->urb_streaming = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* If we don't valid data within 1 second, restart stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) mod_timer(&dev->bulk_timeout, jiffies + (HZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) dev->bulk_timeout_running = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) static void au0828_start_transport(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) au0828_write(dev, 0x608, 0x90);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) au0828_write(dev, 0x609, 0x72);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) au0828_write(dev, 0x60a, 0x71);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) au0828_write(dev, 0x60b, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static void au0828_stop_transport(struct au0828_dev *dev, int full_stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (full_stop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) au0828_write(dev, 0x608, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) au0828_write(dev, 0x609, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) au0828_write(dev, 0x60a, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) au0828_write(dev, 0x60b, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static int au0828_dvb_start_feed(struct dvb_demux_feed *feed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct dvb_demux *demux = feed->demux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct au0828_dev *dev = (struct au0828_dev *) demux->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct au0828_dvb *dvb = &dev->dvb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (!demux->dmx.frontend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (dvb->frontend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) mutex_lock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) dvb->start_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) dprintk(1, "%s(), start_count: %d, stop_count: %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dvb->start_count, dvb->stop_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (dvb->feeding++ == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* Start transport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) au0828_start_transport(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) ret = start_urb_transfer(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) au0828_stop_transport(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) dvb->feeding--; /* We ran out of memory... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) mutex_unlock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static int au0828_dvb_stop_feed(struct dvb_demux_feed *feed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) struct dvb_demux *demux = feed->demux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct au0828_dev *dev = (struct au0828_dev *) demux->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct au0828_dvb *dvb = &dev->dvb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (dvb->frontend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) cancel_work_sync(&dev->restart_streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) mutex_lock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) dvb->stop_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) dprintk(1, "%s(), start_count: %d, stop_count: %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) dvb->start_count, dvb->stop_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (dvb->feeding > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) dvb->feeding--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (dvb->feeding == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /* Stop transport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ret = stop_urb_transfer(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) au0828_stop_transport(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) mutex_unlock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static void au0828_restart_dvb_streaming(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) struct au0828_dev *dev = container_of(work, struct au0828_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) restart_streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) struct au0828_dvb *dvb = &dev->dvb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (!dev->urb_streaming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) dprintk(1, "Restarting streaming...!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) mutex_lock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) /* Stop transport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) stop_urb_transfer(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) au0828_stop_transport(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* Start transport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) au0828_start_transport(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) start_urb_transfer(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) mutex_unlock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static int au0828_set_frontend(struct dvb_frontend *fe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct au0828_dev *dev = fe->dvb->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct au0828_dvb *dvb = &dev->dvb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) int ret, was_streaming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) mutex_lock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) was_streaming = dev->urb_streaming;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (was_streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) au0828_stop_transport(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * We can't hold a mutex here, as the restart_streaming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * kthread may also hold it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) mutex_unlock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) cancel_work_sync(&dev->restart_streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) mutex_lock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) stop_urb_transfer(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) mutex_unlock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) ret = dvb->set_frontend(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (was_streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) mutex_lock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) au0828_start_transport(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) start_urb_transfer(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) mutex_unlock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static int dvb_register(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct au0828_dvb *dvb = &dev->dvb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (preallocate_big_buffers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) for (i = 0; i < URB_COUNT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) dev->dig_transfer_buffer[i] = kzalloc(URB_BUFSIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (!dev->dig_transfer_buffer[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) result = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) pr_err("failed buffer allocation (errno = %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) goto fail_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) INIT_WORK(&dev->restart_streaming, au0828_restart_dvb_streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) /* register adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) result = dvb_register_adapter(&dvb->adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) KBUILD_MODNAME, THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) &dev->usbdev->dev, adapter_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) pr_err("dvb_register_adapter failed (errno = %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) goto fail_adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) #ifdef CONFIG_MEDIA_CONTROLLER_DVB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) dvb->adapter.mdev = dev->media_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) dvb->adapter.priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /* register frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) pr_err("dvb_register_frontend failed (errno = %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) goto fail_frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) /* Hook dvb frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) dvb->set_frontend = dvb->frontend->ops.set_frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) dvb->frontend->ops.set_frontend = au0828_set_frontend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* register demux stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) dvb->demux.dmx.capabilities =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) DMX_TS_FILTERING | DMX_SECTION_FILTERING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) DMX_MEMORY_BASED_FILTERING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) dvb->demux.priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) dvb->demux.filternum = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) dvb->demux.feednum = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) dvb->demux.start_feed = au0828_dvb_start_feed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) dvb->demux.stop_feed = au0828_dvb_stop_feed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) result = dvb_dmx_init(&dvb->demux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) pr_err("dvb_dmx_init failed (errno = %d)\n", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) goto fail_dmx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) dvb->dmxdev.filternum = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) dvb->dmxdev.demux = &dvb->demux.dmx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) dvb->dmxdev.capabilities = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) pr_err("dvb_dmxdev_init failed (errno = %d)\n", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) goto fail_dmxdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) dvb->fe_hw.source = DMX_FRONTEND_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) pr_err("add_frontend failed (DMX_FRONTEND_0, errno = %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) goto fail_fe_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) dvb->fe_mem.source = DMX_MEMORY_FE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) pr_err("add_frontend failed (DMX_MEMORY_FE, errno = %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) goto fail_fe_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (result < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) pr_err("connect_frontend failed (errno = %d)\n", result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) goto fail_fe_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /* register network adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) dvb->start_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) dvb->stop_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) result = dvb_create_media_graph(&dvb->adapter, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (result < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) goto fail_create_graph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) fail_create_graph:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) dvb_net_release(&dvb->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) fail_fe_conn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) fail_fe_mem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) fail_fe_hw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) dvb_dmxdev_release(&dvb->dmxdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) fail_dmxdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) dvb_dmx_release(&dvb->demux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) fail_dmx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) dvb_unregister_frontend(dvb->frontend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) fail_frontend:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) dvb_frontend_detach(dvb->frontend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) dvb_unregister_adapter(&dvb->adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) fail_adapter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (preallocate_big_buffers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) for (i = 0; i < URB_COUNT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) kfree(dev->dig_transfer_buffer[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) void au0828_dvb_unregister(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct au0828_dvb *dvb = &dev->dvb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (dvb->frontend == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) cancel_work_sync(&dev->restart_streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) dvb_net_release(&dvb->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) dvb_dmxdev_release(&dvb->dmxdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) dvb_dmx_release(&dvb->demux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) dvb_unregister_frontend(dvb->frontend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) dvb_frontend_detach(dvb->frontend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) dvb_unregister_adapter(&dvb->adapter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (preallocate_big_buffers) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) for (i = 0; i < URB_COUNT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) kfree(dev->dig_transfer_buffer[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) dvb->frontend = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /* All the DVB attach calls go here, this function gets modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * for each new card. No other function in this file needs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * to change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) int au0828_dvb_register(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct au0828_dvb *dvb = &dev->dvb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) dprintk(1, "%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /* init frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) switch (dev->boardnr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) case AU0828_BOARD_HAUPPAUGE_HVR850:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) case AU0828_BOARD_HAUPPAUGE_HVR950Q:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) dvb->frontend = dvb_attach(au8522_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) &hauppauge_hvr950q_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) &dev->i2c_adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (dvb->frontend != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) switch (dev->board.tuner_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) case TUNER_XC5000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) dvb_attach(xc5000_attach, dvb->frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) &dev->i2c_adap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) &hauppauge_xc5000a_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) case TUNER_XC5000C:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) dvb_attach(xc5000_attach, dvb->frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) &dev->i2c_adap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) &hauppauge_xc5000c_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) dvb->frontend = dvb_attach(au8522_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) &hauppauge_hvr950q_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) &dev->i2c_adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (dvb->frontend != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) dvb_attach(mxl5007t_attach, dvb->frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) &dev->i2c_adap, 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) &mxl5007t_hvr950q_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) case AU0828_BOARD_HAUPPAUGE_WOODBURY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) dvb->frontend = dvb_attach(au8522_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) &hauppauge_woodbury_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) &dev->i2c_adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (dvb->frontend != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) dvb_attach(tda18271_attach, dvb->frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 0x60, &dev->i2c_adap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) &hauppauge_woodbury_tunerconfig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) case AU0828_BOARD_DVICO_FUSIONHDTV7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) dvb->frontend = dvb_attach(au8522_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) &fusionhdtv7usb_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) &dev->i2c_adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (dvb->frontend != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) dvb_attach(xc5000_attach, dvb->frontend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) &dev->i2c_adap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) &hauppauge_xc5000a_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) pr_warn("The frontend of your DVB/ATSC card isn't supported yet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if (NULL == dvb->frontend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) pr_err("%s() Frontend initialization failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /* define general-purpose callback pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) dvb->frontend->callback = au0828_tuner_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) /* register everything */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) ret = dvb_register(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (dvb->frontend->ops.release)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) dvb->frontend->ops.release(dvb->frontend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) dvb->frontend = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) timer_setup(&dev->bulk_timeout, au0828_bulk_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) void au0828_dvb_suspend(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) struct au0828_dvb *dvb = &dev->dvb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (dvb->frontend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (dev->urb_streaming) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) cancel_work_sync(&dev->restart_streaming);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) /* Stop transport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) mutex_lock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) stop_urb_transfer(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) au0828_stop_transport(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) mutex_unlock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) dev->need_urb_start = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /* suspend frontend - does tuner and fe to sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) rc = dvb_frontend_suspend(dvb->frontend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) pr_info("au0828_dvb_suspend(): Suspending DVB fe %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) void au0828_dvb_resume(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) struct au0828_dvb *dvb = &dev->dvb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (dvb->frontend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) /* resume frontend - does fe and tuner init */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) rc = dvb_frontend_resume(dvb->frontend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) pr_info("au0828_dvb_resume(): Resuming DVB fe %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (dev->need_urb_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /* Start transport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) mutex_lock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) au0828_start_transport(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) start_urb_transfer(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) mutex_unlock(&dvb->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }