aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/dvb-usb-v2
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/usb/dvb-usb-v2')
-rw-r--r--drivers/media/usb/dvb-usb-v2/Kconfig8
-rw-r--r--drivers/media/usb/dvb-usb-v2/Makefile3
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9015.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9015.h4
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9035.c267
-rw-r--r--drivers/media/usb/dvb-usb-v2/af9035.h7
-rw-r--r--drivers/media/usb/dvb-usb-v2/anysee.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/anysee.h4
-rw-r--r--drivers/media/usb/dvb-usb-v2/au6610.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/au6610.h4
-rw-r--r--drivers/media/usb/dvb-usb-v2/ce6230.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/ce6230.h4
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvb_usb_core.c12
-rw-r--r--drivers/media/usb/dvb-usb-v2/dvbsky.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/ec168.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/ec168.h4
-rw-r--r--drivers/media/usb/dvb-usb-v2/lmedm04.c22
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h4
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h4
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h4
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h4
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h4
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c4
-rw-r--r--drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h4
-rw-r--r--drivers/media/usb/dvb-usb-v2/rtl28xxu.c2
-rw-r--r--drivers/media/usb/dvb-usb-v2/zd1301.c298
30 files changed, 454 insertions, 253 deletions
diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig
index 524533d3eb29..0e4944b2b0f4 100644
--- a/drivers/media/usb/dvb-usb-v2/Kconfig
+++ b/drivers/media/usb/dvb-usb-v2/Kconfig
@@ -156,3 +156,11 @@ config DVB_USB_DVBSKY
select DVB_SP2 if MEDIA_SUBDRV_AUTOSELECT
help
Say Y here to support the USB receivers from DVBSky.
+
+config DVB_USB_ZD1301
+ tristate "ZyDAS ZD1301"
+ depends on DVB_USB_V2
+ select DVB_ZD1301_DEMOD if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
+ help
+ Say Y here to support the ZyDAS ZD1301 DVB USB receiver.
diff --git a/drivers/media/usb/dvb-usb-v2/Makefile b/drivers/media/usb/dvb-usb-v2/Makefile
index f10d4df0eae5..969f68e55265 100644
--- a/drivers/media/usb/dvb-usb-v2/Makefile
+++ b/drivers/media/usb/dvb-usb-v2/Makefile
@@ -40,6 +40,9 @@ obj-$(CONFIG_DVB_USB_RTL28XXU) += dvb-usb-rtl28xxu.o
dvb-usb-dvbsky-objs := dvbsky.o
obj-$(CONFIG_DVB_USB_DVBSKY) += dvb-usb-dvbsky.o
+dvb-usb-zd1301-objs := zd1301.o
+obj-$(CONFIG_DVB_USB_ZD1301) += zd1301.o
+
ccflags-y += -I$(srctree)/drivers/media/dvb-core
ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
ccflags-y += -I$(srctree)/drivers/media/tuners
diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c
index 29011dfabb11..caa1e6101f58 100644
--- a/drivers/media/usb/dvb-usb-v2/af9015.c
+++ b/drivers/media/usb/dvb-usb-v2/af9015.c
@@ -15,10 +15,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
*/
#include "af9015.h"
diff --git a/drivers/media/usb/dvb-usb-v2/af9015.h b/drivers/media/usb/dvb-usb-v2/af9015.h
index 1db1bb0d57bc..2dd9231a8ece 100644
--- a/drivers/media/usb/dvb-usb-v2/af9015.h
+++ b/drivers/media/usb/dvb-usb-v2/af9015.h
@@ -15,10 +15,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
*/
#ifndef AF9015_H
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index c673726d9b70..4df9486e19b9 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -335,14 +335,12 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
/* TODO: correct limits > 40 */
ret = -EOPNOTSUPP;
} else if ((msg[0].addr == state->af9033_i2c_addr[0]) ||
- (msg[0].addr == state->af9033_i2c_addr[1]) ||
- (state->chip_type == 0x9135)) {
+ (msg[0].addr == state->af9033_i2c_addr[1])) {
/* demod access via firmware interface */
u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
msg[0].buf[2];
- if (msg[0].addr == state->af9033_i2c_addr[1] ||
- msg[0].addr == (state->af9033_i2c_addr[1] >> 1))
+ if (msg[0].addr == state->af9033_i2c_addr[1])
reg |= 0x100000;
ret = af9035_rd_regs(d, reg, &msg[1].buf[0],
@@ -396,14 +394,12 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
/* TODO: correct limits > 40 */
ret = -EOPNOTSUPP;
} else if ((msg[0].addr == state->af9033_i2c_addr[0]) ||
- (msg[0].addr == state->af9033_i2c_addr[1]) ||
- (state->chip_type == 0x9135)) {
+ (msg[0].addr == state->af9033_i2c_addr[1])) {
/* demod access via firmware interface */
u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 |
msg[0].buf[2];
- if (msg[0].addr == state->af9033_i2c_addr[1] ||
- msg[0].addr == (state->af9033_i2c_addr[1] >> 1))
+ if (msg[0].addr == state->af9033_i2c_addr[1])
reg |= 0x100000;
ret = af9035_wr_regs(d, reg, &msg[0].buf[3],
@@ -496,7 +492,8 @@ static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
{
struct state *state = d_to_priv(d);
struct usb_interface *intf = d->intf;
- int ret, ts_mode_invalid;
+ int ret, i, ts_mode_invalid;
+ unsigned int utmp, eeprom_addr;
u8 tmp;
u8 wbuf[1] = { 1 };
u8 rbuf[4];
@@ -518,25 +515,48 @@ static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
state->prechip_version, state->chip_version, state->chip_type);
if (state->chip_type == 0x9135) {
- if (state->chip_version == 0x02)
+ if (state->chip_version == 0x02) {
*name = AF9035_FIRMWARE_IT9135_V2;
- else
+ utmp = 0x00461d;
+ } else {
*name = AF9035_FIRMWARE_IT9135_V1;
- state->eeprom_addr = EEPROM_BASE_IT9135;
+ utmp = 0x00461b;
+ }
+
+ /* Check if eeprom exists */
+ ret = af9035_rd_reg(d, utmp, &tmp);
+ if (ret < 0)
+ goto err;
+
+ if (tmp == 0x00) {
+ dev_dbg(&intf->dev, "no eeprom\n");
+ state->no_eeprom = true;
+ goto check_firmware_status;
+ }
+
+ eeprom_addr = EEPROM_BASE_IT9135;
} else if (state->chip_type == 0x9306) {
*name = AF9035_FIRMWARE_IT9303;
- state->eeprom_addr = EEPROM_BASE_IT9135;
+ state->no_eeprom = true;
+ goto check_firmware_status;
} else {
*name = AF9035_FIRMWARE_AF9035;
- state->eeprom_addr = EEPROM_BASE_AF9035;
+ eeprom_addr = EEPROM_BASE_AF9035;
+ }
+
+ /* Read and store eeprom */
+ for (i = 0; i < 256; i += 32) {
+ ret = af9035_rd_regs(d, eeprom_addr + i, &state->eeprom[i], 32);
+ if (ret < 0)
+ goto err;
}
+ dev_dbg(&intf->dev, "eeprom dump:\n");
+ for (i = 0; i < 256; i += 16)
+ dev_dbg(&intf->dev, "%*ph\n", 16, &state->eeprom[i]);
/* check for dual tuner mode */
- ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_TS_MODE, &tmp);
- if (ret < 0)
- goto err;
-
+ tmp = state->eeprom[EEPROM_TS_MODE];
ts_mode_invalid = 0;
switch (tmp) {
case 0:
@@ -560,7 +580,7 @@ static int af9035_identify_state(struct dvb_usb_device *d, const char **name)
if (ts_mode_invalid)
dev_info(&intf->dev, "ts mode=%d not supported, defaulting to single tuner mode!", tmp);
-
+check_firmware_status:
ret = af9035_ctrl_msg(d, &req);
if (ret < 0)
goto err;
@@ -750,15 +770,11 @@ static int af9035_download_firmware(struct dvb_usb_device *d,
goto err;
/* tell the slave I2C address */
- ret = af9035_rd_reg(d,
- state->eeprom_addr + EEPROM_2ND_DEMOD_ADDR,
- &tmp);
- if (ret < 0)
- goto err;
+ tmp = state->eeprom[EEPROM_2ND_DEMOD_ADDR];
- /* use default I2C address if eeprom has no address set */
+ /* Use default I2C address if eeprom has no address set */
if (!tmp)
- tmp = 0x3a;
+ tmp = 0x1d << 1; /* 8-bit format used by chip */
if ((state->chip_type == 0x9135) ||
(state->chip_type == 0x9306)) {
@@ -819,11 +835,11 @@ static int af9035_read_config(struct dvb_usb_device *d)
struct state *state = d_to_priv(d);
int ret, i;
u8 tmp;
- u16 tmp16, addr;
+ u16 tmp16;
- /* demod I2C "address" */
- state->af9033_i2c_addr[0] = 0x38;
- state->af9033_i2c_addr[1] = 0x3a;
+ /* Demod I2C address */
+ state->af9033_i2c_addr[0] = 0x1c;
+ state->af9033_i2c_addr[1] = 0x1d;
state->af9033_config[0].adc_multiplier = AF9033_ADC_MULTIPLIER_2X;
state->af9033_config[1].adc_multiplier = AF9033_ADC_MULTIPLIER_2X;
state->af9033_config[0].ts_mode = AF9033_TS_MODE_USB;
@@ -837,20 +853,16 @@ static int af9035_read_config(struct dvb_usb_device *d)
if (state->chip_version == 0x02) {
state->af9033_config[0].tuner = AF9033_TUNER_IT9135_60;
state->af9033_config[1].tuner = AF9033_TUNER_IT9135_60;
- tmp16 = 0x00461d; /* eeprom memory mapped location */
} else {
state->af9033_config[0].tuner = AF9033_TUNER_IT9135_38;
state->af9033_config[1].tuner = AF9033_TUNER_IT9135_38;
- tmp16 = 0x00461b; /* eeprom memory mapped location */
}
- /* check if eeprom exists */
- ret = af9035_rd_reg(d, tmp16, &tmp);
- if (ret < 0)
- goto err;
+ if (state->no_eeprom) {
+ /* Remote controller to NEC polling by default */
+ state->ir_mode = 0x05;
+ state->ir_type = 0x00;
- if (tmp == 0x00) {
- dev_dbg(&intf->dev, "no eeprom\n");
goto skip_eeprom;
}
} else if (state->chip_type == 0x9306) {
@@ -861,29 +873,25 @@ static int af9035_read_config(struct dvb_usb_device *d)
return 0;
}
+ /* Remote controller */
+ state->ir_mode = state->eeprom[EEPROM_IR_MODE];
+ state->ir_type = state->eeprom[EEPROM_IR_TYPE];
if (state->dual_mode) {
- /* read 2nd demodulator I2C address */
- ret = af9035_rd_reg(d,
- state->eeprom_addr + EEPROM_2ND_DEMOD_ADDR,
- &tmp);
- if (ret < 0)
- goto err;
-
+ /* Read 2nd demodulator I2C address. 8-bit format on eeprom */
+ tmp = state->eeprom[EEPROM_2ND_DEMOD_ADDR];
if (tmp)
- state->af9033_i2c_addr[1] = tmp;
+ state->af9033_i2c_addr[1] = tmp >> 1;
- dev_dbg(&intf->dev, "2nd demod I2C addr=%02x\n", tmp);
+ dev_dbg(&intf->dev, "2nd demod I2C addr=%02x\n",
+ state->af9033_i2c_addr[1]);
}
- addr = state->eeprom_addr;
-
for (i = 0; i < state->dual_mode + 1; i++) {
- /* tuner */
- ret = af9035_rd_reg(d, addr + EEPROM_1_TUNER_ID, &tmp);
- if (ret < 0)
- goto err;
+ unsigned int eeprom_offset = 0;
+ /* tuner */
+ tmp = state->eeprom[EEPROM_1_TUNER_ID + eeprom_offset];
dev_dbg(&intf->dev, "[%d]tuner=%02x\n", i, tmp);
/* tuner sanity check */
@@ -956,21 +964,13 @@ static int af9035_read_config(struct dvb_usb_device *d)
}
/* tuner IF frequency */
- ret = af9035_rd_reg(d, addr + EEPROM_1_IF_L, &tmp);
- if (ret < 0)
- goto err;
-
- tmp16 = tmp;
-
- ret = af9035_rd_reg(d, addr + EEPROM_1_IF_H, &tmp);
- if (ret < 0)
- goto err;
-
+ tmp = state->eeprom[EEPROM_1_IF_L + eeprom_offset];
+ tmp16 = tmp << 0;
+ tmp = state->eeprom[EEPROM_1_IF_H + eeprom_offset];
tmp16 |= tmp << 8;
-
dev_dbg(&intf->dev, "[%d]IF=%d\n", i, tmp16);
- addr += 0x10; /* shift for the 2nd tuner params */
+ eeprom_offset += 0x10; /* shift for the 2nd tuner params */
}
skip_eeprom:
@@ -1247,30 +1247,11 @@ static int af9035_frontend_detach(struct dvb_usb_adapter *adap)
struct state *state = adap_to_priv(adap);
struct dvb_usb_device *d = adap_to_d(adap);
struct usb_interface *intf = d->intf;
- int demod2;
dev_dbg(&intf->dev, "adap->id=%d\n", adap->id);
- /*
- * For dual tuner devices we have to resolve 2nd demod client, as there
- * is two different kind of tuner drivers; one is using I2C binding
- * and the other is using DVB attach/detach binding.
- */
- switch (state->af9033_config[adap->id].tuner) {
- case AF9033_TUNER_IT9135_38:
- case AF9033_TUNER_IT9135_51:
- case AF9033_TUNER_IT9135_52:
- case AF9033_TUNER_IT9135_60:
- case AF9033_TUNER_IT9135_61:
- case AF9033_TUNER_IT9135_62:
- demod2 = 2;
- break;
- default:
- demod2 = 1;
- }
-
if (adap->id == 1) {
- if (state->i2c_client[demod2])
+ if (state->i2c_client[1])
af9035_del_i2c_dev(d);
} else if (adap->id == 0) {
if (state->i2c_client[0])
@@ -1510,50 +1491,58 @@ static int af9035_tuner_attach(struct dvb_usb_adapter *adap)
case AF9033_TUNER_IT9135_38:
case AF9033_TUNER_IT9135_51:
case AF9033_TUNER_IT9135_52:
- {
- struct it913x_config it913x_config = {
- .fe = adap->fe[0],
- .chip_ver = 1,
- };
-
- if (state->dual_mode) {
- if (adap->id == 0)
- it913x_config.role = IT913X_ROLE_DUAL_MASTER;
- else
- it913x_config.role = IT913X_ROLE_DUAL_SLAVE;
- }
-
- ret = af9035_add_i2c_dev(d, "it913x",
- state->af9033_i2c_addr[adap->id] >> 1,
- &it913x_config, &d->i2c_adap);
- if (ret)
- goto err;
-
- fe = adap->fe[0];
- break;
- }
case AF9033_TUNER_IT9135_60:
case AF9033_TUNER_IT9135_61:
case AF9033_TUNER_IT9135_62:
{
- struct it913x_config it913x_config = {
+ struct platform_device *pdev;
+ const char *name;
+ struct it913x_platform_data it913x_pdata = {
+ .regmap = state->af9033_config[adap->id].regmap,
.fe = adap->fe[0],
- .chip_ver = 2,
};
+ switch (state->af9033_config[adap->id].tuner) {
+ case AF9033_TUNER_IT9135_38:
+ case AF9033_TUNER_IT9135_51:
+ case AF9033_TUNER_IT9135_52:
+ name = "it9133ax-tuner";
+ break;
+ case AF9033_TUNER_IT9135_60:
+ case AF9033_TUNER_IT9135_61:
+ case AF9033_TUNER_IT9135_62:
+ name = "it9133bx-tuner";
+ break;
+ default:
+ ret = -ENODEV;
+ goto err;
+ }
+
if (state->dual_mode) {
if (adap->id == 0)
- it913x_config.role = IT913X_ROLE_DUAL_MASTER;
+ it913x_pdata.role = IT913X_ROLE_DUAL_MASTER;
else
- it913x_config.role = IT913X_ROLE_DUAL_SLAVE;
+ it913x_pdata.role = IT913X_ROLE_DUAL_SLAVE;
+ } else {
+ it913x_pdata.role = IT913X_ROLE_SINGLE;
}
- ret = af9035_add_i2c_dev(d, "it913x",
- state->af9033_i2c_addr[adap->id] >> 1,
- &it913x_config, &d->i2c_adap);
- if (ret)
+ request_module("%s", "it913x");
+ pdev = platform_device_register_data(&d->intf->dev, name,
+ PLATFORM_DEVID_AUTO,
+ &it913x_pdata,
+ sizeof(it913x_pdata));
+ if (IS_ERR(pdev) || !pdev->dev.driver) {
+ ret = -ENODEV;
+ goto err;
+ }
+ if (!try_module_get(pdev->dev.driver->owner)) {
+ platform_device_unregister(pdev);
+ ret = -ENODEV;
goto err;
+ }
+ state->platform_device_tuner[adap->id] = pdev;
fe = adap->fe[0];
break;
}
@@ -1675,12 +1664,6 @@ static int af9035_tuner_detach(struct dvb_usb_adapter *adap)
switch (state->af9033_config[adap->id].tuner) {
case AF9033_TUNER_TUA9001:
case AF9033_TUNER_FC2580:
- case AF9033_TUNER_IT9135_38:
- case AF9033_TUNER_IT9135_51:
- case AF9033_TUNER_IT9135_52:
- case AF9033_TUNER_IT9135_60:
- case AF9033_TUNER_IT9135_61:
- case AF9033_TUNER_IT9135_62:
if (adap->id == 1) {
if (state->i2c_client[3])
af9035_del_i2c_dev(d);
@@ -1688,6 +1671,23 @@ static int af9035_tuner_detach(struct dvb_usb_adapter *adap)
if (state->i2c_client[1])
af9035_del_i2c_dev(d);
}
+ break;
+ case AF9033_TUNER_IT9135_38:
+ case AF9033_TUNER_IT9135_51:
+ case AF9033_TUNER_IT9135_52:
+ case AF9033_TUNER_IT9135_60:
+ case AF9033_TUNER_IT9135_61:
+ case AF9033_TUNER_IT9135_62:
+ {
+ struct platform_device *pdev;
+
+ pdev = state->platform_device_tuner[adap->id];
+ if (pdev) {
+ module_put(pdev->dev.driver->owner);
+ platform_device_unregister(pdev);
+ }
+ break;
+ }
}
return 0;
@@ -1872,25 +1872,13 @@ static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
{
struct state *state = d_to_priv(d);
struct usb_interface *intf = d->intf;
- int ret;
- u8 tmp;
-
- ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_IR_MODE, &tmp);
- if (ret < 0)
- goto err;
- dev_dbg(&intf->dev, "ir_mode=%02x\n", tmp);
+ dev_dbg(&intf->dev, "ir_mode=%02x ir_type=%02x\n",
+ state->ir_mode, state->ir_type);
/* don't activate rc if in HID mode or if not available */
- if (tmp == 5) {
- ret = af9035_rd_reg(d, state->eeprom_addr + EEPROM_IR_TYPE,
- &tmp);
- if (ret < 0)
- goto err;
-
- dev_dbg(&intf->dev, "ir_type=%02x\n", tmp);
-
- switch (tmp) {
+ if (state->ir_mode == 0x05) {
+ switch (state->ir_type) {
case 0: /* NEC */
default:
rc->allowed_protos = RC_BIT_NEC | RC_BIT_NECX |
@@ -1910,11 +1898,6 @@ static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc)
}
return 0;
-
-err:
- dev_dbg(&intf->dev, "failed=%d\n", ret);
-
- return ret;
}
#else
#define af9035_get_rc_config NULL
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h
index 1f83c9218ad0..a76e6bf0ab1e 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.h
+++ b/drivers/media/usb/dvb-usb-v2/af9035.h
@@ -22,6 +22,7 @@
#ifndef AF9035_H
#define AF9035_H
+#include <linux/platform_device.h>
#include "dvb_usb.h"
#include "af9033.h"
#include "tua9001.h"
@@ -61,15 +62,19 @@ struct state {
u8 prechip_version;
u8 chip_version;
u16 chip_type;
+ u8 eeprom[256];
+ bool no_eeprom;
+ u8 ir_mode;
+ u8 ir_type;
u8 dual_mode:1;
u8 no_read:1;
- u16 eeprom_addr;
u8 af9033_i2c_addr[2];
struct af9033_config af9033_config[2];
struct af9033_ops ops;
#define AF9035_I2C_CLIENT_MAX 4
struct i2c_client *i2c_client[AF9035_I2C_CLIENT_MAX];
struct i2c_adapter *i2c_adapter_demod;
+ struct platform_device *platform_device_tuner[2];
};
static const u32 clock_lut_af9035[] = {
diff --git a/drivers/media/usb/dvb-usb-v2/anysee.c b/drivers/media/usb/dvb-usb-v2/anysee.c
index ae917c042a52..6795c0c609b1 100644
--- a/drivers/media/usb/dvb-usb-v2/anysee.c
+++ b/drivers/media/usb/dvb-usb-v2/anysee.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
* TODO:
* - add smart card reader support for Conditional Access (CA)
*
diff --git a/drivers/media/usb/dvb-usb-v2/anysee.h b/drivers/media/usb/dvb-usb-v2/anysee.h
index 3ca2bca4ebaf..393e2fce2aed 100644
--- a/drivers/media/usb/dvb-usb-v2/anysee.h
+++ b/drivers/media/usb/dvb-usb-v2/anysee.h
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
* TODO:
* - add smart card reader support for Conditional Access (CA)
*
diff --git a/drivers/media/usb/dvb-usb-v2/au6610.c b/drivers/media/usb/dvb-usb-v2/au6610.c
index ae6a671b7fd5..6ee01cb64ca5 100644
--- a/drivers/media/usb/dvb-usb-v2/au6610.c
+++ b/drivers/media/usb/dvb-usb-v2/au6610.c
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "au6610.h"
diff --git a/drivers/media/usb/dvb-usb-v2/au6610.h b/drivers/media/usb/dvb-usb-v2/au6610.h
index ea337bfc00b1..aacfcc6fa0f5 100644
--- a/drivers/media/usb/dvb-usb-v2/au6610.h
+++ b/drivers/media/usb/dvb-usb-v2/au6610.h
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef AU6610_H
diff --git a/drivers/media/usb/dvb-usb-v2/ce6230.c b/drivers/media/usb/dvb-usb-v2/ce6230.c
index f67b14bc32e3..e596031a708d 100644
--- a/drivers/media/usb/dvb-usb-v2/ce6230.c
+++ b/drivers/media/usb/dvb-usb-v2/ce6230.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
*/
#include "ce6230.h"
diff --git a/drivers/media/usb/dvb-usb-v2/ce6230.h b/drivers/media/usb/dvb-usb-v2/ce6230.h
index 299e57e3390b..b25b3b938e49 100644
--- a/drivers/media/usb/dvb-usb-v2/ce6230.h
+++ b/drivers/media/usb/dvb-usb-v2/ce6230.h
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
*/
#ifndef CE6230_H
diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
index a8e6624fbe83..955fb0d07507 100644
--- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
+++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c
@@ -147,7 +147,7 @@ static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
if (!d->rc.map_name)
return 0;
- dev = rc_allocate_device();
+ dev = rc_allocate_device(d->rc.driver_type);
if (!dev) {
ret = -ENOMEM;
goto err;
@@ -162,7 +162,6 @@ static int dvb_usbv2_remote_init(struct dvb_usb_device *d)
/* TODO: likely RC-core should took const char * */
dev->driver_name = (char *) d->props->driver_name;
dev->map_name = d->rc.map_name;
- dev->driver_type = d->rc.driver_type;
dev->allowed_protocols = d->rc.allowed_protos;
dev->change_protocol = d->rc.change_protocol;
dev->priv = d;
@@ -1013,8 +1012,8 @@ EXPORT_SYMBOL(dvb_usbv2_probe);
void dvb_usbv2_disconnect(struct usb_interface *intf)
{
struct dvb_usb_device *d = usb_get_intfdata(intf);
- const char *name = d->name;
- struct device dev = d->udev->dev;
+ const char *devname = kstrdup(dev_name(&d->udev->dev), GFP_KERNEL);
+ const char *drvname = d->name;
dev_dbg(&d->udev->dev, "%s: bInterfaceNumber=%d\n", __func__,
intf->cur_altsetting->desc.bInterfaceNumber);
@@ -1024,8 +1023,9 @@ void dvb_usbv2_disconnect(struct usb_interface *intf)
dvb_usbv2_exit(d);
- dev_info(&dev, "%s: '%s' successfully deinitialized and disconnected\n",
- KBUILD_MODNAME, name);
+ pr_info("%s: '%s:%s' successfully deinitialized and disconnected\n",
+ KBUILD_MODNAME, drvname, devname);
+ kfree(devname);
}
EXPORT_SYMBOL(dvb_usbv2_disconnect);
diff --git a/drivers/media/usb/dvb-usb-v2/dvbsky.c b/drivers/media/usb/dvb-usb-v2/dvbsky.c
index 0636eac37bbb..5730760e4e93 100644
--- a/drivers/media/usb/dvb-usb-v2/dvbsky.c
+++ b/drivers/media/usb/dvb-usb-v2/dvbsky.c
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "dvb_usb.h"
diff --git a/drivers/media/usb/dvb-usb-v2/ec168.c b/drivers/media/usb/dvb-usb-v2/ec168.c
index 0c2b377704ff..1db8aeef3655 100644
--- a/drivers/media/usb/dvb-usb-v2/ec168.c
+++ b/drivers/media/usb/dvb-usb-v2/ec168.c
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
*/
#include "ec168.h"
diff --git a/drivers/media/usb/dvb-usb-v2/ec168.h b/drivers/media/usb/dvb-usb-v2/ec168.h
index 615a6569421f..704955bcaa10 100644
--- a/drivers/media/usb/dvb-usb-v2/ec168.h
+++ b/drivers/media/usb/dvb-usb-v2/ec168.h
@@ -13,10 +13,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
*/
#ifndef EC168_H
diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c
index 5fea02672685..924adfdb660d 100644
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -48,10 +48,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
*
* see Documentation/dvb/README.dvb-usb for more information
*
@@ -99,9 +95,7 @@ static int dvb_usb_lme2510_debug;
} while (0)
#define deb_info(level, args...) lme_debug(dvb_usb_lme2510_debug, level, args)
#define debug_data_snipet(level, name, p) \
- deb_info(level, name" (%02x%02x%02x%02x%02x%02x%02x%02x)", \
- *p, *(p+1), *(p+2), *(p+3), *(p+4), \
- *(p+5), *(p+6), *(p+7));
+ deb_info(level, name" (%8phN)", p);
#define info(args...) pr_info(DVB_USB_LOG_PREFIX": "args)
module_param_named(debug, dvb_usb_lme2510_debug, int, 0644);
@@ -315,7 +309,7 @@ static void lme2510_int_response(struct urb *lme_urb)
{
struct dvb_usb_adapter *adap = lme_urb->context;
struct lme2510_state *st = adap_to_priv(adap);
- static u8 *ibuf, *rbuf;
+ u8 *ibuf, *rbuf;
int i = 0, offset;
u32 key;
u8 signal_lock = 0;
@@ -1002,8 +996,9 @@ static int lme_name(struct dvb_usb_adapter *adap)
struct dvb_usb_device *d = adap_to_d(adap);
struct lme2510_state *st = adap_to_priv(adap);
const char *desc = d->name;
- char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395",
- " SHARP:BS2F7HZ0194", " RS2000"};
+ static const char * const fe_name[] = {
+ "", " LG TDQY-P001F", " SHARP:BS2F7HZ7395",
+ " SHARP:BS2F7HZ0194", " RS2000"};
char *name = adap->fe[0]->ops.info.name;
strlcpy(name, desc, 128);
@@ -1124,7 +1119,7 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
{
struct dvb_usb_device *d = adap_to_d(adap);
struct lme2510_state *st = adap_to_priv(adap);
- char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA", "RS2000"};
+ static const char * const tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA", "RS2000"};
int ret = 0;
switch (st->tuner_config) {
@@ -1178,10 +1173,7 @@ static int lme2510_powerup(struct dvb_usb_device *d, int onoff)
mutex_lock(&d->i2c_mutex);
- if (onoff)
- ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
- else
- ret = lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
+ ret = lme2510_usb_talk(d, onoff ? lnb_on : lnb_off, len, rbuf, rlen);
st->i2c_talk_onoff = 1;
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
index 639e156e0c1b..f0ed37da73d4 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "mxl111sf-demod.h"
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h
index e6eae9d88e9f..9cb4972ce7a3 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.h
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __MXL111SF_DEMOD_H__
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c
index 2180c13a6dcc..c66861c9342b 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.c
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "mxl111sf-gpio.h"
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h
index 16fa4d4daf88..af2c7bc8f301 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-gpio.h
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _DVB_USB_MXL111SF_GPIO_H_
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c
index 6427137a09ef..ffb49c28b15a 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.c
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "mxl111sf-i2c.h"
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h
index c486fe02f018..28877c7a8175 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-i2c.h
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _DVB_USB_MXL111SF_I2C_H_
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c
index 5b0191178f9f..ffb6e7c72f57 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.c
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "mxl111sf-phy.h"
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h
index 25aa4a1ea755..0a61e8a56584 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-phy.h
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _DVB_USB_MXL111SF_PHY_H_
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h
index 1f4bfbcdbabb..ad3f806dcc7a 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-reg.h
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _DVB_USB_MXL111SF_REG_H_
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
index f84bef6034dc..240d736bf1bb 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "mxl111sf-tuner.h"
diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
index e96d9a444ed1..11ea07a73271 100644
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.h
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __MXL111SF_TUNER_H__
diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
index c583c638e468..e16ca07acf1d 100644
--- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
+++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c
@@ -1778,7 +1778,7 @@ static int rtl2832u_get_rc_config(struct dvb_usb_device *d,
/* load empty to enable rc */
if (!rc->map_name)
rc->map_name = RC_MAP_EMPTY;
- rc->allowed_protos = RC_BIT_ALL;
+ rc->allowed_protos = RC_BIT_ALL_IR_DECODER;
rc->driver_type = RC_DRIVER_IR_RAW;
rc->query = rtl2832u_rc_query;
rc->interval = 200;
diff --git a/drivers/media/usb/dvb-usb-v2/zd1301.c b/drivers/media/usb/dvb-usb-v2/zd1301.c
new file mode 100644
index 000000000000..d1eb4b7bc051
--- /dev/null
+++ b/drivers/media/usb/dvb-usb-v2/zd1301.c
@@ -0,0 +1,298 @@
+/*
+ * ZyDAS ZD1301 driver (USB interface)
+ *
+ * Copyright (C) 2015 Antti Palosaari <crope@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "dvb_usb.h"
+#include "zd1301_demod.h"
+#include "mt2060.h"
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+struct zd1301_dev {
+ #define BUF_LEN 8
+ u8 buf[BUF_LEN]; /* bulk USB control message */
+ struct zd1301_demod_platform_data demod_pdata;
+ struct mt2060_platform_data mt2060_pdata;
+ struct platform_device *platform_device_demod;
+ struct i2c_client *i2c_client_tuner;
+};
+
+static int zd1301_ctrl_msg(struct dvb_usb_device *d, const u8 *wbuf,
+ unsigned int wlen, u8 *rbuf, unsigned int rlen)
+{
+ struct zd1301_dev *dev = d_to_priv(d);
+ struct usb_interface *intf = d->intf;
+ int ret, actual_length;
+
+ mutex_lock(&d->usb_mutex);
+
+ memcpy(&dev->buf, wbuf, wlen);
+
+ dev_dbg(&intf->dev, ">>> %*ph\n", wlen, dev->buf);
+
+ ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev, 0x04), dev->buf,
+ wlen, &actual_length, 1000);
+ if (ret) {
+ dev_err(&intf->dev, "1st usb_bulk_msg() failed %d\n", ret);
+ goto err_mutex_unlock;
+ }
+
+ if (rlen) {
+ ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 0x83),
+ dev->buf, rlen, &actual_length, 1000);
+ if (ret) {
+ dev_err(&intf->dev,
+ "2nd usb_bulk_msg() failed %d\n", ret);
+ goto err_mutex_unlock;
+ }
+
+ dev_dbg(&intf->dev, "<<< %*ph\n", actual_length, dev->buf);
+
+ if (actual_length != rlen) {
+ /*
+ * Chip replies often with 3 byte len stub. On that case
+ * we have to query new reply.
+ */
+ dev_dbg(&intf->dev, "repeating reply message\n");
+
+ ret = usb_bulk_msg(d->udev,
+ usb_rcvbulkpipe(d->udev, 0x83),
+ dev->buf, rlen, &actual_length,
+ 1000);
+ if (ret) {
+ dev_err(&intf->dev,
+ "3rd usb_bulk_msg() failed %d\n", ret);
+ goto err_mutex_unlock;
+ }
+
+ dev_dbg(&intf->dev,
+ "<<< %*ph\n", actual_length, dev->buf);
+ }
+
+ memcpy(rbuf, dev->buf, rlen);
+ }
+
+err_mutex_unlock:
+ mutex_unlock(&d->usb_mutex);
+ return ret;
+}
+
+static int zd1301_demod_wreg(void *reg_priv, u16 reg, u8 val)
+{
+ struct dvb_usb_device *d = reg_priv;
+ struct usb_interface *intf = d->intf;
+ int ret;
+ u8 buf[7] = {0x07, 0x00, 0x03, 0x01,
+ (reg >> 0) & 0xff, (reg >> 8) & 0xff, val};
+
+ ret = zd1301_ctrl_msg(d, buf, 7, NULL, 0);
+ if (ret)
+ goto err;
+
+ return 0;
+err:
+ dev_dbg(&intf->dev, "failed=%d\n", ret);
+ return ret;
+}
+
+static int zd1301_demod_rreg(void *reg_priv, u16 reg, u8 *val)
+{
+ struct dvb_usb_device *d = reg_priv;
+ struct usb_interface *intf = d->intf;
+ int ret;
+ u8 buf[7] = {0x07, 0x00, 0x04, 0x01,
+ (reg >> 0) & 0xff, (reg >> 8) & 0xff, 0};
+
+ ret = zd1301_ctrl_msg(d, buf, 7, buf, 7);
+ if (ret)
+ goto err;
+
+ *val = buf[6];
+
+ return 0;
+err:
+ dev_dbg(&intf->dev, "failed=%d\n", ret);
+ return ret;
+}
+
+static int zd1301_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct zd1301_dev *dev = adap_to_priv(adap);
+ struct usb_interface *intf = d->intf;
+ struct platform_device *pdev;
+ struct i2c_client *client;
+ struct i2c_board_info board_info;
+ struct i2c_adapter *adapter;
+ struct dvb_frontend *frontend;
+ int ret;
+
+ dev_dbg(&intf->dev, "\n");
+
+ /* Add platform demod */
+ dev->demod_pdata.reg_priv = d;
+ dev->demod_pdata.reg_read = zd1301_demod_rreg;
+ dev->demod_pdata.reg_write = zd1301_demod_wreg;
+ request_module("%s", "zd1301_demod");
+ pdev = platform_device_register_data(&intf->dev,
+ "zd1301_demod",
+ PLATFORM_DEVID_AUTO,
+ &dev->demod_pdata,
+ sizeof(dev->demod_pdata));
+ if (IS_ERR(pdev)) {
+ ret = PTR_ERR(pdev);
+ goto err;
+ }
+ if (!pdev->dev.driver) {
+ ret = -ENODEV;
+ goto err;
+ }
+ if (!try_module_get(pdev->dev.driver->owner)) {
+ ret = -ENODEV;
+ goto err_platform_device_unregister;
+ }
+
+ adapter = zd1301_demod_get_i2c_adapter(pdev);
+ frontend = zd1301_demod_get_dvb_frontend(pdev);
+ if (!adapter || !frontend) {
+ ret = -ENODEV;
+ goto err_module_put_demod;
+ }
+
+ /* Add I2C tuner */
+ dev->mt2060_pdata.i2c_write_max = 9;
+ dev->mt2060_pdata.dvb_frontend = frontend;
+ memset(&board_info, 0, sizeof(board_info));
+ strlcpy(board_info.type, "mt2060", I2C_NAME_SIZE);
+ board_info.addr = 0x60;
+ board_info.platform_data = &dev->mt2060_pdata;
+ request_module("%s", "mt2060");
+ client = i2c_new_device(adapter, &board_info);
+ if (!client || !client->dev.driver) {
+ ret = -ENODEV;
+ goto err_module_put_demod;
+ }
+ if (!try_module_get(client->dev.driver->owner)) {
+ ret = -ENODEV;
+ goto err_i2c_unregister_device;
+ }
+
+ dev->platform_device_demod = pdev;
+ dev->i2c_client_tuner = client;
+ adap->fe[0] = frontend;
+
+ return 0;
+err_i2c_unregister_device:
+ i2c_unregister_device(client);
+err_module_put_demod:
+ module_put(pdev->dev.driver->owner);
+err_platform_device_unregister:
+ platform_device_unregister(pdev);
+err:
+ dev_dbg(&intf->dev, "failed=%d\n", ret);
+ return ret;
+}
+
+static int zd1301_frontend_detach(struct dvb_usb_adapter *adap)
+{
+ struct dvb_usb_device *d = adap_to_d(adap);
+ struct zd1301_dev *dev = d_to_priv(d);
+ struct usb_interface *intf = d->intf;
+ struct platform_device *pdev;
+ struct i2c_client *client;
+
+ dev_dbg(&intf->dev, "\n");
+
+ client = dev->i2c_client_tuner;
+ pdev = dev->platform_device_demod;
+
+ /* Remove I2C tuner */
+ if (client) {
+ module_put(client->dev.driver->owner);
+ i2c_unregister_device(client);
+ }
+
+ /* Remove platform demod */
+ if (pdev) {
+ module_put(pdev->dev.driver->owner);
+ platform_device_unregister(pdev);
+ }
+
+ return 0;
+}
+
+static int zd1301_streaming_ctrl(struct dvb_frontend *fe, int onoff)
+{
+ struct dvb_usb_device *d = fe_to_d(fe);
+ struct usb_interface *intf = d->intf;
+ int ret;
+ u8 buf[3] = {0x03, 0x00, onoff ? 0x07 : 0x08};
+
+ dev_dbg(&intf->dev, "onoff=%d\n", onoff);
+
+ ret = zd1301_ctrl_msg(d, buf, 3, NULL, 0);
+ if (ret)
+ goto err;
+
+ return 0;
+err:
+ dev_dbg(&intf->dev, "failed=%d\n", ret);
+ return ret;
+}
+
+static const struct dvb_usb_device_properties zd1301_props = {
+ .driver_name = KBUILD_MODNAME,
+ .owner = THIS_MODULE,
+ .adapter_nr = adapter_nr,
+ .size_of_priv = sizeof(struct zd1301_dev),
+
+ .frontend_attach = zd1301_frontend_attach,
+ .frontend_detach = zd1301_frontend_detach,
+ .streaming_ctrl = zd1301_streaming_ctrl,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .stream = DVB_USB_STREAM_BULK(0x81, 6, 21 * 188),
+ },
+ },
+};
+
+static const struct usb_device_id zd1301_id_table[] = {
+ {DVB_USB_DEVICE(USB_VID_ZYDAS, 0x13a1, &zd1301_props,
+ "ZyDAS ZD1301 reference design", NULL)},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, zd1301_id_table);
+
+/* Usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver zd1301_usb_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = zd1301_id_table,
+ .probe = dvb_usbv2_probe,
+ .disconnect = dvb_usbv2_disconnect,
+ .suspend = dvb_usbv2_suspend,
+ .resume = dvb_usbv2_resume,
+ .reset_resume = dvb_usbv2_reset_resume,
+ .no_dynamic_id = 1,
+ .soft_unbind = 1,
+};
+module_usb_driver(zd1301_usb_driver);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("ZyDAS ZD1301 driver");
+MODULE_LICENSE("GPL");