Enable Sony CXD2837ER slave demon on the Astrometa DVB-T2, known as the 2018 update. Originally based on the patch by kapitanf at https://github.com/torvalds/linux/pull/567, it was not quite right. This is more correct, but probably still wrong. I'm not a kernel dev, but someone may be better positioned to handle the niceties. diff --git a/drivers/media/usb/dvb-usb-v2/Kconfig b/drivers/media/usb/dvb-usb-v2/Kconfig index df4412245a8a..d44ddd5ee29e 100644 --- a/drivers/media/usb/dvb-usb-v2/Kconfig +++ b/drivers/media/usb/dvb-usb-v2/Kconfig @@ -137,6 +137,7 @@ config DVB_USB_RTL28XXU select DVB_RTL2832 select DVB_RTL2832_SDR if (MEDIA_SUBDRV_AUTOSELECT && MEDIA_SDR_SUPPORT) select DVB_SI2168 if MEDIA_SUBDRV_AUTOSELECT + select DVB_CXD2841ER if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_E4000 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_FC0012 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_FC0013 if MEDIA_SUBDRV_AUTOSELECT diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index a970224a94bd..db4f4da43781 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -386,6 +386,7 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) struct rtl28xxu_req req_mn88473 = {0xff38, CMD_I2C_RD, 1, buf}; struct rtl28xxu_req req_si2157 = {0x00c0, CMD_I2C_RD, 1, buf}; struct rtl28xxu_req req_si2168 = {0x00c8, CMD_I2C_RD, 1, buf}; + struct rtl28xxu_req req_cxd2837er = {0x68d8, CMD_I2C_RD, 1, buf}; dev_dbg(&d->intf->dev, "\n"); @@ -567,6 +568,13 @@ static int rtl2832u_read_config(struct dvb_usb_device *d) dev->slave_demod = SLAVE_DEMOD_MN88473; goto demod_found; } + + ret = rtl28xxu_ctrl_msg(d, &req_cxd2837er); + if (ret == 0 && buf[0] == 0x03) { + dev_dbg(&d->intf->dev, "CXD2837ER found"); + dev->slave_demod = SLAVE_DEMOD_CXD2841ER; + goto demod_found; + } } if (dev->tuner == TUNER_RTL2832_SI2157) { /* check Si2168 ID register; reg=c8 val=80 */ @@ -988,6 +996,27 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap) goto err_slave_demod_failed; } + dev->i2c_client_slave_demod = client; + } else if (dev->slave_demod == SLAVE_DEMOD_CXD2841ER) { + struct cxd2841er_config cxd2837er_config = {}; + cxd2837er_config.i2c_addr = 0xd8; + cxd2837er_config.xtal = SONY_XTAL_20500; + cxd2837er_config.flags = CXD2841ER_AUTO_IFHZ | CXD2841ER_EARLY_TUNE | + CXD2841ER_NO_WAIT_LOCK | CXD2841ER_NO_AGCNEG | + CXD2841ER_TSBITS | CXD2841ER_TS_SERIAL; + + adap->fe[1] = dvb_attach( cxd2841er_attach_t_c, &cxd2837er_config, &d->i2c_adap ); + if (!adap->fe[1]) { + dev_err(&d->intf->dev, "CXD2837ER attach failed!\n"); + return -ENODEV; + } + + if (!try_module_get(client->dev.driver->owner)) { + i2c_unregister_device(client); + dev->slave_demod = SLAVE_DEMOD_NONE; + goto err_slave_demod_failed; + } + dev->i2c_client_slave_demod = client; } else { struct si2168_config si2168_config = {}; @@ -1046,10 +1075,14 @@ static int rtl28xxu_frontend_detach(struct dvb_usb_adapter *adap) dev_dbg(&d->intf->dev, "\n"); /* remove I2C slave demod */ - client = dev->i2c_client_slave_demod; - if (client) { - module_put(client->dev.driver->owner); - i2c_unregister_device(client); + if (dev->slave_demod == SLAVE_DEMOD_CXD2841ER) { + dev_info(&d->intf->dev,"Sony CXD2837ER detached automatically."); + } else { + client = dev->i2c_client_slave_demod; + if (client) { + module_put(client->dev.driver->owner); + i2c_unregister_device(client); + } } /* remove I2C demod */ diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h index 138062960a73..5a615d73fc34 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.h +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.h @@ -43,6 +43,7 @@ #include "r820t.h" #include "si2168.h" #include "si2157.h" +#include "cxd2841er.h" /* * USB commands @@ -87,7 +88,8 @@ struct rtl28xxu_dev { #define SLAVE_DEMOD_MN88472 1 #define SLAVE_DEMOD_MN88473 2 #define SLAVE_DEMOD_SI2168 3 - unsigned int slave_demod:2; + #define SLAVE_DEMOD_CXD2841ER 4 + unsigned int slave_demod:3; union { struct rtl2830_platform_data rtl2830_platform_data; struct rtl2832_platform_data rtl2832_platform_data;