^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for AzureWave 6007 DVB-C/T USB2.0 and clones
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) Henry Wang <Henry.wang@AzureWave.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * This driver was made publicly available by Terratec, at:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * The original driver's license is GPL, as declared with MODULE_LICENSE()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright (c) 2010-2012 Mauro Carvalho Chehab
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Driver modified by in order to work with upstream drxk driver, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * tons of bugs got fixed, and converted to use dvb-usb-v2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "drxk.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "mt2063.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <media/dvb_ca_en50221.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "dvb_usb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "cypress_firmware.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define AZ6007_FIRMWARE "dvb-usb-terratec-h7-az6007.fw"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static int az6007_xfer_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) module_param_named(xfer_debug, az6007_xfer_debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) MODULE_PARM_DESC(xfer_debug, "Enable xfer debug");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) /* Known requests (Cypress FX2 firmware + az6007 "private" ones*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define FX2_OED 0xb5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define AZ6007_READ_DATA 0xb7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define AZ6007_I2C_RD 0xb9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define AZ6007_POWER 0xbc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define AZ6007_I2C_WR 0xbd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define FX2_SCON1 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define AZ6007_TS_THROUGH 0xc7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define AZ6007_READ_IR 0xb4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct az6007_device_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct mutex mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct mutex ca_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct dvb_ca_en50221 ca;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned warm:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) int (*gate_ctrl) (struct dvb_frontend *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) unsigned char data[4096];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) static struct drxk_config terratec_h7_drxk = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) .adr = 0x29,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .parallel_ts = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) .dynamic_clk = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .single_master = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .enable_merr_cfg = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .no_i2c_bridge = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .chunk_size = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) .mpeg_out_clk_strength = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) .qam_demod_parameter_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .microcode_name = "dvb-usb-terratec-h7-drxk.fw",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static struct drxk_config cablestar_hdci_drxk = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .adr = 0x29,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .parallel_ts = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .dynamic_clk = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .single_master = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .enable_merr_cfg = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .no_i2c_bridge = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .chunk_size = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .mpeg_out_clk_strength = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) .qam_demod_parameter_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) .microcode_name = "dvb-usb-technisat-cablestar-hdci-drxk.fw",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct az6007_device_state *st = fe_to_priv(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct dvb_usb_adapter *adap = fe->sec_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) pr_debug("%s: %s\n", __func__, enable ? "enable" : "disable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (!adap || !st)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) status = st->gate_ctrl(fe, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) status = st->gate_ctrl(fe, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static struct mt2063_config az6007_mt2063_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) .tuner_address = 0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) .refclock = 36125000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static int __az6007_read(struct usb_device *udev, u8 req, u16 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) u16 index, u8 *b, int blen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ret = usb_control_msg(udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) usb_rcvctrlpipe(udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) USB_TYPE_VENDOR | USB_DIR_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) value, index, b, blen, 5000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) pr_warn("usb read operation failed. (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (az6007_xfer_debug) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) printk(KERN_DEBUG "az6007: IN req: %02x, value: %04x, index: %04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) req, value, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) print_hex_dump_bytes("az6007: payload: ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) DUMP_PREFIX_NONE, b, blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int az6007_read(struct dvb_usb_device *d, u8 req, u16 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u16 index, u8 *b, int blen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct az6007_device_state *st = d->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (mutex_lock_interruptible(&st->mutex) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) ret = __az6007_read(d->udev, req, value, index, b, blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) mutex_unlock(&st->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static int __az6007_write(struct usb_device *udev, u8 req, u16 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) u16 index, u8 *b, int blen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (az6007_xfer_debug) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) printk(KERN_DEBUG "az6007: OUT req: %02x, value: %04x, index: %04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) req, value, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) print_hex_dump_bytes("az6007: payload: ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) DUMP_PREFIX_NONE, b, blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (blen > 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) pr_err("az6007: tried to write %d bytes, but I2C max size is 64 bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ret = usb_control_msg(udev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) usb_sndctrlpipe(udev, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) USB_TYPE_VENDOR | USB_DIR_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) value, index, b, blen, 5000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (ret != blen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) pr_err("usb write operation failed. (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static int az6007_write(struct dvb_usb_device *d, u8 req, u16 value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) u16 index, u8 *b, int blen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct az6007_device_state *st = d->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (mutex_lock_interruptible(&st->mutex) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ret = __az6007_write(d->udev, req, value, index, b, blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) mutex_unlock(&st->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) return ret;
^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 az6007_streaming_ctrl(struct dvb_frontend *fe, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct dvb_usb_device *d = fe_to_d(fe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) pr_debug("%s: %s\n", __func__, onoff ? "enable" : "disable");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return az6007_write(d, 0xbc, onoff, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #if IS_ENABLED(CONFIG_RC_CORE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* remote control stuff (does not work with my box) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int az6007_rc_query(struct dvb_usb_device *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct az6007_device_state *st = d_to_priv(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) unsigned code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) enum rc_proto proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (st->data[1] == 0x44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if ((st->data[3] ^ st->data[4]) == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if ((st->data[1] ^ st->data[2]) == 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) code = RC_SCANCODE_NEC(st->data[1], st->data[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) proto = RC_PROTO_NEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) code = RC_SCANCODE_NECX(st->data[1] << 8 | st->data[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) st->data[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) proto = RC_PROTO_NECX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) code = RC_SCANCODE_NEC32(st->data[1] << 24 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) st->data[2] << 16 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) st->data[3] << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) st->data[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) proto = RC_PROTO_NEC32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) rc_keydown(d->rc_dev, proto, code, st->data[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static int az6007_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) pr_debug("Getting az6007 Remote Control properties\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) rc->allowed_protos = RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) RC_PROTO_BIT_NEC32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) rc->query = az6007_rc_query;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) rc->interval = 400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #define az6007_get_rc_config NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static int az6007_ci_read_attribute_mem(struct dvb_ca_en50221 *ca,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct az6007_device_state *state = d_to_priv(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) u8 req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) u16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) u16 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) int blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) u8 *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (slot != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) b = kmalloc(12, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (!b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) mutex_lock(&state->ca_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) req = 0xC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) value = address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) blen = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ret = az6007_read(d, req, value, index, b, blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) pr_warn("usb in operation failed. (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ret = b[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) mutex_unlock(&state->ca_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) kfree(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static int az6007_ci_write_attribute_mem(struct dvb_ca_en50221 *ca,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) int address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct az6007_device_state *state = d_to_priv(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) u8 req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u16 value1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) u16 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) pr_debug("%s(), slot %d\n", __func__, slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (slot != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) mutex_lock(&state->ca_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) req = 0xC2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) value1 = address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) index = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) blen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ret = az6007_write(d, req, value1, index, NULL, blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) pr_warn("usb out operation failed. (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) mutex_unlock(&state->ca_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static int az6007_ci_read_cam_control(struct dvb_ca_en50221 *ca,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) u8 address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct az6007_device_state *state = d_to_priv(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) u8 req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) u16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) u16 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) int blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) u8 *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (slot != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) b = kmalloc(12, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (!b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) mutex_lock(&state->ca_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) req = 0xC3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) value = address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) blen = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) ret = az6007_read(d, req, value, index, b, blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) pr_warn("usb in operation failed. (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (b[0] == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) pr_warn("Read CI IO error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) ret = b[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) pr_debug("read cam data = %x from 0x%x\n", b[1], value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) mutex_unlock(&state->ca_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) kfree(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static int az6007_ci_write_cam_control(struct dvb_ca_en50221 *ca,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) u8 address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct az6007_device_state *state = d_to_priv(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) u8 req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) u16 value1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) u16 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) int blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (slot != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) mutex_lock(&state->ca_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) req = 0xC4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) value1 = address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) index = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) blen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ret = az6007_write(d, req, value1, index, NULL, blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) pr_warn("usb out operation failed. (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) goto failed;
^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) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) mutex_unlock(&state->ca_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static int CI_CamReady(struct dvb_ca_en50221 *ca, int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) u8 req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) u16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) u16 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) u8 *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) b = kmalloc(12, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (!b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) req = 0xC8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) blen = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ret = az6007_read(d, req, value, index, b, blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) pr_warn("usb in operation failed. (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) } else{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ret = b[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) kfree(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static int az6007_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct az6007_device_state *state = d_to_priv(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) u8 req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) u16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) u16 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) int blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) mutex_lock(&state->ca_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) req = 0xC6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) value = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) blen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ret = az6007_write(d, req, value, index, NULL, blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) pr_warn("usb out operation failed. (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) msleep(500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) req = 0xC6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) blen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) ret = az6007_write(d, req, value, index, NULL, blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) pr_warn("usb out operation failed. (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) for (i = 0; i < 15; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (CI_CamReady(ca, slot)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) pr_debug("CAM Ready\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) msleep(5000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) mutex_unlock(&state->ca_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static int az6007_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) static int az6007_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct az6007_device_state *state = d_to_priv(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) u8 req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) u16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) u16 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) int blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) pr_debug("%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) mutex_lock(&state->ca_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) req = 0xC7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) value = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) blen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ret = az6007_write(d, req, value, index, NULL, blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) pr_warn("usb out operation failed. (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) mutex_unlock(&state->ca_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static int az6007_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct dvb_usb_device *d = (struct dvb_usb_device *)ca->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) struct az6007_device_state *state = d_to_priv(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) u8 req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) u16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) u16 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) int blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) u8 *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) b = kmalloc(12, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (!b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) mutex_lock(&state->ca_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) req = 0xC5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) blen = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) ret = az6007_read(d, req, value, index, b, blen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) pr_warn("usb in operation failed. (%d)\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (!ret && b[0] == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) ret = DVB_CA_EN50221_POLL_CAM_PRESENT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) DVB_CA_EN50221_POLL_CAM_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) mutex_unlock(&state->ca_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) kfree(b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static void az6007_ci_uninit(struct dvb_usb_device *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) struct az6007_device_state *state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) pr_debug("%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) if (NULL == d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) state = d_to_priv(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (NULL == state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (NULL == state->ca.data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) dvb_ca_en50221_release(&state->ca);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) memset(&state->ca, 0, sizeof(state->ca));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static int az6007_ci_init(struct dvb_usb_adapter *adap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) struct dvb_usb_device *d = adap_to_d(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct az6007_device_state *state = adap_to_priv(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) pr_debug("%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) mutex_init(&state->ca_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) state->ca.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) state->ca.read_attribute_mem = az6007_ci_read_attribute_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) state->ca.write_attribute_mem = az6007_ci_write_attribute_mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) state->ca.read_cam_control = az6007_ci_read_cam_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) state->ca.write_cam_control = az6007_ci_write_cam_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) state->ca.slot_reset = az6007_ci_slot_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) state->ca.slot_shutdown = az6007_ci_slot_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) state->ca.slot_ts_enable = az6007_ci_slot_ts_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) state->ca.poll_slot_status = az6007_ci_poll_slot_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) state->ca.data = d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) ret = dvb_ca_en50221_init(&adap->dvb_adap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) &state->ca,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 0, /* flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 1);/* n_slots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) pr_err("Cannot initialize CI: Error %d.\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) memset(&state->ca, 0, sizeof(state->ca));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) pr_debug("CI initialized.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static int az6007_read_mac_addr(struct dvb_usb_adapter *adap, u8 mac[6])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct dvb_usb_device *d = adap_to_d(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct az6007_device_state *st = adap_to_priv(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) ret = az6007_read(d, AZ6007_READ_DATA, 6, 0, st->data, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) memcpy(mac, st->data, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) pr_debug("%s: mac is %pM\n", __func__, mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static int az6007_frontend_attach(struct dvb_usb_adapter *adap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) struct az6007_device_state *st = adap_to_priv(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct dvb_usb_device *d = adap_to_d(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) pr_debug("attaching demod drxk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) adap->fe[0] = dvb_attach(drxk_attach, &terratec_h7_drxk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) &d->i2c_adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (!adap->fe[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) adap->fe[0]->sec_priv = adap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) st->gate_ctrl = adap->fe[0]->ops.i2c_gate_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) adap->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) az6007_ci_init(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static int az6007_cablestar_hdci_frontend_attach(struct dvb_usb_adapter *adap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct az6007_device_state *st = adap_to_priv(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) struct dvb_usb_device *d = adap_to_d(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) pr_debug("attaching demod drxk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) adap->fe[0] = dvb_attach(drxk_attach, &cablestar_hdci_drxk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) &d->i2c_adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (!adap->fe[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) adap->fe[0]->sec_priv = adap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) st->gate_ctrl = adap->fe[0]->ops.i2c_gate_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) adap->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) az6007_ci_init(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static int az6007_tuner_attach(struct dvb_usb_adapter *adap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct dvb_usb_device *d = adap_to_d(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) pr_debug("attaching tuner mt2063\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) /* Attach mt2063 to DVB-C frontend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (adap->fe[0]->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if (!dvb_attach(mt2063_attach, adap->fe[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) &az6007_mt2063_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) &d->i2c_adap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (adap->fe[0]->ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) static int az6007_power_ctrl(struct dvb_usb_device *d, int onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) struct az6007_device_state *state = d_to_priv(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) pr_debug("%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (!state->warm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) mutex_init(&state->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) ret = az6007_write(d, AZ6007_POWER, 0, 2, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) msleep(60);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) ret = az6007_write(d, AZ6007_POWER, 1, 3, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) msleep(400);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) ret = az6007_write(d, FX2_SCON1, 0, 3, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) msleep(150);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ret = az6007_write(d, FX2_SCON1, 1, 3, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) msleep(430);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) ret = az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) state->warm = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (!onoff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) az6007_write(d, AZ6007_TS_THROUGH, 0, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) /* I2C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct dvb_usb_device *d = i2c_get_adapdata(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct az6007_device_state *st = d_to_priv(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) int i, j, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) u16 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) u16 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) u8 req, addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (mutex_lock_interruptible(&st->mutex) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) for (i = 0; i < num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) addr = msgs[i].addr << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (((i + 1) < num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) && (msgs[i].len == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) && ((msgs[i].flags & I2C_M_RD) != I2C_M_RD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) && (msgs[i + 1].flags & I2C_M_RD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) && (msgs[i].addr == msgs[i + 1].addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * A write + read xfer for the same address, where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) * the first xfer has just 1 byte length.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) * Need to join both into one operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (az6007_xfer_debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) printk(KERN_DEBUG "az6007: I2C W/R addr=0x%x len=%d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) addr, msgs[i].len, msgs[i + 1].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) req = AZ6007_I2C_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) index = msgs[i].buf[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) value = addr | (1 << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) length = 6 + msgs[i + 1].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) len = msgs[i + 1].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) ret = __az6007_read(d->udev, req, value, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) st->data, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (ret >= len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) for (j = 0; j < len; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) msgs[i + 1].buf[j] = st->data[j + 5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) } else if (!(msgs[i].flags & I2C_M_RD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) /* write bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (az6007_xfer_debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) printk(KERN_DEBUG "az6007: I2C W addr=0x%x len=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) addr, msgs[i].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) req = AZ6007_I2C_WR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) index = msgs[i].buf[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) value = addr | (1 << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) length = msgs[i].len - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) len = msgs[i].len - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) for (j = 0; j < len; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) st->data[j] = msgs[i].buf[j + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) ret = __az6007_write(d->udev, req, value, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) st->data, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) /* read bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (az6007_xfer_debug)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) printk(KERN_DEBUG "az6007: I2C R addr=0x%x len=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) addr, msgs[i].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) req = AZ6007_I2C_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) index = msgs[i].buf[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) value = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) length = msgs[i].len + 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) len = msgs[i].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) ret = __az6007_read(d->udev, req, value, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) st->data, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) for (j = 0; j < len; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) msgs[i].buf[j] = st->data[j + 5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) mutex_unlock(&st->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) pr_info("%s ERROR: %i\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) static u32 az6007_i2c_func(struct i2c_adapter *adapter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) return I2C_FUNC_I2C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) static struct i2c_algorithm az6007_i2c_algo = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) .master_xfer = az6007_i2c_xfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) .functionality = az6007_i2c_func,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) static int az6007_identify_state(struct dvb_usb_device *d, const char **name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) u8 *mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) pr_debug("Identifying az6007 state\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) mac = kmalloc(6, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (!mac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) /* Try to read the mac address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) ret = __az6007_read(d->udev, AZ6007_READ_DATA, 6, 0, mac, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (ret == 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) ret = WARM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) ret = COLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) kfree(mac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (ret == COLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) __az6007_write(d->udev, 0x09, 1, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) __az6007_write(d->udev, 0x00, 0, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) __az6007_write(d->udev, 0x00, 0, 0, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) pr_debug("Device is on %s state\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) ret == WARM ? "warm" : "cold");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) static void az6007_usb_disconnect(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) struct dvb_usb_device *d = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) az6007_ci_uninit(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) dvb_usbv2_disconnect(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) static int az6007_download_firmware(struct dvb_usb_device *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) const struct firmware *fw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) pr_debug("Loading az6007 firmware\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) return cypress_load_firmware(d->udev, fw, CYPRESS_FX2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) /* DVB USB Driver stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static struct dvb_usb_device_properties az6007_props = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) .driver_name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) .firmware = AZ6007_FIRMWARE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) .adapter_nr = adapter_nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) .size_of_priv = sizeof(struct az6007_device_state),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) .i2c_algo = &az6007_i2c_algo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) .tuner_attach = az6007_tuner_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) .frontend_attach = az6007_frontend_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) .streaming_ctrl = az6007_streaming_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) .get_rc_config = az6007_get_rc_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) .read_mac_address = az6007_read_mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) .download_firmware = az6007_download_firmware,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) .identify_state = az6007_identify_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) .power_ctrl = az6007_power_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) .num_adapters = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) .adapter = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) { .stream = DVB_USB_STREAM_BULK(0x02, 10, 4096), }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) static struct dvb_usb_device_properties az6007_cablestar_hdci_props = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) .driver_name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) .firmware = AZ6007_FIRMWARE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) .adapter_nr = adapter_nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) .size_of_priv = sizeof(struct az6007_device_state),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) .i2c_algo = &az6007_i2c_algo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) .tuner_attach = az6007_tuner_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) .frontend_attach = az6007_cablestar_hdci_frontend_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) .streaming_ctrl = az6007_streaming_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) /* ditch get_rc_config as it can't work (TS35 remote, I believe it's rc5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) .get_rc_config = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) .read_mac_address = az6007_read_mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) .download_firmware = az6007_download_firmware,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) .identify_state = az6007_identify_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) .power_ctrl = az6007_power_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) .num_adapters = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) .adapter = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) { .stream = DVB_USB_STREAM_BULK(0x02, 10, 4096), }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) static const struct usb_device_id az6007_usb_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {DVB_USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) &az6007_props, "Azurewave 6007", RC_MAP_EMPTY)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) {DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) {DVB_USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) &az6007_props, "Terratec H7", RC_MAP_NEC_TERRATEC_CINERGY_XS)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) {DVB_USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_CABLESTAR_HDCI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) &az6007_cablestar_hdci_props, "Technisat CableStar Combo HD CI", RC_MAP_EMPTY)},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) {0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) MODULE_DEVICE_TABLE(usb, az6007_usb_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) static int az6007_suspend(struct usb_interface *intf, pm_message_t msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) struct dvb_usb_device *d = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) az6007_ci_uninit(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) return dvb_usbv2_suspend(intf, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) static int az6007_resume(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) struct dvb_usb_device *d = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) struct dvb_usb_adapter *adap = &d->adapter[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) az6007_ci_init(adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) return dvb_usbv2_resume(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) /* usb specific object needed to register this driver with the usb subsystem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) static struct usb_driver az6007_usb_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) .name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) .id_table = az6007_usb_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) .probe = dvb_usbv2_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) .disconnect = az6007_usb_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) .no_dynamic_id = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) .soft_unbind = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) * FIXME: need to implement reset_resume, likely with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) * dvb-usb-v2 core support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) .suspend = az6007_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) .resume = az6007_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) module_usb_driver(az6007_usb_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) MODULE_AUTHOR("Henry Wang <Henry.wang@AzureWave.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) MODULE_AUTHOR("Mauro Carvalho Chehab");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) MODULE_VERSION("2.0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) MODULE_FIRMWARE(AZ6007_FIRMWARE);