mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media update from Mauro Carvalho Chehab: - OF documentation and patches at core and drivers, to be used by for embedded media systems - some I2C drivers used on go7007 were rewritten/promoted from staging: sony-btf-mpx, tw2804, tw9903, tw9906, wis-ov7640, wis-uda1342 - add fimc-is driver (Exynos) - add a new radio driver: radio-si476x - add a two new tuners: r820t and tuner_it913x - split camera code on em28xx driver and add more models - the cypress firmware load is used outside dvb usb drivers. So, move it to a common directory to make easier to re-use it - siano media driver updated to work with sms2270 devices - several work done in order to promote go7007 and solo6x1x out of staging (still, there are some pending issues) - several API compliance fixes at v4l2 drivers that don't behave as expected - as usual, lots of driver fixes, improvements, cleanups and new device addition at the existing drivers. * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (831 commits) [media] cx88: make core less verbose [media] em28xx: fix oops at em28xx_dvb_bus_ctrl() [media] s5c73m3: fix indentation of the help section in Kconfig [media] cx25821-alsa: get rid of a __must_check warning [media] cx25821-video: declare cx25821_vidioc_s_std as static [media] cx25821-video: remove maxw from cx25821_vidioc_try_fmt_vid_cap [media] r820t: Remove a warning for an unused value [media] dib0090: Fix a warning at dib0090_set_EFUSE [media] dib8000: fix a warning [media] dib8000: Fix sub-channel range [media] dib8000: store dtv_property_cache in a temp var [media] dib8000: warning fix: declare internal functions as static [media] r820t: quiet gcc warning on n_ring [media] r820t: memory leak in release() [media] r820t: precendence bug in r820t_xtal_check() [media] videodev2.h: Remove the unused old V4L1 buffer types [media] anysee: Grammar s/report the/report to/ [media] anysee: Initialize ret = 0 in anysee_frontend_attach() [media] media: videobuf2: fix the length check for mmap [media] em28xx: save isoc endpoint number for DVB only if endpoint has alt settings with xMaxPacketSize != 0 ...
This commit is contained in:
commit
240c3c3424
653 changed files with 40821 additions and 28643 deletions
|
|
@ -16,6 +16,10 @@ config VIDEO_TVEEPROM
|
|||
tristate
|
||||
depends on I2C
|
||||
|
||||
config CYPRESS_FIRMWARE
|
||||
tristate "Cypress firmware helper routines"
|
||||
depends on USB
|
||||
|
||||
source "drivers/media/common/b2c2/Kconfig"
|
||||
source "drivers/media/common/saa7146/Kconfig"
|
||||
source "drivers/media/common/siano/Kconfig"
|
||||
|
|
|
|||
|
|
@ -2,3 +2,4 @@ obj-y += b2c2/ saa7146/ siano/
|
|||
obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
|
||||
obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
|
||||
obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
|
||||
obj-$(CONFIG_CYPRESS_FIRMWARE) += cypress_firmware.o
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ static int skystar2_rev27_attach(struct flexcop_device *fc,
|
|||
/* enable no_base_addr - no repeated start when reading */
|
||||
fc->fc_i2c_adap[2].no_base_addr = 1;
|
||||
if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
|
||||
0x08, 1, 1)) {
|
||||
0x08, 1, 1, false)) {
|
||||
err("ISL6421 could NOT be attached");
|
||||
goto fail_isl;
|
||||
}
|
||||
|
|
@ -391,7 +391,7 @@ static int skystar2_rev28_attach(struct flexcop_device *fc,
|
|||
|
||||
fc->fc_i2c_adap[2].no_base_addr = 1;
|
||||
if (!dvb_attach(isl6421_attach, fc->fe, &fc->fc_i2c_adap[2].i2c_adap,
|
||||
0x08, 0, 0)) {
|
||||
0x08, 0, 0, false)) {
|
||||
err("ISL6421 could NOT be attached");
|
||||
fc->fc_i2c_adap[2].no_base_addr = 0;
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "dvb_usb.h"
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/firmware.h>
|
||||
#include "cypress_firmware.h"
|
||||
|
||||
struct usb_cypress_controller {
|
||||
|
|
@ -30,75 +33,12 @@ static const struct usb_cypress_controller cypress[] = {
|
|||
static int usb_cypress_writemem(struct usb_device *udev, u16 addr, u8 *data,
|
||||
u8 len)
|
||||
{
|
||||
dvb_usb_dbg_usb_control_msg(udev,
|
||||
0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len);
|
||||
|
||||
return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
|
||||
0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5000);
|
||||
}
|
||||
|
||||
int usbv2_cypress_load_firmware(struct usb_device *udev,
|
||||
const struct firmware *fw, int type)
|
||||
{
|
||||
struct hexline *hx;
|
||||
int ret, pos = 0;
|
||||
|
||||
hx = kmalloc(sizeof(struct hexline), GFP_KERNEL);
|
||||
if (!hx) {
|
||||
dev_err(&udev->dev, "%s: kmalloc() failed\n", KBUILD_MODNAME);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* stop the CPU */
|
||||
hx->data[0] = 1;
|
||||
ret = usb_cypress_writemem(udev, cypress[type].cs_reg, hx->data, 1);
|
||||
if (ret != 1) {
|
||||
dev_err(&udev->dev, "%s: CPU stop failed=%d\n",
|
||||
KBUILD_MODNAME, ret);
|
||||
ret = -EIO;
|
||||
goto err_kfree;
|
||||
}
|
||||
|
||||
/* write firmware to memory */
|
||||
for (;;) {
|
||||
ret = dvb_usbv2_get_hexline(fw, hx, &pos);
|
||||
if (ret < 0)
|
||||
goto err_kfree;
|
||||
else if (ret == 0)
|
||||
break;
|
||||
|
||||
ret = usb_cypress_writemem(udev, hx->addr, hx->data, hx->len);
|
||||
if (ret < 0) {
|
||||
goto err_kfree;
|
||||
} else if (ret != hx->len) {
|
||||
dev_err(&udev->dev, "%s: error while transferring " \
|
||||
"firmware (transferred size=%d, " \
|
||||
"block size=%d)\n",
|
||||
KBUILD_MODNAME, ret, hx->len);
|
||||
ret = -EIO;
|
||||
goto err_kfree;
|
||||
}
|
||||
}
|
||||
|
||||
/* start the CPU */
|
||||
hx->data[0] = 0;
|
||||
ret = usb_cypress_writemem(udev, cypress[type].cs_reg, hx->data, 1);
|
||||
if (ret != 1) {
|
||||
dev_err(&udev->dev, "%s: CPU start failed=%d\n",
|
||||
KBUILD_MODNAME, ret);
|
||||
ret = -EIO;
|
||||
goto err_kfree;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
err_kfree:
|
||||
kfree(hx);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(usbv2_cypress_load_firmware);
|
||||
|
||||
int dvb_usbv2_get_hexline(const struct firmware *fw, struct hexline *hx,
|
||||
int *pos)
|
||||
static int cypress_get_hexline(const struct firmware *fw,
|
||||
struct hexline *hx, int *pos)
|
||||
{
|
||||
u8 *b = (u8 *) &fw->data[*pos];
|
||||
int data_offs = 4;
|
||||
|
|
@ -127,7 +67,65 @@ int dvb_usbv2_get_hexline(const struct firmware *fw, struct hexline *hx,
|
|||
|
||||
return *pos;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_usbv2_get_hexline);
|
||||
|
||||
int cypress_load_firmware(struct usb_device *udev,
|
||||
const struct firmware *fw, int type)
|
||||
{
|
||||
struct hexline *hx;
|
||||
int ret, pos = 0;
|
||||
|
||||
hx = kmalloc(sizeof(struct hexline), GFP_KERNEL);
|
||||
if (!hx) {
|
||||
dev_err(&udev->dev, "%s: kmalloc() failed\n", KBUILD_MODNAME);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* stop the CPU */
|
||||
hx->data[0] = 1;
|
||||
ret = usb_cypress_writemem(udev, cypress[type].cs_reg, hx->data, 1);
|
||||
if (ret != 1) {
|
||||
dev_err(&udev->dev, "%s: CPU stop failed=%d\n",
|
||||
KBUILD_MODNAME, ret);
|
||||
ret = -EIO;
|
||||
goto err_kfree;
|
||||
}
|
||||
|
||||
/* write firmware to memory */
|
||||
for (;;) {
|
||||
ret = cypress_get_hexline(fw, hx, &pos);
|
||||
if (ret < 0)
|
||||
goto err_kfree;
|
||||
else if (ret == 0)
|
||||
break;
|
||||
|
||||
ret = usb_cypress_writemem(udev, hx->addr, hx->data, hx->len);
|
||||
if (ret < 0) {
|
||||
goto err_kfree;
|
||||
} else if (ret != hx->len) {
|
||||
dev_err(&udev->dev,
|
||||
"%s: error while transferring firmware (transferred size=%d, block size=%d)\n",
|
||||
KBUILD_MODNAME, ret, hx->len);
|
||||
ret = -EIO;
|
||||
goto err_kfree;
|
||||
}
|
||||
}
|
||||
|
||||
/* start the CPU */
|
||||
hx->data[0] = 0;
|
||||
ret = usb_cypress_writemem(udev, cypress[type].cs_reg, hx->data, 1);
|
||||
if (ret != 1) {
|
||||
dev_err(&udev->dev, "%s: CPU start failed=%d\n",
|
||||
KBUILD_MODNAME, ret);
|
||||
ret = -EIO;
|
||||
goto err_kfree;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
err_kfree:
|
||||
kfree(hx);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(cypress_load_firmware);
|
||||
|
||||
MODULE_AUTHOR("Antti Palosaari <[email protected]>");
|
||||
MODULE_DESCRIPTION("Cypress firmware download");
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
/* cypress_firmware.h is part of the DVB USB library.
|
||||
*
|
||||
/*
|
||||
* Copyright (C) 2004-6 Patrick Boettcher (patrick.boettcher@desy.de)
|
||||
* see dvb-usb-init.c for copyright information.
|
||||
*
|
||||
|
|
@ -23,9 +22,7 @@ struct hexline {
|
|||
u8 data[255];
|
||||
u8 chk;
|
||||
};
|
||||
extern int usbv2_cypress_load_firmware(struct usb_device *,
|
||||
const struct firmware *, int);
|
||||
extern int dvb_usbv2_get_hexline(const struct firmware *,
|
||||
struct hexline *, int *);
|
||||
|
||||
int cypress_load_firmware(struct usb_device *, const struct firmware *, int);
|
||||
|
||||
#endif
|
||||
|
|
@ -832,7 +832,7 @@ static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm)
|
|||
}
|
||||
*/
|
||||
|
||||
static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
|
||||
static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id id)
|
||||
{
|
||||
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
|
||||
struct saa7146_vv *vv = dev->vv_data;
|
||||
|
|
@ -856,7 +856,7 @@ static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
|
|||
}
|
||||
|
||||
for (i = 0; i < dev->ext_vv_data->num_stds; i++)
|
||||
if (*id & dev->ext_vv_data->stds[i].id)
|
||||
if (id & dev->ext_vv_data->stds[i].id)
|
||||
break;
|
||||
if (i != dev->ext_vv_data->num_stds) {
|
||||
vv->standard = &dev->ext_vv_data->stds[i];
|
||||
|
|
|
|||
|
|
@ -17,3 +17,15 @@ config SMS_SIANO_RC
|
|||
default y
|
||||
---help---
|
||||
Choose Y to select Remote Controller support for Siano driver.
|
||||
|
||||
config SMS_SIANO_DEBUGFS
|
||||
bool "Enable debugfs for smsdvb"
|
||||
depends on SMS_SIANO_MDTV
|
||||
depends on DEBUG_FS
|
||||
depends on SMS_USB_DRV
|
||||
---help---
|
||||
Choose Y to enable visualizing a dump of the frontend
|
||||
statistics response packets via debugfs. Currently, works
|
||||
only with Siano USB devices.
|
||||
|
||||
Useful only for developers. In doubt, say N.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o
|
||||
smsdvb-objs := smsdvb-main.o
|
||||
|
||||
obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o
|
||||
|
||||
|
|
@ -6,6 +7,10 @@ ifeq ($(CONFIG_SMS_SIANO_RC),y)
|
|||
smsmdtv-objs += smsir.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SMS_SIANO_DEBUGFS),y)
|
||||
smsdvb-objs += smsdvb-debugfs.o
|
||||
endif
|
||||
|
||||
ccflags-y += -Idrivers/media/dvb-core
|
||||
ccflags-y += $(extra-cflags-y) $(extra-cflags-m)
|
||||
|
||||
|
|
|
|||
|
|
@ -28,43 +28,53 @@ MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
|
|||
static struct sms_board sms_boards[] = {
|
||||
[SMS_BOARD_UNKNOWN] = {
|
||||
.name = "Unknown board",
|
||||
.type = SMS_UNKNOWN_TYPE,
|
||||
.default_mode = DEVICE_MODE_NONE,
|
||||
},
|
||||
[SMS1XXX_BOARD_SIANO_STELLAR] = {
|
||||
.name = "Siano Stellar Digital Receiver",
|
||||
.type = SMS_STELLAR,
|
||||
.default_mode = DEVICE_MODE_DVBT_BDA,
|
||||
},
|
||||
[SMS1XXX_BOARD_SIANO_NOVA_A] = {
|
||||
.name = "Siano Nova A Digital Receiver",
|
||||
.type = SMS_NOVA_A0,
|
||||
.default_mode = DEVICE_MODE_DVBT_BDA,
|
||||
},
|
||||
[SMS1XXX_BOARD_SIANO_NOVA_B] = {
|
||||
.name = "Siano Nova B Digital Receiver",
|
||||
.type = SMS_NOVA_B0,
|
||||
.default_mode = DEVICE_MODE_DVBT_BDA,
|
||||
},
|
||||
[SMS1XXX_BOARD_SIANO_VEGA] = {
|
||||
.name = "Siano Vega Digital Receiver",
|
||||
.type = SMS_VEGA,
|
||||
.default_mode = DEVICE_MODE_CMMB,
|
||||
},
|
||||
[SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT] = {
|
||||
.name = "Hauppauge Catamount",
|
||||
.type = SMS_STELLAR,
|
||||
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-stellar-dvbt-01.fw",
|
||||
.fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_STELLAR,
|
||||
.default_mode = DEVICE_MODE_DVBT_BDA,
|
||||
},
|
||||
[SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A] = {
|
||||
.name = "Hauppauge Okemo-A",
|
||||
.type = SMS_NOVA_A0,
|
||||
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-a-dvbt-01.fw",
|
||||
.fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_NOVA_A,
|
||||
.default_mode = DEVICE_MODE_DVBT_BDA,
|
||||
},
|
||||
[SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B] = {
|
||||
.name = "Hauppauge Okemo-B",
|
||||
.type = SMS_NOVA_B0,
|
||||
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-nova-b-dvbt-01.fw",
|
||||
.fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_NOVA_B,
|
||||
.default_mode = DEVICE_MODE_DVBT_BDA,
|
||||
},
|
||||
[SMS1XXX_BOARD_HAUPPAUGE_WINDHAM] = {
|
||||
.name = "Hauppauge WinTV MiniStick",
|
||||
.type = SMS_NOVA_B0,
|
||||
.fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
|
||||
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
|
||||
.fw[DEVICE_MODE_ISDBT_BDA] = SMS_FW_ISDBT_HCW_55XXX,
|
||||
.fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_HCW_55XXX,
|
||||
.default_mode = DEVICE_MODE_DVBT_BDA,
|
||||
.rc_codes = RC_MAP_HAUPPAUGE,
|
||||
.board_cfg.leds_power = 26,
|
||||
.board_cfg.led0 = 27,
|
||||
|
|
@ -77,7 +87,8 @@ static struct sms_board sms_boards[] = {
|
|||
[SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD] = {
|
||||
.name = "Hauppauge WinTV MiniCard",
|
||||
.type = SMS_NOVA_B0,
|
||||
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
|
||||
.fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_HCW_55XXX,
|
||||
.default_mode = DEVICE_MODE_DVBT_BDA,
|
||||
.lna_ctrl = 29,
|
||||
.board_cfg.foreign_lna0_ctrl = 29,
|
||||
.rf_switch = 17,
|
||||
|
|
@ -86,18 +97,65 @@ static struct sms_board sms_boards[] = {
|
|||
[SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
|
||||
.name = "Hauppauge WinTV MiniCard",
|
||||
.type = SMS_NOVA_B0,
|
||||
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
|
||||
.fw[DEVICE_MODE_DVBT_BDA] = SMS_FW_DVBT_HCW_55XXX,
|
||||
.default_mode = DEVICE_MODE_DVBT_BDA,
|
||||
.lna_ctrl = -1,
|
||||
},
|
||||
[SMS1XXX_BOARD_SIANO_NICE] = {
|
||||
/* 11 */
|
||||
.name = "Siano Nice Digital Receiver",
|
||||
.type = SMS_NOVA_B0,
|
||||
.default_mode = DEVICE_MODE_DVBT_BDA,
|
||||
},
|
||||
[SMS1XXX_BOARD_SIANO_VENICE] = {
|
||||
/* 12 */
|
||||
.name = "Siano Venice Digital Receiver",
|
||||
.type = SMS_VEGA,
|
||||
.default_mode = DEVICE_MODE_CMMB,
|
||||
},
|
||||
[SMS1XXX_BOARD_SIANO_STELLAR_ROM] = {
|
||||
.name = "Siano Stellar Digital Receiver ROM",
|
||||
.type = SMS_STELLAR,
|
||||
.default_mode = DEVICE_MODE_DVBT_BDA,
|
||||
.intf_num = 1,
|
||||
},
|
||||
[SMS1XXX_BOARD_ZTE_DVB_DATA_CARD] = {
|
||||
.name = "ZTE Data Card Digital Receiver",
|
||||
.type = SMS_NOVA_B0,
|
||||
.default_mode = DEVICE_MODE_DVBT_BDA,
|
||||
.intf_num = 5,
|
||||
.mtu = 15792,
|
||||
},
|
||||
[SMS1XXX_BOARD_ONDA_MDTV_DATA_CARD] = {
|
||||
.name = "ONDA Data Card Digital Receiver",
|
||||
.type = SMS_NOVA_B0,
|
||||
.default_mode = DEVICE_MODE_DVBT_BDA,
|
||||
.intf_num = 6,
|
||||
.mtu = 15792,
|
||||
},
|
||||
[SMS1XXX_BOARD_SIANO_MING] = {
|
||||
.name = "Siano Ming Digital Receiver",
|
||||
.type = SMS_MING,
|
||||
.default_mode = DEVICE_MODE_CMMB,
|
||||
},
|
||||
[SMS1XXX_BOARD_SIANO_PELE] = {
|
||||
.name = "Siano Pele Digital Receiver",
|
||||
.type = SMS_PELE,
|
||||
.default_mode = DEVICE_MODE_ISDBT_BDA,
|
||||
},
|
||||
[SMS1XXX_BOARD_SIANO_RIO] = {
|
||||
.name = "Siano Rio Digital Receiver",
|
||||
.type = SMS_RIO,
|
||||
.default_mode = DEVICE_MODE_ISDBT_BDA,
|
||||
},
|
||||
[SMS1XXX_BOARD_SIANO_DENVER_1530] = {
|
||||
.name = "Siano Denver (ATSC-M/H) Digital Receiver",
|
||||
.type = SMS_DENVER_1530,
|
||||
.default_mode = DEVICE_MODE_ATSC,
|
||||
.crystal = 2400,
|
||||
},
|
||||
[SMS1XXX_BOARD_SIANO_DENVER_2160] = {
|
||||
.name = "Siano Denver (TDMB) Digital Receiver",
|
||||
.type = SMS_DENVER_2160,
|
||||
.default_mode = DEVICE_MODE_DAB_TDMB,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -109,20 +167,21 @@ struct sms_board *sms_get_board(unsigned id)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(sms_get_board);
|
||||
static inline void sms_gpio_assign_11xx_default_led_config(
|
||||
struct smscore_gpio_config *pGpioConfig) {
|
||||
pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT;
|
||||
pGpioConfig->InputCharacteristics =
|
||||
SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL;
|
||||
pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA;
|
||||
pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS;
|
||||
pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE;
|
||||
struct smscore_config_gpio *p_gpio_config) {
|
||||
p_gpio_config->direction = SMS_GPIO_DIRECTION_OUTPUT;
|
||||
p_gpio_config->inputcharacteristics =
|
||||
SMS_GPIO_INPUTCHARACTERISTICS_NORMAL;
|
||||
p_gpio_config->outputdriving = SMS_GPIO_OUTPUTDRIVING_4mA;
|
||||
p_gpio_config->outputslewrate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS;
|
||||
p_gpio_config->pullupdown = SMS_GPIO_PULLUPDOWN_NONE;
|
||||
}
|
||||
|
||||
int sms_board_event(struct smscore_device_t *coredev,
|
||||
enum SMS_BOARD_EVENTS gevent) {
|
||||
struct smscore_gpio_config MyGpioConfig;
|
||||
enum SMS_BOARD_EVENTS gevent)
|
||||
{
|
||||
struct smscore_config_gpio my_gpio_config;
|
||||
|
||||
sms_gpio_assign_11xx_default_led_config(&MyGpioConfig);
|
||||
sms_gpio_assign_11xx_default_led_config(&my_gpio_config);
|
||||
|
||||
switch (gevent) {
|
||||
case BOARD_EVENT_POWER_INIT: /* including hotplug */
|
||||
|
|
@ -182,8 +241,8 @@ static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
|
|||
.direction = SMS_GPIO_DIRECTION_OUTPUT,
|
||||
.pullupdown = SMS_GPIO_PULLUPDOWN_NONE,
|
||||
.inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL,
|
||||
.outputslewrate = SMS_GPIO_OUTPUTSLEWRATE_FAST,
|
||||
.outputdriving = SMS_GPIO_OUTPUTDRIVING_4mA,
|
||||
.outputslewrate = SMS_GPIO_OUTPUT_SLEW_RATE_FAST,
|
||||
.outputdriving = SMS_GPIO_OUTPUTDRIVING_S_4mA,
|
||||
};
|
||||
|
||||
if (pin == 0)
|
||||
|
|
@ -293,19 +352,7 @@ EXPORT_SYMBOL_GPL(sms_board_lna_control);
|
|||
|
||||
int sms_board_load_modules(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT:
|
||||
case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
|
||||
case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
|
||||
case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
|
||||
case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
|
||||
case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
|
||||
request_module("smsdvb");
|
||||
break;
|
||||
default:
|
||||
/* do nothing */
|
||||
break;
|
||||
}
|
||||
request_module("smsdvb");
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sms_board_load_modules);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,14 @@
|
|||
#define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10
|
||||
#define SMS1XXX_BOARD_SIANO_NICE 11
|
||||
#define SMS1XXX_BOARD_SIANO_VENICE 12
|
||||
#define SMS1XXX_BOARD_SIANO_STELLAR_ROM 13
|
||||
#define SMS1XXX_BOARD_ZTE_DVB_DATA_CARD 14
|
||||
#define SMS1XXX_BOARD_ONDA_MDTV_DATA_CARD 15
|
||||
#define SMS1XXX_BOARD_SIANO_MING 16
|
||||
#define SMS1XXX_BOARD_SIANO_PELE 17
|
||||
#define SMS1XXX_BOARD_SIANO_RIO 18
|
||||
#define SMS1XXX_BOARD_SIANO_DENVER_1530 19
|
||||
#define SMS1XXX_BOARD_SIANO_DENVER_2160 20
|
||||
|
||||
struct sms_board_gpio_cfg {
|
||||
int lna_vhf_exist;
|
||||
|
|
@ -79,6 +87,12 @@ struct sms_board {
|
|||
|
||||
/* gpios */
|
||||
int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
|
||||
|
||||
char intf_num;
|
||||
int default_mode;
|
||||
unsigned int mtu;
|
||||
unsigned int crystal;
|
||||
struct sms_antenna_config_ST *antenna_config;
|
||||
};
|
||||
|
||||
struct sms_board *sms_get_board(unsigned id);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
551
drivers/media/common/siano/smsdvb-debugfs.c
Normal file
551
drivers/media/common/siano/smsdvb-debugfs.c
Normal file
|
|
@ -0,0 +1,551 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* Copyright(c) 2013 Mauro Carvalho Chehab <mchehab@redhat.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/usb.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
#include "smscoreapi.h"
|
||||
|
||||
#include "smsdvb.h"
|
||||
|
||||
static struct dentry *smsdvb_debugfs_usb_root;
|
||||
|
||||
struct smsdvb_debugfs {
|
||||
struct kref refcount;
|
||||
spinlock_t lock;
|
||||
|
||||
char stats_data[PAGE_SIZE];
|
||||
unsigned stats_count;
|
||||
bool stats_was_read;
|
||||
|
||||
wait_queue_head_t stats_queue;
|
||||
};
|
||||
|
||||
static void smsdvb_print_dvb_stats(struct smsdvb_debugfs *debug_data,
|
||||
struct sms_stats *p)
|
||||
{
|
||||
int n = 0;
|
||||
char *buf;
|
||||
|
||||
spin_lock(&debug_data->lock);
|
||||
if (debug_data->stats_count) {
|
||||
spin_unlock(&debug_data->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = debug_data->stats_data;
|
||||
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"is_rf_locked = %d\n", p->is_rf_locked);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"is_demod_locked = %d\n", p->is_demod_locked);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"is_external_lna_on = %d\n", p->is_external_lna_on);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"SNR = %d\n", p->SNR);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"ber = %d\n", p->ber);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"FIB_CRC = %d\n", p->FIB_CRC);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"ts_per = %d\n", p->ts_per);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"MFER = %d\n", p->MFER);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"RSSI = %d\n", p->RSSI);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"in_band_pwr = %d\n", p->in_band_pwr);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"carrier_offset = %d\n", p->carrier_offset);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"modem_state = %d\n", p->modem_state);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"frequency = %d\n", p->frequency);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"bandwidth = %d\n", p->bandwidth);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"transmission_mode = %d\n", p->transmission_mode);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"modem_state = %d\n", p->modem_state);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"guard_interval = %d\n", p->guard_interval);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"code_rate = %d\n", p->code_rate);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"lp_code_rate = %d\n", p->lp_code_rate);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"hierarchy = %d\n", p->hierarchy);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"constellation = %d\n", p->constellation);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"burst_size = %d\n", p->burst_size);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"burst_duration = %d\n", p->burst_duration);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"burst_cycle_time = %d\n", p->burst_cycle_time);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"calc_burst_cycle_time = %d\n",
|
||||
p->calc_burst_cycle_time);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"num_of_rows = %d\n", p->num_of_rows);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"num_of_padd_cols = %d\n", p->num_of_padd_cols);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"num_of_punct_cols = %d\n", p->num_of_punct_cols);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"error_ts_packets = %d\n", p->error_ts_packets);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"total_ts_packets = %d\n", p->total_ts_packets);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"num_of_valid_mpe_tlbs = %d\n", p->num_of_valid_mpe_tlbs);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"num_of_invalid_mpe_tlbs = %d\n", p->num_of_invalid_mpe_tlbs);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"num_of_corrected_mpe_tlbs = %d\n", p->num_of_corrected_mpe_tlbs);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"ber_error_count = %d\n", p->ber_error_count);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"ber_bit_count = %d\n", p->ber_bit_count);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"pre_ber = %d\n", p->pre_ber);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"cell_id = %d\n", p->cell_id);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"dvbh_srv_ind_hp = %d\n", p->dvbh_srv_ind_hp);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"dvbh_srv_ind_lp = %d\n", p->dvbh_srv_ind_lp);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"num_mpe_received = %d\n", p->num_mpe_received);
|
||||
|
||||
debug_data->stats_count = n;
|
||||
spin_unlock(&debug_data->lock);
|
||||
wake_up(&debug_data->stats_queue);
|
||||
}
|
||||
|
||||
static void smsdvb_print_isdb_stats(struct smsdvb_debugfs *debug_data,
|
||||
struct sms_isdbt_stats *p)
|
||||
{
|
||||
int i, n = 0;
|
||||
char *buf;
|
||||
|
||||
spin_lock(&debug_data->lock);
|
||||
if (debug_data->stats_count) {
|
||||
spin_unlock(&debug_data->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = debug_data->stats_data;
|
||||
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"statistics_type = %d\t", p->statistics_type);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"full_size = %d\n", p->full_size);
|
||||
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"is_rf_locked = %d\t\t", p->is_rf_locked);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"is_demod_locked = %d\t", p->is_demod_locked);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"is_external_lna_on = %d\n", p->is_external_lna_on);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"SNR = %d dB\t\t", p->SNR);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"RSSI = %d dBm\t\t", p->RSSI);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"in_band_pwr = %d dBm\n", p->in_band_pwr);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"carrier_offset = %d\t", p->carrier_offset);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"bandwidth = %d\t\t", p->bandwidth);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"frequency = %d Hz\n", p->frequency);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"transmission_mode = %d\t", p->transmission_mode);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"modem_state = %d\t\t", p->modem_state);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"guard_interval = %d\n", p->guard_interval);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"system_type = %d\t\t", p->system_type);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"partial_reception = %d\t", p->partial_reception);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"num_of_layers = %d\n", p->num_of_layers);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"sms_to_host_tx_errors = %d\n", p->sms_to_host_tx_errors);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (p->layer_info[i].number_of_segments < 1 ||
|
||||
p->layer_info[i].number_of_segments > 13)
|
||||
continue;
|
||||
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",
|
||||
p->layer_info[i].code_rate);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",
|
||||
p->layer_info[i].constellation);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",
|
||||
p->layer_info[i].ber);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "\tber_error_count = %-5d\t",
|
||||
p->layer_info[i].ber_error_count);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",
|
||||
p->layer_info[i].ber_bit_count);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",
|
||||
p->layer_info[i].pre_ber);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",
|
||||
p->layer_info[i].ts_per);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "\terror_ts_packets = %-5d\t",
|
||||
p->layer_info[i].error_ts_packets);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "total_ts_packets = %-5d\t",
|
||||
p->layer_info[i].total_ts_packets);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",
|
||||
p->layer_info[i].ti_ldepth_i);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"\tnumber_of_segments = %d\t",
|
||||
p->layer_info[i].number_of_segments);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",
|
||||
p->layer_info[i].tmcc_errors);
|
||||
}
|
||||
|
||||
debug_data->stats_count = n;
|
||||
spin_unlock(&debug_data->lock);
|
||||
wake_up(&debug_data->stats_queue);
|
||||
}
|
||||
|
||||
static void smsdvb_print_isdb_stats_ex(struct smsdvb_debugfs *debug_data,
|
||||
struct sms_isdbt_stats_ex *p)
|
||||
{
|
||||
int i, n = 0;
|
||||
char *buf;
|
||||
|
||||
spin_lock(&debug_data->lock);
|
||||
if (debug_data->stats_count) {
|
||||
spin_unlock(&debug_data->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
buf = debug_data->stats_data;
|
||||
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"statistics_type = %d\t", p->statistics_type);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"full_size = %d\n", p->full_size);
|
||||
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"is_rf_locked = %d\t\t", p->is_rf_locked);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"is_demod_locked = %d\t", p->is_demod_locked);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"is_external_lna_on = %d\n", p->is_external_lna_on);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"SNR = %d dB\t\t", p->SNR);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"RSSI = %d dBm\t\t", p->RSSI);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"in_band_pwr = %d dBm\n", p->in_band_pwr);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"carrier_offset = %d\t", p->carrier_offset);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"bandwidth = %d\t\t", p->bandwidth);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"frequency = %d Hz\n", p->frequency);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"transmission_mode = %d\t", p->transmission_mode);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"modem_state = %d\t\t", p->modem_state);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"guard_interval = %d\n", p->guard_interval);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"system_type = %d\t\t", p->system_type);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"partial_reception = %d\t", p->partial_reception);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"num_of_layers = %d\n", p->num_of_layers);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "segment_number = %d\t",
|
||||
p->segment_number);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "tune_bw = %d\n",
|
||||
p->tune_bw);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (p->layer_info[i].number_of_segments < 1 ||
|
||||
p->layer_info[i].number_of_segments > 13)
|
||||
continue;
|
||||
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "\nLayer %d\n", i);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "\tcode_rate = %d\t",
|
||||
p->layer_info[i].code_rate);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "constellation = %d\n",
|
||||
p->layer_info[i].constellation);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "\tber = %-5d\t",
|
||||
p->layer_info[i].ber);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "\tber_error_count = %-5d\t",
|
||||
p->layer_info[i].ber_error_count);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "ber_bit_count = %-5d\n",
|
||||
p->layer_info[i].ber_bit_count);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "\tpre_ber = %-5d\t",
|
||||
p->layer_info[i].pre_ber);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "\tts_per = %-5d\n",
|
||||
p->layer_info[i].ts_per);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "\terror_ts_packets = %-5d\t",
|
||||
p->layer_info[i].error_ts_packets);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "total_ts_packets = %-5d\t",
|
||||
p->layer_info[i].total_ts_packets);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "ti_ldepth_i = %d\n",
|
||||
p->layer_info[i].ti_ldepth_i);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n,
|
||||
"\tnumber_of_segments = %d\t",
|
||||
p->layer_info[i].number_of_segments);
|
||||
n += snprintf(&buf[n], PAGE_SIZE - n, "tmcc_errors = %d\n",
|
||||
p->layer_info[i].tmcc_errors);
|
||||
}
|
||||
|
||||
|
||||
debug_data->stats_count = n;
|
||||
spin_unlock(&debug_data->lock);
|
||||
|
||||
wake_up(&debug_data->stats_queue);
|
||||
}
|
||||
|
||||
static int smsdvb_stats_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct smsdvb_client_t *client = inode->i_private;
|
||||
struct smsdvb_debugfs *debug_data = client->debug_data;
|
||||
|
||||
kref_get(&debug_data->refcount);
|
||||
|
||||
spin_lock(&debug_data->lock);
|
||||
debug_data->stats_count = 0;
|
||||
debug_data->stats_was_read = false;
|
||||
spin_unlock(&debug_data->lock);
|
||||
|
||||
file->private_data = debug_data;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void smsdvb_debugfs_data_release(struct kref *ref)
|
||||
{
|
||||
struct smsdvb_debugfs *debug_data;
|
||||
|
||||
debug_data = container_of(ref, struct smsdvb_debugfs, refcount);
|
||||
kfree(debug_data);
|
||||
}
|
||||
|
||||
static int smsdvb_stats_wait_read(struct smsdvb_debugfs *debug_data)
|
||||
{
|
||||
int rc = 1;
|
||||
|
||||
spin_lock(&debug_data->lock);
|
||||
|
||||
if (debug_data->stats_was_read)
|
||||
goto exit;
|
||||
|
||||
rc = debug_data->stats_count;
|
||||
|
||||
exit:
|
||||
spin_unlock(&debug_data->lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static unsigned int smsdvb_stats_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
struct smsdvb_debugfs *debug_data = file->private_data;
|
||||
int rc;
|
||||
|
||||
kref_get(&debug_data->refcount);
|
||||
|
||||
poll_wait(file, &debug_data->stats_queue, wait);
|
||||
|
||||
rc = smsdvb_stats_wait_read(debug_data);
|
||||
if (rc > 0)
|
||||
rc = POLLIN | POLLRDNORM;
|
||||
|
||||
kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t smsdvb_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t nbytes, loff_t *ppos)
|
||||
{
|
||||
int rc = 0, len;
|
||||
struct smsdvb_debugfs *debug_data = file->private_data;
|
||||
|
||||
kref_get(&debug_data->refcount);
|
||||
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
rc = smsdvb_stats_wait_read(debug_data);
|
||||
if (!rc) {
|
||||
rc = -EWOULDBLOCK;
|
||||
goto ret;
|
||||
}
|
||||
} else {
|
||||
rc = wait_event_interruptible(debug_data->stats_queue,
|
||||
smsdvb_stats_wait_read(debug_data));
|
||||
if (rc < 0)
|
||||
goto ret;
|
||||
}
|
||||
|
||||
if (debug_data->stats_was_read) {
|
||||
rc = 0; /* EOF */
|
||||
goto ret;
|
||||
}
|
||||
|
||||
len = debug_data->stats_count - *ppos;
|
||||
if (len >= 0)
|
||||
rc = simple_read_from_buffer(user_buf, nbytes, ppos,
|
||||
debug_data->stats_data, len);
|
||||
else
|
||||
rc = 0;
|
||||
|
||||
if (*ppos >= debug_data->stats_count) {
|
||||
spin_lock(&debug_data->lock);
|
||||
debug_data->stats_was_read = true;
|
||||
spin_unlock(&debug_data->lock);
|
||||
}
|
||||
ret:
|
||||
kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int smsdvb_stats_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct smsdvb_debugfs *debug_data = file->private_data;
|
||||
|
||||
spin_lock(&debug_data->lock);
|
||||
debug_data->stats_was_read = true; /* return EOF to read() */
|
||||
spin_unlock(&debug_data->lock);
|
||||
wake_up_interruptible_sync(&debug_data->stats_queue);
|
||||
|
||||
kref_put(&debug_data->refcount, smsdvb_debugfs_data_release);
|
||||
file->private_data = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations debugfs_stats_ops = {
|
||||
.open = smsdvb_stats_open,
|
||||
.poll = smsdvb_stats_poll,
|
||||
.read = smsdvb_stats_read,
|
||||
.release = smsdvb_stats_release,
|
||||
.llseek = generic_file_llseek,
|
||||
};
|
||||
|
||||
/*
|
||||
* Functions used by smsdvb, in order to create the interfaces
|
||||
*/
|
||||
|
||||
int smsdvb_debugfs_create(struct smsdvb_client_t *client)
|
||||
{
|
||||
struct smscore_device_t *coredev = client->coredev;
|
||||
struct dentry *d;
|
||||
struct smsdvb_debugfs *debug_data;
|
||||
|
||||
if (!smsdvb_debugfs_usb_root || !coredev->is_usb_device)
|
||||
return -ENODEV;
|
||||
|
||||
client->debugfs = debugfs_create_dir(coredev->devpath,
|
||||
smsdvb_debugfs_usb_root);
|
||||
if (IS_ERR_OR_NULL(client->debugfs)) {
|
||||
pr_info("Unable to create debugfs %s directory.\n",
|
||||
coredev->devpath);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
d = debugfs_create_file("stats", S_IRUGO | S_IWUSR, client->debugfs,
|
||||
client, &debugfs_stats_ops);
|
||||
if (!d) {
|
||||
debugfs_remove(client->debugfs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
debug_data = kzalloc(sizeof(*client->debug_data), GFP_KERNEL);
|
||||
if (!debug_data)
|
||||
return -ENOMEM;
|
||||
|
||||
client->debug_data = debug_data;
|
||||
client->prt_dvb_stats = smsdvb_print_dvb_stats;
|
||||
client->prt_isdb_stats = smsdvb_print_isdb_stats;
|
||||
client->prt_isdb_stats_ex = smsdvb_print_isdb_stats_ex;
|
||||
|
||||
init_waitqueue_head(&debug_data->stats_queue);
|
||||
spin_lock_init(&debug_data->lock);
|
||||
kref_init(&debug_data->refcount);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void smsdvb_debugfs_release(struct smsdvb_client_t *client)
|
||||
{
|
||||
if (!client->debugfs)
|
||||
return;
|
||||
|
||||
client->prt_dvb_stats = NULL;
|
||||
client->prt_isdb_stats = NULL;
|
||||
client->prt_isdb_stats_ex = NULL;
|
||||
|
||||
debugfs_remove_recursive(client->debugfs);
|
||||
kref_put(&client->debug_data->refcount, smsdvb_debugfs_data_release);
|
||||
|
||||
client->debug_data = NULL;
|
||||
client->debugfs = NULL;
|
||||
}
|
||||
|
||||
int smsdvb_debugfs_register(void)
|
||||
{
|
||||
struct dentry *d;
|
||||
|
||||
/*
|
||||
* FIXME: This was written to debug Siano USB devices. So, it creates
|
||||
* the debugfs node under <debugfs>/usb.
|
||||
* A similar logic would be needed for Siano sdio devices, but, in that
|
||||
* case, usb_debug_root is not a good choice.
|
||||
*
|
||||
* Perhaps the right fix here would be to create another sysfs root
|
||||
* node for sdio-based boards, but this may need some logic at sdio
|
||||
* subsystem.
|
||||
*/
|
||||
d = debugfs_create_dir("smsdvb", usb_debug_root);
|
||||
if (IS_ERR_OR_NULL(d)) {
|
||||
sms_err("Couldn't create sysfs node for smsdvb");
|
||||
return PTR_ERR(d);
|
||||
} else {
|
||||
smsdvb_debugfs_usb_root = d;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void smsdvb_debugfs_unregister(void)
|
||||
{
|
||||
debugfs_remove_recursive(smsdvb_debugfs_usb_root);
|
||||
smsdvb_debugfs_usb_root = NULL;
|
||||
}
|
||||
1230
drivers/media/common/siano/smsdvb-main.c
Normal file
1230
drivers/media/common/siano/smsdvb-main.c
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
130
drivers/media/common/siano/smsdvb.h
Normal file
130
drivers/media/common/siano/smsdvb.h
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
struct smsdvb_debugfs;
|
||||
struct smsdvb_client_t;
|
||||
|
||||
typedef void (*sms_prt_dvb_stats_t)(struct smsdvb_debugfs *debug_data,
|
||||
struct sms_stats *p);
|
||||
|
||||
typedef void (*sms_prt_isdb_stats_t)(struct smsdvb_debugfs *debug_data,
|
||||
struct sms_isdbt_stats *p);
|
||||
|
||||
typedef void (*sms_prt_isdb_stats_ex_t)
|
||||
(struct smsdvb_debugfs *debug_data,
|
||||
struct sms_isdbt_stats_ex *p);
|
||||
|
||||
|
||||
struct smsdvb_client_t {
|
||||
struct list_head entry;
|
||||
|
||||
struct smscore_device_t *coredev;
|
||||
struct smscore_client_t *smsclient;
|
||||
|
||||
struct dvb_adapter adapter;
|
||||
struct dvb_demux demux;
|
||||
struct dmxdev dmxdev;
|
||||
struct dvb_frontend frontend;
|
||||
|
||||
fe_status_t fe_status;
|
||||
|
||||
struct completion tune_done;
|
||||
struct completion stats_done;
|
||||
|
||||
int last_per;
|
||||
|
||||
int legacy_ber, legacy_per;
|
||||
|
||||
int event_fe_state;
|
||||
int event_unc_state;
|
||||
|
||||
unsigned long get_stats_jiffies;
|
||||
|
||||
int feed_users;
|
||||
bool has_tuned;
|
||||
|
||||
/* stats debugfs data */
|
||||
struct dentry *debugfs;
|
||||
|
||||
struct smsdvb_debugfs *debug_data;
|
||||
|
||||
sms_prt_dvb_stats_t prt_dvb_stats;
|
||||
sms_prt_isdb_stats_t prt_isdb_stats;
|
||||
sms_prt_isdb_stats_ex_t prt_isdb_stats_ex;
|
||||
};
|
||||
|
||||
/*
|
||||
* This struct is a mix of struct sms_rx_stats_ex and
|
||||
* struct sms_srvm_signal_status.
|
||||
* It was obtained by comparing the way it was filled by the original code
|
||||
*/
|
||||
struct RECEPTION_STATISTICS_PER_SLICES_S {
|
||||
u32 result;
|
||||
u32 snr;
|
||||
s32 in_band_power;
|
||||
u32 ts_packets;
|
||||
u32 ets_packets;
|
||||
u32 constellation;
|
||||
u32 hp_code;
|
||||
u32 tps_srv_ind_lp;
|
||||
u32 tps_srv_ind_hp;
|
||||
u32 cell_id;
|
||||
u32 reason;
|
||||
u32 request_id;
|
||||
u32 modem_state; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
|
||||
|
||||
u32 ber; /* Post Viterbi BER [1E-5] */
|
||||
s32 RSSI; /* dBm */
|
||||
s32 carrier_offset; /* Carrier Offset in bin/1024 */
|
||||
|
||||
u32 is_rf_locked; /* 0 - not locked, 1 - locked */
|
||||
u32 is_demod_locked; /* 0 - not locked, 1 - locked */
|
||||
|
||||
u32 ber_bit_count; /* Total number of SYNC bits. */
|
||||
u32 ber_error_count; /* Number of erronous SYNC bits. */
|
||||
|
||||
s32 MRC_SNR; /* dB */
|
||||
s32 mrc_in_band_pwr; /* In band power in dBM */
|
||||
s32 MRC_RSSI; /* dBm */
|
||||
};
|
||||
|
||||
/* From smsdvb-debugfs.c */
|
||||
#ifdef CONFIG_SMS_SIANO_DEBUGFS
|
||||
|
||||
int smsdvb_debugfs_create(struct smsdvb_client_t *client);
|
||||
void smsdvb_debugfs_release(struct smsdvb_client_t *client);
|
||||
int smsdvb_debugfs_register(void);
|
||||
void smsdvb_debugfs_unregister(void);
|
||||
|
||||
#else
|
||||
|
||||
static inline int smsdvb_debugfs_create(struct smsdvb_client_t *client)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void smsdvb_debugfs_release(struct smsdvb_client_t *client) {}
|
||||
|
||||
static inline int smsdvb_debugfs_register(void)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
static inline void smsdvb_debugfs_unregister(void) {};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -28,23 +28,23 @@
|
|||
void smsendian_handle_tx_message(void *buffer)
|
||||
{
|
||||
#ifdef __BIG_ENDIAN
|
||||
struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
|
||||
struct sms_msg_data *msg = (struct sms_msg_data *)buffer;
|
||||
int i;
|
||||
int msgWords;
|
||||
int msg_words;
|
||||
|
||||
switch (msg->xMsgHeader.msgType) {
|
||||
switch (msg->x_msg_header.msg_type) {
|
||||
case MSG_SMS_DATA_DOWNLOAD_REQ:
|
||||
{
|
||||
msg->msgData[0] = le32_to_cpu(msg->msgData[0]);
|
||||
msg->msg_data[0] = le32_to_cpu(msg->msg_data[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
msgWords = (msg->xMsgHeader.msgLength -
|
||||
sizeof(struct SmsMsgHdr_ST))/4;
|
||||
msg_words = (msg->x_msg_header.msg_length -
|
||||
sizeof(struct sms_msg_hdr))/4;
|
||||
|
||||
for (i = 0; i < msgWords; i++)
|
||||
msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
|
||||
for (i = 0; i < msg_words; i++)
|
||||
msg->msg_data[i] = le32_to_cpu(msg->msg_data[i]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -55,16 +55,16 @@ EXPORT_SYMBOL_GPL(smsendian_handle_tx_message);
|
|||
void smsendian_handle_rx_message(void *buffer)
|
||||
{
|
||||
#ifdef __BIG_ENDIAN
|
||||
struct SmsMsgData_ST *msg = (struct SmsMsgData_ST *)buffer;
|
||||
struct sms_msg_data *msg = (struct sms_msg_data *)buffer;
|
||||
int i;
|
||||
int msgWords;
|
||||
int msg_words;
|
||||
|
||||
switch (msg->xMsgHeader.msgType) {
|
||||
switch (msg->x_msg_header.msg_type) {
|
||||
case MSG_SMS_GET_VERSION_EX_RES:
|
||||
{
|
||||
struct SmsVersionRes_ST *ver =
|
||||
(struct SmsVersionRes_ST *) msg;
|
||||
ver->ChipModel = le16_to_cpu(ver->ChipModel);
|
||||
struct sms_version_res *ver =
|
||||
(struct sms_version_res *) msg;
|
||||
ver->chip_model = le16_to_cpu(ver->chip_model);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -77,11 +77,11 @@ void smsendian_handle_rx_message(void *buffer)
|
|||
|
||||
default:
|
||||
{
|
||||
msgWords = (msg->xMsgHeader.msgLength -
|
||||
sizeof(struct SmsMsgHdr_ST))/4;
|
||||
msg_words = (msg->x_msg_header.msg_length -
|
||||
sizeof(struct sms_msg_hdr))/4;
|
||||
|
||||
for (i = 0; i < msgWords; i++)
|
||||
msg->msgData[i] = le32_to_cpu(msg->msgData[i]);
|
||||
for (i = 0; i < msg_words; i++)
|
||||
msg->msg_data[i] = le32_to_cpu(msg->msg_data[i]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -93,11 +93,11 @@ EXPORT_SYMBOL_GPL(smsendian_handle_rx_message);
|
|||
void smsendian_handle_message_header(void *msg)
|
||||
{
|
||||
#ifdef __BIG_ENDIAN
|
||||
struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)msg;
|
||||
struct sms_msg_hdr *phdr = (struct sms_msg_hdr *)msg;
|
||||
|
||||
phdr->msgType = le16_to_cpu(phdr->msgType);
|
||||
phdr->msgLength = le16_to_cpu(phdr->msgLength);
|
||||
phdr->msgFlags = le16_to_cpu(phdr->msgFlags);
|
||||
phdr->msg_type = le16_to_cpu(phdr->msg_type);
|
||||
phdr->msg_length = le16_to_cpu(phdr->msg_length);
|
||||
phdr->msg_flags = le16_to_cpu(phdr->msg_flags);
|
||||
#endif /* __BIG_ENDIAN */
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(smsendian_handle_message_header);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ struct ir_t {
|
|||
char phys[32];
|
||||
|
||||
char *rc_codes;
|
||||
u64 protocol;
|
||||
|
||||
u32 timeout;
|
||||
u32 controller;
|
||||
|
|
|
|||
|
|
@ -83,45 +83,6 @@ enum dmx_success {
|
|||
#define TS_DEMUX 8 /* in case TS_PACKET is set, send the TS to
|
||||
the demux device, not to the dvr device */
|
||||
|
||||
/* PES type for filters which write to built-in decoder */
|
||||
/* these should be kept identical to the types in dmx.h */
|
||||
|
||||
enum dmx_ts_pes
|
||||
{ /* also send packets to decoder (if it exists) */
|
||||
DMX_TS_PES_AUDIO0,
|
||||
DMX_TS_PES_VIDEO0,
|
||||
DMX_TS_PES_TELETEXT0,
|
||||
DMX_TS_PES_SUBTITLE0,
|
||||
DMX_TS_PES_PCR0,
|
||||
|
||||
DMX_TS_PES_AUDIO1,
|
||||
DMX_TS_PES_VIDEO1,
|
||||
DMX_TS_PES_TELETEXT1,
|
||||
DMX_TS_PES_SUBTITLE1,
|
||||
DMX_TS_PES_PCR1,
|
||||
|
||||
DMX_TS_PES_AUDIO2,
|
||||
DMX_TS_PES_VIDEO2,
|
||||
DMX_TS_PES_TELETEXT2,
|
||||
DMX_TS_PES_SUBTITLE2,
|
||||
DMX_TS_PES_PCR2,
|
||||
|
||||
DMX_TS_PES_AUDIO3,
|
||||
DMX_TS_PES_VIDEO3,
|
||||
DMX_TS_PES_TELETEXT3,
|
||||
DMX_TS_PES_SUBTITLE3,
|
||||
DMX_TS_PES_PCR3,
|
||||
|
||||
DMX_TS_PES_OTHER
|
||||
};
|
||||
|
||||
#define DMX_TS_PES_AUDIO DMX_TS_PES_AUDIO0
|
||||
#define DMX_TS_PES_VIDEO DMX_TS_PES_VIDEO0
|
||||
#define DMX_TS_PES_TELETEXT DMX_TS_PES_TELETEXT0
|
||||
#define DMX_TS_PES_SUBTITLE DMX_TS_PES_SUBTITLE0
|
||||
#define DMX_TS_PES_PCR DMX_TS_PES_PCR0
|
||||
|
||||
|
||||
struct dmx_ts_feed {
|
||||
int is_filtering; /* Set to non-zero when filtering in progress */
|
||||
struct dmx_demux *parent; /* Back-pointer */
|
||||
|
|
|
|||
|
|
@ -569,7 +569,7 @@ static int dvb_dmxdev_start_feed(struct dmxdev *dmxdev,
|
|||
dmx_output_t otype;
|
||||
int ret;
|
||||
int ts_type;
|
||||
dmx_pes_type_t ts_pes;
|
||||
enum dmx_ts_pes ts_pes;
|
||||
struct dmx_ts_feed *tsfeed;
|
||||
|
||||
feed->ts = NULL;
|
||||
|
|
@ -852,7 +852,8 @@ static int dvb_dmxdev_filter_set(struct dmxdev *dmxdev,
|
|||
struct dmxdev_filter *dmxdevfilter,
|
||||
struct dmx_sct_filter_params *params)
|
||||
{
|
||||
dprintk("function : %s\n", __func__);
|
||||
dprintk("function : %s, PID=0x%04x, flags=%02x, timeout=%d\n",
|
||||
__func__, params->pid, params->flags, params->timeout);
|
||||
|
||||
dvb_dmxdev_filter_stop(dmxdevfilter);
|
||||
|
||||
|
|
|
|||
|
|
@ -124,8 +124,7 @@
|
|||
#define USB_PID_DIBCOM_STK7770P 0x1e80
|
||||
#define USB_PID_DIBCOM_NIM7090 0x1bb2
|
||||
#define USB_PID_DIBCOM_TFE7090PVR 0x1bb4
|
||||
#define USB_PID_DIBCOM_TFE7090E 0x1bb7
|
||||
#define USB_PID_DIBCOM_TFE7790E 0x1e6e
|
||||
#define USB_PID_DIBCOM_TFE7790P 0x1e6e
|
||||
#define USB_PID_DIBCOM_NIM9090M 0x2383
|
||||
#define USB_PID_DIBCOM_NIM9090MD 0x2384
|
||||
#define USB_PID_DPOSH_M9206_COLD 0x9206
|
||||
|
|
|
|||
|
|
@ -440,20 +440,22 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
|
|||
if (!dvb_demux_feed_err_pkts)
|
||||
return;
|
||||
} else /* if TEI bit is set, pid may be wrong- skip pkt counter */
|
||||
if (demux->cnt_storage && dvb_demux_tscheck) {
|
||||
/* check pkt counter */
|
||||
if (pid < MAX_PID) {
|
||||
if ((buf[3] & 0xf) != demux->cnt_storage[pid])
|
||||
dprintk_tscheck("TS packet counter mismatch. "
|
||||
"PID=0x%x expected 0x%x "
|
||||
"got 0x%x\n",
|
||||
if (demux->cnt_storage && dvb_demux_tscheck) {
|
||||
/* check pkt counter */
|
||||
if (pid < MAX_PID) {
|
||||
if (buf[3] & 0x10)
|
||||
demux->cnt_storage[pid] =
|
||||
(demux->cnt_storage[pid] + 1) & 0xf;
|
||||
|
||||
if ((buf[3] & 0xf) != demux->cnt_storage[pid]) {
|
||||
dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n",
|
||||
pid, demux->cnt_storage[pid],
|
||||
buf[3] & 0xf);
|
||||
|
||||
demux->cnt_storage[pid] = ((buf[3] & 0xf) + 1)&0xf;
|
||||
demux->cnt_storage[pid] = buf[3] & 0xf;
|
||||
}
|
||||
}
|
||||
/* end check */
|
||||
}
|
||||
/* end check */
|
||||
}
|
||||
|
||||
list_for_each_entry(feed, &demux->feed_list, list_head) {
|
||||
if ((feed->pid != pid) && (feed->pid != 0x2000))
|
||||
|
|
@ -672,7 +674,7 @@ static int dmx_ts_feed_set(struct dmx_ts_feed *ts_feed, u16 pid, int ts_type,
|
|||
return -ERESTARTSYS;
|
||||
|
||||
if (ts_type & TS_DECODER) {
|
||||
if (pes_type >= DMX_TS_PES_OTHER) {
|
||||
if (pes_type >= DMX_PES_OTHER) {
|
||||
mutex_unlock(&demux->mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -844,7 +846,7 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx,
|
|||
|
||||
feed->pid = 0xffff;
|
||||
|
||||
if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_TS_PES_OTHER)
|
||||
if (feed->ts_type & TS_DECODER && feed->pes_type < DMX_PES_OTHER)
|
||||
demux->pesfilter[feed->pes_type] = NULL;
|
||||
|
||||
mutex_unlock(&demux->mutex);
|
||||
|
|
@ -1266,7 +1268,7 @@ int dvb_dmx_init(struct dvb_demux *dvbdemux)
|
|||
|
||||
INIT_LIST_HEAD(&dvbdemux->frontend_list);
|
||||
|
||||
for (i = 0; i < DMX_TS_PES_OTHER; i++) {
|
||||
for (i = 0; i < DMX_PES_OTHER; i++) {
|
||||
dvbdemux->pesfilter[i] = NULL;
|
||||
dvbdemux->pids[i] = 0xffff;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,8 +119,8 @@ struct dvb_demux {
|
|||
|
||||
struct list_head frontend_list;
|
||||
|
||||
struct dvb_demux_feed *pesfilter[DMX_TS_PES_OTHER];
|
||||
u16 pids[DMX_TS_PES_OTHER];
|
||||
struct dvb_demux_feed *pesfilter[DMX_PES_OTHER];
|
||||
u16 pids[DMX_PES_OTHER];
|
||||
int playing;
|
||||
int recording;
|
||||
|
||||
|
|
|
|||
|
|
@ -920,7 +920,7 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
|
|||
u32 delsys;
|
||||
|
||||
delsys = c->delivery_system;
|
||||
memset(c, 0, sizeof(struct dtv_frontend_properties));
|
||||
memset(c, 0, offsetof(struct dtv_frontend_properties, strength));
|
||||
c->delivery_system = delsys;
|
||||
|
||||
c->state = DTV_CLEAR;
|
||||
|
|
@ -1509,9 +1509,74 @@ static bool is_dvbv3_delsys(u32 delsys)
|
|||
return status;
|
||||
}
|
||||
|
||||
static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
|
||||
/**
|
||||
* emulate_delivery_system - emulate a DVBv5 delivery system with a DVBv3 type
|
||||
* @fe: struct frontend;
|
||||
* @delsys: DVBv5 type that will be used for emulation
|
||||
*
|
||||
* Provides emulation for delivery systems that are compatible with the old
|
||||
* DVBv3 call. Among its usages, it provices support for ISDB-T, and allows
|
||||
* using a DVB-S2 only frontend just like it were a DVB-S, if the frontent
|
||||
* parameters are compatible with DVB-S spec.
|
||||
*/
|
||||
static int emulate_delivery_system(struct dvb_frontend *fe, u32 delsys)
|
||||
{
|
||||
int ncaps, i;
|
||||
int i;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
|
||||
c->delivery_system = delsys;
|
||||
|
||||
/*
|
||||
* If the call is for ISDB-T, put it into full-seg, auto mode, TV
|
||||
*/
|
||||
if (c->delivery_system == SYS_ISDBT) {
|
||||
dev_dbg(fe->dvb->device,
|
||||
"%s: Using defaults for SYS_ISDBT\n",
|
||||
__func__);
|
||||
|
||||
if (!c->bandwidth_hz)
|
||||
c->bandwidth_hz = 6000000;
|
||||
|
||||
c->isdbt_partial_reception = 0;
|
||||
c->isdbt_sb_mode = 0;
|
||||
c->isdbt_sb_subchannel = 0;
|
||||
c->isdbt_sb_segment_idx = 0;
|
||||
c->isdbt_sb_segment_count = 0;
|
||||
c->isdbt_layer_enabled = 7;
|
||||
for (i = 0; i < 3; i++) {
|
||||
c->layer[i].fec = FEC_AUTO;
|
||||
c->layer[i].modulation = QAM_AUTO;
|
||||
c->layer[i].interleaving = 0;
|
||||
c->layer[i].segment_count = 0;
|
||||
}
|
||||
}
|
||||
dev_dbg(fe->dvb->device, "%s: change delivery system on cache to %d\n",
|
||||
__func__, c->delivery_system);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* dvbv5_set_delivery_system - Sets the delivery system for a DVBv5 API call
|
||||
* @fe: frontend struct
|
||||
* @desired_system: delivery system requested by the user
|
||||
*
|
||||
* A DVBv5 call know what's the desired system it wants. So, set it.
|
||||
*
|
||||
* There are, however, a few known issues with early DVBv5 applications that
|
||||
* are also handled by this logic:
|
||||
*
|
||||
* 1) Some early apps use SYS_UNDEFINED as the desired delivery system.
|
||||
* This is an API violation, but, as we don't want to break userspace,
|
||||
* convert it to the first supported delivery system.
|
||||
* 2) Some apps might be using a DVBv5 call in a wrong way, passing, for
|
||||
* example, SYS_DVBT instead of SYS_ISDBT. This is because early usage of
|
||||
* ISDB-T provided backward compat with DVB-T.
|
||||
*/
|
||||
static int dvbv5_set_delivery_system(struct dvb_frontend *fe,
|
||||
u32 desired_system)
|
||||
{
|
||||
int ncaps;
|
||||
u32 delsys = SYS_UNDEFINED;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
enum dvbv3_emulation_type type;
|
||||
|
|
@ -1522,166 +1587,136 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system)
|
|||
* assume that the application wants to use the first supported
|
||||
* delivery system.
|
||||
*/
|
||||
if (c->delivery_system == SYS_UNDEFINED)
|
||||
c->delivery_system = fe->ops.delsys[0];
|
||||
if (desired_system == SYS_UNDEFINED)
|
||||
desired_system = fe->ops.delsys[0];
|
||||
|
||||
if (desired_system == SYS_UNDEFINED) {
|
||||
/*
|
||||
* A DVBv3 call doesn't know what's the desired system.
|
||||
* Also, DVBv3 applications don't know that ops.info->type
|
||||
* could be changed, and they simply dies when it doesn't
|
||||
* match.
|
||||
* So, don't change the current delivery system, as it
|
||||
* may be trying to do the wrong thing, like setting an
|
||||
* ISDB-T frontend as DVB-T. Instead, find the closest
|
||||
* DVBv3 system that matches the delivery system.
|
||||
*/
|
||||
if (is_dvbv3_delsys(c->delivery_system)) {
|
||||
/*
|
||||
* This is a DVBv5 call. So, it likely knows the supported
|
||||
* delivery systems. So, check if the desired delivery system is
|
||||
* supported
|
||||
*/
|
||||
ncaps = 0;
|
||||
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
|
||||
if (fe->ops.delsys[ncaps] == desired_system) {
|
||||
c->delivery_system = desired_system;
|
||||
dev_dbg(fe->dvb->device,
|
||||
"%s: Using delivery system to %d\n",
|
||||
__func__, c->delivery_system);
|
||||
"%s: Changing delivery system to %d\n",
|
||||
__func__, desired_system);
|
||||
return 0;
|
||||
}
|
||||
type = dvbv3_type(c->delivery_system);
|
||||
switch (type) {
|
||||
case DVBV3_QPSK:
|
||||
desired_system = SYS_DVBS;
|
||||
break;
|
||||
case DVBV3_QAM:
|
||||
desired_system = SYS_DVBC_ANNEX_A;
|
||||
break;
|
||||
case DVBV3_ATSC:
|
||||
desired_system = SYS_ATSC;
|
||||
break;
|
||||
case DVBV3_OFDM:
|
||||
desired_system = SYS_DVBT;
|
||||
break;
|
||||
default:
|
||||
dev_dbg(fe->dvb->device, "%s: This frontend doesn't support DVBv3 calls\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
/*
|
||||
* Get a delivery system that is compatible with DVBv3
|
||||
* NOTE: in order for this to work with softwares like Kaffeine that
|
||||
* uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to
|
||||
* DVB-S, drivers that support both should put the SYS_DVBS entry
|
||||
* before the SYS_DVBS2, otherwise it won't switch back to DVB-S.
|
||||
* The real fix is that userspace applications should not use DVBv3
|
||||
* and not trust on calling FE_SET_FRONTEND to switch the delivery
|
||||
* system.
|
||||
*/
|
||||
ncaps = 0;
|
||||
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
|
||||
if (fe->ops.delsys[ncaps] == desired_system) {
|
||||
delsys = desired_system;
|
||||
break;
|
||||
}
|
||||
ncaps++;
|
||||
}
|
||||
if (delsys == SYS_UNDEFINED) {
|
||||
dev_dbg(fe->dvb->device, "%s: Couldn't find a delivery system that matches %d\n",
|
||||
__func__, desired_system);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* This is a DVBv5 call. So, it likely knows the supported
|
||||
* delivery systems.
|
||||
*/
|
||||
|
||||
/* Check if the desired delivery system is supported */
|
||||
ncaps = 0;
|
||||
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
|
||||
if (fe->ops.delsys[ncaps] == desired_system) {
|
||||
c->delivery_system = desired_system;
|
||||
dev_dbg(fe->dvb->device,
|
||||
"%s: Changing delivery system to %d\n",
|
||||
__func__, desired_system);
|
||||
return 0;
|
||||
}
|
||||
ncaps++;
|
||||
}
|
||||
type = dvbv3_type(desired_system);
|
||||
|
||||
/*
|
||||
* The delivery system is not supported. See if it can be
|
||||
* emulated.
|
||||
* The emulation only works if the desired system is one of the
|
||||
* DVBv3 delivery systems
|
||||
*/
|
||||
if (!is_dvbv3_delsys(desired_system)) {
|
||||
dev_dbg(fe->dvb->device,
|
||||
"%s: can't use a DVBv3 FE_SET_FRONTEND call on this frontend\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the last non-DVBv3 delivery system that has the same type
|
||||
* of the desired system
|
||||
*/
|
||||
ncaps = 0;
|
||||
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
|
||||
if ((dvbv3_type(fe->ops.delsys[ncaps]) == type) &&
|
||||
!is_dvbv3_delsys(fe->ops.delsys[ncaps]))
|
||||
delsys = fe->ops.delsys[ncaps];
|
||||
ncaps++;
|
||||
}
|
||||
/* There's nothing compatible with the desired delivery system */
|
||||
if (delsys == SYS_UNDEFINED) {
|
||||
dev_dbg(fe->dvb->device,
|
||||
"%s: Incompatible DVBv3 FE_SET_FRONTEND call for this frontend\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
ncaps++;
|
||||
}
|
||||
|
||||
c->delivery_system = delsys;
|
||||
|
||||
/*
|
||||
* The DVBv3 or DVBv5 call is requesting a different system. So,
|
||||
* emulation is needed.
|
||||
* The requested delivery system isn't supported. Maybe userspace
|
||||
* is requesting a DVBv3 compatible delivery system.
|
||||
*
|
||||
* Emulate newer delivery systems like ISDBT, DVBT and DTMB
|
||||
* for older DVBv5 applications. The emulation will try to use
|
||||
* the auto mode for most things, and will assume that the desired
|
||||
* delivery system is the last one at the ops.delsys[] array
|
||||
* The emulation only works if the desired system is one of the
|
||||
* delivery systems supported by DVBv3 API
|
||||
*/
|
||||
dev_dbg(fe->dvb->device,
|
||||
"%s: Using delivery system %d emulated as if it were a %d\n",
|
||||
__func__, delsys, desired_system);
|
||||
if (!is_dvbv3_delsys(desired_system)) {
|
||||
dev_dbg(fe->dvb->device,
|
||||
"%s: Delivery system %d not supported.\n",
|
||||
__func__, desired_system);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
type = dvbv3_type(desired_system);
|
||||
|
||||
/*
|
||||
* For now, handles ISDB-T calls. More code may be needed here for the
|
||||
* other emulated stuff
|
||||
*/
|
||||
if (type == DVBV3_OFDM) {
|
||||
if (c->delivery_system == SYS_ISDBT) {
|
||||
dev_dbg(fe->dvb->device,
|
||||
"%s: Using defaults for SYS_ISDBT\n",
|
||||
__func__);
|
||||
|
||||
if (!c->bandwidth_hz)
|
||||
c->bandwidth_hz = 6000000;
|
||||
|
||||
c->isdbt_partial_reception = 0;
|
||||
c->isdbt_sb_mode = 0;
|
||||
c->isdbt_sb_subchannel = 0;
|
||||
c->isdbt_sb_segment_idx = 0;
|
||||
c->isdbt_sb_segment_count = 0;
|
||||
c->isdbt_layer_enabled = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
c->layer[i].fec = FEC_AUTO;
|
||||
c->layer[i].modulation = QAM_AUTO;
|
||||
c->layer[i].interleaving = 0;
|
||||
c->layer[i].segment_count = 0;
|
||||
}
|
||||
}
|
||||
* Get the last non-DVBv3 delivery system that has the same type
|
||||
* of the desired system
|
||||
*/
|
||||
ncaps = 0;
|
||||
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
|
||||
if (dvbv3_type(fe->ops.delsys[ncaps]) == type)
|
||||
delsys = fe->ops.delsys[ncaps];
|
||||
ncaps++;
|
||||
}
|
||||
dev_dbg(fe->dvb->device, "%s: change delivery system on cache to %d\n",
|
||||
__func__, c->delivery_system);
|
||||
|
||||
return 0;
|
||||
/* There's nothing compatible with the desired delivery system */
|
||||
if (delsys == SYS_UNDEFINED) {
|
||||
dev_dbg(fe->dvb->device,
|
||||
"%s: Delivery system %d not supported on emulation mode.\n",
|
||||
__func__, desired_system);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev_dbg(fe->dvb->device,
|
||||
"%s: Using delivery system %d emulated as if it were %d\n",
|
||||
__func__, delsys, desired_system);
|
||||
|
||||
return emulate_delivery_system(fe, desired_system);
|
||||
}
|
||||
|
||||
/**
|
||||
* dvbv3_set_delivery_system - Sets the delivery system for a DVBv3 API call
|
||||
* @fe: frontend struct
|
||||
*
|
||||
* A DVBv3 call doesn't know what's the desired system it wants. It also
|
||||
* doesn't allow to switch between different types. Due to that, userspace
|
||||
* should use DVBv5 instead.
|
||||
* However, in order to avoid breaking userspace API, limited backward
|
||||
* compatibility support is provided.
|
||||
*
|
||||
* There are some delivery systems that are incompatible with DVBv3 calls.
|
||||
*
|
||||
* This routine should work fine for frontends that support just one delivery
|
||||
* system.
|
||||
*
|
||||
* For frontends that support multiple frontends:
|
||||
* 1) It defaults to use the first supported delivery system. There's an
|
||||
* userspace application that allows changing it at runtime;
|
||||
*
|
||||
* 2) If the current delivery system is not compatible with DVBv3, it gets
|
||||
* the first one that it is compatible.
|
||||
*
|
||||
* NOTE: in order for this to work with applications like Kaffeine that
|
||||
* uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to
|
||||
* DVB-S, drivers that support both DVB-S and DVB-S2 should have the
|
||||
* SYS_DVBS entry before the SYS_DVBS2, otherwise it won't switch back
|
||||
* to DVB-S.
|
||||
*/
|
||||
static int dvbv3_set_delivery_system(struct dvb_frontend *fe)
|
||||
{
|
||||
int ncaps;
|
||||
u32 delsys = SYS_UNDEFINED;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
|
||||
/* If not set yet, defaults to the first supported delivery system */
|
||||
if (c->delivery_system == SYS_UNDEFINED)
|
||||
c->delivery_system = fe->ops.delsys[0];
|
||||
|
||||
/*
|
||||
* Trivial case: just use the current one, if it already a DVBv3
|
||||
* delivery system
|
||||
*/
|
||||
if (is_dvbv3_delsys(c->delivery_system)) {
|
||||
dev_dbg(fe->dvb->device,
|
||||
"%s: Using delivery system to %d\n",
|
||||
__func__, c->delivery_system);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Seek for the first delivery system that it is compatible with a
|
||||
* DVBv3 standard
|
||||
*/
|
||||
ncaps = 0;
|
||||
while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) {
|
||||
if (dvbv3_type(fe->ops.delsys[ncaps]) != DVBV3_UNKNOWN) {
|
||||
delsys = fe->ops.delsys[ncaps];
|
||||
break;
|
||||
}
|
||||
ncaps++;
|
||||
}
|
||||
if (delsys == SYS_UNDEFINED) {
|
||||
dev_dbg(fe->dvb->device,
|
||||
"%s: Couldn't find a delivery system that works with FE_SET_FRONTEND\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
return emulate_delivery_system(fe, delsys);
|
||||
}
|
||||
|
||||
static int dtv_property_process_set(struct dvb_frontend *fe,
|
||||
|
|
@ -1742,7 +1777,7 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
|
|||
c->rolloff = tvp->u.data;
|
||||
break;
|
||||
case DTV_DELIVERY_SYSTEM:
|
||||
r = set_delivery_system(fe, tvp->u.data);
|
||||
r = dvbv5_set_delivery_system(fe, tvp->u.data);
|
||||
break;
|
||||
case DTV_VOLTAGE:
|
||||
c->voltage = tvp->u.data;
|
||||
|
|
@ -2335,7 +2370,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
|
|||
break;
|
||||
|
||||
case FE_SET_FRONTEND:
|
||||
err = set_delivery_system(fe, SYS_UNDEFINED);
|
||||
err = dvbv3_set_delivery_system(fe);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
|
|
@ -2594,7 +2629,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
|
|||
* first supported delivery system (ops->delsys[0])
|
||||
*/
|
||||
|
||||
fe->dtv_property_cache.delivery_system = fe->ops.delsys[0];
|
||||
fe->dtv_property_cache.delivery_system = fe->ops.delsys[0];
|
||||
dvb_frontend_clear_cache(fe);
|
||||
|
||||
mutex_unlock(&frontend_mutex);
|
||||
|
|
|
|||
|
|
@ -245,8 +245,8 @@ struct analog_demod_ops {
|
|||
|
||||
void (*set_params)(struct dvb_frontend *fe,
|
||||
struct analog_parameters *params);
|
||||
int (*has_signal)(struct dvb_frontend *fe);
|
||||
int (*get_afc)(struct dvb_frontend *fe);
|
||||
int (*has_signal)(struct dvb_frontend *fe, u16 *signal);
|
||||
int (*get_afc)(struct dvb_frontend *fe, s32 *afc);
|
||||
void (*tuner_status)(struct dvb_frontend *fe);
|
||||
void (*standby)(struct dvb_frontend *fe);
|
||||
void (*release)(struct dvb_frontend *fe);
|
||||
|
|
|
|||
|
|
@ -1044,7 +1044,7 @@ static int dvb_net_feed_start(struct net_device *dev)
|
|||
ret = priv->tsfeed->set(priv->tsfeed,
|
||||
priv->pid, /* pid */
|
||||
TS_PACKET, /* type */
|
||||
DMX_TS_PES_OTHER, /* pes type */
|
||||
DMX_PES_OTHER, /* pes type */
|
||||
32768, /* circular buffer size */
|
||||
timeout /* timeout */
|
||||
);
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ config DVB_SI21XX
|
|||
config DVB_TS2020
|
||||
tristate "Montage Tehnology TS2020 based tuners"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S/S2 silicon tuner. Say Y when you want to support this tuner.
|
||||
|
||||
|
|
|
|||
|
|
@ -21,12 +21,13 @@
|
|||
#ifndef A8293_H
|
||||
#define A8293_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
|
||||
struct a8293_config {
|
||||
u8 i2c_addr;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_A8293) || \
|
||||
(defined(CONFIG_DVB_A8293_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_A8293)
|
||||
extern struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, const struct a8293_config *cfg);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#ifndef AF9013_H
|
||||
#define AF9013_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
/* AF9013/5 GPIOs (mostly guessed)
|
||||
|
|
@ -102,8 +103,7 @@ struct af9013_config {
|
|||
u8 gpio[4];
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_AF9013) || \
|
||||
(defined(CONFIG_DVB_AF9013_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_AF9013)
|
||||
extern struct dvb_frontend *af9013_attach(const struct af9013_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -156,6 +156,37 @@ static int af9033_rd_reg_mask(struct af9033_state *state, u32 reg, u8 *val,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* write reg val table using reg addr auto increment */
|
||||
static int af9033_wr_reg_val_tab(struct af9033_state *state,
|
||||
const struct reg_val *tab, int tab_len)
|
||||
{
|
||||
int ret, i, j;
|
||||
u8 buf[tab_len];
|
||||
|
||||
dev_dbg(&state->i2c->dev, "%s: tab_len=%d\n", __func__, tab_len);
|
||||
|
||||
for (i = 0, j = 0; i < tab_len; i++) {
|
||||
buf[j] = tab[i].val;
|
||||
|
||||
if (i == tab_len - 1 || tab[i].reg != tab[i + 1].reg - 1) {
|
||||
ret = af9033_wr_regs(state, tab[i].reg - j, buf, j + 1);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
j = 0;
|
||||
} else {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
dev_dbg(&state->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 af9033_div(struct af9033_state *state, u32 a, u32 b, u32 x)
|
||||
{
|
||||
u32 r = 0, c = 0, i;
|
||||
|
|
@ -223,6 +254,7 @@ static int af9033_init(struct dvb_frontend *fe)
|
|||
{ 0x80f986, state->ts_mode_parallel, 0x01 },
|
||||
{ 0x00d827, 0x00, 0xff },
|
||||
{ 0x00d829, 0x00, 0xff },
|
||||
{ 0x800045, state->cfg.adc_multiplier, 0xff },
|
||||
};
|
||||
|
||||
/* program clock control */
|
||||
|
|
@ -286,14 +318,29 @@ static int af9033_init(struct dvb_frontend *fe)
|
|||
|
||||
/* load OFSM settings */
|
||||
dev_dbg(&state->i2c->dev, "%s: load ofsm settings\n", __func__);
|
||||
len = ARRAY_SIZE(ofsm_init);
|
||||
init = ofsm_init;
|
||||
for (i = 0; i < len; i++) {
|
||||
ret = af9033_wr_reg(state, init[i].reg, init[i].val);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
switch (state->cfg.tuner) {
|
||||
case AF9033_TUNER_IT9135_38:
|
||||
case AF9033_TUNER_IT9135_51:
|
||||
case AF9033_TUNER_IT9135_52:
|
||||
len = ARRAY_SIZE(ofsm_init_it9135_v1);
|
||||
init = ofsm_init_it9135_v1;
|
||||
break;
|
||||
case AF9033_TUNER_IT9135_60:
|
||||
case AF9033_TUNER_IT9135_61:
|
||||
case AF9033_TUNER_IT9135_62:
|
||||
len = ARRAY_SIZE(ofsm_init_it9135_v2);
|
||||
init = ofsm_init_it9135_v2;
|
||||
break;
|
||||
default:
|
||||
len = ARRAY_SIZE(ofsm_init);
|
||||
init = ofsm_init;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = af9033_wr_reg_val_tab(state, init, len);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
/* load tuner specific settings */
|
||||
dev_dbg(&state->i2c->dev, "%s: load tuner specific settings\n",
|
||||
__func__);
|
||||
|
|
@ -322,6 +369,30 @@ static int af9033_init(struct dvb_frontend *fe)
|
|||
len = ARRAY_SIZE(tuner_init_fc0012);
|
||||
init = tuner_init_fc0012;
|
||||
break;
|
||||
case AF9033_TUNER_IT9135_38:
|
||||
len = ARRAY_SIZE(tuner_init_it9135_38);
|
||||
init = tuner_init_it9135_38;
|
||||
break;
|
||||
case AF9033_TUNER_IT9135_51:
|
||||
len = ARRAY_SIZE(tuner_init_it9135_51);
|
||||
init = tuner_init_it9135_51;
|
||||
break;
|
||||
case AF9033_TUNER_IT9135_52:
|
||||
len = ARRAY_SIZE(tuner_init_it9135_52);
|
||||
init = tuner_init_it9135_52;
|
||||
break;
|
||||
case AF9033_TUNER_IT9135_60:
|
||||
len = ARRAY_SIZE(tuner_init_it9135_60);
|
||||
init = tuner_init_it9135_60;
|
||||
break;
|
||||
case AF9033_TUNER_IT9135_61:
|
||||
len = ARRAY_SIZE(tuner_init_it9135_61);
|
||||
init = tuner_init_it9135_61;
|
||||
break;
|
||||
case AF9033_TUNER_IT9135_62:
|
||||
len = ARRAY_SIZE(tuner_init_it9135_62);
|
||||
init = tuner_init_it9135_62;
|
||||
break;
|
||||
default:
|
||||
dev_dbg(&state->i2c->dev, "%s: unsupported tuner ID=%d\n",
|
||||
__func__, state->cfg.tuner);
|
||||
|
|
@ -329,11 +400,9 @@ static int af9033_init(struct dvb_frontend *fe)
|
|||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
ret = af9033_wr_reg(state, init[i].reg, init[i].val);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
ret = af9033_wr_reg_val_tab(state, init, len);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
if (state->cfg.ts_mode == AF9033_TS_MODE_SERIAL) {
|
||||
ret = af9033_wr_reg_mask(state, 0x00d91c, 0x01, 0x01);
|
||||
|
|
@ -349,6 +418,15 @@ static int af9033_init(struct dvb_frontend *fe)
|
|||
goto err;
|
||||
}
|
||||
|
||||
switch (state->cfg.tuner) {
|
||||
case AF9033_TUNER_IT9135_60:
|
||||
case AF9033_TUNER_IT9135_61:
|
||||
case AF9033_TUNER_IT9135_62:
|
||||
ret = af9033_wr_reg(state, 0x800000, 0x01);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
state->bandwidth_hz = 0; /* force to program all parameters */
|
||||
|
||||
return 0;
|
||||
|
|
@ -415,7 +493,8 @@ err:
|
|||
static int af9033_get_tune_settings(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_tune_settings *fesettings)
|
||||
{
|
||||
fesettings->min_delay_ms = 800;
|
||||
/* 800 => 2000 because IT9135 v2 is slow to gain lock */
|
||||
fesettings->min_delay_ms = 2000;
|
||||
fesettings->step_size = 0;
|
||||
fesettings->max_drift = 0;
|
||||
|
||||
|
|
@ -498,17 +577,17 @@ static int af9033_set_frontend(struct dvb_frontend *fe)
|
|||
if (spec_inv == -1)
|
||||
freq_cw = 0x800000 - freq_cw;
|
||||
|
||||
/* get adc multiplies */
|
||||
ret = af9033_rd_reg(state, 0x800045, &tmp);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
if (tmp == 1)
|
||||
if (state->cfg.adc_multiplier == AF9033_ADC_MULTIPLIER_2X)
|
||||
freq_cw /= 2;
|
||||
|
||||
buf[0] = (freq_cw >> 0) & 0xff;
|
||||
buf[1] = (freq_cw >> 8) & 0xff;
|
||||
buf[2] = (freq_cw >> 16) & 0x7f;
|
||||
|
||||
/* FIXME: there seems to be calculation error here... */
|
||||
if (if_frequency == 0)
|
||||
buf[2] = 0;
|
||||
|
||||
ret = af9033_wr_regs(state, 0x800029, buf, 3);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
|
@ -934,13 +1013,24 @@ struct dvb_frontend *af9033_attach(const struct af9033_config *config,
|
|||
buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
|
||||
|
||||
/* sleep */
|
||||
ret = af9033_wr_reg(state, 0x80004c, 1);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
switch (state->cfg.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:
|
||||
/* IT9135 did not like to sleep at that early */
|
||||
break;
|
||||
default:
|
||||
ret = af9033_wr_reg(state, 0x80004c, 1);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
ret = af9033_wr_reg(state, 0x800000, 0);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
ret = af9033_wr_reg(state, 0x800000, 0);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* configure internal TS mode */
|
||||
switch (state->cfg.ts_mode) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
#ifndef AF9033_H
|
||||
#define AF9033_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
|
||||
struct af9033_config {
|
||||
/*
|
||||
* I2C address
|
||||
|
|
@ -35,6 +37,13 @@ struct af9033_config {
|
|||
*/
|
||||
u32 clock;
|
||||
|
||||
/*
|
||||
* ADC multiplier
|
||||
*/
|
||||
#define AF9033_ADC_MULTIPLIER_1X 0
|
||||
#define AF9033_ADC_MULTIPLIER_2X 1
|
||||
u8 adc_multiplier;
|
||||
|
||||
/*
|
||||
* tuner
|
||||
*/
|
||||
|
|
@ -44,6 +53,14 @@ struct af9033_config {
|
|||
#define AF9033_TUNER_MXL5007T 0xa0 /* MaxLinear MxL5007T */
|
||||
#define AF9033_TUNER_TDA18218 0xa1 /* NXP TDA 18218HN */
|
||||
#define AF9033_TUNER_FC2580 0x32 /* FCI FC2580 */
|
||||
/* 50-5f Omega */
|
||||
#define AF9033_TUNER_IT9135_38 0x38 /* Omega */
|
||||
#define AF9033_TUNER_IT9135_51 0x51 /* Omega LNA config 1 */
|
||||
#define AF9033_TUNER_IT9135_52 0x52 /* Omega LNA config 2 */
|
||||
/* 60-6f Omega v2 */
|
||||
#define AF9033_TUNER_IT9135_60 0x60 /* Omega v2 */
|
||||
#define AF9033_TUNER_IT9135_61 0x61 /* Omega v2 LNA config 1 */
|
||||
#define AF9033_TUNER_IT9135_62 0x62 /* Omega v2 LNA config 2 */
|
||||
u8 tuner;
|
||||
|
||||
/*
|
||||
|
|
@ -61,8 +78,7 @@ struct af9033_config {
|
|||
};
|
||||
|
||||
|
||||
#if defined(CONFIG_DVB_AF9033) || \
|
||||
(defined(CONFIG_DVB_AF9033_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_AF9033)
|
||||
extern struct dvb_frontend *af9033_attach(const struct af9033_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef __ATBM8830_H__
|
||||
#define __ATBM8830_H__
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
|
|
@ -60,8 +61,7 @@ struct atbm8830_config {
|
|||
u8 agc_hold_loop;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_ATBM8830) || \
|
||||
(defined(CONFIG_DVB_ATBM8830_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_ATBM8830)
|
||||
extern struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef __AU8522_H__
|
||||
#define __AU8522_H__
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
enum au8522_if_freq {
|
||||
|
|
@ -60,8 +61,7 @@ struct au8522_config {
|
|||
enum au8522_if_freq qam_if;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_AU8522) || \
|
||||
(defined(CONFIG_DVB_AU8522_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_AU8522_DTV)
|
||||
extern struct dvb_frontend *au8522_attach(const struct au8522_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -229,15 +229,11 @@ static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
|
|||
/* Provide reasonable defaults for picture tuning values */
|
||||
au8522_writereg(state, AU8522_TVDEC_SHARPNESSREG009H, 0x07);
|
||||
au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, 0xed);
|
||||
state->brightness = 0xed - 128;
|
||||
au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, 0x79);
|
||||
state->contrast = 0x79;
|
||||
au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80);
|
||||
au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80);
|
||||
state->saturation = 0x80;
|
||||
au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00);
|
||||
au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00);
|
||||
state->hue = 0x00;
|
||||
|
||||
/* Other decoder registers */
|
||||
au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
|
||||
|
|
@ -489,75 +485,32 @@ static void set_audio_input(struct au8522_state *state, int aud_input)
|
|||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
|
||||
static int au8522_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct au8522_state *state = to_state(sd);
|
||||
struct au8522_state *state =
|
||||
container_of(ctrl->handler, struct au8522_state, hdl);
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
state->brightness = ctrl->value;
|
||||
au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH,
|
||||
ctrl->value - 128);
|
||||
ctrl->val - 128);
|
||||
break;
|
||||
case V4L2_CID_CONTRAST:
|
||||
state->contrast = ctrl->value;
|
||||
au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH,
|
||||
ctrl->value);
|
||||
ctrl->val);
|
||||
break;
|
||||
case V4L2_CID_SATURATION:
|
||||
state->saturation = ctrl->value;
|
||||
au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH,
|
||||
ctrl->value);
|
||||
ctrl->val);
|
||||
au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH,
|
||||
ctrl->value);
|
||||
ctrl->val);
|
||||
break;
|
||||
case V4L2_CID_HUE:
|
||||
state->hue = ctrl->value;
|
||||
au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH,
|
||||
ctrl->value >> 8);
|
||||
ctrl->val >> 8);
|
||||
au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH,
|
||||
ctrl->value & 0xFF);
|
||||
ctrl->val & 0xFF);
|
||||
break;
|
||||
case V4L2_CID_AUDIO_VOLUME:
|
||||
case V4L2_CID_AUDIO_BASS:
|
||||
case V4L2_CID_AUDIO_TREBLE:
|
||||
case V4L2_CID_AUDIO_BALANCE:
|
||||
case V4L2_CID_AUDIO_MUTE:
|
||||
/* Not yet implemented */
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
|
||||
{
|
||||
struct au8522_state *state = to_state(sd);
|
||||
|
||||
/* Note that we are using values cached in the state structure instead
|
||||
of reading the registers due to issues with i2c reads not working
|
||||
properly/consistently yet on the HVR-950q */
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
ctrl->value = state->brightness;
|
||||
break;
|
||||
case V4L2_CID_CONTRAST:
|
||||
ctrl->value = state->contrast;
|
||||
break;
|
||||
case V4L2_CID_SATURATION:
|
||||
ctrl->value = state->saturation;
|
||||
break;
|
||||
case V4L2_CID_HUE:
|
||||
ctrl->value = state->hue;
|
||||
break;
|
||||
case V4L2_CID_AUDIO_VOLUME:
|
||||
case V4L2_CID_AUDIO_BASS:
|
||||
case V4L2_CID_AUDIO_TREBLE:
|
||||
case V4L2_CID_AUDIO_BALANCE:
|
||||
case V4L2_CID_AUDIO_MUTE:
|
||||
/* Not yet supported */
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -583,7 +536,7 @@ static int au8522_g_register(struct v4l2_subdev *sd,
|
|||
}
|
||||
|
||||
static int au8522_s_register(struct v4l2_subdev *sd,
|
||||
struct v4l2_dbg_register *reg)
|
||||
const struct v4l2_dbg_register *reg)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
struct au8522_state *state = to_state(sd);
|
||||
|
|
@ -616,26 +569,6 @@ static int au8522_s_stream(struct v4l2_subdev *sd, int enable)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
|
||||
{
|
||||
switch (qc->id) {
|
||||
case V4L2_CID_CONTRAST:
|
||||
return v4l2_ctrl_query_fill(qc, 0, 255, 1,
|
||||
AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 109);
|
||||
case V4L2_CID_SATURATION:
|
||||
return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
|
||||
case V4L2_CID_HUE:
|
||||
return v4l2_ctrl_query_fill(qc, -32768, 32768, 1, 0);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
qc->type = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int au8522_reset(struct v4l2_subdev *sd, u32 val)
|
||||
{
|
||||
struct au8522_state *state = to_state(sd);
|
||||
|
|
@ -712,20 +645,11 @@ static int au8522_g_chip_ident(struct v4l2_subdev *sd,
|
|||
return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
|
||||
}
|
||||
|
||||
static int au8522_log_status(struct v4l2_subdev *sd)
|
||||
{
|
||||
/* FIXME: Add some status info here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static const struct v4l2_subdev_core_ops au8522_core_ops = {
|
||||
.log_status = au8522_log_status,
|
||||
.log_status = v4l2_ctrl_subdev_log_status,
|
||||
.g_chip_ident = au8522_g_chip_ident,
|
||||
.g_ctrl = au8522_g_ctrl,
|
||||
.s_ctrl = au8522_s_ctrl,
|
||||
.queryctrl = au8522_queryctrl,
|
||||
.reset = au8522_reset,
|
||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||
.g_register = au8522_g_register,
|
||||
|
|
@ -753,12 +677,17 @@ static const struct v4l2_subdev_ops au8522_ops = {
|
|||
.video = &au8522_video_ops,
|
||||
};
|
||||
|
||||
static const struct v4l2_ctrl_ops au8522_ctrl_ops = {
|
||||
.s_ctrl = au8522_s_ctrl,
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static int au8522_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *did)
|
||||
{
|
||||
struct au8522_state *state;
|
||||
struct v4l2_ctrl_handler *hdl;
|
||||
struct v4l2_subdev *sd;
|
||||
int instance;
|
||||
struct au8522_config *demod_config;
|
||||
|
|
@ -799,6 +728,27 @@ static int au8522_probe(struct i2c_client *client,
|
|||
sd = &state->sd;
|
||||
v4l2_i2c_subdev_init(sd, client, &au8522_ops);
|
||||
|
||||
hdl = &state->hdl;
|
||||
v4l2_ctrl_handler_init(hdl, 4);
|
||||
v4l2_ctrl_new_std(hdl, &au8522_ctrl_ops,
|
||||
V4L2_CID_BRIGHTNESS, 0, 255, 1, 109);
|
||||
v4l2_ctrl_new_std(hdl, &au8522_ctrl_ops,
|
||||
V4L2_CID_CONTRAST, 0, 255, 1,
|
||||
AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
|
||||
v4l2_ctrl_new_std(hdl, &au8522_ctrl_ops,
|
||||
V4L2_CID_SATURATION, 0, 255, 1, 128);
|
||||
v4l2_ctrl_new_std(hdl, &au8522_ctrl_ops,
|
||||
V4L2_CID_HUE, -32768, 32767, 1, 0);
|
||||
sd->ctrl_handler = hdl;
|
||||
if (hdl->error) {
|
||||
int err = hdl->error;
|
||||
|
||||
v4l2_ctrl_handler_free(hdl);
|
||||
kfree(demod_config);
|
||||
kfree(state);
|
||||
return err;
|
||||
}
|
||||
|
||||
state->c = client;
|
||||
state->vid_input = AU8522_COMPOSITE_CH1;
|
||||
state->aud_input = AU8522_AUDIO_NONE;
|
||||
|
|
@ -815,6 +765,7 @@ static int au8522_remove(struct i2c_client *client)
|
|||
{
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
v4l2_device_unregister_subdev(sd);
|
||||
v4l2_ctrl_handler_free(sd->ctrl_handler);
|
||||
au8522_release_state(to_state(sd));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include <linux/i2c.h>
|
||||
#include "dvb_frontend.h"
|
||||
#include "au8522.h"
|
||||
|
|
@ -65,10 +66,7 @@ struct au8522_state {
|
|||
int aud_input;
|
||||
u32 id;
|
||||
u32 rev;
|
||||
u8 brightness;
|
||||
u8 contrast;
|
||||
u8 saturation;
|
||||
s16 hue;
|
||||
struct v4l2_ctrl_handler hdl;
|
||||
};
|
||||
|
||||
/* These are routines shared by both the VSB/QAM demodulator and the analog
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#ifndef CX22702_H
|
||||
#define CX22702_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct cx22702_config {
|
||||
|
|
@ -40,8 +41,7 @@ struct cx22702_config {
|
|||
u8 output_mode;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) \
|
||||
&& defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_CX22702)
|
||||
extern struct dvb_frontend *cx22702_attach(
|
||||
const struct cx22702_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
#ifndef CX24113_H
|
||||
#define CX24113_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
|
||||
struct dvb_frontend;
|
||||
|
||||
struct cx24113_config {
|
||||
|
|
@ -30,8 +32,7 @@ struct cx24113_config {
|
|||
u32 xtal_khz;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_TUNER_CX24113) || \
|
||||
(defined(CONFIG_DVB_TUNER_CX24113_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_TUNER_CX24113)
|
||||
extern struct dvb_frontend *cx24113_attach(struct dvb_frontend *,
|
||||
const struct cx24113_config *config, struct i2c_adapter *i2c);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef CX24116_H
|
||||
#define CX24116_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct cx24116_config {
|
||||
|
|
@ -40,8 +41,7 @@ struct cx24116_config {
|
|||
u16 i2c_wr_max;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_CX24116) || \
|
||||
(defined(CONFIG_DVB_CX24116_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_CX24116)
|
||||
extern struct dvb_frontend *cx24116_attach(
|
||||
const struct cx24116_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
#include "cx24123.h"
|
||||
|
|
@ -452,7 +453,8 @@ static u32 cx24123_int_log2(u32 a, u32 b)
|
|||
|
||||
static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
|
||||
{
|
||||
u32 tmp, sample_rate, ratio, sample_gain;
|
||||
u64 tmp;
|
||||
u32 sample_rate, ratio, sample_gain;
|
||||
u8 pll_mult;
|
||||
|
||||
/* check if symbol rate is within limits */
|
||||
|
|
@ -482,27 +484,11 @@ static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
|
|||
|
||||
sample_rate = pll_mult * XTAL;
|
||||
|
||||
/*
|
||||
SYSSymbolRate[21:0] = (srate << 23) / sample_rate
|
||||
|
||||
We have to use 32 bit unsigned arithmetic without precision loss.
|
||||
The maximum srate is 45000000 or 0x02AEA540. This number has
|
||||
only 6 clear bits on top, hence we can shift it left only 6 bits
|
||||
at a time. Borrowed from cx24110.c
|
||||
*/
|
||||
|
||||
tmp = srate << 6;
|
||||
ratio = tmp / sample_rate;
|
||||
|
||||
tmp = (tmp % sample_rate) << 6;
|
||||
ratio = (ratio << 6) + (tmp / sample_rate);
|
||||
|
||||
tmp = (tmp % sample_rate) << 6;
|
||||
ratio = (ratio << 6) + (tmp / sample_rate);
|
||||
|
||||
tmp = (tmp % sample_rate) << 5;
|
||||
ratio = (ratio << 5) + (tmp / sample_rate);
|
||||
/* SYSSymbolRate[21:0] = (srate << 23) / sample_rate */
|
||||
|
||||
tmp = ((u64)srate) << 23;
|
||||
do_div(tmp, sample_rate);
|
||||
ratio = (u32) tmp;
|
||||
|
||||
cx24123_writereg(state, 0x01, pll_mult * 6);
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef CX24123_H
|
||||
#define CX24123_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct cx24123_config {
|
||||
|
|
@ -38,8 +39,7 @@ struct cx24123_config {
|
|||
void (*agc_callback) (struct dvb_frontend *);
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) \
|
||||
&& defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_CX24123)
|
||||
extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef CXD2820R_H
|
||||
#define CXD2820R_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
#define CXD2820R_GPIO_D (0 << 0) /* disable */
|
||||
|
|
@ -65,8 +66,7 @@ struct cxd2820r_config {
|
|||
};
|
||||
|
||||
|
||||
#if defined(CONFIG_DVB_CXD2820R) || \
|
||||
(defined(CONFIG_DVB_CXD2820R_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_CXD2820R)
|
||||
extern struct dvb_frontend *cxd2820r_attach(
|
||||
const struct cxd2820r_config *config,
|
||||
struct i2c_adapter *i2c,
|
||||
|
|
|
|||
|
|
@ -660,7 +660,8 @@ static const struct dvb_frontend_ops cxd2820r_ops = {
|
|||
FE_CAN_GUARD_INTERVAL_AUTO |
|
||||
FE_CAN_HIERARCHY_AUTO |
|
||||
FE_CAN_MUTE_TS |
|
||||
FE_CAN_2G_MODULATION
|
||||
FE_CAN_2G_MODULATION |
|
||||
FE_CAN_MULTISTREAM
|
||||
},
|
||||
|
||||
.release = cxd2820r_release,
|
||||
|
|
|
|||
|
|
@ -124,6 +124,23 @@ int cxd2820r_set_frontend_t2(struct dvb_frontend *fe)
|
|||
buf[1] = ((if_ctl >> 8) & 0xff);
|
||||
buf[2] = ((if_ctl >> 0) & 0xff);
|
||||
|
||||
/* PLP filtering */
|
||||
if (c->stream_id > 255) {
|
||||
dev_dbg(&priv->i2c->dev, "%s: Disable PLP filtering\n", __func__);
|
||||
ret = cxd2820r_wr_reg(priv, 0x023ad , 0);
|
||||
if (ret)
|
||||
goto error;
|
||||
} else {
|
||||
dev_dbg(&priv->i2c->dev, "%s: Enable PLP filtering = %d\n", __func__,
|
||||
c->stream_id);
|
||||
ret = cxd2820r_wr_reg(priv, 0x023af , c->stream_id & 0xFF);
|
||||
if (ret)
|
||||
goto error;
|
||||
ret = cxd2820r_wr_reg(priv, 0x023ad , 1);
|
||||
if (ret)
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = cxd2820r_wr_regs(priv, 0x020b6, buf, 3);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
|
|
|||
|
|
@ -528,20 +528,19 @@ static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_
|
|||
u16 PllCfg, i, v;
|
||||
|
||||
HARD_RESET(state);
|
||||
|
||||
dib0090_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
|
||||
dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */
|
||||
if (cfg->in_soc)
|
||||
return;
|
||||
|
||||
if (!cfg->in_soc) {
|
||||
/* adcClkOutRatio=8->7, release reset */
|
||||
dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
|
||||
if (cfg->clkoutdrive != 0)
|
||||
dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
|
||||
| (cfg->clkoutdrive << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
|
||||
else
|
||||
dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
|
||||
| (7 << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
|
||||
}
|
||||
dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */
|
||||
/* adcClkOutRatio=8->7, release reset */
|
||||
dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
|
||||
if (cfg->clkoutdrive != 0)
|
||||
dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
|
||||
| (cfg->clkoutdrive << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
|
||||
else
|
||||
dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
|
||||
| (7 << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
|
||||
|
||||
/* Read Pll current config * */
|
||||
PllCfg = dib0090_read_reg(state, 0x21);
|
||||
|
|
@ -694,192 +693,174 @@ void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
|
|||
EXPORT_SYMBOL(dib0090_dcc_freq);
|
||||
|
||||
static const u16 bb_ramp_pwm_normal_socs[] = {
|
||||
550, /* max BB gain in 10th of dB */
|
||||
(1 << 9) | 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
|
||||
550, /* max BB gain in 10th of dB */
|
||||
(1<<9) | 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
|
||||
440,
|
||||
(4 << 9) | 0, /* BB_RAMP3 = 26dB */
|
||||
(0 << 9) | 208, /* BB_RAMP4 */
|
||||
(4 << 9) | 208, /* BB_RAMP5 = 29dB */
|
||||
(0 << 9) | 440, /* BB_RAMP6 */
|
||||
(4 << 9) | 0, /* BB_RAMP3 = 26dB */
|
||||
(0 << 9) | 208, /* BB_RAMP4 */
|
||||
(4 << 9) | 208, /* BB_RAMP5 = 29dB */
|
||||
(0 << 9) | 440, /* BB_RAMP6 */
|
||||
};
|
||||
|
||||
static const u16 rf_ramp_pwm_cband_7090[] = {
|
||||
280, /* max RF gain in 10th of dB */
|
||||
18, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
|
||||
504, /* ramp_max = maximum X used on the ramp */
|
||||
(29 << 10) | 364, /* RF_RAMP5, LNA 1 = 8dB */
|
||||
(0 << 10) | 504, /* RF_RAMP6, LNA 1 */
|
||||
(60 << 10) | 228, /* RF_RAMP7, LNA 2 = 7.7dB */
|
||||
(0 << 10) | 364, /* RF_RAMP8, LNA 2 */
|
||||
(34 << 10) | 109, /* GAIN_4_1, LNA 3 = 6.8dB */
|
||||
(0 << 10) | 228, /* GAIN_4_2, LNA 3 */
|
||||
(37 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */
|
||||
(0 << 10) | 109, /* RF_RAMP4, LNA 4 */
|
||||
static const u16 rf_ramp_pwm_cband_7090p[] = {
|
||||
280, /* max RF gain in 10th of dB */
|
||||
18, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
|
||||
504, /* ramp_max = maximum X used on the ramp */
|
||||
(29 << 10) | 364, /* RF_RAMP5, LNA 1 = 8dB */
|
||||
(0 << 10) | 504, /* RF_RAMP6, LNA 1 */
|
||||
(60 << 10) | 228, /* RF_RAMP7, LNA 2 = 7.7dB */
|
||||
(0 << 10) | 364, /* RF_RAMP8, LNA 2 */
|
||||
(34 << 10) | 109, /* GAIN_4_1, LNA 3 = 6.8dB */
|
||||
(0 << 10) | 228, /* GAIN_4_2, LNA 3 */
|
||||
(37 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */
|
||||
(0 << 10) | 109, /* RF_RAMP4, LNA 4 */
|
||||
};
|
||||
|
||||
static const uint16_t rf_ramp_pwm_cband_7090e_sensitivity[] = {
|
||||
186,
|
||||
40,
|
||||
746,
|
||||
(10 << 10) | 345,
|
||||
(0 << 10) | 746,
|
||||
(0 << 10) | 0,
|
||||
(0 << 10) | 0,
|
||||
(28 << 10) | 200,
|
||||
(0 << 10) | 345,
|
||||
(20 << 10) | 0,
|
||||
(0 << 10) | 200,
|
||||
static const u16 rf_ramp_pwm_cband_7090e_sensitivity[] = {
|
||||
186, /* max RF gain in 10th of dB */
|
||||
40, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
|
||||
746, /* ramp_max = maximum X used on the ramp */
|
||||
(10 << 10) | 345, /* RF_RAMP5, LNA 1 = 10dB */
|
||||
(0 << 10) | 746, /* RF_RAMP6, LNA 1 */
|
||||
(0 << 10) | 0, /* RF_RAMP7, LNA 2 = 0 dB */
|
||||
(0 << 10) | 0, /* RF_RAMP8, LNA 2 */
|
||||
(28 << 10) | 200, /* GAIN_4_1, LNA 3 = 6.8dB */ /* 3.61 dB */
|
||||
(0 << 10) | 345, /* GAIN_4_2, LNA 3 */
|
||||
(20 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */ /* 4.96 dB */
|
||||
(0 << 10) | 200, /* RF_RAMP4, LNA 4 */
|
||||
};
|
||||
|
||||
static const uint16_t rf_ramp_pwm_cband_7090e_aci[] = {
|
||||
86,
|
||||
40,
|
||||
345,
|
||||
(0 << 10) | 0,
|
||||
(0 << 10) | 0,
|
||||
(0 << 10) | 0,
|
||||
(0 << 10) | 0,
|
||||
(28 << 10) | 200,
|
||||
(0 << 10) | 345,
|
||||
(20 << 10) | 0,
|
||||
(0 << 10) | 200,
|
||||
static const u16 rf_ramp_pwm_cband_7090e_aci[] = {
|
||||
86, /* max RF gain in 10th of dB */
|
||||
40, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
|
||||
345, /* ramp_max = maximum X used on the ramp */
|
||||
(0 << 10) | 0, /* RF_RAMP5, LNA 1 = 8dB */ /* 7.47 dB */
|
||||
(0 << 10) | 0, /* RF_RAMP6, LNA 1 */
|
||||
(0 << 10) | 0, /* RF_RAMP7, LNA 2 = 0 dB */
|
||||
(0 << 10) | 0, /* RF_RAMP8, LNA 2 */
|
||||
(28 << 10) | 200, /* GAIN_4_1, LNA 3 = 6.8dB */ /* 3.61 dB */
|
||||
(0 << 10) | 345, /* GAIN_4_2, LNA 3 */
|
||||
(20 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */ /* 4.96 dB */
|
||||
(0 << 10) | 200, /* RF_RAMP4, LNA 4 */
|
||||
};
|
||||
|
||||
static const u16 rf_ramp_pwm_cband_8090[] = {
|
||||
345, /* max RF gain in 10th of dB */
|
||||
29, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
|
||||
1000, /* ramp_max = maximum X used on the ramp */
|
||||
(35 << 10) | 772, /* RF_RAMP3, LNA 1 = 8dB */
|
||||
(0 << 10) | 1000, /* RF_RAMP4, LNA 1 */
|
||||
(58 << 10) | 496, /* RF_RAMP5, LNA 2 = 9.5dB */
|
||||
(0 << 10) | 772, /* RF_RAMP6, LNA 2 */
|
||||
(27 << 10) | 200, /* RF_RAMP7, LNA 3 = 10.5dB */
|
||||
(0 << 10) | 496, /* RF_RAMP8, LNA 3 */
|
||||
(40 << 10) | 0, /* GAIN_4_1, LNA 4 = 7dB */
|
||||
(0 << 10) | 200, /* GAIN_4_2, LNA 4 */
|
||||
345, /* max RF gain in 10th of dB */
|
||||
29, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
|
||||
1000, /* ramp_max = maximum X used on the ramp */
|
||||
(35 << 10) | 772, /* RF_RAMP3, LNA 1 = 8dB */
|
||||
(0 << 10) | 1000, /* RF_RAMP4, LNA 1 */
|
||||
(58 << 10) | 496, /* RF_RAMP5, LNA 2 = 9.5dB */
|
||||
(0 << 10) | 772, /* RF_RAMP6, LNA 2 */
|
||||
(27 << 10) | 200, /* RF_RAMP7, LNA 3 = 10.5dB */
|
||||
(0 << 10) | 496, /* RF_RAMP8, LNA 3 */
|
||||
(40 << 10) | 0, /* GAIN_4_1, LNA 4 = 7dB */
|
||||
(0 << 10) | 200, /* GAIN_4_2, LNA 4 */
|
||||
};
|
||||
|
||||
static const u16 rf_ramp_pwm_uhf_7090[] = {
|
||||
407, /* max RF gain in 10th of dB */
|
||||
13, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
|
||||
529, /* ramp_max = maximum X used on the ramp */
|
||||
(23 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
|
||||
(0 << 10) | 176, /* RF_RAMP4, LNA 1 */
|
||||
(63 << 10) | 400, /* RF_RAMP5, LNA 2 = 8dB */
|
||||
(0 << 10) | 529, /* RF_RAMP6, LNA 2 */
|
||||
(48 << 10) | 316, /* RF_RAMP7, LNA 3 = 6.8dB */
|
||||
(0 << 10) | 400, /* RF_RAMP8, LNA 3 */
|
||||
(29 << 10) | 176, /* GAIN_4_1, LNA 4 = 11.5dB */
|
||||
(0 << 10) | 316, /* GAIN_4_2, LNA 4 */
|
||||
407, /* max RF gain in 10th of dB */
|
||||
13, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
|
||||
529, /* ramp_max = maximum X used on the ramp */
|
||||
(23 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
|
||||
(0 << 10) | 176, /* RF_RAMP4, LNA 1 */
|
||||
(63 << 10) | 400, /* RF_RAMP5, LNA 2 = 8dB */
|
||||
(0 << 10) | 529, /* RF_RAMP6, LNA 2 */
|
||||
(48 << 10) | 316, /* RF_RAMP7, LNA 3 = 6.8dB */
|
||||
(0 << 10) | 400, /* RF_RAMP8, LNA 3 */
|
||||
(29 << 10) | 176, /* GAIN_4_1, LNA 4 = 11.5dB */
|
||||
(0 << 10) | 316, /* GAIN_4_2, LNA 4 */
|
||||
};
|
||||
|
||||
static const u16 rf_ramp_pwm_uhf_8090[] = {
|
||||
388, /* max RF gain in 10th of dB */
|
||||
26, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
|
||||
1008, /* ramp_max = maximum X used on the ramp */
|
||||
(11 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
|
||||
(0 << 10) | 369, /* RF_RAMP4, LNA 1 */
|
||||
(41 << 10) | 809, /* RF_RAMP5, LNA 2 = 8dB */
|
||||
(0 << 10) | 1008, /* RF_RAMP6, LNA 2 */
|
||||
(27 << 10) | 659, /* RF_RAMP7, LNA 3 = 6dB */
|
||||
(0 << 10) | 809, /* RF_RAMP8, LNA 3 */
|
||||
(14 << 10) | 369, /* GAIN_4_1, LNA 4 = 11.5dB */
|
||||
(0 << 10) | 659, /* GAIN_4_2, LNA 4 */
|
||||
388, /* max RF gain in 10th of dB */
|
||||
26, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
|
||||
1008, /* ramp_max = maximum X used on the ramp */
|
||||
(11 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
|
||||
(0 << 10) | 369, /* RF_RAMP4, LNA 1 */
|
||||
(41 << 10) | 809, /* RF_RAMP5, LNA 2 = 8dB */
|
||||
(0 << 10) | 1008, /* RF_RAMP6, LNA 2 */
|
||||
(27 << 10) | 659, /* RF_RAMP7, LNA 3 = 6dB */
|
||||
(0 << 10) | 809, /* RF_RAMP8, LNA 3 */
|
||||
(14 << 10) | 369, /* GAIN_4_1, LNA 4 = 11.5dB */
|
||||
(0 << 10) | 659, /* GAIN_4_2, LNA 4 */
|
||||
};
|
||||
|
||||
/* GENERAL PWM ramp definition for all other Krosus */
|
||||
static const u16 bb_ramp_pwm_normal[] = {
|
||||
500, /* max BB gain in 10th of dB */
|
||||
8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
|
||||
400,
|
||||
(2 << 9) | 0, /* BB_RAMP3 = 21dB */
|
||||
(0 << 9) | 168, /* BB_RAMP4 */
|
||||
(2 << 9) | 168, /* BB_RAMP5 = 29dB */
|
||||
(0 << 9) | 400, /* BB_RAMP6 */
|
||||
};
|
||||
|
||||
static const u16 bb_ramp_pwm_boost[] = {
|
||||
550, /* max BB gain in 10th of dB */
|
||||
8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
|
||||
440,
|
||||
(2 << 9) | 0, /* BB_RAMP3 = 26dB */
|
||||
(0 << 9) | 208, /* BB_RAMP4 */
|
||||
(2 << 9) | 208, /* BB_RAMP5 = 29dB */
|
||||
(0 << 9) | 440, /* BB_RAMP6 */
|
||||
};
|
||||
|
||||
static const u16 rf_ramp_pwm_cband[] = {
|
||||
0, /* max RF gain in 10th of dB */
|
||||
0, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
|
||||
0, /* ramp_max = maximum X used on the ramp */
|
||||
(0 << 10) | 0, /* 0x2c, LNA 1 = 0dB */
|
||||
(0 << 10) | 0, /* 0x2d, LNA 1 */
|
||||
(0 << 10) | 0, /* 0x2e, LNA 2 = 0dB */
|
||||
(0 << 10) | 0, /* 0x2f, LNA 2 */
|
||||
(0 << 10) | 0, /* 0x30, LNA 3 = 0dB */
|
||||
(0 << 10) | 0, /* 0x31, LNA 3 */
|
||||
(0 << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */
|
||||
(0 << 10) | 0, /* GAIN_4_2, LNA 4 */
|
||||
};
|
||||
|
||||
static const u16 rf_ramp_vhf[] = {
|
||||
412, /* max RF gain in 10th of dB */
|
||||
132, 307, 127, /* LNA1, 13.2dB */
|
||||
105, 412, 255, /* LNA2, 10.5dB */
|
||||
50, 50, 127, /* LNA3, 5dB */
|
||||
125, 175, 127, /* LNA4, 12.5dB */
|
||||
0, 0, 127, /* CBAND, 0dB */
|
||||
};
|
||||
|
||||
static const u16 rf_ramp_uhf[] = {
|
||||
412, /* max RF gain in 10th of dB */
|
||||
132, 307, 127, /* LNA1 : total gain = 13.2dB, point on the ramp where this amp is full gain, value to write to get full gain */
|
||||
105, 412, 255, /* LNA2 : 10.5 dB */
|
||||
50, 50, 127, /* LNA3 : 5.0 dB */
|
||||
125, 175, 127, /* LNA4 : 12.5 dB */
|
||||
0, 0, 127, /* CBAND : 0.0 dB */
|
||||
};
|
||||
|
||||
static const u16 rf_ramp_cband_broadmatching[] = /* for p1G only */
|
||||
{
|
||||
314, /* Calibrated at 200MHz order has been changed g4-g3-g2-g1 */
|
||||
84, 314, 127, /* LNA1 */
|
||||
80, 230, 255, /* LNA2 */
|
||||
80, 150, 127, /* LNA3 It was measured 12dB, do not lock if 120 */
|
||||
70, 70, 127, /* LNA4 */
|
||||
0, 0, 127, /* CBAND */
|
||||
};
|
||||
|
||||
static const u16 rf_ramp_cband[] = {
|
||||
332, /* max RF gain in 10th of dB */
|
||||
132, 252, 127, /* LNA1, dB */
|
||||
80, 332, 255, /* LNA2, dB */
|
||||
0, 0, 127, /* LNA3, dB */
|
||||
0, 0, 127, /* LNA4, dB */
|
||||
120, 120, 127, /* LT1 CBAND */
|
||||
314, /* max RF gain in 10th of dB */
|
||||
33, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
|
||||
1023, /* ramp_max = maximum X used on the ramp */
|
||||
(8 << 10) | 743, /* RF_RAMP3, LNA 1 = 0dB */
|
||||
(0 << 10) | 1023, /* RF_RAMP4, LNA 1 */
|
||||
(15 << 10) | 469, /* RF_RAMP5, LNA 2 = 0dB */
|
||||
(0 << 10) | 742, /* RF_RAMP6, LNA 2 */
|
||||
(9 << 10) | 234, /* RF_RAMP7, LNA 3 = 0dB */
|
||||
(0 << 10) | 468, /* RF_RAMP8, LNA 3 */
|
||||
(9 << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */
|
||||
(0 << 10) | 233, /* GAIN_4_2, LNA 4 */
|
||||
};
|
||||
|
||||
static const u16 rf_ramp_pwm_vhf[] = {
|
||||
404, /* max RF gain in 10th of dB */
|
||||
25, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
|
||||
1011, /* ramp_max = maximum X used on the ramp */
|
||||
(6 << 10) | 417, /* 0x2c, LNA 1 = 13.2dB */
|
||||
(0 << 10) | 756, /* 0x2d, LNA 1 */
|
||||
(16 << 10) | 756, /* 0x2e, LNA 2 = 10.5dB */
|
||||
(0 << 10) | 1011, /* 0x2f, LNA 2 */
|
||||
(16 << 10) | 290, /* 0x30, LNA 3 = 5dB */
|
||||
(0 << 10) | 417, /* 0x31, LNA 3 */
|
||||
(7 << 10) | 0, /* GAIN_4_1, LNA 4 = 12.5dB */
|
||||
(0 << 10) | 290, /* GAIN_4_2, LNA 4 */
|
||||
398, /* max RF gain in 10th of dB */
|
||||
24, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
|
||||
954, /* ramp_max = maximum X used on the ramp */
|
||||
(7 << 10) | 0, /* RF_RAMP3, LNA 1 = 13.2dB */
|
||||
(0 << 10) | 290, /* RF_RAMP4, LNA 1 */
|
||||
(16 << 10) | 699, /* RF_RAMP5, LNA 2 = 10.5dB */
|
||||
(0 << 10) | 954, /* RF_RAMP6, LNA 2 */
|
||||
(17 << 10) | 580, /* RF_RAMP7, LNA 3 = 5dB */
|
||||
(0 << 10) | 699, /* RF_RAMP8, LNA 3 */
|
||||
(7 << 10) | 290, /* GAIN_4_1, LNA 4 = 12.5dB */
|
||||
(0 << 10) | 580, /* GAIN_4_2, LNA 4 */
|
||||
};
|
||||
|
||||
static const u16 rf_ramp_pwm_uhf[] = {
|
||||
404, /* max RF gain in 10th of dB */
|
||||
25, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
|
||||
1011, /* ramp_max = maximum X used on the ramp */
|
||||
(6 << 10) | 417, /* 0x2c, LNA 1 = 13.2dB */
|
||||
(0 << 10) | 756, /* 0x2d, LNA 1 */
|
||||
(16 << 10) | 756, /* 0x2e, LNA 2 = 10.5dB */
|
||||
(0 << 10) | 1011, /* 0x2f, LNA 2 */
|
||||
(16 << 10) | 0, /* 0x30, LNA 3 = 5dB */
|
||||
(0 << 10) | 127, /* 0x31, LNA 3 */
|
||||
(7 << 10) | 127, /* GAIN_4_1, LNA 4 = 12.5dB */
|
||||
(0 << 10) | 417, /* GAIN_4_2, LNA 4 */
|
||||
398, /* max RF gain in 10th of dB */
|
||||
24, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
|
||||
954, /* ramp_max = maximum X used on the ramp */
|
||||
(7 << 10) | 0, /* RF_RAMP3, LNA 1 = 13.2dB */
|
||||
(0 << 10) | 290, /* RF_RAMP4, LNA 1 */
|
||||
(16 << 10) | 699, /* RF_RAMP5, LNA 2 = 10.5dB */
|
||||
(0 << 10) | 954, /* RF_RAMP6, LNA 2 */
|
||||
(17 << 10) | 580, /* RF_RAMP7, LNA 3 = 5dB */
|
||||
(0 << 10) | 699, /* RF_RAMP8, LNA 3 */
|
||||
(7 << 10) | 290, /* GAIN_4_1, LNA 4 = 12.5dB */
|
||||
(0 << 10) | 580, /* GAIN_4_2, LNA 4 */
|
||||
};
|
||||
|
||||
static const u16 bb_ramp_boost[] = {
|
||||
550, /* max BB gain in 10th of dB */
|
||||
260, 260, 26, /* BB1, 26dB */
|
||||
290, 550, 29, /* BB2, 29dB */
|
||||
};
|
||||
|
||||
static const u16 bb_ramp_pwm_normal[] = {
|
||||
500, /* max RF gain in 10th of dB */
|
||||
8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x34 */
|
||||
400,
|
||||
(2 << 9) | 0, /* 0x35 = 21dB */
|
||||
(0 << 9) | 168, /* 0x36 */
|
||||
(2 << 9) | 168, /* 0x37 = 29dB */
|
||||
(0 << 9) | 400, /* 0x38 */
|
||||
static const u16 rf_ramp_pwm_sband[] = {
|
||||
253, /* max RF gain in 10th of dB */
|
||||
38, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
|
||||
961,
|
||||
(4 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.1dB */
|
||||
(0 << 10) | 508, /* RF_RAMP4, LNA 1 */
|
||||
(9 << 10) | 508, /* RF_RAMP5, LNA 2 = 11.2dB */
|
||||
(0 << 10) | 961, /* RF_RAMP6, LNA 2 */
|
||||
(0 << 10) | 0, /* RF_RAMP7, LNA 3 = 0dB */
|
||||
(0 << 10) | 0, /* RF_RAMP8, LNA 3 */
|
||||
(0 << 10) | 0, /* GAIN_4_1, LNA 4 = 0dB */
|
||||
(0 << 10) | 0, /* GAIN_4_2, LNA 4 */
|
||||
};
|
||||
|
||||
struct slope {
|
||||
|
|
@ -1089,70 +1070,69 @@ static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
|
|||
void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
|
||||
{
|
||||
struct dib0090_state *state = fe->tuner_priv;
|
||||
/* reset the AGC */
|
||||
u16 *bb_ramp = (u16 *)&bb_ramp_pwm_normal; /* default baseband config */
|
||||
u16 *rf_ramp = NULL;
|
||||
u8 en_pwm_rf_mux = 1;
|
||||
|
||||
/* reset the AGC */
|
||||
if (state->config->use_pwm_agc) {
|
||||
#ifdef CONFIG_BAND_SBAND
|
||||
if (state->current_band == BAND_SBAND) {
|
||||
dib0090_set_rframp_pwm(state, rf_ramp_pwm_sband);
|
||||
dib0090_set_bbramp_pwm(state, bb_ramp_pwm_boost);
|
||||
} else
|
||||
#endif
|
||||
#ifdef CONFIG_BAND_CBAND
|
||||
if (state->current_band == BAND_CBAND) {
|
||||
if (state->identity.in_soc) {
|
||||
dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
|
||||
bb_ramp = (u16 *)&bb_ramp_pwm_normal_socs;
|
||||
if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
|
||||
dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_8090);
|
||||
else if (state->identity.version == SOC_7090_P1G_11R1
|
||||
|| state->identity.version == SOC_7090_P1G_21R1) {
|
||||
rf_ramp = (u16 *)&rf_ramp_pwm_cband_8090;
|
||||
else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1) {
|
||||
if (state->config->is_dib7090e) {
|
||||
if (state->rf_ramp == NULL)
|
||||
dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090e_sensitivity);
|
||||
rf_ramp = (u16 *)&rf_ramp_pwm_cband_7090e_sensitivity;
|
||||
else
|
||||
dib0090_set_rframp_pwm(state, state->rf_ramp);
|
||||
rf_ramp = (u16 *)state->rf_ramp;
|
||||
} else
|
||||
dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090);
|
||||
rf_ramp = (u16 *)&rf_ramp_pwm_cband_7090p;
|
||||
}
|
||||
} else {
|
||||
dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband);
|
||||
dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
|
||||
}
|
||||
} else
|
||||
rf_ramp = (u16 *)&rf_ramp_pwm_cband;
|
||||
} else
|
||||
#endif
|
||||
#ifdef CONFIG_BAND_VHF
|
||||
if (state->current_band == BAND_VHF) {
|
||||
if (state->identity.in_soc) {
|
||||
dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
|
||||
} else {
|
||||
dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf);
|
||||
dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (state->identity.in_soc) {
|
||||
if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
|
||||
dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_8090);
|
||||
else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
|
||||
dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_7090);
|
||||
dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
|
||||
} else {
|
||||
dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf);
|
||||
dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
|
||||
}
|
||||
}
|
||||
|
||||
if (state->rf_ramp[0] != 0)
|
||||
dib0090_write_reg(state, 0x32, (3 << 11));
|
||||
if (state->current_band == BAND_VHF) {
|
||||
if (state->identity.in_soc) {
|
||||
bb_ramp = (u16 *)&bb_ramp_pwm_normal_socs;
|
||||
/* rf_ramp = &rf_ramp_pwm_vhf_socs; */ /* TODO */
|
||||
} else
|
||||
rf_ramp = (u16 *)&rf_ramp_pwm_vhf;
|
||||
} else if (state->current_band == BAND_UHF) {
|
||||
if (state->identity.in_soc) {
|
||||
bb_ramp = (u16 *)&bb_ramp_pwm_normal_socs;
|
||||
if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
|
||||
rf_ramp = (u16 *)&rf_ramp_pwm_uhf_8090;
|
||||
else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
|
||||
rf_ramp = (u16 *)&rf_ramp_pwm_uhf_7090;
|
||||
} else
|
||||
rf_ramp = (u16 *)&rf_ramp_pwm_uhf;
|
||||
}
|
||||
if (rf_ramp)
|
||||
dib0090_set_rframp_pwm(state, rf_ramp);
|
||||
dib0090_set_bbramp_pwm(state, bb_ramp);
|
||||
|
||||
/* activate the ramp generator using PWM control */
|
||||
dprintk("ramp RF gain = %d BAND = %s version = %d", state->rf_ramp[0], (state->current_band == BAND_CBAND) ? "CBAND" : "NOT CBAND", state->identity.version & 0x1f);
|
||||
|
||||
if ((state->rf_ramp[0] == 0) || (state->current_band == BAND_CBAND && (state->identity.version & 0x1f) <= P1D_E_F)) {
|
||||
dprintk("DE-Engage mux for direct gain reg control");
|
||||
en_pwm_rf_mux = 0;
|
||||
} else
|
||||
dprintk("Engage mux for PWM control");
|
||||
|
||||
dib0090_write_reg(state, 0x32, (en_pwm_rf_mux << 12) | (en_pwm_rf_mux << 11));
|
||||
|
||||
/* Set fast servo cutoff to start AGC; 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast*/
|
||||
if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
|
||||
dib0090_write_reg(state, 0x04, 3);
|
||||
else
|
||||
dib0090_write_reg(state, 0x32, (0 << 11));
|
||||
|
||||
dib0090_write_reg(state, 0x04, 0x03);
|
||||
dib0090_write_reg(state, 0x39, (1 << 10));
|
||||
dib0090_write_reg(state, 0x04, 1);
|
||||
dib0090_write_reg(state, 0x39, (1 << 10)); /* 0 gain by default */
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dib0090_pwm_gain_reset);
|
||||
|
||||
void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff)
|
||||
|
|
@ -1193,22 +1173,22 @@ int dib0090_gain_control(struct dvb_frontend *fe)
|
|||
#endif
|
||||
#ifdef CONFIG_BAND_VHF
|
||||
if (state->current_band == BAND_VHF && !state->identity.p1g) {
|
||||
dib0090_set_rframp(state, rf_ramp_vhf);
|
||||
dib0090_set_bbramp(state, bb_ramp_boost);
|
||||
dib0090_set_rframp(state, rf_ramp_pwm_vhf);
|
||||
dib0090_set_bbramp(state, bb_ramp_pwm_normal);
|
||||
} else
|
||||
#endif
|
||||
#ifdef CONFIG_BAND_CBAND
|
||||
if (state->current_band == BAND_CBAND && !state->identity.p1g) {
|
||||
dib0090_set_rframp(state, rf_ramp_cband);
|
||||
dib0090_set_bbramp(state, bb_ramp_boost);
|
||||
dib0090_set_rframp(state, rf_ramp_pwm_cband);
|
||||
dib0090_set_bbramp(state, bb_ramp_pwm_normal);
|
||||
} else
|
||||
#endif
|
||||
if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) {
|
||||
dib0090_set_rframp(state, rf_ramp_cband_broadmatching);
|
||||
dib0090_set_bbramp(state, bb_ramp_boost);
|
||||
dib0090_set_rframp(state, rf_ramp_pwm_cband_7090p);
|
||||
dib0090_set_bbramp(state, bb_ramp_pwm_normal_socs);
|
||||
} else {
|
||||
dib0090_set_rframp(state, rf_ramp_uhf);
|
||||
dib0090_set_bbramp(state, bb_ramp_boost);
|
||||
dib0090_set_rframp(state, rf_ramp_pwm_uhf);
|
||||
dib0090_set_bbramp(state, bb_ramp_pwm_normal);
|
||||
}
|
||||
|
||||
dib0090_write_reg(state, 0x32, 0);
|
||||
|
|
@ -1553,14 +1533,16 @@ static void dib0090_set_EFUSE(struct dib0090_state *state)
|
|||
|
||||
if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN))
|
||||
c = 32;
|
||||
else
|
||||
c += 14;
|
||||
if ((h >= HR_MAX) || (h <= HR_MIN))
|
||||
h = 34;
|
||||
if ((n >= POLY_MAX) || (n <= POLY_MIN))
|
||||
n = 3;
|
||||
|
||||
dib0090_write_reg(state, 0x13, (h << 10)) ;
|
||||
e2 = (n<<11) | ((h>>2)<<6) | (c);
|
||||
dib0090_write_reg(state, 0x2, e2) ; /* Load the BB_2 */
|
||||
dib0090_write_reg(state, 0x13, (h << 10));
|
||||
e2 = (n << 11) | ((h >> 2)<<6) | c;
|
||||
dib0090_write_reg(state, 0x2, e2); /* Load the BB_2 */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
#ifndef DIB3000MC_H
|
||||
#define DIB3000MC_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
|
||||
#include "dibx000_common.h"
|
||||
|
||||
struct dib3000mc_config {
|
||||
|
|
@ -39,8 +41,7 @@ struct dib3000mc_config {
|
|||
#define DEFAULT_DIB3000MC_I2C_ADDRESS 16
|
||||
#define DEFAULT_DIB3000P_I2C_ADDRESS 24
|
||||
|
||||
#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && \
|
||||
defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_DIB3000MC)
|
||||
extern struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap,
|
||||
u8 i2c_addr,
|
||||
struct dib3000mc_config *cfg);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef DIB7000M_H
|
||||
#define DIB7000M_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
|
||||
#include "dibx000_common.h"
|
||||
|
||||
struct dib7000m_config {
|
||||
|
|
@ -38,8 +40,7 @@ struct dib7000m_config {
|
|||
|
||||
#define DEFAULT_DIB7000M_I2C_ADDRESS 18
|
||||
|
||||
#if defined(CONFIG_DVB_DIB7000M) || (defined(CONFIG_DVB_DIB7000M_MODULE) && \
|
||||
defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_DIB7000M)
|
||||
extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
|
||||
u8 i2c_addr,
|
||||
struct dib7000m_config *cfg);
|
||||
|
|
|
|||
|
|
@ -429,6 +429,13 @@ int dib7000p_get_agc_values(struct dvb_frontend *fe,
|
|||
}
|
||||
EXPORT_SYMBOL(dib7000p_get_agc_values);
|
||||
|
||||
int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v)
|
||||
{
|
||||
struct dib7000p_state *state = fe->demodulator_priv;
|
||||
return dib7000p_write_word(state, 108, v);
|
||||
}
|
||||
EXPORT_SYMBOL(dib7000p_set_agc1_min);
|
||||
|
||||
static void dib7000p_reset_pll(struct dib7000p_state *state)
|
||||
{
|
||||
struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
|
||||
|
|
@ -821,6 +828,7 @@ static int dib7000p_agc_startup(struct dvb_frontend *demod)
|
|||
u8 agc_split;
|
||||
u16 reg;
|
||||
u32 upd_demod_gain_period = 0x1000;
|
||||
s32 frequency_offset = 0;
|
||||
|
||||
switch (state->agc_state) {
|
||||
case 0:
|
||||
|
|
@ -841,7 +849,14 @@ static int dib7000p_agc_startup(struct dvb_frontend *demod)
|
|||
if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
|
||||
return -1;
|
||||
|
||||
dib7000p_set_dds(state, 0);
|
||||
if (demod->ops.tuner_ops.get_frequency) {
|
||||
u32 frequency_tuner;
|
||||
|
||||
demod->ops.tuner_ops.get_frequency(demod, &frequency_tuner);
|
||||
frequency_offset = (s32)frequency_tuner / 1000 - ch->frequency / 1000;
|
||||
}
|
||||
|
||||
dib7000p_set_dds(state, frequency_offset);
|
||||
ret = 7;
|
||||
(*agc_state)++;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef DIB7000P_H
|
||||
#define DIB7000P_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
|
||||
#include "dibx000_common.h"
|
||||
|
||||
struct dib7000p_config {
|
||||
|
|
@ -44,8 +46,7 @@ struct dib7000p_config {
|
|||
|
||||
#define DEFAULT_DIB7000P_I2C_ADDRESS 18
|
||||
|
||||
#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && \
|
||||
defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_DIB7000P)
|
||||
extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
|
||||
extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
|
||||
extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
|
||||
|
|
@ -62,6 +63,7 @@ extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe);
|
|||
extern int dib7090_slave_reset(struct dvb_frontend *fe);
|
||||
extern int dib7000p_get_agc_values(struct dvb_frontend *fe,
|
||||
u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd);
|
||||
extern int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v);
|
||||
#else
|
||||
static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
|
||||
{
|
||||
|
|
@ -153,6 +155,12 @@ static inline int dib7000p_get_agc_values(struct dvb_frontend *fe,
|
|||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -33,6 +33,8 @@ struct dib8000_config {
|
|||
u8 output_mode;
|
||||
u8 refclksel;
|
||||
u8 enMpegOutput:1;
|
||||
|
||||
struct dibx000_bandwidth_config *plltable;
|
||||
};
|
||||
|
||||
#define DEFAULT_DIB8000_I2C_ADDRESS 18
|
||||
|
|
@ -58,7 +60,7 @@ extern int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ);
|
|||
extern u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
|
||||
uint8_t op, uint32_t timf);
|
||||
extern int dib8000_update_pll(struct dvb_frontend *fe,
|
||||
struct dibx000_bandwidth_config *pll);
|
||||
struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio);
|
||||
extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
|
||||
extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe);
|
||||
extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
|
||||
|
|
@ -147,7 +149,7 @@ static inline u32 dib8000_ctrl_timf(struct dvb_frontend *fe,
|
|||
return 0;
|
||||
}
|
||||
static inline int dib8000_update_pll(struct dvb_frontend *fe,
|
||||
struct dibx000_bandwidth_config *pll)
|
||||
struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
|
|
|
|||
|
|
@ -193,7 +193,8 @@ enum frontend_tune_state {
|
|||
CT_DEMOD_STEP_8,
|
||||
CT_DEMOD_STEP_9,
|
||||
CT_DEMOD_STEP_10,
|
||||
CT_DEMOD_SEARCH_NEXT = 41,
|
||||
CT_DEMOD_STEP_11,
|
||||
CT_DEMOD_SEARCH_NEXT = 51,
|
||||
CT_DEMOD_STEP_LOCKED,
|
||||
CT_DEMOD_STOP,
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#ifndef _DRXD_H_
|
||||
#define _DRXD_H_
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
|
|
@ -51,8 +52,7 @@ struct drxd_config {
|
|||
s16(*osc_deviation) (void *priv, s16 dev, int flag);
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_DRXD) || \
|
||||
(defined(CONFIG_DVB_DRXD_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_DRXD)
|
||||
extern
|
||||
struct dvb_frontend *drxd_attach(const struct drxd_config *config,
|
||||
void *priv, struct i2c_adapter *i2c,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef _DRXK_H_
|
||||
#define _DRXK_H_
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
|
|
@ -52,8 +53,7 @@ struct drxk_config {
|
|||
int qam_demod_parameter_count;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_DRXK) || (defined(CONFIG_DVB_DRXK_MODULE) \
|
||||
&& defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_DRXK)
|
||||
extern struct dvb_frontend *drxk_attach(const struct drxk_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -1947,8 +1947,7 @@ static int ShutDown(struct drxk_state *state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus,
|
||||
u32 Time)
|
||||
static int GetLockStatus(struct drxk_state *state, u32 *pLockStatus)
|
||||
{
|
||||
int status = -EINVAL;
|
||||
|
||||
|
|
@ -2490,32 +2489,6 @@ error:
|
|||
return status;
|
||||
}
|
||||
|
||||
static int ReadIFAgc(struct drxk_state *state, u32 *pValue)
|
||||
{
|
||||
u16 agcDacLvl;
|
||||
int status;
|
||||
u16 Level = 0;
|
||||
|
||||
dprintk(1, "\n");
|
||||
|
||||
status = read16(state, IQM_AF_AGC_IF__A, &agcDacLvl);
|
||||
if (status < 0) {
|
||||
printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
|
||||
return status;
|
||||
}
|
||||
|
||||
*pValue = 0;
|
||||
|
||||
if (agcDacLvl > DRXK_AGC_DAC_OFFSET)
|
||||
Level = agcDacLvl - DRXK_AGC_DAC_OFFSET;
|
||||
if (Level < 14000)
|
||||
*pValue = (14000 - Level) / 4;
|
||||
else
|
||||
*pValue = 0;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int GetQAMSignalToNoise(struct drxk_state *state,
|
||||
s32 *pSignalToNoise)
|
||||
{
|
||||
|
|
@ -2654,12 +2627,7 @@ static int GetDVBTSignalToNoise(struct drxk_state *state,
|
|||
/* log(x) x = (16bits + 16bits) << 15 ->32 bits */
|
||||
c = Log10Times100(SqrErrIQ);
|
||||
|
||||
iMER = a + b;
|
||||
/* No negative MER, clip to zero */
|
||||
if (iMER > c)
|
||||
iMER -= c;
|
||||
else
|
||||
iMER = 0;
|
||||
iMER = a + b - c;
|
||||
}
|
||||
*pSignalToNoise = iMER;
|
||||
|
||||
|
|
@ -6380,46 +6348,257 @@ static int drxk_set_parameters(struct dvb_frontend *fe)
|
|||
fe->ops.tuner_ops.get_if_frequency(fe, &IF);
|
||||
Start(state, 0, IF);
|
||||
|
||||
/* After set_frontend, stats aren't avaliable */
|
||||
p->strength.stat[0].scale = FE_SCALE_RELATIVE;
|
||||
p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
|
||||
/* printk(KERN_DEBUG "drxk: %s IF=%d done\n", __func__, IF); */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
static int get_strength(struct drxk_state *state, u64 *strength)
|
||||
{
|
||||
struct drxk_state *state = fe->demodulator_priv;
|
||||
u32 stat;
|
||||
int status;
|
||||
struct SCfgAgc rfAgc, ifAgc;
|
||||
u32 totalGain = 0;
|
||||
u32 atten = 0;
|
||||
u32 agcRange = 0;
|
||||
u16 scu_lvl = 0;
|
||||
u16 scu_coc = 0;
|
||||
/* FIXME: those are part of the tuner presets */
|
||||
u16 tunerRfGain = 50; /* Default value on az6007 driver */
|
||||
u16 tunerIfGain = 40; /* Default value on az6007 driver */
|
||||
|
||||
dprintk(1, "\n");
|
||||
*strength = 0;
|
||||
|
||||
if (state->m_DrxkState == DRXK_NO_DEV)
|
||||
return -ENODEV;
|
||||
if (state->m_DrxkState == DRXK_UNINITIALIZED)
|
||||
return -EAGAIN;
|
||||
if (IsDVBT(state)) {
|
||||
rfAgc = state->m_dvbtRfAgcCfg;
|
||||
ifAgc = state->m_dvbtIfAgcCfg;
|
||||
} else if (IsQAM(state)) {
|
||||
rfAgc = state->m_qamRfAgcCfg;
|
||||
ifAgc = state->m_qamIfAgcCfg;
|
||||
} else {
|
||||
rfAgc = state->m_atvRfAgcCfg;
|
||||
ifAgc = state->m_atvIfAgcCfg;
|
||||
}
|
||||
|
||||
if (rfAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
|
||||
/* SCU outputLevel */
|
||||
status = read16(state, SCU_RAM_AGC_RF_IACCU_HI__A, &scu_lvl);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
/* SCU c.o.c. */
|
||||
read16(state, SCU_RAM_AGC_RF_IACCU_HI_CO__A, &scu_coc);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
if (((u32) scu_lvl + (u32) scu_coc) < 0xffff)
|
||||
rfAgc.outputLevel = scu_lvl + scu_coc;
|
||||
else
|
||||
rfAgc.outputLevel = 0xffff;
|
||||
|
||||
/* Take RF gain into account */
|
||||
totalGain += tunerRfGain;
|
||||
|
||||
/* clip output value */
|
||||
if (rfAgc.outputLevel < rfAgc.minOutputLevel)
|
||||
rfAgc.outputLevel = rfAgc.minOutputLevel;
|
||||
if (rfAgc.outputLevel > rfAgc.maxOutputLevel)
|
||||
rfAgc.outputLevel = rfAgc.maxOutputLevel;
|
||||
|
||||
agcRange = (u32) (rfAgc.maxOutputLevel - rfAgc.minOutputLevel);
|
||||
if (agcRange > 0) {
|
||||
atten += 100UL *
|
||||
((u32)(tunerRfGain)) *
|
||||
((u32)(rfAgc.outputLevel - rfAgc.minOutputLevel))
|
||||
/ agcRange;
|
||||
}
|
||||
}
|
||||
|
||||
if (ifAgc.ctrlMode == DRXK_AGC_CTRL_AUTO) {
|
||||
status = read16(state, SCU_RAM_AGC_IF_IACCU_HI__A,
|
||||
&ifAgc.outputLevel);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
status = read16(state, SCU_RAM_AGC_INGAIN_TGT_MIN__A,
|
||||
&ifAgc.top);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
/* Take IF gain into account */
|
||||
totalGain += (u32) tunerIfGain;
|
||||
|
||||
/* clip output value */
|
||||
if (ifAgc.outputLevel < ifAgc.minOutputLevel)
|
||||
ifAgc.outputLevel = ifAgc.minOutputLevel;
|
||||
if (ifAgc.outputLevel > ifAgc.maxOutputLevel)
|
||||
ifAgc.outputLevel = ifAgc.maxOutputLevel;
|
||||
|
||||
agcRange = (u32) (ifAgc.maxOutputLevel - ifAgc.minOutputLevel);
|
||||
if (agcRange > 0) {
|
||||
atten += 100UL *
|
||||
((u32)(tunerIfGain)) *
|
||||
((u32)(ifAgc.outputLevel - ifAgc.minOutputLevel))
|
||||
/ agcRange;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert to 0..65535 scale.
|
||||
* If it can't be measured (AGC is disabled), just show 100%.
|
||||
*/
|
||||
if (totalGain > 0)
|
||||
*strength = (65535UL * atten / totalGain / 100);
|
||||
else
|
||||
*strength = 65535;
|
||||
|
||||
*status = 0;
|
||||
GetLockStatus(state, &stat, 0);
|
||||
if (stat == MPEG_LOCK)
|
||||
*status |= 0x1f;
|
||||
if (stat == FEC_LOCK)
|
||||
*status |= 0x0f;
|
||||
if (stat == DEMOD_LOCK)
|
||||
*status |= 0x07;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
static int drxk_get_stats(struct dvb_frontend *fe)
|
||||
{
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
struct drxk_state *state = fe->demodulator_priv;
|
||||
|
||||
dprintk(1, "\n");
|
||||
int status;
|
||||
u32 stat;
|
||||
u16 reg16;
|
||||
u32 post_bit_count;
|
||||
u32 post_bit_err_count;
|
||||
u32 post_bit_error_scale;
|
||||
u32 pre_bit_err_count;
|
||||
u32 pre_bit_count;
|
||||
u32 pkt_count;
|
||||
u32 pkt_error_count;
|
||||
s32 cnr;
|
||||
|
||||
if (state->m_DrxkState == DRXK_NO_DEV)
|
||||
return -ENODEV;
|
||||
if (state->m_DrxkState == DRXK_UNINITIALIZED)
|
||||
return -EAGAIN;
|
||||
|
||||
*ber = 0;
|
||||
/* get status */
|
||||
state->fe_status = 0;
|
||||
GetLockStatus(state, &stat);
|
||||
if (stat == MPEG_LOCK)
|
||||
state->fe_status |= 0x1f;
|
||||
if (stat == FEC_LOCK)
|
||||
state->fe_status |= 0x0f;
|
||||
if (stat == DEMOD_LOCK)
|
||||
state->fe_status |= 0x07;
|
||||
|
||||
/*
|
||||
* Estimate signal strength from AGC
|
||||
*/
|
||||
get_strength(state, &c->strength.stat[0].uvalue);
|
||||
c->strength.stat[0].scale = FE_SCALE_RELATIVE;
|
||||
|
||||
|
||||
if (stat >= DEMOD_LOCK) {
|
||||
GetSignalToNoise(state, &cnr);
|
||||
c->cnr.stat[0].svalue = cnr * 100;
|
||||
c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
} else {
|
||||
c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (stat < FEC_LOCK) {
|
||||
c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get post BER */
|
||||
|
||||
/* BER measurement is valid if at least FEC lock is achieved */
|
||||
|
||||
/* OFDM_EC_VD_REQ_SMB_CNT__A and/or OFDM_EC_VD_REQ_BIT_CNT can be written
|
||||
to set nr of symbols or bits over which
|
||||
to measure EC_VD_REG_ERR_BIT_CNT__A . See CtrlSetCfg(). */
|
||||
|
||||
/* Read registers for post/preViterbi BER calculation */
|
||||
status = read16(state, OFDM_EC_VD_ERR_BIT_CNT__A, ®16);
|
||||
if (status < 0)
|
||||
goto error;
|
||||
pre_bit_err_count = reg16;
|
||||
|
||||
status = read16(state, OFDM_EC_VD_IN_BIT_CNT__A , ®16);
|
||||
if (status < 0)
|
||||
goto error;
|
||||
pre_bit_count = reg16;
|
||||
|
||||
/* Number of bit-errors */
|
||||
status = read16(state, FEC_RS_NR_BIT_ERRORS__A, ®16);
|
||||
if (status < 0)
|
||||
goto error;
|
||||
post_bit_err_count = reg16;
|
||||
|
||||
status = read16(state, FEC_RS_MEASUREMENT_PRESCALE__A, ®16);
|
||||
if (status < 0)
|
||||
goto error;
|
||||
post_bit_error_scale = reg16;
|
||||
|
||||
status = read16(state, FEC_RS_MEASUREMENT_PERIOD__A, ®16);
|
||||
if (status < 0)
|
||||
goto error;
|
||||
pkt_count = reg16;
|
||||
|
||||
status = read16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, ®16);
|
||||
if (status < 0)
|
||||
goto error;
|
||||
pkt_error_count = reg16;
|
||||
write16(state, SCU_RAM_FEC_ACCUM_PKT_FAILURES__A, 0);
|
||||
|
||||
post_bit_err_count *= post_bit_error_scale;
|
||||
|
||||
post_bit_count = pkt_count * 204 * 8;
|
||||
|
||||
/* Store the results */
|
||||
c->block_error.stat[0].scale = FE_SCALE_COUNTER;
|
||||
c->block_error.stat[0].uvalue += pkt_error_count;
|
||||
c->block_count.stat[0].scale = FE_SCALE_COUNTER;
|
||||
c->block_count.stat[0].uvalue += pkt_count;
|
||||
|
||||
c->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
|
||||
c->pre_bit_error.stat[0].uvalue += pre_bit_err_count;
|
||||
c->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
|
||||
c->pre_bit_count.stat[0].uvalue += pre_bit_count;
|
||||
|
||||
c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
|
||||
c->post_bit_error.stat[0].uvalue += post_bit_err_count;
|
||||
c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
|
||||
c->post_bit_count.stat[0].uvalue += post_bit_count;
|
||||
|
||||
error:
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
{
|
||||
struct drxk_state *state = fe->demodulator_priv;
|
||||
int rc;
|
||||
|
||||
dprintk(1, "\n");
|
||||
|
||||
rc = drxk_get_stats(fe);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
*status = state->fe_status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6427,7 +6606,7 @@ static int drxk_read_signal_strength(struct dvb_frontend *fe,
|
|||
u16 *strength)
|
||||
{
|
||||
struct drxk_state *state = fe->demodulator_priv;
|
||||
u32 val = 0;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
|
||||
dprintk(1, "\n");
|
||||
|
||||
|
|
@ -6436,8 +6615,7 @@ static int drxk_read_signal_strength(struct dvb_frontend *fe,
|
|||
if (state->m_DrxkState == DRXK_UNINITIALIZED)
|
||||
return -EAGAIN;
|
||||
|
||||
ReadIFAgc(state, &val);
|
||||
*strength = val & 0xffff;
|
||||
*strength = c->strength.stat[0].uvalue;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -6454,6 +6632,10 @@ static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
|
|||
return -EAGAIN;
|
||||
|
||||
GetSignalToNoise(state, &snr2);
|
||||
|
||||
/* No negative SNR, clip to zero */
|
||||
if (snr2 < 0)
|
||||
snr2 = 0;
|
||||
*snr = snr2 & 0xffff;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -6529,7 +6711,6 @@ static struct dvb_frontend_ops drxk_ops = {
|
|||
.get_tune_settings = drxk_get_tune_settings,
|
||||
|
||||
.read_status = drxk_read_status,
|
||||
.read_ber = drxk_read_ber,
|
||||
.read_signal_strength = drxk_read_signal_strength,
|
||||
.read_snr = drxk_read_snr,
|
||||
.read_ucblocks = drxk_read_ucblocks,
|
||||
|
|
@ -6538,6 +6719,7 @@ static struct dvb_frontend_ops drxk_ops = {
|
|||
struct dvb_frontend *drxk_attach(const struct drxk_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
struct dtv_frontend_properties *p;
|
||||
struct drxk_state *state = NULL;
|
||||
u8 adr = config->adr;
|
||||
int status;
|
||||
|
|
@ -6618,6 +6800,27 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config,
|
|||
} else if (init_drxk(state) < 0)
|
||||
goto error;
|
||||
|
||||
|
||||
/* Initialize stats */
|
||||
p = &state->frontend.dtv_property_cache;
|
||||
p->strength.len = 1;
|
||||
p->cnr.len = 1;
|
||||
p->block_error.len = 1;
|
||||
p->block_count.len = 1;
|
||||
p->pre_bit_error.len = 1;
|
||||
p->pre_bit_count.len = 1;
|
||||
p->post_bit_error.len = 1;
|
||||
p->post_bit_count.len = 1;
|
||||
|
||||
p->strength.stat[0].scale = FE_SCALE_RELATIVE;
|
||||
p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
|
||||
printk(KERN_INFO "drxk: frontend initialized.\n");
|
||||
return &state->frontend;
|
||||
|
||||
|
|
|
|||
|
|
@ -345,6 +345,8 @@ struct drxk_state {
|
|||
bool antenna_dvbt;
|
||||
u16 antenna_gpio;
|
||||
|
||||
fe_status_t fe_status;
|
||||
|
||||
/* Firmware */
|
||||
const char *microcode_name;
|
||||
struct completion fw_wait_load;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#define FEC_RS_COMM_EXEC_STOP 0x0
|
||||
#define FEC_RS_MEASUREMENT_PERIOD__A 0x1C30012
|
||||
#define FEC_RS_MEASUREMENT_PRESCALE__A 0x1C30013
|
||||
#define FEC_RS_NR_BIT_ERRORS__A 0x1C30014
|
||||
#define FEC_OC_MODE__A 0x1C40011
|
||||
#define FEC_OC_MODE_PARITY__M 0x1
|
||||
#define FEC_OC_DTO_MODE__A 0x1C40014
|
||||
|
|
@ -129,6 +130,8 @@
|
|||
#define OFDM_EC_SB_PRIOR__A 0x3410013
|
||||
#define OFDM_EC_SB_PRIOR_HI 0x0
|
||||
#define OFDM_EC_SB_PRIOR_LO 0x1
|
||||
#define OFDM_EC_VD_ERR_BIT_CNT__A 0x3420017
|
||||
#define OFDM_EC_VD_IN_BIT_CNT__A 0x3420018
|
||||
#define OFDM_EQ_TOP_TD_TPS_CONST__A 0x3010054
|
||||
#define OFDM_EQ_TOP_TD_TPS_CONST__M 0x3
|
||||
#define OFDM_EQ_TOP_TD_TPS_CONST_64QAM 0x2
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef DS3000_H
|
||||
#define DS3000_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct ds3000_config {
|
||||
|
|
@ -34,8 +35,7 @@ struct ds3000_config {
|
|||
void (*set_lock_led)(struct dvb_frontend *fe, int offon);
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_DS3000) || \
|
||||
(defined(CONFIG_DVB_DS3000_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_DS3000)
|
||||
extern struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@
|
|||
#ifndef DVB_DUMMY_FE_H
|
||||
#define DVB_DUMMY_FE_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
#if defined(CONFIG_DVB_DUMMY_FE) || (defined(CONFIG_DVB_DUMMY_FE_MODULE) && \
|
||||
defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_DUMMY_FE)
|
||||
extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
|
||||
extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void);
|
||||
extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef EC100_H
|
||||
#define EC100_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct ec100_config {
|
||||
|
|
@ -30,8 +31,7 @@ struct ec100_config {
|
|||
};
|
||||
|
||||
|
||||
#if defined(CONFIG_DVB_EC100) || \
|
||||
(defined(CONFIG_DVB_EC100_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_EC100)
|
||||
extern struct dvb_frontend *ec100_attach(const struct ec100_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#ifndef HD29L2_H
|
||||
#define HD29L2_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct hd29l2_config {
|
||||
|
|
@ -50,8 +51,7 @@ struct hd29l2_config {
|
|||
};
|
||||
|
||||
|
||||
#if defined(CONFIG_DVB_HD29L2) || \
|
||||
(defined(CONFIG_DVB_HD29L2_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_HD29L2)
|
||||
extern struct dvb_frontend *hd29l2_attach(const struct hd29l2_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -89,6 +89,30 @@ static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
|
|||
return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
static int isl6421_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
|
||||
{
|
||||
struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
|
||||
struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0,
|
||||
.buf = &isl6421->config,
|
||||
.len = sizeof(isl6421->config) };
|
||||
|
||||
switch (tone) {
|
||||
case SEC_TONE_ON:
|
||||
isl6421->config |= ISL6421_ENT1;
|
||||
break;
|
||||
case SEC_TONE_OFF:
|
||||
isl6421->config &= ~ISL6421_ENT1;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
isl6421->config |= isl6421->override_or;
|
||||
isl6421->config &= isl6421->override_and;
|
||||
|
||||
return (i2c_transfer(isl6421->i2c, &msg, 1) == 1) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
static void isl6421_release(struct dvb_frontend *fe)
|
||||
{
|
||||
/* power off */
|
||||
|
|
@ -100,7 +124,7 @@ static void isl6421_release(struct dvb_frontend *fe)
|
|||
}
|
||||
|
||||
struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
|
||||
u8 override_set, u8 override_clear)
|
||||
u8 override_set, u8 override_clear, bool override_tone)
|
||||
{
|
||||
struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL);
|
||||
if (!isl6421)
|
||||
|
|
@ -131,6 +155,8 @@ struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter
|
|||
/* override frontend ops */
|
||||
fe->ops.set_voltage = isl6421_set_voltage;
|
||||
fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage;
|
||||
if (override_tone)
|
||||
fe->ops.set_tone = isl6421_set_tone;
|
||||
|
||||
return fe;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,10 +42,10 @@
|
|||
#if IS_ENABLED(CONFIG_DVB_ISL6421)
|
||||
/* override_set and override_clear control which system register bits (above) to always set & clear */
|
||||
extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
|
||||
u8 override_set, u8 override_clear);
|
||||
u8 override_set, u8 override_clear, bool override_tone);
|
||||
#else
|
||||
static inline struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
|
||||
u8 override_set, u8 override_clear)
|
||||
u8 override_set, u8 override_clear, bool override_tone)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef IT913X_FE_H
|
||||
#define IT913X_FE_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
|
|
@ -38,8 +39,7 @@ struct ite_config {
|
|||
u8 read_slevel;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_IT913X_FE) || (defined(CONFIG_DVB_IT913X_FE_MODULE) && \
|
||||
defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_IT913X_FE)
|
||||
extern struct dvb_frontend *it913x_fe_attach(struct i2c_adapter *i2c_adap,
|
||||
u8 i2c_addr, struct ite_config *config);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#ifndef DVB_IX2505V_H
|
||||
#define DVB_IX2505V_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/i2c.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
|
|
@ -48,8 +49,7 @@ struct ix2505v_config {
|
|||
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_IX2505V) || \
|
||||
(defined(CONFIG_DVB_IX2505V_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_IX2505V)
|
||||
extern struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe,
|
||||
const struct ix2505v_config *config, struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef _LG2160_H_
|
||||
#define _LG2160_H_
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/i2c.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
|
|
@ -56,18 +57,17 @@ struct lg2160_config {
|
|||
u16 if_khz;
|
||||
|
||||
/* disable i2c repeater - 0:repeater enabled 1:repeater disabled */
|
||||
int deny_i2c_rptr:1;
|
||||
unsigned int deny_i2c_rptr:1;
|
||||
|
||||
/* spectral inversion - 0:disabled 1:enabled */
|
||||
int spectral_inversion:1;
|
||||
unsigned int spectral_inversion:1;
|
||||
|
||||
unsigned int output_if;
|
||||
enum lg2160_spi_clock spi_clock;
|
||||
enum lg_chip_type lg_chip;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_LG2160) || (defined(CONFIG_DVB_LG2160_MODULE) && \
|
||||
defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_LG2160)
|
||||
extern
|
||||
struct dvb_frontend *lg2160_attach(const struct lg2160_config *config,
|
||||
struct i2c_adapter *i2c_adap);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef _LGDT3305_H_
|
||||
#define _LGDT3305_H_
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/i2c.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
|
|
@ -73,8 +74,7 @@ struct lgdt3305_config {
|
|||
enum lgdt_demod_chip_type demod_chip;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_LGDT3305) || (defined(CONFIG_DVB_LGDT3305_MODULE) && \
|
||||
defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_LGDT3305)
|
||||
extern
|
||||
struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
|
||||
struct i2c_adapter *i2c_adap);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#ifndef LGS8GL5_H
|
||||
#define LGS8GL5_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct lgs8gl5_config {
|
||||
|
|
@ -30,8 +31,7 @@ struct lgs8gl5_config {
|
|||
u8 demod_address;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_LGS8GL5) || \
|
||||
(defined(CONFIG_DVB_LGS8GL5_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_LGS8GL5)
|
||||
extern struct dvb_frontend *lgs8gl5_attach(
|
||||
const struct lgs8gl5_config *config, struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#ifndef __LGS8GXX_H__
|
||||
#define __LGS8GXX_H__
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
|
|
@ -79,8 +80,7 @@ struct lgs8gxx_config {
|
|||
u8 tuner_address;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_LGS8GXX) || \
|
||||
(defined(CONFIG_DVB_LGS8GXX_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_LGS8GXX)
|
||||
extern struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#ifndef _LNBH24_H
|
||||
#define _LNBH24_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
|
||||
/* system register bits */
|
||||
#define LNBH24_OLF 0x01
|
||||
#define LNBH24_OTF 0x02
|
||||
|
|
@ -35,8 +37,7 @@
|
|||
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
|
||||
&& defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_LNBP21)
|
||||
/* override_set and override_clear control which
|
||||
system register bits (above) to always set & clear */
|
||||
extern struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#ifndef _LNBP21_H
|
||||
#define _LNBP21_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
|
||||
/* system register bits */
|
||||
/* [RO] 0=OK; 1=over current limit flag */
|
||||
#define LNBP21_OLF 0x01
|
||||
|
|
@ -55,8 +57,7 @@
|
|||
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
|
||||
&& defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_LNBP21)
|
||||
/* override_set and override_clear control which
|
||||
system register bits (above) to always set & clear */
|
||||
extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#ifndef _LNBP22_H
|
||||
#define _LNBP22_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
|
||||
/* Enable */
|
||||
#define LNBP22_EN 0x10
|
||||
/* Voltage selection */
|
||||
|
|
@ -37,8 +39,7 @@
|
|||
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
#if defined(CONFIG_DVB_LNBP22) || \
|
||||
(defined(CONFIG_DVB_LNBP22_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_LNBP22)
|
||||
/*
|
||||
* override_set and override_clear control which system register bits (above)
|
||||
* to always set & clear
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#ifndef M88RS2000_H
|
||||
#define M88RS2000_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
|
|
@ -40,8 +41,7 @@ enum {
|
|||
CALL_IS_READ,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_M88RS2000) || (defined(CONFIG_DVB_M88RS2000_MODULE) && \
|
||||
defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_M88RS2000)
|
||||
extern struct dvb_frontend *m88rs2000_attach(
|
||||
const struct m88rs2000_config *config, struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -20,10 +20,24 @@
|
|||
#include "dvb_frontend.h"
|
||||
#include "mb86a20s.h"
|
||||
|
||||
#define NUM_LAYERS 3
|
||||
|
||||
static int debug = 1;
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
|
||||
|
||||
enum mb86a20s_bandwidth {
|
||||
MB86A20S_13SEG = 0,
|
||||
MB86A20S_13SEG_PARTIAL = 1,
|
||||
MB86A20S_1SEG = 2,
|
||||
MB86A20S_3SEG = 3,
|
||||
};
|
||||
|
||||
u8 mb86a20s_subchannel[] = {
|
||||
0xb0, 0xc0, 0xd0, 0xe0,
|
||||
0xf0, 0x00, 0x10, 0x20,
|
||||
};
|
||||
|
||||
struct mb86a20s_state {
|
||||
struct i2c_adapter *i2c;
|
||||
const struct mb86a20s_config *config;
|
||||
|
|
@ -31,7 +45,13 @@ struct mb86a20s_state {
|
|||
|
||||
struct dvb_frontend frontend;
|
||||
|
||||
u32 estimated_rate[3];
|
||||
u32 if_freq;
|
||||
enum mb86a20s_bandwidth bw;
|
||||
bool inversion;
|
||||
u32 subchannel;
|
||||
|
||||
u32 estimated_rate[NUM_LAYERS];
|
||||
unsigned long get_strength_time;
|
||||
|
||||
bool need_init;
|
||||
};
|
||||
|
|
@ -47,35 +67,33 @@ struct regdata {
|
|||
* Initialization sequence: Use whatevere default values that PV SBTVD
|
||||
* does on its initialisation, obtained via USB snoop
|
||||
*/
|
||||
static struct regdata mb86a20s_init[] = {
|
||||
static struct regdata mb86a20s_init1[] = {
|
||||
{ 0x70, 0x0f },
|
||||
{ 0x70, 0xff },
|
||||
{ 0x08, 0x01 },
|
||||
{ 0x09, 0x3e },
|
||||
{ 0x50, 0xd1 }, { 0x51, 0x22 },
|
||||
{ 0x39, 0x01 },
|
||||
{ 0x71, 0x00 },
|
||||
{ 0x28, 0x2a }, { 0x29, 0x00 }, { 0x2a, 0xff }, { 0x2b, 0x80 },
|
||||
{ 0x28, 0x20 }, { 0x29, 0x33 }, { 0x2a, 0xdf }, { 0x2b, 0xa9 },
|
||||
{ 0x50, 0xd1 }, { 0x51, 0x20 },
|
||||
};
|
||||
|
||||
static struct regdata mb86a20s_init2[] = {
|
||||
{ 0x28, 0x22 }, { 0x29, 0x00 }, { 0x2a, 0x1f }, { 0x2b, 0xf0 },
|
||||
{ 0x3b, 0x21 },
|
||||
{ 0x3c, 0x3a },
|
||||
{ 0x3c, 0x38 },
|
||||
{ 0x01, 0x0d },
|
||||
{ 0x04, 0x08 }, { 0x05, 0x05 },
|
||||
{ 0x04, 0x08 }, { 0x05, 0x03 },
|
||||
{ 0x04, 0x0e }, { 0x05, 0x00 },
|
||||
{ 0x04, 0x0f }, { 0x05, 0x14 },
|
||||
{ 0x04, 0x0b }, { 0x05, 0x8c },
|
||||
{ 0x04, 0x0f }, { 0x05, 0x37 },
|
||||
{ 0x04, 0x0b }, { 0x05, 0x78 },
|
||||
{ 0x04, 0x00 }, { 0x05, 0x00 },
|
||||
{ 0x04, 0x01 }, { 0x05, 0x07 },
|
||||
{ 0x04, 0x02 }, { 0x05, 0x0f },
|
||||
{ 0x04, 0x03 }, { 0x05, 0xa0 },
|
||||
{ 0x04, 0x01 }, { 0x05, 0x1e },
|
||||
{ 0x04, 0x02 }, { 0x05, 0x07 },
|
||||
{ 0x04, 0x03 }, { 0x05, 0xd0 },
|
||||
{ 0x04, 0x09 }, { 0x05, 0x00 },
|
||||
{ 0x04, 0x0a }, { 0x05, 0xff },
|
||||
{ 0x04, 0x27 }, { 0x05, 0x64 },
|
||||
{ 0x04, 0x27 }, { 0x05, 0x00 },
|
||||
{ 0x04, 0x28 }, { 0x05, 0x00 },
|
||||
{ 0x04, 0x1e }, { 0x05, 0xff },
|
||||
{ 0x04, 0x29 }, { 0x05, 0x0a },
|
||||
{ 0x04, 0x32 }, { 0x05, 0x0a },
|
||||
{ 0x04, 0x1e }, { 0x05, 0x00 },
|
||||
{ 0x04, 0x29 }, { 0x05, 0x64 },
|
||||
{ 0x04, 0x32 }, { 0x05, 0x02 },
|
||||
{ 0x04, 0x14 }, { 0x05, 0x02 },
|
||||
{ 0x04, 0x04 }, { 0x05, 0x00 },
|
||||
{ 0x04, 0x05 }, { 0x05, 0x22 },
|
||||
|
|
@ -142,39 +160,39 @@ static struct regdata mb86a20s_init[] = {
|
|||
{ 0x50, 0xd5 }, { 0x51, 0x01 }, /* Serial */
|
||||
{ 0x50, 0xd6 }, { 0x51, 0x1f },
|
||||
{ 0x50, 0xd2 }, { 0x51, 0x03 },
|
||||
{ 0x50, 0xd7 }, { 0x51, 0x3f },
|
||||
{ 0x28, 0x74 }, { 0x29, 0x00 }, { 0x28, 0x74 }, { 0x29, 0x40 },
|
||||
{ 0x28, 0x46 }, { 0x29, 0x2c }, { 0x28, 0x46 }, { 0x29, 0x0c },
|
||||
{ 0x50, 0xd7 }, { 0x51, 0xbf },
|
||||
{ 0x28, 0x74 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xff },
|
||||
{ 0x28, 0x46 }, { 0x29, 0x00 }, { 0x2a, 0x1a }, { 0x2b, 0x0c },
|
||||
|
||||
{ 0x04, 0x40 }, { 0x05, 0x00 },
|
||||
{ 0x28, 0x00 }, { 0x29, 0x10 },
|
||||
{ 0x28, 0x05 }, { 0x29, 0x02 },
|
||||
{ 0x28, 0x00 }, { 0x2b, 0x08 },
|
||||
{ 0x28, 0x05 }, { 0x2b, 0x00 },
|
||||
{ 0x1c, 0x01 },
|
||||
{ 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x03 },
|
||||
{ 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0d },
|
||||
{ 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 },
|
||||
{ 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x01 },
|
||||
{ 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x21 },
|
||||
{ 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x29 },
|
||||
{ 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 },
|
||||
{ 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x31 },
|
||||
{ 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0e },
|
||||
{ 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x4e },
|
||||
{ 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x46 },
|
||||
{ 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f },
|
||||
{ 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x56 },
|
||||
{ 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x35 },
|
||||
{ 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbe },
|
||||
{ 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0x84 },
|
||||
{ 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x03 }, { 0x2b, 0xee },
|
||||
{ 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x98 },
|
||||
{ 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x9f },
|
||||
{ 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xb2 },
|
||||
{ 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0xc2 },
|
||||
{ 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0x4a },
|
||||
{ 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbc },
|
||||
{ 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x04 }, { 0x2b, 0xba },
|
||||
{ 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0x14 },
|
||||
{ 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x1f },
|
||||
{ 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x18 },
|
||||
{ 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x12 },
|
||||
{ 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x30 },
|
||||
{ 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x37 },
|
||||
{ 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 },
|
||||
{ 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x09 },
|
||||
{ 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x06 },
|
||||
{ 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7b },
|
||||
{ 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x76 },
|
||||
{ 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7d },
|
||||
{ 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x08 },
|
||||
{ 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0b },
|
||||
{ 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 },
|
||||
{ 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf2 },
|
||||
{ 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf3 },
|
||||
{ 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x05 },
|
||||
{ 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 },
|
||||
{ 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f },
|
||||
{ 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xef },
|
||||
{ 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xd8 },
|
||||
{ 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xf1 },
|
||||
{ 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x3d },
|
||||
{ 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x94 },
|
||||
{ 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xba },
|
||||
{ 0x50, 0x1e }, { 0x51, 0x5d },
|
||||
{ 0x50, 0x22 }, { 0x51, 0x00 },
|
||||
{ 0x50, 0x23 }, { 0x51, 0xc8 },
|
||||
|
|
@ -183,6 +201,8 @@ static struct regdata mb86a20s_init[] = {
|
|||
{ 0x50, 0x26 }, { 0x51, 0x00 },
|
||||
{ 0x50, 0x27 }, { 0x51, 0xc3 },
|
||||
{ 0x50, 0x39 }, { 0x51, 0x02 },
|
||||
{ 0xec, 0x0f },
|
||||
{ 0xeb, 0x1f },
|
||||
{ 0x28, 0x6a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 },
|
||||
{ 0xd0, 0x00 },
|
||||
};
|
||||
|
|
@ -308,15 +328,23 @@ static int mb86a20s_read_status(struct dvb_frontend *fe, fe_status_t *status)
|
|||
dev_dbg(&state->i2c->dev, "%s: Status = 0x%02x (state = %d)\n",
|
||||
__func__, *status, val);
|
||||
|
||||
return 0;
|
||||
return val;
|
||||
}
|
||||
|
||||
static int mb86a20s_read_signal_strength(struct dvb_frontend *fe)
|
||||
{
|
||||
struct mb86a20s_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
int rc;
|
||||
unsigned rf_max, rf_min, rf;
|
||||
|
||||
if (state->get_strength_time &&
|
||||
(!time_after(jiffies, state->get_strength_time)))
|
||||
return c->strength.stat[0].uvalue;
|
||||
|
||||
/* Reset its value if an error happen */
|
||||
c->strength.stat[0].uvalue = 0;
|
||||
|
||||
/* Does a binary search to get RF strength */
|
||||
rf_max = 0xfff;
|
||||
rf_min = 0;
|
||||
|
|
@ -331,7 +359,7 @@ static int mb86a20s_read_signal_strength(struct dvb_frontend *fe)
|
|||
rc = mb86a20s_writereg(state, 0x04, 0x20);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
rc = mb86a20s_writereg(state, 0x04, rf);
|
||||
rc = mb86a20s_writereg(state, 0x05, rf);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
|
|
@ -346,15 +374,19 @@ static int mb86a20s_read_signal_strength(struct dvb_frontend *fe)
|
|||
rf = (rf_max + rf_min) / 2;
|
||||
|
||||
/* Rescale it from 2^12 (4096) to 2^16 */
|
||||
rf <<= (16 - 12);
|
||||
rf = rf << (16 - 12);
|
||||
if (rf)
|
||||
rf |= (1 << 12) - 1;
|
||||
|
||||
dev_dbg(&state->i2c->dev,
|
||||
"%s: signal strength = %d (%d < RF=%d < %d)\n",
|
||||
__func__, rf, rf_min, rf >> 4, rf_max);
|
||||
return rf;
|
||||
c->strength.stat[0].uvalue = rf;
|
||||
state->get_strength_time = jiffies +
|
||||
msecs_to_jiffies(1000);
|
||||
return 0;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mb86a20s_get_modulation(struct mb86a20s_state *state,
|
||||
|
|
@ -534,12 +566,13 @@ static u32 isdbt_rate[3][5][4] = {
|
|||
};
|
||||
|
||||
static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer,
|
||||
u32 modulation, u32 fec, u32 interleaving,
|
||||
u32 modulation, u32 forward_error_correction,
|
||||
u32 interleaving,
|
||||
u32 segment)
|
||||
{
|
||||
struct mb86a20s_state *state = fe->demodulator_priv;
|
||||
u32 rate;
|
||||
int m, f, i;
|
||||
int mod, fec, guard;
|
||||
|
||||
/*
|
||||
* If modulation/fec/interleaving is not detected, the default is
|
||||
|
|
@ -550,54 +583,54 @@ static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer,
|
|||
case DQPSK:
|
||||
case QPSK:
|
||||
default:
|
||||
m = 0;
|
||||
mod = 0;
|
||||
break;
|
||||
case QAM_16:
|
||||
m = 1;
|
||||
mod = 1;
|
||||
break;
|
||||
case QAM_64:
|
||||
m = 2;
|
||||
mod = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (fec) {
|
||||
switch (forward_error_correction) {
|
||||
default:
|
||||
case FEC_1_2:
|
||||
case FEC_AUTO:
|
||||
f = 0;
|
||||
fec = 0;
|
||||
break;
|
||||
case FEC_2_3:
|
||||
f = 1;
|
||||
fec = 1;
|
||||
break;
|
||||
case FEC_3_4:
|
||||
f = 2;
|
||||
fec = 2;
|
||||
break;
|
||||
case FEC_5_6:
|
||||
f = 3;
|
||||
fec = 3;
|
||||
break;
|
||||
case FEC_7_8:
|
||||
f = 4;
|
||||
fec = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (interleaving) {
|
||||
default:
|
||||
case GUARD_INTERVAL_1_4:
|
||||
i = 0;
|
||||
guard = 0;
|
||||
break;
|
||||
case GUARD_INTERVAL_1_8:
|
||||
i = 1;
|
||||
guard = 1;
|
||||
break;
|
||||
case GUARD_INTERVAL_1_16:
|
||||
i = 2;
|
||||
guard = 2;
|
||||
break;
|
||||
case GUARD_INTERVAL_1_32:
|
||||
i = 3;
|
||||
guard = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Samples BER at BER_SAMPLING_RATE seconds */
|
||||
rate = isdbt_rate[m][f][i] * segment * BER_SAMPLING_RATE;
|
||||
rate = isdbt_rate[mod][fec][guard] * segment * BER_SAMPLING_RATE;
|
||||
|
||||
/* Avoids sampling too quickly or to overflow the register */
|
||||
if (rate < 256)
|
||||
|
|
@ -607,18 +640,18 @@ static void mb86a20s_layer_bitrate(struct dvb_frontend *fe, u32 layer,
|
|||
|
||||
dev_dbg(&state->i2c->dev,
|
||||
"%s: layer %c bitrate: %d kbps; counter = %d (0x%06x)\n",
|
||||
__func__, 'A' + layer, segment * isdbt_rate[m][f][i]/1000,
|
||||
__func__, 'A' + layer,
|
||||
segment * isdbt_rate[mod][fec][guard]/1000,
|
||||
rate, rate);
|
||||
|
||||
state->estimated_rate[layer] = rate;
|
||||
}
|
||||
|
||||
|
||||
static int mb86a20s_get_frontend(struct dvb_frontend *fe)
|
||||
{
|
||||
struct mb86a20s_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
int i, rc;
|
||||
int layer, rc;
|
||||
|
||||
dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
|
||||
|
||||
|
|
@ -636,43 +669,43 @@ static int mb86a20s_get_frontend(struct dvb_frontend *fe)
|
|||
|
||||
/* Get per-layer data */
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (layer = 0; layer < NUM_LAYERS; layer++) {
|
||||
dev_dbg(&state->i2c->dev, "%s: getting data for layer %c.\n",
|
||||
__func__, 'A' + i);
|
||||
__func__, 'A' + layer);
|
||||
|
||||
rc = mb86a20s_get_segment_count(state, i);
|
||||
rc = mb86a20s_get_segment_count(state, layer);
|
||||
if (rc < 0)
|
||||
goto noperlayer_error;
|
||||
if (rc >= 0 && rc < 14) {
|
||||
c->layer[i].segment_count = rc;
|
||||
c->layer[layer].segment_count = rc;
|
||||
} else {
|
||||
c->layer[i].segment_count = 0;
|
||||
state->estimated_rate[i] = 0;
|
||||
c->layer[layer].segment_count = 0;
|
||||
state->estimated_rate[layer] = 0;
|
||||
continue;
|
||||
}
|
||||
c->isdbt_layer_enabled |= 1 << i;
|
||||
rc = mb86a20s_get_modulation(state, i);
|
||||
c->isdbt_layer_enabled |= 1 << layer;
|
||||
rc = mb86a20s_get_modulation(state, layer);
|
||||
if (rc < 0)
|
||||
goto noperlayer_error;
|
||||
dev_dbg(&state->i2c->dev, "%s: modulation %d.\n",
|
||||
__func__, rc);
|
||||
c->layer[i].modulation = rc;
|
||||
rc = mb86a20s_get_fec(state, i);
|
||||
c->layer[layer].modulation = rc;
|
||||
rc = mb86a20s_get_fec(state, layer);
|
||||
if (rc < 0)
|
||||
goto noperlayer_error;
|
||||
dev_dbg(&state->i2c->dev, "%s: FEC %d.\n",
|
||||
__func__, rc);
|
||||
c->layer[i].fec = rc;
|
||||
rc = mb86a20s_get_interleaving(state, i);
|
||||
c->layer[layer].fec = rc;
|
||||
rc = mb86a20s_get_interleaving(state, layer);
|
||||
if (rc < 0)
|
||||
goto noperlayer_error;
|
||||
dev_dbg(&state->i2c->dev, "%s: interleaving %d.\n",
|
||||
__func__, rc);
|
||||
c->layer[i].interleaving = rc;
|
||||
mb86a20s_layer_bitrate(fe, i, c->layer[i].modulation,
|
||||
c->layer[i].fec,
|
||||
c->layer[i].interleaving,
|
||||
c->layer[i].segment_count);
|
||||
c->layer[layer].interleaving = rc;
|
||||
mb86a20s_layer_bitrate(fe, layer, c->layer[layer].modulation,
|
||||
c->layer[layer].fec,
|
||||
c->layer[layer].interleaving,
|
||||
c->layer[layer].segment_count);
|
||||
}
|
||||
|
||||
rc = mb86a20s_writereg(state, 0x6d, 0x84);
|
||||
|
|
@ -735,7 +768,6 @@ static int mb86a20s_reset_counters(struct dvb_frontend *fe)
|
|||
|
||||
/* Reset the counters, if the channel changed */
|
||||
if (state->last_frequency != c->frequency) {
|
||||
memset(&c->strength, 0, sizeof(c->strength));
|
||||
memset(&c->cnr, 0, sizeof(c->cnr));
|
||||
memset(&c->pre_bit_error, 0, sizeof(c->pre_bit_error));
|
||||
memset(&c->pre_bit_count, 0, sizeof(c->pre_bit_count));
|
||||
|
|
@ -799,7 +831,7 @@ static int mb86a20s_get_pre_ber(struct dvb_frontend *fe,
|
|||
|
||||
dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
|
||||
|
||||
if (layer >= 3)
|
||||
if (layer >= NUM_LAYERS)
|
||||
return -EINVAL;
|
||||
|
||||
/* Check if the BER measures are already available */
|
||||
|
|
@ -933,7 +965,7 @@ static int mb86a20s_get_post_ber(struct dvb_frontend *fe,
|
|||
|
||||
dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
|
||||
|
||||
if (layer >= 3)
|
||||
if (layer >= NUM_LAYERS)
|
||||
return -EINVAL;
|
||||
|
||||
/* Check if the BER measures are already available */
|
||||
|
|
@ -1060,7 +1092,7 @@ static int mb86a20s_get_blk_error(struct dvb_frontend *fe,
|
|||
u32 collect_rate;
|
||||
dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
|
||||
|
||||
if (layer >= 3)
|
||||
if (layer >= NUM_LAYERS)
|
||||
return -EINVAL;
|
||||
|
||||
/* Check if the PER measures are already available */
|
||||
|
|
@ -1095,7 +1127,7 @@ static int mb86a20s_get_blk_error(struct dvb_frontend *fe,
|
|||
if (rc < 0)
|
||||
return rc;
|
||||
*error |= rc;
|
||||
dev_err(&state->i2c->dev, "%s: block error for layer %c: %d.\n",
|
||||
dev_dbg(&state->i2c->dev, "%s: block error for layer %c: %d.\n",
|
||||
__func__, 'A' + layer, *error);
|
||||
|
||||
/* Read Bit Count */
|
||||
|
|
@ -1386,7 +1418,7 @@ static int mb86a20s_get_main_CNR(struct dvb_frontend *fe)
|
|||
return rc;
|
||||
|
||||
if (!(rc & 0x40)) {
|
||||
dev_info(&state->i2c->dev, "%s: CNR is not available yet.\n",
|
||||
dev_dbg(&state->i2c->dev, "%s: CNR is not available yet.\n",
|
||||
__func__);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
|
@ -1425,7 +1457,7 @@ static int mb86a20s_get_blk_error_layer_CNR(struct dvb_frontend *fe)
|
|||
struct mb86a20s_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
u32 mer, cnr;
|
||||
int rc, val, i;
|
||||
int rc, val, layer;
|
||||
struct linear_segments *segs;
|
||||
unsigned segs_len;
|
||||
|
||||
|
|
@ -1441,33 +1473,33 @@ static int mb86a20s_get_blk_error_layer_CNR(struct dvb_frontend *fe)
|
|||
|
||||
/* Check if data is available */
|
||||
if (!(rc & 0x01)) {
|
||||
dev_info(&state->i2c->dev,
|
||||
dev_dbg(&state->i2c->dev,
|
||||
"%s: MER measures aren't available yet.\n", __func__);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Read all layers */
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (!(c->isdbt_layer_enabled & (1 << i))) {
|
||||
c->cnr.stat[1 + i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
for (layer = 0; layer < NUM_LAYERS; layer++) {
|
||||
if (!(c->isdbt_layer_enabled & (1 << layer))) {
|
||||
c->cnr.stat[1 + layer].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = mb86a20s_writereg(state, 0x50, 0x52 + i * 3);
|
||||
rc = mb86a20s_writereg(state, 0x50, 0x52 + layer * 3);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
rc = mb86a20s_readreg(state, 0x51);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
mer = rc << 16;
|
||||
rc = mb86a20s_writereg(state, 0x50, 0x53 + i * 3);
|
||||
rc = mb86a20s_writereg(state, 0x50, 0x53 + layer * 3);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
rc = mb86a20s_readreg(state, 0x51);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
mer |= rc << 8;
|
||||
rc = mb86a20s_writereg(state, 0x50, 0x54 + i * 3);
|
||||
rc = mb86a20s_writereg(state, 0x50, 0x54 + layer * 3);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
rc = mb86a20s_readreg(state, 0x51);
|
||||
|
|
@ -1475,7 +1507,7 @@ static int mb86a20s_get_blk_error_layer_CNR(struct dvb_frontend *fe)
|
|||
return rc;
|
||||
mer |= rc;
|
||||
|
||||
switch (c->layer[i].modulation) {
|
||||
switch (c->layer[layer].modulation) {
|
||||
case DQPSK:
|
||||
case QPSK:
|
||||
segs = cnr_qpsk_table;
|
||||
|
|
@ -1493,12 +1525,12 @@ static int mb86a20s_get_blk_error_layer_CNR(struct dvb_frontend *fe)
|
|||
}
|
||||
cnr = interpolate_value(mer, segs, segs_len);
|
||||
|
||||
c->cnr.stat[1 + i].scale = FE_SCALE_DECIBEL;
|
||||
c->cnr.stat[1 + i].svalue = cnr;
|
||||
c->cnr.stat[1 + layer].scale = FE_SCALE_DECIBEL;
|
||||
c->cnr.stat[1 + layer].svalue = cnr;
|
||||
|
||||
dev_dbg(&state->i2c->dev,
|
||||
"%s: CNR for layer %c is %d.%03d dB (MER = %d).\n",
|
||||
__func__, 'A' + i, cnr / 1000, cnr % 1000, mer);
|
||||
__func__, 'A' + layer, cnr / 1000, cnr % 1000, mer);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1526,7 +1558,7 @@ static void mb86a20s_stats_not_ready(struct dvb_frontend *fe)
|
|||
{
|
||||
struct mb86a20s_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
int i;
|
||||
int layer;
|
||||
|
||||
dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
|
||||
|
||||
|
|
@ -1536,35 +1568,35 @@ static void mb86a20s_stats_not_ready(struct dvb_frontend *fe)
|
|||
c->strength.len = 1;
|
||||
|
||||
/* Per-layer stats - 3 layers + global */
|
||||
c->cnr.len = 4;
|
||||
c->pre_bit_error.len = 4;
|
||||
c->pre_bit_count.len = 4;
|
||||
c->post_bit_error.len = 4;
|
||||
c->post_bit_count.len = 4;
|
||||
c->block_error.len = 4;
|
||||
c->block_count.len = 4;
|
||||
c->cnr.len = NUM_LAYERS + 1;
|
||||
c->pre_bit_error.len = NUM_LAYERS + 1;
|
||||
c->pre_bit_count.len = NUM_LAYERS + 1;
|
||||
c->post_bit_error.len = NUM_LAYERS + 1;
|
||||
c->post_bit_count.len = NUM_LAYERS + 1;
|
||||
c->block_error.len = NUM_LAYERS + 1;
|
||||
c->block_count.len = NUM_LAYERS + 1;
|
||||
|
||||
/* Signal is always available */
|
||||
c->strength.stat[0].scale = FE_SCALE_RELATIVE;
|
||||
c->strength.stat[0].uvalue = 0;
|
||||
|
||||
/* Put all of them at FE_SCALE_NOT_AVAILABLE */
|
||||
for (i = 0; i < 4; i++) {
|
||||
c->cnr.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->pre_bit_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->pre_bit_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->post_bit_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->post_bit_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->block_error.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->block_count.stat[i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
for (layer = 0; layer < NUM_LAYERS + 1; layer++) {
|
||||
c->cnr.stat[layer].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->pre_bit_error.stat[layer].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->pre_bit_count.stat[layer].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->post_bit_error.stat[layer].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->post_bit_count.stat[layer].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->block_error.stat[layer].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->block_count.stat[layer].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
static int mb86a20s_get_stats(struct dvb_frontend *fe)
|
||||
static int mb86a20s_get_stats(struct dvb_frontend *fe, int status_nr)
|
||||
{
|
||||
struct mb86a20s_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
int rc = 0, i;
|
||||
int rc = 0, layer;
|
||||
u32 bit_error = 0, bit_count = 0;
|
||||
u32 t_pre_bit_error = 0, t_pre_bit_count = 0;
|
||||
u32 t_post_bit_error = 0, t_post_bit_count = 0;
|
||||
|
|
@ -1580,90 +1612,98 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe)
|
|||
/* Get per-layer stats */
|
||||
mb86a20s_get_blk_error_layer_CNR(fe);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (c->isdbt_layer_enabled & (1 << i)) {
|
||||
/*
|
||||
* At state 7, only CNR is available
|
||||
* For BER measures, state=9 is required
|
||||
* FIXME: we may get MER measures with state=8
|
||||
*/
|
||||
if (status_nr < 9)
|
||||
return 0;
|
||||
|
||||
for (layer = 0; layer < NUM_LAYERS; layer++) {
|
||||
if (c->isdbt_layer_enabled & (1 << layer)) {
|
||||
/* Layer is active and has rc segments */
|
||||
active_layers++;
|
||||
|
||||
/* Handle BER before vterbi */
|
||||
rc = mb86a20s_get_pre_ber(fe, i,
|
||||
rc = mb86a20s_get_pre_ber(fe, layer,
|
||||
&bit_error, &bit_count);
|
||||
if (rc >= 0) {
|
||||
c->pre_bit_error.stat[1 + i].scale = FE_SCALE_COUNTER;
|
||||
c->pre_bit_error.stat[1 + i].uvalue += bit_error;
|
||||
c->pre_bit_count.stat[1 + i].scale = FE_SCALE_COUNTER;
|
||||
c->pre_bit_count.stat[1 + i].uvalue += bit_count;
|
||||
c->pre_bit_error.stat[1 + layer].scale = FE_SCALE_COUNTER;
|
||||
c->pre_bit_error.stat[1 + layer].uvalue += bit_error;
|
||||
c->pre_bit_count.stat[1 + layer].scale = FE_SCALE_COUNTER;
|
||||
c->pre_bit_count.stat[1 + layer].uvalue += bit_count;
|
||||
} else if (rc != -EBUSY) {
|
||||
/*
|
||||
* If an I/O error happened,
|
||||
* measures are now unavailable
|
||||
*/
|
||||
c->pre_bit_error.stat[1 + i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->pre_bit_count.stat[1 + i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->pre_bit_error.stat[1 + layer].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->pre_bit_count.stat[1 + layer].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
dev_err(&state->i2c->dev,
|
||||
"%s: Can't get BER for layer %c (error %d).\n",
|
||||
__func__, 'A' + i, rc);
|
||||
__func__, 'A' + layer, rc);
|
||||
}
|
||||
if (c->block_error.stat[1 + i].scale != FE_SCALE_NOT_AVAILABLE)
|
||||
if (c->block_error.stat[1 + layer].scale != FE_SCALE_NOT_AVAILABLE)
|
||||
pre_ber_layers++;
|
||||
|
||||
/* Handle BER post vterbi */
|
||||
rc = mb86a20s_get_post_ber(fe, i,
|
||||
rc = mb86a20s_get_post_ber(fe, layer,
|
||||
&bit_error, &bit_count);
|
||||
if (rc >= 0) {
|
||||
c->post_bit_error.stat[1 + i].scale = FE_SCALE_COUNTER;
|
||||
c->post_bit_error.stat[1 + i].uvalue += bit_error;
|
||||
c->post_bit_count.stat[1 + i].scale = FE_SCALE_COUNTER;
|
||||
c->post_bit_count.stat[1 + i].uvalue += bit_count;
|
||||
c->post_bit_error.stat[1 + layer].scale = FE_SCALE_COUNTER;
|
||||
c->post_bit_error.stat[1 + layer].uvalue += bit_error;
|
||||
c->post_bit_count.stat[1 + layer].scale = FE_SCALE_COUNTER;
|
||||
c->post_bit_count.stat[1 + layer].uvalue += bit_count;
|
||||
} else if (rc != -EBUSY) {
|
||||
/*
|
||||
* If an I/O error happened,
|
||||
* measures are now unavailable
|
||||
*/
|
||||
c->post_bit_error.stat[1 + i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->post_bit_count.stat[1 + i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->post_bit_error.stat[1 + layer].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->post_bit_count.stat[1 + layer].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
dev_err(&state->i2c->dev,
|
||||
"%s: Can't get BER for layer %c (error %d).\n",
|
||||
__func__, 'A' + i, rc);
|
||||
__func__, 'A' + layer, rc);
|
||||
}
|
||||
if (c->block_error.stat[1 + i].scale != FE_SCALE_NOT_AVAILABLE)
|
||||
if (c->block_error.stat[1 + layer].scale != FE_SCALE_NOT_AVAILABLE)
|
||||
post_ber_layers++;
|
||||
|
||||
/* Handle Block errors for PER/UCB reports */
|
||||
rc = mb86a20s_get_blk_error(fe, i,
|
||||
rc = mb86a20s_get_blk_error(fe, layer,
|
||||
&block_error,
|
||||
&block_count);
|
||||
if (rc >= 0) {
|
||||
c->block_error.stat[1 + i].scale = FE_SCALE_COUNTER;
|
||||
c->block_error.stat[1 + i].uvalue += block_error;
|
||||
c->block_count.stat[1 + i].scale = FE_SCALE_COUNTER;
|
||||
c->block_count.stat[1 + i].uvalue += block_count;
|
||||
c->block_error.stat[1 + layer].scale = FE_SCALE_COUNTER;
|
||||
c->block_error.stat[1 + layer].uvalue += block_error;
|
||||
c->block_count.stat[1 + layer].scale = FE_SCALE_COUNTER;
|
||||
c->block_count.stat[1 + layer].uvalue += block_count;
|
||||
} else if (rc != -EBUSY) {
|
||||
/*
|
||||
* If an I/O error happened,
|
||||
* measures are now unavailable
|
||||
*/
|
||||
c->block_error.stat[1 + i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->block_count.stat[1 + i].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->block_error.stat[1 + layer].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
c->block_count.stat[1 + layer].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
dev_err(&state->i2c->dev,
|
||||
"%s: Can't get PER for layer %c (error %d).\n",
|
||||
__func__, 'A' + i, rc);
|
||||
__func__, 'A' + layer, rc);
|
||||
|
||||
}
|
||||
if (c->block_error.stat[1 + i].scale != FE_SCALE_NOT_AVAILABLE)
|
||||
if (c->block_error.stat[1 + layer].scale != FE_SCALE_NOT_AVAILABLE)
|
||||
per_layers++;
|
||||
|
||||
/* Update total preBER */
|
||||
t_pre_bit_error += c->pre_bit_error.stat[1 + i].uvalue;
|
||||
t_pre_bit_count += c->pre_bit_count.stat[1 + i].uvalue;
|
||||
t_pre_bit_error += c->pre_bit_error.stat[1 + layer].uvalue;
|
||||
t_pre_bit_count += c->pre_bit_count.stat[1 + layer].uvalue;
|
||||
|
||||
/* Update total postBER */
|
||||
t_post_bit_error += c->post_bit_error.stat[1 + i].uvalue;
|
||||
t_post_bit_count += c->post_bit_count.stat[1 + i].uvalue;
|
||||
t_post_bit_error += c->post_bit_error.stat[1 + layer].uvalue;
|
||||
t_post_bit_count += c->post_bit_count.stat[1 + layer].uvalue;
|
||||
|
||||
/* Update total PER */
|
||||
t_block_error += c->block_error.stat[1 + i].uvalue;
|
||||
t_block_count += c->block_count.stat[1 + i].uvalue;
|
||||
t_block_error += c->block_error.stat[1 + layer].uvalue;
|
||||
t_block_count += c->block_count.stat[1 + layer].uvalue;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1737,8 +1777,10 @@ static int mb86a20s_get_stats(struct dvb_frontend *fe)
|
|||
static int mb86a20s_initfe(struct dvb_frontend *fe)
|
||||
{
|
||||
struct mb86a20s_state *state = fe->demodulator_priv;
|
||||
u64 pll;
|
||||
u32 fclk;
|
||||
int rc;
|
||||
u8 regD5 = 1;
|
||||
u8 regD5 = 1, reg71, reg09 = 0x3a;
|
||||
|
||||
dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
|
||||
|
||||
|
|
@ -1746,10 +1788,78 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
|
|||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
|
||||
/* Initialize the frontend */
|
||||
rc = mb86a20s_writeregdata(state, mb86a20s_init);
|
||||
rc = mb86a20s_writeregdata(state, mb86a20s_init1);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
|
||||
if (!state->inversion)
|
||||
reg09 |= 0x04;
|
||||
rc = mb86a20s_writereg(state, 0x09, reg09);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
if (!state->bw)
|
||||
reg71 = 1;
|
||||
else
|
||||
reg71 = 0;
|
||||
rc = mb86a20s_writereg(state, 0x39, reg71);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
rc = mb86a20s_writereg(state, 0x71, state->bw);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
if (state->subchannel) {
|
||||
rc = mb86a20s_writereg(state, 0x44, state->subchannel);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
fclk = state->config->fclk;
|
||||
if (!fclk)
|
||||
fclk = 32571428;
|
||||
|
||||
/* Adjust IF frequency to match tuner */
|
||||
if (fe->ops.tuner_ops.get_if_frequency)
|
||||
fe->ops.tuner_ops.get_if_frequency(fe, &state->if_freq);
|
||||
|
||||
if (!state->if_freq)
|
||||
state->if_freq = 3300000;
|
||||
|
||||
pll = (((u64)1) << 34) * state->if_freq;
|
||||
do_div(pll, 63 * fclk);
|
||||
pll = (1 << 25) - pll;
|
||||
rc = mb86a20s_writereg(state, 0x28, 0x2a);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
rc = mb86a20s_writereg(state, 0x29, (pll >> 16) & 0xff);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
rc = mb86a20s_writereg(state, 0x2a, (pll >> 8) & 0xff);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
rc = mb86a20s_writereg(state, 0x2b, pll & 0xff);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
dev_dbg(&state->i2c->dev, "%s: fclk=%d, IF=%d, clock reg=0x%06llx\n",
|
||||
__func__, fclk, state->if_freq, (long long)pll);
|
||||
|
||||
/* pll = freq[Hz] * 2^24/10^6 / 16.285714286 */
|
||||
pll = state->if_freq * 1677721600L;
|
||||
do_div(pll, 1628571429L);
|
||||
rc = mb86a20s_writereg(state, 0x28, 0x20);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
rc = mb86a20s_writereg(state, 0x29, (pll >> 16) & 0xff);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
rc = mb86a20s_writereg(state, 0x2a, (pll >> 8) & 0xff);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
rc = mb86a20s_writereg(state, 0x2b, pll & 0xff);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
dev_dbg(&state->i2c->dev, "%s: IF=%d, IF reg=0x%06llx\n",
|
||||
__func__, state->if_freq, (long long)pll);
|
||||
|
||||
if (!state->config->is_serial) {
|
||||
regD5 &= ~1;
|
||||
|
||||
|
|
@ -1761,6 +1871,11 @@ static int mb86a20s_initfe(struct dvb_frontend *fe)
|
|||
goto err;
|
||||
}
|
||||
|
||||
rc = mb86a20s_writeregdata(state, mb86a20s_init2);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
|
||||
|
||||
err:
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
|
|
@ -1779,15 +1894,34 @@ err:
|
|||
static int mb86a20s_set_frontend(struct dvb_frontend *fe)
|
||||
{
|
||||
struct mb86a20s_state *state = fe->demodulator_priv;
|
||||
int rc;
|
||||
#if 0
|
||||
/*
|
||||
* FIXME: Properly implement the set frontend properties
|
||||
*/
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
#endif
|
||||
int rc, if_freq;
|
||||
dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
|
||||
|
||||
if (!c->isdbt_layer_enabled)
|
||||
c->isdbt_layer_enabled = 7;
|
||||
|
||||
if (c->isdbt_layer_enabled == 1)
|
||||
state->bw = MB86A20S_1SEG;
|
||||
else if (c->isdbt_partial_reception)
|
||||
state->bw = MB86A20S_13SEG_PARTIAL;
|
||||
else
|
||||
state->bw = MB86A20S_13SEG;
|
||||
|
||||
if (c->inversion == INVERSION_ON)
|
||||
state->inversion = true;
|
||||
else
|
||||
state->inversion = false;
|
||||
|
||||
if (!c->isdbt_sb_mode) {
|
||||
state->subchannel = 0;
|
||||
} else {
|
||||
if (c->isdbt_sb_subchannel >= ARRAY_SIZE(mb86a20s_subchannel))
|
||||
c->isdbt_sb_subchannel = 0;
|
||||
|
||||
state->subchannel = mb86a20s_subchannel[c->isdbt_sb_subchannel];
|
||||
}
|
||||
|
||||
/*
|
||||
* Gate should already be opened, but it doesn't hurt to
|
||||
* double-check
|
||||
|
|
@ -1796,6 +1930,9 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe)
|
|||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
fe->ops.tuner_ops.set_params(fe);
|
||||
|
||||
if (fe->ops.tuner_ops.get_if_frequency)
|
||||
fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
|
||||
|
||||
/*
|
||||
* Make it more reliable: if, for some reason, the initial
|
||||
* device initialization doesn't happen, initialize it when
|
||||
|
|
@ -1805,15 +1942,22 @@ static int mb86a20s_set_frontend(struct dvb_frontend *fe)
|
|||
* the agc callback logic is not called during DVB attach time,
|
||||
* causing mb86a20s to not be initialized with Kworld SBTVD.
|
||||
* So, this hack is needed, in order to make Kworld SBTVD to work.
|
||||
*
|
||||
* It is also needed to change the IF after the initial init.
|
||||
*
|
||||
* HACK: Always init the frontend when set_frontend is called:
|
||||
* it was noticed that, on some devices, it fails to lock on a
|
||||
* different channel. So, it is better to reset everything, even
|
||||
* wasting some time, than to loose channel lock.
|
||||
*/
|
||||
if (state->need_init)
|
||||
mb86a20s_initfe(fe);
|
||||
mb86a20s_initfe(fe);
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
|
||||
rc = mb86a20s_writeregdata(state, mb86a20s_reset_reception);
|
||||
mb86a20s_reset_counters(fe);
|
||||
mb86a20s_stats_not_ready(fe);
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
|
|
@ -1825,8 +1969,7 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
|
|||
fe_status_t *status)
|
||||
{
|
||||
struct mb86a20s_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
int rc;
|
||||
int rc, status_nr;
|
||||
|
||||
dev_dbg(&state->i2c->dev, "%s called.\n", __func__);
|
||||
|
||||
|
|
@ -1834,12 +1977,12 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
|
|||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
|
||||
/* Get lock */
|
||||
rc = mb86a20s_read_status(fe, status);
|
||||
if (!(*status & FE_HAS_LOCK)) {
|
||||
status_nr = mb86a20s_read_status(fe, status);
|
||||
if (status_nr < 7) {
|
||||
mb86a20s_stats_not_ready(fe);
|
||||
mb86a20s_reset_frontend_cache(fe);
|
||||
}
|
||||
if (rc < 0) {
|
||||
if (status_nr < 0) {
|
||||
dev_err(&state->i2c->dev,
|
||||
"%s: Can't read frontend lock status\n", __func__);
|
||||
goto error;
|
||||
|
|
@ -1856,10 +1999,8 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
|
|||
rc = 0; /* Status is OK */
|
||||
goto error;
|
||||
}
|
||||
/* Fill signal strength */
|
||||
c->strength.stat[0].uvalue = rc;
|
||||
|
||||
if (*status & FE_HAS_LOCK) {
|
||||
if (status_nr >= 7) {
|
||||
/* Get TMCC info*/
|
||||
rc = mb86a20s_get_frontend(fe);
|
||||
if (rc < 0) {
|
||||
|
|
@ -1870,7 +2011,7 @@ static int mb86a20s_read_status_and_stats(struct dvb_frontend *fe,
|
|||
}
|
||||
|
||||
/* Get statistics */
|
||||
rc = mb86a20s_get_stats(fe);
|
||||
rc = mb86a20s_get_stats(fe, status_nr);
|
||||
if (rc < 0 && rc != -EBUSY) {
|
||||
dev_err(&state->i2c->dev,
|
||||
"%s: Can't get FE statistics.\n", __func__);
|
||||
|
|
@ -1994,7 +2135,7 @@ static struct dvb_frontend_ops mb86a20s_ops = {
|
|||
/* Use dib8000 values per default */
|
||||
.info = {
|
||||
.name = "Fujitsu mb86A20s",
|
||||
.caps = FE_CAN_INVERSION_AUTO | FE_CAN_RECOVER |
|
||||
.caps = FE_CAN_RECOVER |
|
||||
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
|
||||
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
|
||||
FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
|
||||
|
|
|
|||
|
|
@ -16,21 +16,25 @@
|
|||
#ifndef MB86A20S_H
|
||||
#define MB86A20S_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
/**
|
||||
* struct mb86a20s_config - Define the per-device attributes of the frontend
|
||||
*
|
||||
* @fclk: Clock frequency. If zero, assumes the default
|
||||
* (32.57142 Mhz)
|
||||
* @demod_address: the demodulator's i2c address
|
||||
* @is_serial: if true, TS is serial. Otherwise, TS is parallel
|
||||
*/
|
||||
|
||||
struct mb86a20s_config {
|
||||
u8 demod_address;
|
||||
bool is_serial;
|
||||
u32 fclk;
|
||||
u8 demod_address;
|
||||
bool is_serial;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_MB86A20S) || (defined(CONFIG_DVB_MB86A20S_MODULE) \
|
||||
&& defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_MB86A20S)
|
||||
extern struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
extern struct i2c_adapter *mb86a20s_get_tuner_i2c_adapter(struct dvb_frontend *);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef RTL2830_H
|
||||
#define RTL2830_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct rtl2830_config {
|
||||
|
|
@ -59,8 +60,7 @@ struct rtl2830_config {
|
|||
u8 agc_targ_val;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_RTL2830) || \
|
||||
(defined(CONFIG_DVB_RTL2830_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_RTL2830)
|
||||
extern struct dvb_frontend *rtl2830_attach(
|
||||
const struct rtl2830_config *config,
|
||||
struct i2c_adapter *i2c
|
||||
|
|
|
|||
|
|
@ -380,13 +380,41 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int rtl2832_set_if(struct dvb_frontend *fe, u32 if_freq)
|
||||
{
|
||||
struct rtl2832_priv *priv = fe->demodulator_priv;
|
||||
int ret;
|
||||
u64 pset_iffreq;
|
||||
u8 en_bbin = (if_freq == 0 ? 0x1 : 0x0);
|
||||
|
||||
/*
|
||||
* PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
|
||||
* / CrystalFreqHz)
|
||||
*/
|
||||
|
||||
pset_iffreq = if_freq % priv->cfg.xtal;
|
||||
pset_iffreq *= 0x400000;
|
||||
pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
|
||||
pset_iffreq = -pset_iffreq;
|
||||
pset_iffreq = pset_iffreq & 0x3fffff;
|
||||
dev_dbg(&priv->i2c->dev, "%s: if_frequency=%d pset_iffreq=%08x\n",
|
||||
__func__, if_freq, (unsigned)pset_iffreq);
|
||||
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int rtl2832_init(struct dvb_frontend *fe)
|
||||
{
|
||||
struct rtl2832_priv *priv = fe->demodulator_priv;
|
||||
int i, ret, len;
|
||||
u8 en_bbin;
|
||||
u64 pset_iffreq;
|
||||
const struct rtl2832_reg_value *init;
|
||||
int i, ret, len;
|
||||
|
||||
/* initialization values for the demodulator registers */
|
||||
struct rtl2832_reg_value rtl2832_initial_regs[] = {
|
||||
|
|
@ -432,22 +460,10 @@ static int rtl2832_init(struct dvb_frontend *fe)
|
|||
{DVBT_TR_THD_SET2, 0x6},
|
||||
{DVBT_TRK_KC_I2, 0x5},
|
||||
{DVBT_CR_THD_SET2, 0x1},
|
||||
{DVBT_SPEC_INV, 0x0},
|
||||
};
|
||||
|
||||
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
|
||||
|
||||
en_bbin = (priv->cfg.if_dvbt == 0 ? 0x1 : 0x0);
|
||||
|
||||
/*
|
||||
* PSET_IFFREQ = - floor((IfFreqHz % CrystalFreqHz) * pow(2, 22)
|
||||
* / CrystalFreqHz)
|
||||
*/
|
||||
pset_iffreq = priv->cfg.if_dvbt % priv->cfg.xtal;
|
||||
pset_iffreq *= 0x400000;
|
||||
pset_iffreq = div_u64(pset_iffreq, priv->cfg.xtal);
|
||||
pset_iffreq = pset_iffreq & 0x3fffff;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rtl2832_initial_regs); i++) {
|
||||
ret = rtl2832_wr_demod_reg(priv, rtl2832_initial_regs[i].reg,
|
||||
rtl2832_initial_regs[i].value);
|
||||
|
|
@ -472,6 +488,10 @@ static int rtl2832_init(struct dvb_frontend *fe)
|
|||
len = ARRAY_SIZE(rtl2832_tuner_init_e4000);
|
||||
init = rtl2832_tuner_init_e4000;
|
||||
break;
|
||||
case RTL2832_TUNER_R820T:
|
||||
len = ARRAY_SIZE(rtl2832_tuner_init_r820t);
|
||||
init = rtl2832_tuner_init_r820t;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
|
|
@ -483,14 +503,26 @@ static int rtl2832_init(struct dvb_frontend *fe)
|
|||
goto err;
|
||||
}
|
||||
|
||||
/* if frequency settings */
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
|
||||
if (!fe->ops.tuner_ops.get_if_frequency) {
|
||||
ret = rtl2832_set_if(fe, priv->cfg.if_dvbt);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
|
||||
if (ret)
|
||||
goto err;
|
||||
/*
|
||||
* r820t NIM code does a software reset here at the demod -
|
||||
* may not be needed, as there's already a software reset at set_params()
|
||||
*/
|
||||
#if 1
|
||||
/* soft reset */
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x1);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_SOFT_RST, 0x0);
|
||||
if (ret)
|
||||
goto err;
|
||||
#endif
|
||||
|
||||
priv->sleeping = false;
|
||||
|
||||
|
|
@ -564,6 +596,19 @@ static int rtl2832_set_frontend(struct dvb_frontend *fe)
|
|||
if (fe->ops.tuner_ops.set_params)
|
||||
fe->ops.tuner_ops.set_params(fe);
|
||||
|
||||
/* If the frontend has get_if_frequency(), use it */
|
||||
if (fe->ops.tuner_ops.get_if_frequency) {
|
||||
u32 if_freq;
|
||||
|
||||
ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_freq);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = rtl2832_set_if(fe, if_freq);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
switch (c->bandwidth_hz) {
|
||||
case 6000000:
|
||||
i = 0;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef RTL2832_H
|
||||
#define RTL2832_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct rtl2832_config {
|
||||
|
|
@ -51,11 +52,11 @@ struct rtl2832_config {
|
|||
#define RTL2832_TUNER_FC0012 0x26
|
||||
#define RTL2832_TUNER_E4000 0x27
|
||||
#define RTL2832_TUNER_FC0013 0x29
|
||||
#define RTL2832_TUNER_R820T 0x2a
|
||||
u8 tuner;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_RTL2832) || \
|
||||
(defined(CONFIG_DVB_RTL2832_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_RTL2832)
|
||||
extern struct dvb_frontend *rtl2832_attach(
|
||||
const struct rtl2832_config *cfg,
|
||||
struct i2c_adapter *i2c
|
||||
|
|
|
|||
|
|
@ -267,6 +267,7 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_tua9001[] = {
|
|||
{DVBT_OPT_ADC_IQ, 0x1},
|
||||
{DVBT_AD_AVI, 0x0},
|
||||
{DVBT_AD_AVQ, 0x0},
|
||||
{DVBT_SPEC_INV, 0x0},
|
||||
};
|
||||
|
||||
static const struct rtl2832_reg_value rtl2832_tuner_init_fc0012[] = {
|
||||
|
|
@ -300,6 +301,7 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_fc0012[] = {
|
|||
{DVBT_GI_PGA_STATE, 0x0},
|
||||
{DVBT_EN_AGC_PGA, 0x1},
|
||||
{DVBT_IF_AGC_MAN, 0x0},
|
||||
{DVBT_SPEC_INV, 0x0},
|
||||
};
|
||||
|
||||
static const struct rtl2832_reg_value rtl2832_tuner_init_e4000[] = {
|
||||
|
|
@ -337,6 +339,32 @@ static const struct rtl2832_reg_value rtl2832_tuner_init_e4000[] = {
|
|||
{DVBT_REG_MONSEL, 0x1},
|
||||
{DVBT_REG_MON, 0x1},
|
||||
{DVBT_REG_4MSEL, 0x0},
|
||||
{DVBT_SPEC_INV, 0x0},
|
||||
};
|
||||
|
||||
static const struct rtl2832_reg_value rtl2832_tuner_init_r820t[] = {
|
||||
{DVBT_DAGC_TRG_VAL, 0x39},
|
||||
{DVBT_AGC_TARG_VAL_0, 0x0},
|
||||
{DVBT_AGC_TARG_VAL_8_1, 0x40},
|
||||
{DVBT_AAGC_LOOP_GAIN, 0x16},
|
||||
{DVBT_LOOP_GAIN2_3_0, 0x8},
|
||||
{DVBT_LOOP_GAIN2_4, 0x1},
|
||||
{DVBT_LOOP_GAIN3, 0x18},
|
||||
{DVBT_VTOP1, 0x35},
|
||||
{DVBT_VTOP2, 0x21},
|
||||
{DVBT_VTOP3, 0x21},
|
||||
{DVBT_KRF1, 0x0},
|
||||
{DVBT_KRF2, 0x40},
|
||||
{DVBT_KRF3, 0x10},
|
||||
{DVBT_KRF4, 0x10},
|
||||
{DVBT_IF_AGC_MIN, 0x80},
|
||||
{DVBT_IF_AGC_MAX, 0x7f},
|
||||
{DVBT_RF_AGC_MIN, 0x80},
|
||||
{DVBT_RF_AGC_MAX, 0x7f},
|
||||
{DVBT_POLAR_RF_AGC, 0x0},
|
||||
{DVBT_POLAR_IF_AGC, 0x0},
|
||||
{DVBT_AD7_SETTING, 0xe9f4},
|
||||
{DVBT_SPEC_INV, 0x1},
|
||||
};
|
||||
|
||||
#endif /* RTL2832_PRIV_H */
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef __S5H1409_H__
|
||||
#define __S5H1409_H__
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct s5h1409_config {
|
||||
|
|
@ -66,8 +67,7 @@ struct s5h1409_config {
|
|||
u8 hvr1600_opt;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \
|
||||
&& defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_S5H1409)
|
||||
extern struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef __S5H1411_H__
|
||||
#define __S5H1411_H__
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
#define S5H1411_I2C_TOP_ADDR (0x32 >> 1)
|
||||
|
|
@ -68,8 +69,7 @@ struct s5h1411_config {
|
|||
u8 status_mode;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_S5H1411) || \
|
||||
(defined(CONFIG_DVB_S5H1411_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_S5H1411)
|
||||
extern struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef __S5H1432_H__
|
||||
#define __S5H1432_H__
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
#define S5H1432_I2C_TOP_ADDR (0x02 >> 1)
|
||||
|
|
@ -74,8 +75,7 @@ struct s5h1432_config {
|
|||
u8 status_mode;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_S5H1432) || \
|
||||
(defined(CONFIG_DVB_S5H1432_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_S5H1432)
|
||||
extern struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#ifndef S921_H
|
||||
#define S921_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct s921_config {
|
||||
|
|
@ -24,8 +25,7 @@ struct s921_config {
|
|||
u8 demod_address;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) \
|
||||
&& defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_S921)
|
||||
extern struct dvb_frontend *s921_attach(const struct s921_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
extern struct i2c_adapter *s921_get_tuner_i2c_adapter(struct dvb_frontend *);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef SI21XX_H
|
||||
#define SI21XX_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
|
|
@ -12,8 +13,7 @@ struct si21xx_config {
|
|||
int min_delay_ms;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_SI21XX) || \
|
||||
(defined(CONFIG_DVB_SI21XX_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_SI21XX)
|
||||
extern struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#ifndef __DVB_STB6000_H__
|
||||
#define __DVB_STB6000_H__
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/i2c.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
|
|
@ -34,8 +35,7 @@
|
|||
* @param i2c i2c adapter to use.
|
||||
* @return FE pointer on success, NULL on failure.
|
||||
*/
|
||||
#if defined(CONFIG_DVB_STB6000) || (defined(CONFIG_DVB_STB6000_MODULE) \
|
||||
&& defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_STB6000)
|
||||
extern struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#ifndef STV0288_H
|
||||
#define STV0288_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
|
|
@ -42,8 +43,7 @@ struct stv0288_config {
|
|||
int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_STV0288) || (defined(CONFIG_DVB_STV0288_MODULE) && \
|
||||
defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_STV0288)
|
||||
extern struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#ifndef STV0367_H
|
||||
#define STV0367_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
|
|
@ -38,8 +39,7 @@ struct stv0367_config {
|
|||
int clk_pol;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_STV0367) || (defined(CONFIG_DVB_STV0367_MODULE) \
|
||||
&& defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_STV0367)
|
||||
extern struct
|
||||
dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#ifndef STV0900_H
|
||||
#define STV0900_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
|
|
@ -57,8 +58,7 @@ struct stv0900_config {
|
|||
void (*set_lock_led)(struct dvb_frontend *fe, int offon);
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \
|
||||
&& defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_STV0900)
|
||||
extern struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
|
||||
struct i2c_adapter *i2c, int demod);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -3906,12 +3906,12 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
|||
reg = stv090x_read_reg(state, STV090x_TSTTNR1);
|
||||
STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0);
|
||||
if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
/* power off DiSEqC 1 */
|
||||
reg = stv090x_read_reg(state, STV090x_TSTTNR2);
|
||||
STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0);
|
||||
if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
|
||||
/* check whether path 2 is already sleeping, that is when
|
||||
ADC2 is off */
|
||||
|
|
@ -3930,7 +3930,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
|||
if (full_standby)
|
||||
STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
|
||||
if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
reg = stv090x_read_reg(state, STV090x_STOPCLK2);
|
||||
/* sampling 1 clock */
|
||||
STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1);
|
||||
|
|
@ -3941,7 +3941,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
|||
if (full_standby)
|
||||
STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
|
||||
if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
break;
|
||||
|
||||
case STV090x_DEMODULATOR_1:
|
||||
|
|
@ -3949,12 +3949,12 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
|||
reg = stv090x_read_reg(state, STV090x_TSTTNR3);
|
||||
STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0);
|
||||
if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
/* power off DiSEqC 2 */
|
||||
reg = stv090x_read_reg(state, STV090x_TSTTNR4);
|
||||
STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0);
|
||||
if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
|
||||
/* check whether path 1 is already sleeping, that is when
|
||||
ADC1 is off */
|
||||
|
|
@ -3973,7 +3973,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
|||
if (full_standby)
|
||||
STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
|
||||
if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
reg = stv090x_read_reg(state, STV090x_STOPCLK2);
|
||||
/* sampling 2 clock */
|
||||
STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1);
|
||||
|
|
@ -3984,7 +3984,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
|||
if (full_standby)
|
||||
STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
|
||||
if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -3997,7 +3997,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
|||
reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
|
||||
STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
|
||||
if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
mutex_unlock(&state->internal->demod_lock);
|
||||
|
|
@ -4005,8 +4005,10 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
|||
|
||||
err_gateoff:
|
||||
stv090x_i2c_gate_ctrl(state, 0);
|
||||
err:
|
||||
goto err;
|
||||
err_unlock:
|
||||
mutex_unlock(&state->internal->demod_lock);
|
||||
err:
|
||||
dprintk(FE_ERROR, 1, "I/O error");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#ifndef __DVB_STV6110_H__
|
||||
#define __DVB_STV6110_H__
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/i2c.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
|
|
@ -45,8 +46,7 @@ struct stv6110_config {
|
|||
u8 clk_div; /* divisor value for the output clock */
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_STV6110) || (defined(CONFIG_DVB_STV6110_MODULE) \
|
||||
&& defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_STV6110)
|
||||
extern struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
|
||||
const struct stv6110_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef TDA10048_H
|
||||
#define TDA10048_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include <linux/firmware.h>
|
||||
|
||||
|
|
@ -72,8 +73,7 @@ struct tda10048_config {
|
|||
u8 pll_n;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_TDA10048) || \
|
||||
(defined(CONFIG_DVB_TDA10048_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_TDA10048)
|
||||
extern struct dvb_frontend *tda10048_attach(
|
||||
const struct tda10048_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef TDA10071_H
|
||||
#define TDA10071_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct tda10071_config {
|
||||
|
|
@ -71,8 +72,7 @@ struct tda10071_config {
|
|||
};
|
||||
|
||||
|
||||
#if defined(CONFIG_DVB_TDA10071) || \
|
||||
(defined(CONFIG_DVB_TDA10071_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_TDA10071)
|
||||
extern struct dvb_frontend *tda10071_attach(
|
||||
const struct tda10071_config *config, struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
#ifndef _TDA18271C2DD_H_
|
||||
#define _TDA18271C2DD_H_
|
||||
#if defined(CONFIG_DVB_TDA18271C2DD) || (defined(CONFIG_DVB_TDA18271C2DD_MODULE) \
|
||||
&& defined(MODULE))
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_DVB_TDA18271C2DD)
|
||||
struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, u8 adr);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#ifndef TS2020_H
|
||||
#define TS2020_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct ts2020_config {
|
||||
|
|
@ -29,8 +30,7 @@ struct ts2020_config {
|
|||
u8 clk_out_div;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_TS2020) || \
|
||||
(defined(CONFIG_DVB_TS2020_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_TS2020)
|
||||
|
||||
extern struct dvb_frontend *ts2020_attach(
|
||||
struct dvb_frontend *fe,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#ifndef DVB_ZL10036_H
|
||||
#define DVB_ZL10036_H
|
||||
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/i2c.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
|
|
@ -37,8 +38,7 @@ struct zl10036_config {
|
|||
int rf_loop_enable;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_ZL10036) || \
|
||||
(defined(CONFIG_DVB_ZL10036_MODULE) && defined(MODULE))
|
||||
#if IS_ENABLED(CONFIG_DVB_ZL10036)
|
||||
extern struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
|
||||
const struct zl10036_config *config, struct i2c_adapter *i2c);
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -22,8 +22,9 @@
|
|||
#ifndef ZL10039_H
|
||||
#define ZL10039_H
|
||||
|
||||
#if defined(CONFIG_DVB_ZL10039) || (defined(CONFIG_DVB_ZL10039_MODULE) \
|
||||
&& defined(MODULE))
|
||||
#include <linux/kconfig.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_DVB_ZL10039)
|
||||
struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe,
|
||||
u8 i2c_addr,
|
||||
struct i2c_adapter *i2c);
|
||||
|
|
|
|||
|
|
@ -71,11 +71,11 @@ int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed)
|
|||
|
||||
if (dvbdmxfeed->type == DMX_TYPE_TS) {
|
||||
switch (dvbdmxfeed->pes_type) {
|
||||
case DMX_TS_PES_VIDEO:
|
||||
case DMX_TS_PES_AUDIO:
|
||||
case DMX_TS_PES_TELETEXT:
|
||||
case DMX_TS_PES_PCR:
|
||||
case DMX_TS_PES_OTHER:
|
||||
case DMX_PES_VIDEO:
|
||||
case DMX_PES_AUDIO:
|
||||
case DMX_PES_TELETEXT:
|
||||
case DMX_PES_PCR:
|
||||
case DMX_PES_OTHER:
|
||||
c = alloc_channel(fdtv);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -132,7 +132,7 @@ int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
|
|||
(demux->dmx.frontend->source != DMX_MEMORY_FE))) {
|
||||
|
||||
if (dvbdmxfeed->ts_type & TS_DECODER) {
|
||||
if (dvbdmxfeed->pes_type >= DMX_TS_PES_OTHER ||
|
||||
if (dvbdmxfeed->pes_type >= DMX_PES_OTHER ||
|
||||
!demux->pesfilter[dvbdmxfeed->pes_type])
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
|
|||
}
|
||||
|
||||
if (!(dvbdmxfeed->ts_type & TS_DECODER &&
|
||||
dvbdmxfeed->pes_type < DMX_TS_PES_OTHER))
|
||||
dvbdmxfeed->pes_type < DMX_PES_OTHER))
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,6 +112,15 @@ config VIDEO_TLV320AIC23B
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called tlv320aic23b.
|
||||
|
||||
config VIDEO_UDA1342
|
||||
tristate "Philips UDA1342 audio codec"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
---help---
|
||||
Support for the Philips UDA1342 audio codec.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called uda1342.
|
||||
|
||||
config VIDEO_WM8775
|
||||
tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
|
|
@ -133,7 +142,7 @@ config VIDEO_WM8739
|
|||
module will be called wm8739.
|
||||
|
||||
config VIDEO_VP27SMPX
|
||||
tristate "Panasonic VP27s internal MPX"
|
||||
tristate "Panasonic VP27's internal MPX"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
---help---
|
||||
Support for the internal MPX of the Panasonic VP27s tuner.
|
||||
|
|
@ -141,6 +150,15 @@ config VIDEO_VP27SMPX
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called vp27smpx.
|
||||
|
||||
config VIDEO_SONY_BTF_MPX
|
||||
tristate "Sony BTF's internal MPX"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
help
|
||||
Support for the internal MPX of the Sony BTF-PG472Z tuner.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called sony-btf-mpx.
|
||||
|
||||
comment "RDS decoders"
|
||||
|
||||
config VIDEO_SAA6588
|
||||
|
|
@ -283,6 +301,35 @@ config VIDEO_TVP7002
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called tvp7002.
|
||||
|
||||
config VIDEO_TW2804
|
||||
tristate "Techwell TW2804 multiple video decoder"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
---help---
|
||||
Support for the Techwell tw2804 multiple video decoder.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called tw2804.
|
||||
|
||||
config VIDEO_TW9903
|
||||
tristate "Techwell TW9903 video decoder"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
---help---
|
||||
Support for the Techwell tw9903 multi-standard video decoder
|
||||
with high quality down scaler.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called tw9903.
|
||||
|
||||
config VIDEO_TW9906
|
||||
tristate "Techwell TW9906 video decoder"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
---help---
|
||||
Support for the Techwell tw9906 enhanced multi-standard comb filter
|
||||
video decoder with YCbCr input support.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called tw9906.
|
||||
|
||||
config VIDEO_VPX3220
|
||||
tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
|
|
@ -386,6 +433,17 @@ config VIDEO_APTINA_PLL
|
|||
config VIDEO_SMIAPP_PLL
|
||||
tristate
|
||||
|
||||
config VIDEO_OV7640
|
||||
tristate "OmniVision OV7640 sensor support"
|
||||
depends on I2C && VIDEO_V4L2
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
---help---
|
||||
This is a Video4Linux2 sensor-level driver for the OmniVision
|
||||
OV7640 camera.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ov7640.
|
||||
|
||||
config VIDEO_OV7670
|
||||
tristate "OmniVision OV7670 sensor support"
|
||||
depends on I2C && VIDEO_V4L2
|
||||
|
|
@ -501,8 +559,8 @@ config VIDEO_S5C73M3
|
|||
tristate "Samsung S5C73M3 sensor support"
|
||||
depends on I2C && SPI && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
---help---
|
||||
This is a V4L2 sensor-level driver for Samsung S5C73M3
|
||||
8 Mpixel camera.
|
||||
This is a V4L2 sensor-level driver for Samsung S5C73M3
|
||||
8 Mpixel camera.
|
||||
|
||||
comment "Flash devices"
|
||||
|
||||
|
|
@ -550,10 +608,10 @@ config VIDEO_UPD64083
|
|||
comment "Miscelaneous helper chips"
|
||||
|
||||
config VIDEO_THS7303
|
||||
tristate "THS7303 Video Amplifier"
|
||||
depends on I2C
|
||||
tristate "THS7303/53 Video Amplifier"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
help
|
||||
Support for TI THS7303 video amplifier
|
||||
Support for TI THS7303/53 video amplifier
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ths7303.
|
||||
|
|
|
|||
|
|
@ -37,16 +37,22 @@ obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
|
|||
obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
|
||||
obj-$(CONFIG_VIDEO_TVP514X) += tvp514x.o
|
||||
obj-$(CONFIG_VIDEO_TVP7002) += tvp7002.o
|
||||
obj-$(CONFIG_VIDEO_TW2804) += tw2804.o
|
||||
obj-$(CONFIG_VIDEO_TW9903) += tw9903.o
|
||||
obj-$(CONFIG_VIDEO_TW9906) += tw9906.o
|
||||
obj-$(CONFIG_VIDEO_CS5345) += cs5345.o
|
||||
obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
|
||||
obj-$(CONFIG_VIDEO_M52790) += m52790.o
|
||||
obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
|
||||
obj-$(CONFIG_VIDEO_UDA1342) += uda1342.o
|
||||
obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
|
||||
obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
|
||||
obj-$(CONFIG_VIDEO_VP27SMPX) += vp27smpx.o
|
||||
obj-$(CONFIG_VIDEO_SONY_BTF_MPX) += sony-btf-mpx.o
|
||||
obj-$(CONFIG_VIDEO_UPD64031A) += upd64031a.o
|
||||
obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o
|
||||
obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
|
||||
obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
|
||||
obj-$(CONFIG_VIDEO_OV7670) += ov7670.o
|
||||
obj-$(CONFIG_VIDEO_OV9650) += ov9650.o
|
||||
obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
|
||||
obj-$(CONFIG_VIDEO_MT9M032) += mt9m032.o
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ static int ad9389b_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ad9389b_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
|
||||
static int ad9389b_s_register(struct v4l2_subdev *sd, const struct v4l2_dbg_register *reg)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue