mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: "This is the first part of the media patches for v3.6. This patch series contain: - new DVB frontend: rtl2832 - new video drivers: adv7393 - some unused files got removed - a selection API cleanup between V4L2 and V4L2 subdev API's - a major redesign at v4l-ioctl2, in order to clean it up - several driver fixes and improvements." * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (174 commits) v4l: Export v4l2-common.h in include/linux/Kbuild media: Revert "[media] Terratec Cinergy S2 USB HD Rev.2" [media] media: Use pr_info not homegrown pr_reg macro [media] Terratec Cinergy S2 USB HD Rev.2 [media] v4l: Correct conflicting V4L2 subdev selection API documentation [media] Feature removal: V4L2 selections API target and flag definitions [media] v4l: Unify selection flags documentation [media] v4l: Unify selection flags [media] v4l: Common documentation for selection targets [media] v4l: Unify selection targets across V4L2 and V4L2 subdev interfaces [media] v4l: Remove "_ACTUAL" from subdev selection API target definition names [media] V4L: Remove "_ACTIVE" from the selection target name definitions [media] media: dvb-usb: print mac address via native %pM [media] s5p-tv: Use module_i2c_driver in sii9234_drv.c file [media] media: gpio-ir-recv: add allowed_protos for platform data [media] s5p-jpeg: Use module_platform_driver in jpeg-core.c file [media] saa7134: fix spelling of detach in label [media] cx88-blackbird: replace ioctl by unlocked_ioctl [media] cx88: don't use current_norm [media] cx88: fix a number of v4l2-compliance violations ...
This commit is contained in:
commit
6df419e45d
156 changed files with 7584 additions and 5523 deletions
|
|
@ -6,20 +6,82 @@ menuconfig MEDIA_SUPPORT
|
|||
tristate "Multimedia support"
|
||||
depends on HAS_IOMEM
|
||||
help
|
||||
If you want to use Video for Linux, DVB for Linux, or DAB adapters,
|
||||
If you want to use Webcams, Video grabber devices and/or TV devices
|
||||
enable this option and other options below.
|
||||
Additional info and docs are available on the web at
|
||||
<http://linuxtv.org>
|
||||
|
||||
if MEDIA_SUPPORT
|
||||
|
||||
comment "Multimedia core support"
|
||||
|
||||
#
|
||||
# Multimedia support - automatically enable V4L2 and DVB core
|
||||
#
|
||||
config MEDIA_CAMERA_SUPPORT
|
||||
bool "Cameras/video grabbers support"
|
||||
---help---
|
||||
Enable support for webcams and video grabbers.
|
||||
|
||||
Say Y when you have a webcam or a video capture grabber board.
|
||||
|
||||
config MEDIA_ANALOG_TV_SUPPORT
|
||||
bool "Analog TV support"
|
||||
---help---
|
||||
Enable analog TV support.
|
||||
|
||||
Say Y when you have a TV board with analog support or with a
|
||||
hybrid analog/digital TV chipset.
|
||||
|
||||
Note: There are several DVB cards that are based on chips that
|
||||
support both analog and digital TV. Disabling this option
|
||||
will disable support for them.
|
||||
|
||||
config MEDIA_DIGITAL_TV_SUPPORT
|
||||
bool "Digital TV support"
|
||||
---help---
|
||||
Enable digital TV support.
|
||||
|
||||
Say Y when you have a board with digital support or a board with
|
||||
hybrid digital TV and analog TV.
|
||||
|
||||
config MEDIA_RADIO_SUPPORT
|
||||
bool "AM/FM radio receivers/transmitters support"
|
||||
---help---
|
||||
Enable AM/FM radio support.
|
||||
|
||||
Additional info and docs are available on the web at
|
||||
<http://linuxtv.org>
|
||||
|
||||
Say Y when you have a board with radio support.
|
||||
|
||||
Note: There are several TV cards that are based on chips that
|
||||
support radio reception. Disabling this option will
|
||||
disable support for them.
|
||||
|
||||
config MEDIA_RC_SUPPORT
|
||||
bool "Remote Controller support"
|
||||
depends on INPUT
|
||||
---help---
|
||||
Enable support for Remote Controllers on Linux. This is
|
||||
needed in order to support several video capture adapters,
|
||||
standalone IR receivers/transmitters, and RF receivers.
|
||||
|
||||
Enable this option if you have a video capture board even
|
||||
if you don't need IR, as otherwise, you may not be able to
|
||||
compile the driver for your adapter.
|
||||
|
||||
Say Y when you have a TV or an IR device.
|
||||
|
||||
#
|
||||
# Media controller
|
||||
# Selectable only for webcam/grabbers, as other drivers don't use it
|
||||
#
|
||||
|
||||
config MEDIA_CONTROLLER
|
||||
bool "Media Controller API (EXPERIMENTAL)"
|
||||
depends on EXPERIMENTAL
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
---help---
|
||||
Enable the media controller API used to query media devices internal
|
||||
topology and configure it dynamically.
|
||||
|
|
@ -27,26 +89,15 @@ config MEDIA_CONTROLLER
|
|||
This API is mostly used by camera interfaces in embedded platforms.
|
||||
|
||||
#
|
||||
# V4L core and enabled API's
|
||||
# Video4Linux support
|
||||
# Only enables if one of the V4L2 types (ATV, webcam, radio) is selected
|
||||
#
|
||||
|
||||
config VIDEO_DEV
|
||||
tristate "Video For Linux"
|
||||
---help---
|
||||
V4L core support for video capture and overlay devices, webcams and
|
||||
AM/FM radio cards.
|
||||
|
||||
This kernel includes support for the new Video for Linux Two API,
|
||||
(V4L2).
|
||||
|
||||
Additional info and docs are available on the web at
|
||||
<http://linuxtv.org>
|
||||
|
||||
Documentation for V4L2 is also available on the web at
|
||||
<http://bytesex.org/v4l/>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called videodev.
|
||||
tristate
|
||||
depends on MEDIA_SUPPORT
|
||||
depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT
|
||||
default y
|
||||
|
||||
config VIDEO_V4L2_COMMON
|
||||
tristate
|
||||
|
|
@ -64,25 +115,15 @@ config VIDEO_V4L2_SUBDEV_API
|
|||
|
||||
#
|
||||
# DVB Core
|
||||
# Only enables if one of DTV is selected
|
||||
#
|
||||
|
||||
config DVB_CORE
|
||||
tristate "DVB for Linux"
|
||||
tristate
|
||||
depends on MEDIA_SUPPORT
|
||||
depends on MEDIA_DIGITAL_TV_SUPPORT
|
||||
default y
|
||||
select CRC32
|
||||
help
|
||||
DVB core utility functions for device handling, software fallbacks etc.
|
||||
|
||||
Enable this if you own a DVB/ATSC adapter and want to use it or if
|
||||
you compile Linux for a digital SetTopBox.
|
||||
|
||||
Say Y when you have a DVB or an ATSC card and want to use it.
|
||||
|
||||
API specs and user tools are available from <http://www.linuxtv.org/>.
|
||||
|
||||
Please report problems regarding this support to the LinuxDVB
|
||||
mailing list.
|
||||
|
||||
If unsure say N.
|
||||
|
||||
config DVB_NET
|
||||
bool "DVB Network Support"
|
||||
|
|
@ -97,12 +138,7 @@ config DVB_NET
|
|||
You may want to disable the network support on embedded devices. If
|
||||
unsure say Y.
|
||||
|
||||
config VIDEO_MEDIA
|
||||
tristate
|
||||
default (DVB_CORE && (VIDEO_DEV = n)) || (VIDEO_DEV && (DVB_CORE = n)) || (DVB_CORE && VIDEO_DEV)
|
||||
|
||||
comment "Multimedia drivers"
|
||||
|
||||
comment "Media drivers"
|
||||
source "drivers/media/common/Kconfig"
|
||||
source "drivers/media/rc/Kconfig"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
config MEDIA_ATTACH
|
||||
bool "Load and attach frontend and tuner driver modules as needed"
|
||||
depends on VIDEO_MEDIA
|
||||
depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT
|
||||
depends on MODULES
|
||||
default y if !EXPERT
|
||||
help
|
||||
Remove the static dependency of DVB card drivers on all
|
||||
frontend modules for all possible card variants. Instead,
|
||||
|
|
@ -19,15 +20,15 @@ config MEDIA_ATTACH
|
|||
|
||||
config MEDIA_TUNER
|
||||
tristate
|
||||
default VIDEO_MEDIA && I2C
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on (MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT) && I2C
|
||||
default y
|
||||
select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE && EXPERIMENTAL
|
||||
select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE && MEDIA_RADIO_SUPPORT && EXPERIMENTAL
|
||||
select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMISE && MEDIA_RADIO_SUPPORT
|
||||
select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
|
||||
|
|
@ -47,10 +48,11 @@ config MEDIA_TUNER_CUSTOMISE
|
|||
|
||||
menu "Customize TV tuners"
|
||||
visible if MEDIA_TUNER_CUSTOMISE
|
||||
depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT
|
||||
|
||||
config MEDIA_TUNER_SIMPLE
|
||||
tristate "Simple tuner support"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
select MEDIA_TUNER_TDA9887
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
|
|
@ -58,7 +60,7 @@ config MEDIA_TUNER_SIMPLE
|
|||
|
||||
config MEDIA_TUNER_TDA8290
|
||||
tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
select MEDIA_TUNER_TDA827X
|
||||
select MEDIA_TUNER_TDA18271
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
|
|
@ -67,21 +69,21 @@ config MEDIA_TUNER_TDA8290
|
|||
|
||||
config MEDIA_TUNER_TDA827X
|
||||
tristate "Philips TDA827X silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
A DVB-T silicon tuner module. Say Y when you want to support this tuner.
|
||||
|
||||
config MEDIA_TUNER_TDA18271
|
||||
tristate "NXP TDA18271 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
A silicon tuner module. Say Y when you want to support this tuner.
|
||||
|
||||
config MEDIA_TUNER_TDA9887
|
||||
tristate "TDA 9885/6/7 analog IF demodulator"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Say Y here to include support for Philips TDA9885/6/7
|
||||
|
|
@ -89,7 +91,7 @@ config MEDIA_TUNER_TDA9887
|
|||
|
||||
config MEDIA_TUNER_TEA5761
|
||||
tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
depends on EXPERIMENTAL
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
|
|
@ -97,63 +99,63 @@ config MEDIA_TUNER_TEA5761
|
|||
|
||||
config MEDIA_TUNER_TEA5767
|
||||
tristate "TEA 5767 radio tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Say Y here to include support for the Philips TEA5767 radio tuner.
|
||||
|
||||
config MEDIA_TUNER_MT20XX
|
||||
tristate "Microtune 2032 / 2050 tuners"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Say Y here to include support for the MT2032 / MT2050 tuner.
|
||||
|
||||
config MEDIA_TUNER_MT2060
|
||||
tristate "Microtune MT2060 silicon IF tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
A driver for the silicon IF tuner MT2060 from Microtune.
|
||||
|
||||
config MEDIA_TUNER_MT2063
|
||||
tristate "Microtune MT2063 silicon IF tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
A driver for the silicon IF tuner MT2063 from Microtune.
|
||||
|
||||
config MEDIA_TUNER_MT2266
|
||||
tristate "Microtune MT2266 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
A driver for the silicon baseband tuner MT2266 from Microtune.
|
||||
|
||||
config MEDIA_TUNER_MT2131
|
||||
tristate "Microtune MT2131 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
A driver for the silicon baseband tuner MT2131 from Microtune.
|
||||
|
||||
config MEDIA_TUNER_QT1010
|
||||
tristate "Quantek QT1010 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
A driver for the silicon tuner QT1010 from Quantek.
|
||||
|
||||
config MEDIA_TUNER_XC2028
|
||||
tristate "XCeive xc2028/xc3028 tuners"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Say Y here to include support for the xc2028/xc3028 tuners.
|
||||
|
||||
config MEDIA_TUNER_XC5000
|
||||
tristate "Xceive XC5000 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
A driver for the silicon tuner XC5000 from Xceive.
|
||||
|
|
@ -162,7 +164,7 @@ config MEDIA_TUNER_XC5000
|
|||
|
||||
config MEDIA_TUNER_XC4000
|
||||
tristate "Xceive XC4000 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
A driver for the silicon tuner XC4000 from Xceive.
|
||||
|
|
@ -171,70 +173,70 @@ config MEDIA_TUNER_XC4000
|
|||
|
||||
config MEDIA_TUNER_MXL5005S
|
||||
tristate "MaxLinear MSL5005S silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
A driver for the silicon tuner MXL5005S from MaxLinear.
|
||||
|
||||
config MEDIA_TUNER_MXL5007T
|
||||
tristate "MaxLinear MxL5007T silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
A driver for the silicon tuner MxL5007T from MaxLinear.
|
||||
|
||||
config MEDIA_TUNER_MC44S803
|
||||
tristate "Freescale MC44S803 Low Power CMOS Broadband tuners"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Say Y here to support the Freescale MC44S803 based tuners
|
||||
|
||||
config MEDIA_TUNER_MAX2165
|
||||
tristate "Maxim MAX2165 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
A driver for the silicon tuner MAX2165 from Maxim.
|
||||
|
||||
config MEDIA_TUNER_TDA18218
|
||||
tristate "NXP TDA18218 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
NXP TDA18218 silicon tuner driver.
|
||||
|
||||
config MEDIA_TUNER_FC0011
|
||||
tristate "Fitipower FC0011 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Fitipower FC0011 silicon tuner driver.
|
||||
|
||||
config MEDIA_TUNER_FC0012
|
||||
tristate "Fitipower FC0012 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Fitipower FC0012 silicon tuner driver.
|
||||
|
||||
config MEDIA_TUNER_FC0013
|
||||
tristate "Fitipower FC0013 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Fitipower FC0013 silicon tuner driver.
|
||||
|
||||
config MEDIA_TUNER_TDA18212
|
||||
tristate "NXP TDA18212 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
NXP TDA18212 silicon tuner driver.
|
||||
|
||||
config MEDIA_TUNER_TUA9001
|
||||
tristate "Infineon TUA 9001 silicon tuner"
|
||||
depends on VIDEO_MEDIA && I2C
|
||||
depends on MEDIA_SUPPORT && I2C
|
||||
default m if MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Infineon TUA 9001 silicon tuner driver.
|
||||
|
|
|
|||
|
|
@ -90,11 +90,22 @@ struct firmware_properties {
|
|||
int scode_nr;
|
||||
};
|
||||
|
||||
enum xc2028_state {
|
||||
XC2028_NO_FIRMWARE = 0,
|
||||
XC2028_WAITING_FIRMWARE,
|
||||
XC2028_ACTIVE,
|
||||
XC2028_SLEEP,
|
||||
XC2028_NODEV,
|
||||
};
|
||||
|
||||
struct xc2028_data {
|
||||
struct list_head hybrid_tuner_instance_list;
|
||||
struct tuner_i2c_props i2c_props;
|
||||
__u32 frequency;
|
||||
|
||||
enum xc2028_state state;
|
||||
const char *fname;
|
||||
|
||||
struct firmware_description *firm;
|
||||
int firm_size;
|
||||
__u16 firm_version;
|
||||
|
|
@ -255,6 +266,21 @@ static v4l2_std_id parse_audio_std_option(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int check_device_status(struct xc2028_data *priv)
|
||||
{
|
||||
switch (priv->state) {
|
||||
case XC2028_NO_FIRMWARE:
|
||||
case XC2028_WAITING_FIRMWARE:
|
||||
return -EAGAIN;
|
||||
case XC2028_ACTIVE:
|
||||
case XC2028_SLEEP:
|
||||
return 0;
|
||||
case XC2028_NODEV:
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void free_firmware(struct xc2028_data *priv)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -270,45 +296,28 @@ static void free_firmware(struct xc2028_data *priv)
|
|||
|
||||
priv->firm = NULL;
|
||||
priv->firm_size = 0;
|
||||
priv->state = XC2028_NO_FIRMWARE;
|
||||
|
||||
memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
|
||||
}
|
||||
|
||||
static int load_all_firmwares(struct dvb_frontend *fe)
|
||||
static int load_all_firmwares(struct dvb_frontend *fe,
|
||||
const struct firmware *fw)
|
||||
{
|
||||
struct xc2028_data *priv = fe->tuner_priv;
|
||||
const struct firmware *fw = NULL;
|
||||
const unsigned char *p, *endp;
|
||||
int rc = 0;
|
||||
int n, n_array;
|
||||
char name[33];
|
||||
char *fname;
|
||||
|
||||
tuner_dbg("%s called\n", __func__);
|
||||
|
||||
if (!firmware_name[0])
|
||||
fname = priv->ctrl.fname;
|
||||
else
|
||||
fname = firmware_name;
|
||||
|
||||
tuner_dbg("Reading firmware %s\n", fname);
|
||||
rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
|
||||
if (rc < 0) {
|
||||
if (rc == -ENOENT)
|
||||
tuner_err("Error: firmware %s not found.\n",
|
||||
fname);
|
||||
else
|
||||
tuner_err("Error %d while requesting firmware %s \n",
|
||||
rc, fname);
|
||||
|
||||
return rc;
|
||||
}
|
||||
p = fw->data;
|
||||
endp = p + fw->size;
|
||||
|
||||
if (fw->size < sizeof(name) - 1 + 2 + 2) {
|
||||
tuner_err("Error: firmware file %s has invalid size!\n",
|
||||
fname);
|
||||
priv->fname);
|
||||
goto corrupt;
|
||||
}
|
||||
|
||||
|
|
@ -323,7 +332,7 @@ static int load_all_firmwares(struct dvb_frontend *fe)
|
|||
p += 2;
|
||||
|
||||
tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n",
|
||||
n_array, fname, name,
|
||||
n_array, priv->fname, name,
|
||||
priv->firm_version >> 8, priv->firm_version & 0xff);
|
||||
|
||||
priv->firm = kcalloc(n_array, sizeof(*priv->firm), GFP_KERNEL);
|
||||
|
|
@ -417,9 +426,10 @@ err:
|
|||
free_firmware(priv);
|
||||
|
||||
done:
|
||||
release_firmware(fw);
|
||||
if (rc == 0)
|
||||
tuner_dbg("Firmware files loaded.\n");
|
||||
else
|
||||
priv->state = XC2028_NODEV;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -707,22 +717,15 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type,
|
|||
{
|
||||
struct xc2028_data *priv = fe->tuner_priv;
|
||||
struct firmware_properties new_fw;
|
||||
int rc = 0, retry_count = 0;
|
||||
int rc, retry_count = 0;
|
||||
u16 version, hwmodel;
|
||||
v4l2_std_id std0;
|
||||
|
||||
tuner_dbg("%s called\n", __func__);
|
||||
|
||||
if (!priv->firm) {
|
||||
if (!priv->ctrl.fname) {
|
||||
tuner_info("xc2028/3028 firmware name not set!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = load_all_firmwares(fe);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
rc = check_device_status(priv);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (priv->ctrl.mts && !(type & FM))
|
||||
type |= MTS;
|
||||
|
|
@ -749,9 +752,13 @@ retry:
|
|||
printk("scode_nr %d\n", new_fw.scode_nr);
|
||||
}
|
||||
|
||||
/* No need to reload base firmware if it matches */
|
||||
if (((BASE | new_fw.type) & BASE_TYPES) ==
|
||||
(priv->cur_fw.type & BASE_TYPES)) {
|
||||
/*
|
||||
* No need to reload base firmware if it matches and if the tuner
|
||||
* is not at sleep mode
|
||||
*/
|
||||
if ((priv->state = XC2028_ACTIVE) &&
|
||||
(((BASE | new_fw.type) & BASE_TYPES) ==
|
||||
(priv->cur_fw.type & BASE_TYPES))) {
|
||||
tuner_dbg("BASE firmware not changed.\n");
|
||||
goto skip_base;
|
||||
}
|
||||
|
|
@ -872,10 +879,13 @@ read_not_reliable:
|
|||
* 2. Tell whether BASE firmware was just changed the next time through.
|
||||
*/
|
||||
priv->cur_fw.type |= BASE;
|
||||
priv->state = XC2028_ACTIVE;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
priv->state = XC2028_SLEEP;
|
||||
|
||||
memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
|
||||
if (retry_count < 8) {
|
||||
msleep(50);
|
||||
|
|
@ -893,28 +903,39 @@ static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
|
|||
{
|
||||
struct xc2028_data *priv = fe->tuner_priv;
|
||||
u16 frq_lock, signal = 0;
|
||||
int rc;
|
||||
int rc, i;
|
||||
|
||||
tuner_dbg("%s called\n", __func__);
|
||||
|
||||
rc = check_device_status(priv);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
mutex_lock(&priv->lock);
|
||||
|
||||
/* Sync Lock Indicator */
|
||||
rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock);
|
||||
if (rc < 0)
|
||||
goto ret;
|
||||
for (i = 0; i < 3; i++) {
|
||||
rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock);
|
||||
if (rc < 0)
|
||||
goto ret;
|
||||
|
||||
/* Frequency is locked */
|
||||
if (frq_lock == 1)
|
||||
signal = 1 << 11;
|
||||
if (frq_lock)
|
||||
break;
|
||||
msleep(6);
|
||||
}
|
||||
|
||||
/* Frequency didn't lock */
|
||||
if (frq_lock == 2)
|
||||
goto ret;
|
||||
|
||||
/* Get SNR of the video signal */
|
||||
rc = xc2028_get_reg(priv, XREG_SNR, &signal);
|
||||
if (rc < 0)
|
||||
goto ret;
|
||||
|
||||
/* Use both frq_lock and signal to generate the result */
|
||||
signal = signal || ((signal & 0x07) << 12);
|
||||
/* Signal level is 3 bits only */
|
||||
|
||||
signal = ((1 << 12) - 1) | ((signal & 0x07) << 12);
|
||||
|
||||
ret:
|
||||
mutex_unlock(&priv->lock);
|
||||
|
|
@ -926,6 +947,49 @@ ret:
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int xc2028_get_afc(struct dvb_frontend *fe, s32 *afc)
|
||||
{
|
||||
struct xc2028_data *priv = fe->tuner_priv;
|
||||
int i, rc;
|
||||
u16 frq_lock = 0;
|
||||
s16 afc_reg = 0;
|
||||
|
||||
rc = check_device_status(priv);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
mutex_lock(&priv->lock);
|
||||
|
||||
/* Sync Lock Indicator */
|
||||
for (i = 0; i < 3; i++) {
|
||||
rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock);
|
||||
if (rc < 0)
|
||||
goto ret;
|
||||
|
||||
if (frq_lock)
|
||||
break;
|
||||
msleep(6);
|
||||
}
|
||||
|
||||
/* Frequency didn't lock */
|
||||
if (frq_lock == 2)
|
||||
goto ret;
|
||||
|
||||
/* Get AFC */
|
||||
rc = xc2028_get_reg(priv, XREG_FREQ_ERROR, &afc_reg);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
*afc = afc_reg * 15625; /* Hz */
|
||||
|
||||
tuner_dbg("AFC is %d Hz\n", *afc);
|
||||
|
||||
ret:
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#define DIV 15625
|
||||
|
||||
static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
|
||||
|
|
@ -1111,11 +1175,16 @@ static int xc2028_set_params(struct dvb_frontend *fe)
|
|||
u32 delsys = c->delivery_system;
|
||||
u32 bw = c->bandwidth_hz;
|
||||
struct xc2028_data *priv = fe->tuner_priv;
|
||||
unsigned int type=0;
|
||||
int rc;
|
||||
unsigned int type = 0;
|
||||
u16 demod = 0;
|
||||
|
||||
tuner_dbg("%s called\n", __func__);
|
||||
|
||||
rc = check_device_status(priv);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
switch (delsys) {
|
||||
case SYS_DVBT:
|
||||
case SYS_DVBT2:
|
||||
|
|
@ -1201,7 +1270,11 @@ static int xc2028_set_params(struct dvb_frontend *fe)
|
|||
static int xc2028_sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
struct xc2028_data *priv = fe->tuner_priv;
|
||||
int rc = 0;
|
||||
int rc;
|
||||
|
||||
rc = check_device_status(priv);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Avoid firmware reload on slow devices or if PM disabled */
|
||||
if (no_poweroff || priv->ctrl.disable_power_mgmt)
|
||||
|
|
@ -1220,7 +1293,7 @@ static int xc2028_sleep(struct dvb_frontend *fe)
|
|||
else
|
||||
rc = send_seq(priv, {0x80, XREG_POWER_DOWN, 0x00, 0x00});
|
||||
|
||||
priv->cur_fw.type = 0; /* need firmware reload */
|
||||
priv->state = XC2028_SLEEP;
|
||||
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
|
|
@ -1237,8 +1310,9 @@ static int xc2028_dvb_release(struct dvb_frontend *fe)
|
|||
|
||||
/* only perform final cleanup if this is the last instance */
|
||||
if (hybrid_tuner_report_instance_count(priv) == 1) {
|
||||
kfree(priv->ctrl.fname);
|
||||
free_firmware(priv);
|
||||
kfree(priv->ctrl.fname);
|
||||
priv->ctrl.fname = NULL;
|
||||
}
|
||||
|
||||
if (priv)
|
||||
|
|
@ -1254,14 +1328,42 @@ static int xc2028_dvb_release(struct dvb_frontend *fe)
|
|||
static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
{
|
||||
struct xc2028_data *priv = fe->tuner_priv;
|
||||
int rc;
|
||||
|
||||
tuner_dbg("%s called\n", __func__);
|
||||
|
||||
rc = check_device_status(priv);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
*frequency = priv->frequency;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void load_firmware_cb(const struct firmware *fw,
|
||||
void *context)
|
||||
{
|
||||
struct dvb_frontend *fe = context;
|
||||
struct xc2028_data *priv = fe->tuner_priv;
|
||||
int rc;
|
||||
|
||||
tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error");
|
||||
if (!fw) {
|
||||
tuner_err("Could not load firmware %s.\n", priv->fname);
|
||||
priv->state = XC2028_NODEV;
|
||||
return;
|
||||
}
|
||||
|
||||
rc = load_all_firmwares(fe, fw);
|
||||
|
||||
release_firmware(fw);
|
||||
|
||||
if (rc < 0)
|
||||
return;
|
||||
priv->state = XC2028_SLEEP;
|
||||
}
|
||||
|
||||
static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
|
||||
{
|
||||
struct xc2028_data *priv = fe->tuner_priv;
|
||||
|
|
@ -1272,21 +1374,49 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
|
|||
|
||||
mutex_lock(&priv->lock);
|
||||
|
||||
/*
|
||||
* Copy the config data.
|
||||
* For the firmware name, keep a local copy of the string,
|
||||
* in order to avoid troubles during device release.
|
||||
*/
|
||||
if (priv->ctrl.fname)
|
||||
kfree(priv->ctrl.fname);
|
||||
memcpy(&priv->ctrl, p, sizeof(priv->ctrl));
|
||||
if (priv->ctrl.max_len < 9)
|
||||
priv->ctrl.max_len = 13;
|
||||
|
||||
if (p->fname) {
|
||||
if (priv->ctrl.fname && strcmp(p->fname, priv->ctrl.fname)) {
|
||||
kfree(priv->ctrl.fname);
|
||||
free_firmware(priv);
|
||||
}
|
||||
|
||||
priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL);
|
||||
if (priv->ctrl.fname == NULL)
|
||||
rc = -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* If firmware name changed, frees firmware. As free_firmware will
|
||||
* reset the status to NO_FIRMWARE, this forces a new request_firmware
|
||||
*/
|
||||
if (!firmware_name[0] && p->fname &&
|
||||
priv->fname && strcmp(p->fname, priv->fname))
|
||||
free_firmware(priv);
|
||||
|
||||
if (priv->ctrl.max_len < 9)
|
||||
priv->ctrl.max_len = 13;
|
||||
|
||||
if (priv->state == XC2028_NO_FIRMWARE) {
|
||||
if (!firmware_name[0])
|
||||
priv->fname = priv->ctrl.fname;
|
||||
else
|
||||
priv->fname = firmware_name;
|
||||
|
||||
rc = request_firmware_nowait(THIS_MODULE, 1,
|
||||
priv->fname,
|
||||
priv->i2c_props.adap->dev.parent,
|
||||
GFP_KERNEL,
|
||||
fe, load_firmware_cb);
|
||||
if (rc < 0) {
|
||||
tuner_err("Failed to request firmware %s\n",
|
||||
priv->fname);
|
||||
priv->state = XC2028_NODEV;
|
||||
}
|
||||
priv->state = XC2028_WAITING_FIRMWARE;
|
||||
}
|
||||
mutex_unlock(&priv->lock);
|
||||
|
||||
return rc;
|
||||
|
|
@ -1305,6 +1435,7 @@ static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = {
|
|||
.release = xc2028_dvb_release,
|
||||
.get_frequency = xc2028_get_frequency,
|
||||
.get_rf_strength = xc2028_signal,
|
||||
.get_afc = xc2028_get_afc,
|
||||
.set_params = xc2028_set_params,
|
||||
.sleep = xc2028_sleep,
|
||||
};
|
||||
|
|
@ -1375,3 +1506,5 @@ MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver");
|
|||
MODULE_AUTHOR("Michel Ludwig <[email protected]>");
|
||||
MODULE_AUTHOR("Mauro Carvalho Chehab <[email protected]>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_FIRMWARE(XC2028_DEFAULT_FIRMWARE);
|
||||
MODULE_FIRMWARE(XC3028L_DEFAULT_FIRMWARE);
|
||||
|
|
|
|||
|
|
@ -717,6 +717,12 @@ static int xc5000_set_params(struct dvb_frontend *fe)
|
|||
priv->freq_hz = freq - 1750000;
|
||||
priv->video_standard = DTV6;
|
||||
break;
|
||||
case SYS_ISDBT:
|
||||
/* All ISDB-T are currently for 6 MHz bw */
|
||||
if (!bw)
|
||||
bw = 6000000;
|
||||
/* fall to OFDM handling */
|
||||
case SYS_DMBTH:
|
||||
case SYS_DVBT:
|
||||
case SYS_DVBT2:
|
||||
dprintk(1, "%s() OFDM\n", __func__);
|
||||
|
|
|
|||
|
|
@ -578,6 +578,7 @@ static int demod_attach_drxk(struct ddb_input *input)
|
|||
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.microcode_name = "drxk_a3.mc";
|
||||
config.qam_demod_parameter_count = 4;
|
||||
config.adr = 0x29 + (input->nr & 1);
|
||||
|
||||
fe = input->fe = dvb_attach(drxk_attach, &config, i2c);
|
||||
|
|
|
|||
|
|
@ -220,6 +220,7 @@ struct dvb_tuner_ops {
|
|||
#define TUNER_STATUS_STEREO 2
|
||||
int (*get_status)(struct dvb_frontend *fe, u32 *status);
|
||||
int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength);
|
||||
int (*get_afc)(struct dvb_frontend *fe, s32 *afc);
|
||||
|
||||
/** These are provided separately from set_params in order to facilitate silicon
|
||||
* tuners which require sophisticated tuning loops, controlling each parameter separately. */
|
||||
|
|
|
|||
|
|
@ -418,9 +418,12 @@ config DVB_USB_RTL28XXU
|
|||
tristate "Realtek RTL28xxU DVB USB support"
|
||||
depends on DVB_USB && EXPERIMENTAL
|
||||
select DVB_RTL2830
|
||||
select DVB_RTL2832
|
||||
select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_FC0012 if !MEDIA_TUNER_CUSTOMISE
|
||||
select MEDIA_TUNER_FC0013 if !MEDIA_TUNER_CUSTOMISE
|
||||
help
|
||||
Say Y here to support the Realtek RTL28xxU DVB USB receiver.
|
||||
|
||||
|
|
|
|||
|
|
@ -593,9 +593,7 @@ static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6])
|
|||
memcpy(mac, st->data, sizeof(mac));
|
||||
|
||||
if (ret > 0)
|
||||
deb_info("%s: mac is %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
__func__, mac[0], mac[1], mac[2],
|
||||
mac[3], mac[4], mac[5]);
|
||||
deb_info("%s: mac is %pM\n", __func__, mac);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@
|
|||
#define USB_PID_CONCEPTRONIC_CTVDIGRCU 0xe397
|
||||
#define USB_PID_CONEXANT_D680_DMB 0x86d6
|
||||
#define USB_PID_CREATIX_CTX1921 0x1921
|
||||
#define USB_PID_DELOCK_USB2_DVBT 0xb803
|
||||
#define USB_PID_DIBCOM_HOOK_DEFAULT 0x0064
|
||||
#define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM 0x0065
|
||||
#define USB_PID_DIBCOM_MOD3000_COLD 0x0bb8
|
||||
|
|
@ -160,6 +161,7 @@
|
|||
#define USB_PID_TERRATEC_CINERGY_T_STICK 0x0093
|
||||
#define USB_PID_TERRATEC_CINERGY_T_STICK_RC 0x0097
|
||||
#define USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC 0x0099
|
||||
#define USB_PID_TERRATEC_CINERGY_T_STICK_BLACK_REV1 0x00a9
|
||||
#define USB_PID_TWINHAN_VP7041_COLD 0x3201
|
||||
#define USB_PID_TWINHAN_VP7041_WARM 0x3202
|
||||
#define USB_PID_TWINHAN_VP7020_COLD 0x3203
|
||||
|
|
@ -245,6 +247,7 @@
|
|||
#define USB_PID_TERRATEC_H7_2 0x10a3
|
||||
#define USB_PID_TERRATEC_T3 0x10a0
|
||||
#define USB_PID_TERRATEC_T5 0x10a1
|
||||
#define USB_PID_NOXON_DAB_STICK 0x00b3
|
||||
#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e
|
||||
#define USB_PID_PINNACLE_PCTV2000E 0x022c
|
||||
#define USB_PID_PINNACLE_PCTV_DVB_T_FLASH 0x0228
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
|
||||
* Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
|
||||
* Copyright (C) 2012 Thomas Mair <thomas.mair86@googlemail.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
|
||||
|
|
@ -22,10 +23,13 @@
|
|||
#include "rtl28xxu.h"
|
||||
|
||||
#include "rtl2830.h"
|
||||
#include "rtl2832.h"
|
||||
|
||||
#include "qt1010.h"
|
||||
#include "mt2060.h"
|
||||
#include "mxl5005s.h"
|
||||
#include "fc0012.h"
|
||||
#include "fc0013.h"
|
||||
|
||||
/* debug */
|
||||
static int dvb_usb_rtl28xxu_debug;
|
||||
|
|
@ -80,7 +84,7 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int rtl2831_wr_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len)
|
||||
static int rtl28xx_wr_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len)
|
||||
{
|
||||
struct rtl28xxu_req req;
|
||||
|
||||
|
|
@ -116,12 +120,12 @@ static int rtl2831_rd_regs(struct dvb_usb_device *d, u16 reg, u8 *val, int len)
|
|||
return rtl28xxu_ctrl_msg(d, &req);
|
||||
}
|
||||
|
||||
static int rtl2831_wr_reg(struct dvb_usb_device *d, u16 reg, u8 val)
|
||||
static int rtl28xx_wr_reg(struct dvb_usb_device *d, u16 reg, u8 val)
|
||||
{
|
||||
return rtl2831_wr_regs(d, reg, &val, 1);
|
||||
return rtl28xx_wr_regs(d, reg, &val, 1);
|
||||
}
|
||||
|
||||
static int rtl2831_rd_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
|
||||
static int rtl28xx_rd_reg(struct dvb_usb_device *d, u16 reg, u8 *val)
|
||||
{
|
||||
return rtl2831_rd_regs(d, reg, val, 1);
|
||||
}
|
||||
|
|
@ -308,12 +312,12 @@ static int rtl2831u_frontend_attach(struct dvb_usb_adapter *adap)
|
|||
*/
|
||||
|
||||
/* GPIO direction */
|
||||
ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a);
|
||||
ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* enable as output GPIO0, GPIO2, GPIO4 */
|
||||
ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15);
|
||||
ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
|
@ -381,34 +385,159 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct rtl2832_config rtl28xxu_rtl2832_fc0012_config = {
|
||||
.i2c_addr = 0x10, /* 0x20 */
|
||||
.xtal = 28800000,
|
||||
.if_dvbt = 0,
|
||||
.tuner = TUNER_RTL2832_FC0012
|
||||
};
|
||||
|
||||
static struct rtl2832_config rtl28xxu_rtl2832_fc0013_config = {
|
||||
.i2c_addr = 0x10, /* 0x20 */
|
||||
.xtal = 28800000,
|
||||
.if_dvbt = 0,
|
||||
.tuner = TUNER_RTL2832_FC0013
|
||||
};
|
||||
|
||||
static int rtl2832u_fc0012_tuner_callback(struct dvb_usb_device *d,
|
||||
int cmd, int arg)
|
||||
{
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
deb_info("%s cmd=%d arg=%d\n", __func__, cmd, arg);
|
||||
switch (cmd) {
|
||||
case FC_FE_CALLBACK_VHF_ENABLE:
|
||||
/* set output values */
|
||||
ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (arg)
|
||||
val &= 0xbf; /* set GPIO6 low */
|
||||
else
|
||||
val |= 0x40; /* set GPIO6 high */
|
||||
|
||||
|
||||
ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
|
||||
if (ret)
|
||||
goto err;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err:
|
||||
err("%s: failed=%d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int rtl2832u_fc0013_tuner_callback(struct dvb_usb_device *d,
|
||||
int cmd, int arg)
|
||||
{
|
||||
/* TODO implement*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl2832u_tuner_callback(struct dvb_usb_device *d, int cmd, int arg)
|
||||
{
|
||||
struct rtl28xxu_priv *priv = d->priv;
|
||||
|
||||
switch (priv->tuner) {
|
||||
case TUNER_RTL2832_FC0012:
|
||||
return rtl2832u_fc0012_tuner_callback(d, cmd, arg);
|
||||
|
||||
case TUNER_RTL2832_FC0013:
|
||||
return rtl2832u_fc0013_tuner_callback(d, cmd, arg);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int rtl2832u_frontend_callback(void *adapter_priv, int component,
|
||||
int cmd, int arg)
|
||||
{
|
||||
struct i2c_adapter *adap = adapter_priv;
|
||||
struct dvb_usb_device *d = i2c_get_adapdata(adap);
|
||||
|
||||
switch (component) {
|
||||
case DVB_FRONTEND_COMPONENT_TUNER:
|
||||
return rtl2832u_tuner_callback(d, cmd, arg);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
|
||||
{
|
||||
int ret;
|
||||
struct rtl28xxu_priv *priv = adap->dev->priv;
|
||||
u8 buf[1];
|
||||
struct rtl2832_config *rtl2832_config;
|
||||
|
||||
u8 buf[2], val;
|
||||
/* open RTL2832U/RTL2832 I2C gate */
|
||||
struct rtl28xxu_req req_gate_open = {0x0120, 0x0011, 0x0001, "\x18"};
|
||||
/* close RTL2832U/RTL2832 I2C gate */
|
||||
struct rtl28xxu_req req_gate_close = {0x0120, 0x0011, 0x0001, "\x10"};
|
||||
/* for FC0012 tuner probe */
|
||||
struct rtl28xxu_req req_fc0012 = {0x00c6, CMD_I2C_RD, 1, buf};
|
||||
/* for FC0013 tuner probe */
|
||||
struct rtl28xxu_req req_fc0013 = {0x00c6, CMD_I2C_RD, 1, buf};
|
||||
/* for MT2266 tuner probe */
|
||||
struct rtl28xxu_req req_mt2266 = {0x00c0, CMD_I2C_RD, 1, buf};
|
||||
/* for FC2580 tuner probe */
|
||||
struct rtl28xxu_req req_fc2580 = {0x01ac, CMD_I2C_RD, 1, buf};
|
||||
/* for MT2063 tuner probe */
|
||||
struct rtl28xxu_req req_mt2063 = {0x00c0, CMD_I2C_RD, 1, buf};
|
||||
/* for MAX3543 tuner probe */
|
||||
struct rtl28xxu_req req_max3543 = {0x00c0, CMD_I2C_RD, 1, buf};
|
||||
/* for TUA9001 tuner probe */
|
||||
struct rtl28xxu_req req_tua9001 = {0x7ec0, CMD_I2C_RD, 2, buf};
|
||||
/* for MXL5007T tuner probe */
|
||||
struct rtl28xxu_req req_mxl5007t = {0xd9c0, CMD_I2C_RD, 1, buf};
|
||||
/* for E4000 tuner probe */
|
||||
struct rtl28xxu_req req_e4000 = {0x02c8, CMD_I2C_RD, 1, buf};
|
||||
/* for TDA18272 tuner probe */
|
||||
struct rtl28xxu_req req_tda18272 = {0x00c0, CMD_I2C_RD, 2, buf};
|
||||
|
||||
deb_info("%s:\n", __func__);
|
||||
|
||||
/* GPIO direction */
|
||||
ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_DIR, 0x0a);
|
||||
|
||||
ret = rtl28xx_rd_reg(adap->dev, SYS_GPIO_DIR, &val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* enable as output GPIO0, GPIO2, GPIO4 */
|
||||
ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_EN, 0x15);
|
||||
val &= 0xbf;
|
||||
|
||||
ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_DIR, val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = rtl2831_wr_reg(adap->dev, SYS_DEMOD_CTL, 0xe8);
|
||||
|
||||
/* enable as output GPIO3 and GPIO6*/
|
||||
ret = rtl28xx_rd_reg(adap->dev, SYS_GPIO_OUT_EN, &val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
val |= 0x48;
|
||||
|
||||
ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_OUT_EN, val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Probe used tuner. We need to know used tuner before demod attach
|
||||
* since there is some demod params needed to set according to tuner.
|
||||
|
|
@ -419,25 +548,108 @@ static int rtl2832u_frontend_attach(struct dvb_usb_adapter *adap)
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
priv->tuner = TUNER_NONE;
|
||||
|
||||
/* check FC0012 ID register; reg=00 val=a1 */
|
||||
ret = rtl28xxu_ctrl_msg(adap->dev, &req_fc0012);
|
||||
if (ret == 0 && buf[0] == 0xa1) {
|
||||
priv->tuner = TUNER_RTL2832_FC0012;
|
||||
rtl2832_config = &rtl28xxu_rtl2832_fc0012_config;
|
||||
info("%s: FC0012 tuner found", __func__);
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* check FC0013 ID register; reg=00 val=a3 */
|
||||
ret = rtl28xxu_ctrl_msg(adap->dev, &req_fc0013);
|
||||
if (ret == 0 && buf[0] == 0xa3) {
|
||||
priv->tuner = TUNER_RTL2832_FC0013;
|
||||
rtl2832_config = &rtl28xxu_rtl2832_fc0013_config;
|
||||
info("%s: FC0013 tuner found", __func__);
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* check MT2266 ID register; reg=00 val=85 */
|
||||
ret = rtl28xxu_ctrl_msg(adap->dev, &req_mt2266);
|
||||
if (ret == 0 && buf[0] == 0x85) {
|
||||
priv->tuner = TUNER_RTL2832_MT2266;
|
||||
/* TODO implement tuner */
|
||||
info("%s: MT2266 tuner found", __func__);
|
||||
goto unsupported;
|
||||
}
|
||||
|
||||
/* check FC2580 ID register; reg=01 val=56 */
|
||||
ret = rtl28xxu_ctrl_msg(adap->dev, &req_fc2580);
|
||||
if (ret == 0 && buf[0] == 0x56) {
|
||||
priv->tuner = TUNER_RTL2832_FC2580;
|
||||
deb_info("%s: FC2580\n", __func__);
|
||||
goto found;
|
||||
} else {
|
||||
deb_info("%s: FC2580 probe failed=%d - %02x\n",
|
||||
__func__, ret, buf[0]);
|
||||
/* TODO implement tuner */
|
||||
info("%s: FC2580 tuner found", __func__);
|
||||
goto unsupported;
|
||||
}
|
||||
|
||||
/* check MT2063 ID register; reg=00 val=9e || 9c */
|
||||
ret = rtl28xxu_ctrl_msg(adap->dev, &req_mt2063);
|
||||
if (ret == 0 && (buf[0] == 0x9e || buf[0] == 0x9c)) {
|
||||
priv->tuner = TUNER_RTL2832_MT2063;
|
||||
/* TODO implement tuner */
|
||||
info("%s: MT2063 tuner found", __func__);
|
||||
goto unsupported;
|
||||
}
|
||||
|
||||
/* check MAX3543 ID register; reg=00 val=38 */
|
||||
ret = rtl28xxu_ctrl_msg(adap->dev, &req_max3543);
|
||||
if (ret == 0 && buf[0] == 0x38) {
|
||||
priv->tuner = TUNER_RTL2832_MAX3543;
|
||||
/* TODO implement tuner */
|
||||
info("%s: MAX3534 tuner found", __func__);
|
||||
goto unsupported;
|
||||
}
|
||||
|
||||
/* check TUA9001 ID register; reg=7e val=2328 */
|
||||
ret = rtl28xxu_ctrl_msg(adap->dev, &req_tua9001);
|
||||
if (ret == 0 && buf[0] == 0x23 && buf[1] == 0x28) {
|
||||
priv->tuner = TUNER_RTL2832_TUA9001;
|
||||
/* TODO implement tuner */
|
||||
info("%s: TUA9001 tuner found", __func__);
|
||||
goto unsupported;
|
||||
}
|
||||
|
||||
/* check MXL5007R ID register; reg=d9 val=14 */
|
||||
ret = rtl28xxu_ctrl_msg(adap->dev, &req_mxl5007t);
|
||||
if (ret == 0 && buf[0] == 0x14) {
|
||||
priv->tuner = TUNER_RTL2832_MXL5007T;
|
||||
/* TODO implement tuner */
|
||||
info("%s: MXL5007T tuner found", __func__);
|
||||
goto unsupported;
|
||||
}
|
||||
|
||||
/* check E4000 ID register; reg=02 val=40 */
|
||||
ret = rtl28xxu_ctrl_msg(adap->dev, &req_e4000);
|
||||
if (ret == 0 && buf[0] == 0x40) {
|
||||
priv->tuner = TUNER_RTL2832_E4000;
|
||||
/* TODO implement tuner */
|
||||
info("%s: E4000 tuner found", __func__);
|
||||
goto unsupported;
|
||||
}
|
||||
|
||||
/* check TDA18272 ID register; reg=00 val=c760 */
|
||||
ret = rtl28xxu_ctrl_msg(adap->dev, &req_tda18272);
|
||||
if (ret == 0 && (buf[0] == 0xc7 || buf[1] == 0x60)) {
|
||||
priv->tuner = TUNER_RTL2832_TDA18272;
|
||||
/* TODO implement tuner */
|
||||
info("%s: TDA18272 tuner found", __func__);
|
||||
goto unsupported;
|
||||
}
|
||||
|
||||
unsupported:
|
||||
/* close demod I2C gate */
|
||||
ret = rtl28xxu_ctrl_msg(adap->dev, &req_gate_close);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* tuner not found */
|
||||
deb_info("No compatible tuner found");
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
return ret;
|
||||
|
||||
found:
|
||||
/* close demod I2C gate */
|
||||
|
|
@ -446,9 +658,18 @@ found:
|
|||
goto err;
|
||||
|
||||
/* attach demodulator */
|
||||
/* TODO: */
|
||||
adap->fe_adap[0].fe = dvb_attach(rtl2832_attach, rtl2832_config,
|
||||
&adap->dev->i2c_adap);
|
||||
if (adap->fe_adap[0].fe == NULL) {
|
||||
ret = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* set fe callbacks */
|
||||
adap->fe_adap[0].fe->callback = rtl2832u_frontend_callback;
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
deb_info("%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
|
|
@ -531,10 +752,24 @@ static int rtl2832u_tuner_attach(struct dvb_usb_adapter *adap)
|
|||
deb_info("%s:\n", __func__);
|
||||
|
||||
switch (priv->tuner) {
|
||||
case TUNER_RTL2832_FC2580:
|
||||
/* TODO: */
|
||||
fe = NULL;
|
||||
case TUNER_RTL2832_FC0012:
|
||||
fe = dvb_attach(fc0012_attach, adap->fe_adap[0].fe,
|
||||
&adap->dev->i2c_adap, 0xc6>>1, 0, FC_XTAL_28_8_MHZ);
|
||||
|
||||
/* since fc0012 includs reading the signal strength delegate
|
||||
* that to the tuner driver */
|
||||
adap->fe_adap[0].fe->ops.read_signal_strength = adap->fe_adap[0].
|
||||
fe->ops.tuner_ops.get_rf_strength;
|
||||
return 0;
|
||||
break;
|
||||
case TUNER_RTL2832_FC0013:
|
||||
fe = dvb_attach(fc0013_attach, adap->fe_adap[0].fe,
|
||||
&adap->dev->i2c_adap, 0xc6>>1, 0, FC_XTAL_28_8_MHZ);
|
||||
|
||||
/* fc0013 also supports signal strength reading */
|
||||
adap->fe_adap[0].fe->ops.read_signal_strength = adap->fe_adap[0]
|
||||
.fe->ops.tuner_ops.get_rf_strength;
|
||||
return 0;
|
||||
default:
|
||||
fe = NULL;
|
||||
err("unknown tuner=%d", priv->tuner);
|
||||
|
|
@ -551,14 +786,14 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int rtl28xxu_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff)
|
||||
static int rtl2831u_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[2], gpio;
|
||||
|
||||
deb_info("%s: onoff=%d\n", __func__, onoff);
|
||||
|
||||
ret = rtl2831_rd_reg(adap->dev, SYS_GPIO_OUT_VAL, &gpio);
|
||||
ret = rtl28xx_rd_reg(adap->dev, SYS_GPIO_OUT_VAL, &gpio);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
|
@ -572,11 +807,11 @@ static int rtl28xxu_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff)
|
|||
gpio &= (~0x04); /* LED off */
|
||||
}
|
||||
|
||||
ret = rtl2831_wr_reg(adap->dev, SYS_GPIO_OUT_VAL, gpio);
|
||||
ret = rtl28xx_wr_reg(adap->dev, SYS_GPIO_OUT_VAL, gpio);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = rtl2831_wr_regs(adap->dev, USB_EPA_CTL, buf, 2);
|
||||
ret = rtl28xx_wr_regs(adap->dev, USB_EPA_CTL, buf, 2);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
|
@ -586,7 +821,33 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int rtl28xxu_power_ctrl(struct dvb_usb_device *d, int onoff)
|
||||
static int rtl2832u_streaming_ctrl(struct dvb_usb_adapter *adap , int onoff)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[2];
|
||||
|
||||
deb_info("%s: onoff=%d\n", __func__, onoff);
|
||||
|
||||
|
||||
if (onoff) {
|
||||
buf[0] = 0x00;
|
||||
buf[1] = 0x00;
|
||||
} else {
|
||||
buf[0] = 0x10; /* stall EPA */
|
||||
buf[1] = 0x02; /* reset EPA */
|
||||
}
|
||||
|
||||
ret = rtl28xx_wr_regs(adap->dev, USB_EPA_CTL, buf, 2);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
return ret;
|
||||
err:
|
||||
deb_info("%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtl2831u_power_ctrl(struct dvb_usb_device *d, int onoff)
|
||||
{
|
||||
int ret;
|
||||
u8 gpio, sys0;
|
||||
|
|
@ -594,12 +855,12 @@ static int rtl28xxu_power_ctrl(struct dvb_usb_device *d, int onoff)
|
|||
deb_info("%s: onoff=%d\n", __func__, onoff);
|
||||
|
||||
/* demod adc */
|
||||
ret = rtl2831_rd_reg(d, SYS_SYS0, &sys0);
|
||||
ret = rtl28xx_rd_reg(d, SYS_SYS0, &sys0);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* tuner power, read GPIOs */
|
||||
ret = rtl2831_rd_reg(d, SYS_GPIO_OUT_VAL, &gpio);
|
||||
ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &gpio);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
|
@ -619,12 +880,12 @@ static int rtl28xxu_power_ctrl(struct dvb_usb_device *d, int onoff)
|
|||
deb_info("%s: WR SYS0=%02x GPIO_OUT_VAL=%02x\n", __func__, sys0, gpio);
|
||||
|
||||
/* demod adc */
|
||||
ret = rtl2831_wr_reg(d, SYS_SYS0, sys0);
|
||||
ret = rtl28xx_wr_reg(d, SYS_SYS0, sys0);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* tuner power, write GPIOs */
|
||||
ret = rtl2831_wr_reg(d, SYS_GPIO_OUT_VAL, gpio);
|
||||
ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, gpio);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
|
@ -634,6 +895,128 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int rtl2832u_power_ctrl(struct dvb_usb_device *d, int onoff)
|
||||
{
|
||||
int ret;
|
||||
u8 val;
|
||||
|
||||
deb_info("%s: onoff=%d\n", __func__, onoff);
|
||||
|
||||
if (onoff) {
|
||||
/* set output values */
|
||||
ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
val |= 0x08;
|
||||
val &= 0xef;
|
||||
|
||||
ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* demod_ctl_1 */
|
||||
ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
val &= 0xef;
|
||||
|
||||
ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* demod control */
|
||||
/* PLL enable */
|
||||
ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* bit 7 to 1 */
|
||||
val |= 0x80;
|
||||
|
||||
ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* demod HW reset */
|
||||
ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
|
||||
if (ret)
|
||||
goto err;
|
||||
/* bit 5 to 0 */
|
||||
val &= 0xdf;
|
||||
|
||||
ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
val |= 0x20;
|
||||
|
||||
ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
mdelay(5);
|
||||
|
||||
/*enable ADC_Q and ADC_I */
|
||||
ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
val |= 0x48;
|
||||
|
||||
ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
||||
} else {
|
||||
/* demod_ctl_1 */
|
||||
ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL1, &val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
val |= 0x0c;
|
||||
|
||||
ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL1, val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* set output values */
|
||||
ret = rtl28xx_rd_reg(d, SYS_GPIO_OUT_VAL, &val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
val |= 0x10;
|
||||
|
||||
ret = rtl28xx_wr_reg(d, SYS_GPIO_OUT_VAL, val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* demod control */
|
||||
ret = rtl28xx_rd_reg(d, SYS_DEMOD_CTL, &val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
val &= 0x37;
|
||||
|
||||
ret = rtl28xx_wr_reg(d, SYS_DEMOD_CTL, val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
err:
|
||||
deb_info("%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int rtl2831u_rc_query(struct dvb_usb_device *d)
|
||||
{
|
||||
int ret, i;
|
||||
|
|
@ -660,7 +1043,7 @@ static int rtl2831u_rc_query(struct dvb_usb_device *d)
|
|||
/* init remote controller */
|
||||
if (!priv->rc_active) {
|
||||
for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) {
|
||||
ret = rtl2831_wr_reg(d, rc_nec_tab[i].reg,
|
||||
ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg,
|
||||
rc_nec_tab[i].val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
|
@ -690,12 +1073,12 @@ static int rtl2831u_rc_query(struct dvb_usb_device *d)
|
|||
|
||||
rc_keydown(d->rc_dev, rc_code, 0);
|
||||
|
||||
ret = rtl2831_wr_reg(d, SYS_IRRC_SR, 1);
|
||||
ret = rtl28xx_wr_reg(d, SYS_IRRC_SR, 1);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* repeated intentionally to avoid extra keypress */
|
||||
ret = rtl2831_wr_reg(d, SYS_IRRC_SR, 1);
|
||||
ret = rtl28xx_wr_reg(d, SYS_IRRC_SR, 1);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
|
@ -732,7 +1115,7 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d)
|
|||
/* init remote controller */
|
||||
if (!priv->rc_active) {
|
||||
for (i = 0; i < ARRAY_SIZE(rc_nec_tab); i++) {
|
||||
ret = rtl2831_wr_reg(d, rc_nec_tab[i].reg,
|
||||
ret = rtl28xx_wr_reg(d, rc_nec_tab[i].reg,
|
||||
rc_nec_tab[i].val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
|
@ -740,14 +1123,14 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d)
|
|||
priv->rc_active = true;
|
||||
}
|
||||
|
||||
ret = rtl2831_rd_reg(d, IR_RX_IF, &buf[0]);
|
||||
ret = rtl28xx_rd_reg(d, IR_RX_IF, &buf[0]);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (buf[0] != 0x83)
|
||||
goto exit;
|
||||
|
||||
ret = rtl2831_rd_reg(d, IR_RX_BC, &buf[0]);
|
||||
ret = rtl28xx_rd_reg(d, IR_RX_BC, &buf[0]);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
|
@ -756,9 +1139,9 @@ static int rtl2832u_rc_query(struct dvb_usb_device *d)
|
|||
|
||||
/* TODO: pass raw IR to Kernel IR decoder */
|
||||
|
||||
ret = rtl2831_wr_reg(d, IR_RX_IF, 0x03);
|
||||
ret = rtl2831_wr_reg(d, IR_RX_BUF_CTRL, 0x80);
|
||||
ret = rtl2831_wr_reg(d, IR_RX_CTRL, 0x80);
|
||||
ret = rtl28xx_wr_reg(d, IR_RX_IF, 0x03);
|
||||
ret = rtl28xx_wr_reg(d, IR_RX_BUF_CTRL, 0x80);
|
||||
ret = rtl28xx_wr_reg(d, IR_RX_CTRL, 0x80);
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
|
|
@ -771,6 +1154,9 @@ enum rtl28xxu_usb_table_entry {
|
|||
RTL2831U_0BDA_2831,
|
||||
RTL2831U_14AA_0160,
|
||||
RTL2831U_14AA_0161,
|
||||
RTL2832U_0CCD_00A9,
|
||||
RTL2832U_1F4D_B803,
|
||||
RTL2832U_0CCD_00B3,
|
||||
};
|
||||
|
||||
static struct usb_device_id rtl28xxu_table[] = {
|
||||
|
|
@ -783,6 +1169,12 @@ static struct usb_device_id rtl28xxu_table[] = {
|
|||
USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_FREECOM_DVBT_2)},
|
||||
|
||||
/* RTL2832U */
|
||||
[RTL2832U_0CCD_00A9] = {
|
||||
USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_STICK_BLACK_REV1)},
|
||||
[RTL2832U_1F4D_B803] = {
|
||||
USB_DEVICE(USB_VID_GTEK, USB_PID_DELOCK_USB2_DVBT)},
|
||||
[RTL2832U_0CCD_00B3] = {
|
||||
USB_DEVICE(USB_VID_TERRATEC, USB_PID_NOXON_DAB_STICK)},
|
||||
{} /* terminating entry */
|
||||
};
|
||||
|
||||
|
|
@ -805,7 +1197,7 @@ static struct dvb_usb_device_properties rtl28xxu_properties[] = {
|
|||
{
|
||||
.frontend_attach = rtl2831u_frontend_attach,
|
||||
.tuner_attach = rtl2831u_tuner_attach,
|
||||
.streaming_ctrl = rtl28xxu_streaming_ctrl,
|
||||
.streaming_ctrl = rtl2831u_streaming_ctrl,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 6,
|
||||
|
|
@ -821,7 +1213,7 @@ static struct dvb_usb_device_properties rtl28xxu_properties[] = {
|
|||
}
|
||||
},
|
||||
|
||||
.power_ctrl = rtl28xxu_power_ctrl,
|
||||
.power_ctrl = rtl2831u_power_ctrl,
|
||||
|
||||
.rc.core = {
|
||||
.protocol = RC_TYPE_NEC,
|
||||
|
|
@ -867,7 +1259,7 @@ static struct dvb_usb_device_properties rtl28xxu_properties[] = {
|
|||
{
|
||||
.frontend_attach = rtl2832u_frontend_attach,
|
||||
.tuner_attach = rtl2832u_tuner_attach,
|
||||
.streaming_ctrl = rtl28xxu_streaming_ctrl,
|
||||
.streaming_ctrl = rtl2832u_streaming_ctrl,
|
||||
.stream = {
|
||||
.type = USB_BULK,
|
||||
.count = 6,
|
||||
|
|
@ -883,7 +1275,7 @@ static struct dvb_usb_device_properties rtl28xxu_properties[] = {
|
|||
}
|
||||
},
|
||||
|
||||
.power_ctrl = rtl28xxu_power_ctrl,
|
||||
.power_ctrl = rtl2832u_power_ctrl,
|
||||
|
||||
.rc.core = {
|
||||
.protocol = RC_TYPE_NEC,
|
||||
|
|
@ -896,10 +1288,25 @@ static struct dvb_usb_device_properties rtl28xxu_properties[] = {
|
|||
|
||||
.i2c_algo = &rtl28xxu_i2c_algo,
|
||||
|
||||
.num_device_descs = 0, /* disabled as no support for RTL2832 */
|
||||
.num_device_descs = 3,
|
||||
.devices = {
|
||||
{
|
||||
.name = "Realtek RTL2832U reference design",
|
||||
.name = "Terratec Cinergy T Stick Black",
|
||||
.warm_ids = {
|
||||
&rtl28xxu_table[RTL2832U_0CCD_00A9],
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "G-Tek Electronics Group Lifeview LV5TDLX DVB-T",
|
||||
.warm_ids = {
|
||||
&rtl28xxu_table[RTL2832U_1F4D_B803],
|
||||
},
|
||||
},
|
||||
{
|
||||
.name = "NOXON DAB/DAB+ USB dongle",
|
||||
.warm_ids = {
|
||||
&rtl28xxu_table[RTL2832U_0CCD_00B3],
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
|
@ -910,6 +1317,7 @@ static int rtl28xxu_probe(struct usb_interface *intf,
|
|||
const struct usb_device_id *id)
|
||||
{
|
||||
int ret, i;
|
||||
u8 val;
|
||||
int properties_count = ARRAY_SIZE(rtl28xxu_properties);
|
||||
struct dvb_usb_device *d;
|
||||
struct usb_device *udev;
|
||||
|
|
@ -954,16 +1362,25 @@ static int rtl28xxu_probe(struct usb_interface *intf,
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
||||
/* init USB endpoints */
|
||||
ret = rtl2831_wr_reg(d, USB_SYSCTL_0, 0x09);
|
||||
ret = rtl28xx_rd_reg(d, USB_SYSCTL_0, &val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* enable DMA and Full Packet Mode*/
|
||||
val |= 0x09;
|
||||
ret = rtl28xx_wr_reg(d, USB_SYSCTL_0, val);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = rtl2831_wr_regs(d, USB_EPA_MAXPKT, "\x00\x02\x00\x00", 4);
|
||||
/* set EPA maximum packet size to 0x0200 */
|
||||
ret = rtl28xx_wr_regs(d, USB_EPA_MAXPKT, "\x00\x02\x00\x00", 4);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = rtl2831_wr_regs(d, USB_EPA_FIFO_CFG, "\x14\x00\x00\x00", 4);
|
||||
/* change EPA FIFO length */
|
||||
ret = rtl28xx_wr_regs(d, USB_EPA_FIFO_CFG, "\x14\x00\x00\x00", 4);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
|
@ -1007,4 +1424,5 @@ module_exit(rtl28xxu_module_exit);
|
|||
|
||||
MODULE_DESCRIPTION("Realtek RTL28xxU DVB USB driver");
|
||||
MODULE_AUTHOR("Antti Palosaari <[email protected]>");
|
||||
MODULE_AUTHOR("Thomas Mair <[email protected]>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
config DVB_FE_CUSTOMISE
|
||||
bool "Customise the frontend modules to build"
|
||||
depends on DVB_CORE
|
||||
depends on EXPERT
|
||||
default y if EXPERT
|
||||
help
|
||||
This allows the user to select/deselect frontend drivers for their
|
||||
|
|
@ -432,6 +433,13 @@ config DVB_RTL2830
|
|||
help
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_RTL2832
|
||||
tristate "Realtek RTL2832 DVB-T"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
help
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
comment "DVB-C (cable) frontends"
|
||||
depends on DVB_CORE
|
||||
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ obj-$(CONFIG_DVB_IT913X_FE) += it913x-fe.o
|
|||
obj-$(CONFIG_DVB_A8293) += a8293.o
|
||||
obj-$(CONFIG_DVB_TDA10071) += tda10071.o
|
||||
obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
|
||||
obj-$(CONFIG_DVB_RTL2832) += rtl2832.o
|
||||
obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
|
||||
obj-$(CONFIG_DVB_AF9033) += af9033.o
|
||||
|
||||
|
|
|
|||
|
|
@ -21,24 +21,6 @@
|
|||
#include "dvb_frontend.h"
|
||||
#include "a8293.h"
|
||||
|
||||
static int debug;
|
||||
module_param(debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
|
||||
|
||||
#define LOG_PREFIX "a8293"
|
||||
|
||||
#undef dbg
|
||||
#define dbg(f, arg...) \
|
||||
if (debug) \
|
||||
printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
|
||||
#undef err
|
||||
#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
|
||||
#undef info
|
||||
#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
|
||||
#undef warn
|
||||
#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
|
||||
|
||||
|
||||
struct a8293_priv {
|
||||
struct i2c_adapter *i2c;
|
||||
const struct a8293_config *cfg;
|
||||
|
|
@ -65,7 +47,8 @@ static int a8293_i2c(struct a8293_priv *priv, u8 *val, int len, bool rd)
|
|||
if (ret == 1) {
|
||||
ret = 0;
|
||||
} else {
|
||||
warn("i2c failed=%d rd=%d", ret, rd);
|
||||
dev_warn(&priv->i2c->dev, "%s: i2c failed=%d rd=%d\n",
|
||||
KBUILD_MODNAME, ret, rd);
|
||||
ret = -EREMOTEIO;
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +71,8 @@ static int a8293_set_voltage(struct dvb_frontend *fe,
|
|||
struct a8293_priv *priv = fe->sec_priv;
|
||||
int ret;
|
||||
|
||||
dbg("%s: fe_sec_voltage=%d", __func__, fe_sec_voltage);
|
||||
dev_dbg(&priv->i2c->dev, "%s: fe_sec_voltage=%d\n", __func__,
|
||||
fe_sec_voltage);
|
||||
|
||||
switch (fe_sec_voltage) {
|
||||
case SEC_VOLTAGE_OFF:
|
||||
|
|
@ -114,14 +98,12 @@ static int a8293_set_voltage(struct dvb_frontend *fe,
|
|||
|
||||
return ret;
|
||||
err:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void a8293_release_sec(struct dvb_frontend *fe)
|
||||
{
|
||||
dbg("%s:", __func__);
|
||||
|
||||
a8293_set_voltage(fe, SEC_VOLTAGE_OFF);
|
||||
|
||||
kfree(fe->sec_priv);
|
||||
|
|
@ -154,7 +136,7 @@ struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
|
|||
|
||||
/* ENB=0 */
|
||||
priv->reg[0] = 0x10;
|
||||
ret = a8293_wr(priv, &priv->reg[1], 1);
|
||||
ret = a8293_wr(priv, &priv->reg[0], 1);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
|
@ -164,16 +146,17 @@ struct dvb_frontend *a8293_attach(struct dvb_frontend *fe,
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
info("Allegro A8293 SEC attached.");
|
||||
|
||||
fe->ops.release_sec = a8293_release_sec;
|
||||
|
||||
/* override frontend ops */
|
||||
fe->ops.set_voltage = a8293_set_voltage;
|
||||
|
||||
dev_info(&priv->i2c->dev, "%s: Allegro A8293 SEC attached\n",
|
||||
KBUILD_MODNAME);
|
||||
|
||||
return fe;
|
||||
err:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
kfree(priv);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,14 @@
|
|||
* means that 1=DVBC, 0 = DVBT. Zero means the opposite.
|
||||
* @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength.
|
||||
* @microcode_name: Name of the firmware file with the microcode
|
||||
* @qam_demod_parameter_count: The number of parameters used for the command
|
||||
* to set the demodulator parameters. All
|
||||
* firmwares are using the 2-parameter commmand.
|
||||
* An exception is the "drxk_a3.mc" firmware,
|
||||
* which uses the 4-parameter command.
|
||||
* A value of 0 (default) or lower indicates that
|
||||
* the correct number of parameters will be
|
||||
* automatically detected.
|
||||
*
|
||||
* On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is
|
||||
* UIO-3.
|
||||
|
|
@ -38,7 +46,8 @@ struct drxk_config {
|
|||
u8 mpeg_out_clk_strength;
|
||||
int chunk_size;
|
||||
|
||||
const char *microcode_name;
|
||||
const char *microcode_name;
|
||||
int qam_demod_parameter_count;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_DRXK) || (defined(CONFIG_DVB_DRXK_MODULE) \
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include <linux/delay.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
|
|
@ -308,16 +309,42 @@ static u32 Log10Times100(u32 x)
|
|||
/* I2C **********************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static int i2c_read1(struct i2c_adapter *adapter, u8 adr, u8 *val)
|
||||
static int drxk_i2c_lock(struct drxk_state *state)
|
||||
{
|
||||
i2c_lock_adapter(state->i2c);
|
||||
state->drxk_i2c_exclusive_lock = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void drxk_i2c_unlock(struct drxk_state *state)
|
||||
{
|
||||
if (!state->drxk_i2c_exclusive_lock)
|
||||
return;
|
||||
|
||||
i2c_unlock_adapter(state->i2c);
|
||||
state->drxk_i2c_exclusive_lock = false;
|
||||
}
|
||||
|
||||
static int drxk_i2c_transfer(struct drxk_state *state, struct i2c_msg *msgs,
|
||||
unsigned len)
|
||||
{
|
||||
if (state->drxk_i2c_exclusive_lock)
|
||||
return __i2c_transfer(state->i2c, msgs, len);
|
||||
else
|
||||
return i2c_transfer(state->i2c, msgs, len);
|
||||
}
|
||||
|
||||
static int i2c_read1(struct drxk_state *state, u8 adr, u8 *val)
|
||||
{
|
||||
struct i2c_msg msgs[1] = { {.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = 1}
|
||||
};
|
||||
|
||||
return i2c_transfer(adapter, msgs, 1);
|
||||
return drxk_i2c_transfer(state, msgs, 1);
|
||||
}
|
||||
|
||||
static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
|
||||
static int i2c_write(struct drxk_state *state, u8 adr, u8 *data, int len)
|
||||
{
|
||||
int status;
|
||||
struct i2c_msg msg = {
|
||||
|
|
@ -330,7 +357,7 @@ static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
|
|||
printk(KERN_CONT " %02x", data[i]);
|
||||
printk(KERN_CONT "\n");
|
||||
}
|
||||
status = i2c_transfer(adap, &msg, 1);
|
||||
status = drxk_i2c_transfer(state, &msg, 1);
|
||||
if (status >= 0 && status != 1)
|
||||
status = -EIO;
|
||||
|
||||
|
|
@ -340,7 +367,7 @@ static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
|
|||
return status;
|
||||
}
|
||||
|
||||
static int i2c_read(struct i2c_adapter *adap,
|
||||
static int i2c_read(struct drxk_state *state,
|
||||
u8 adr, u8 *msg, int len, u8 *answ, int alen)
|
||||
{
|
||||
int status;
|
||||
|
|
@ -351,7 +378,7 @@ static int i2c_read(struct i2c_adapter *adap,
|
|||
.buf = answ, .len = alen}
|
||||
};
|
||||
|
||||
status = i2c_transfer(adap, msgs, 2);
|
||||
status = drxk_i2c_transfer(state, msgs, 2);
|
||||
if (status != 2) {
|
||||
if (debug > 2)
|
||||
printk(KERN_CONT ": ERROR!\n");
|
||||
|
|
@ -394,7 +421,7 @@ static int read16_flags(struct drxk_state *state, u32 reg, u16 *data, u8 flags)
|
|||
len = 2;
|
||||
}
|
||||
dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
|
||||
status = i2c_read(state->i2c, adr, mm1, len, mm2, 2);
|
||||
status = i2c_read(state, adr, mm1, len, mm2, 2);
|
||||
if (status < 0)
|
||||
return status;
|
||||
if (data)
|
||||
|
|
@ -428,7 +455,7 @@ static int read32_flags(struct drxk_state *state, u32 reg, u32 *data, u8 flags)
|
|||
len = 2;
|
||||
}
|
||||
dprintk(2, "(0x%08x, 0x%02x)\n", reg, flags);
|
||||
status = i2c_read(state->i2c, adr, mm1, len, mm2, 4);
|
||||
status = i2c_read(state, adr, mm1, len, mm2, 4);
|
||||
if (status < 0)
|
||||
return status;
|
||||
if (data)
|
||||
|
|
@ -464,7 +491,7 @@ static int write16_flags(struct drxk_state *state, u32 reg, u16 data, u8 flags)
|
|||
mm[len + 1] = (data >> 8) & 0xff;
|
||||
|
||||
dprintk(2, "(0x%08x, 0x%04x, 0x%02x)\n", reg, data, flags);
|
||||
return i2c_write(state->i2c, adr, mm, len + 2);
|
||||
return i2c_write(state, adr, mm, len + 2);
|
||||
}
|
||||
|
||||
static int write16(struct drxk_state *state, u32 reg, u16 data)
|
||||
|
|
@ -495,7 +522,7 @@ static int write32_flags(struct drxk_state *state, u32 reg, u32 data, u8 flags)
|
|||
mm[len + 3] = (data >> 24) & 0xff;
|
||||
dprintk(2, "(0x%08x, 0x%08x, 0x%02x)\n", reg, data, flags);
|
||||
|
||||
return i2c_write(state->i2c, adr, mm, len + 4);
|
||||
return i2c_write(state, adr, mm, len + 4);
|
||||
}
|
||||
|
||||
static int write32(struct drxk_state *state, u32 reg, u32 data)
|
||||
|
|
@ -542,7 +569,7 @@ static int write_block(struct drxk_state *state, u32 Address,
|
|||
printk(KERN_CONT " %02x", pBlock[i]);
|
||||
printk(KERN_CONT "\n");
|
||||
}
|
||||
status = i2c_write(state->i2c, state->demod_address,
|
||||
status = i2c_write(state, state->demod_address,
|
||||
&state->Chunk[0], Chunk + AdrLength);
|
||||
if (status < 0) {
|
||||
printk(KERN_ERR "drxk: %s: i2c write error at addr 0x%02x\n",
|
||||
|
|
@ -568,17 +595,17 @@ int PowerUpDevice(struct drxk_state *state)
|
|||
|
||||
dprintk(1, "\n");
|
||||
|
||||
status = i2c_read1(state->i2c, state->demod_address, &data);
|
||||
status = i2c_read1(state, state->demod_address, &data);
|
||||
if (status < 0) {
|
||||
do {
|
||||
data = 0;
|
||||
status = i2c_write(state->i2c, state->demod_address,
|
||||
status = i2c_write(state, state->demod_address,
|
||||
&data, 1);
|
||||
msleep(10);
|
||||
retryCount++;
|
||||
if (status < 0)
|
||||
continue;
|
||||
status = i2c_read1(state->i2c, state->demod_address,
|
||||
status = i2c_read1(state, state->demod_address,
|
||||
&data);
|
||||
} while (status < 0 &&
|
||||
(retryCount < DRXK_MAX_RETRIES_POWERUP));
|
||||
|
|
@ -932,7 +959,7 @@ static int GetDeviceCapabilities(struct drxk_state *state)
|
|||
if (status < 0)
|
||||
goto error;
|
||||
|
||||
printk(KERN_ERR "drxk: status = 0x%08x\n", sioTopJtagidLo);
|
||||
printk(KERN_INFO "drxk: status = 0x%08x\n", sioTopJtagidLo);
|
||||
|
||||
/* driver 0.9.0 */
|
||||
switch ((sioTopJtagidLo >> 29) & 0xF) {
|
||||
|
|
@ -2824,7 +2851,7 @@ static int ConfigureI2CBridge(struct drxk_state *state, bool bEnableBridge)
|
|||
dprintk(1, "\n");
|
||||
|
||||
if (state->m_DrxkState == DRXK_UNINITIALIZED)
|
||||
goto error;
|
||||
return 0;
|
||||
if (state->m_DrxkState == DRXK_POWERED_DOWN)
|
||||
goto error;
|
||||
|
||||
|
|
@ -2977,7 +3004,7 @@ static int ADCSynchronization(struct drxk_state *state)
|
|||
status = read16(state, IQM_AF_CLKNEG__A, &clkNeg);
|
||||
if (status < 0)
|
||||
goto error;
|
||||
if ((clkNeg | IQM_AF_CLKNEG_CLKNEGDATA__M) ==
|
||||
if ((clkNeg & IQM_AF_CLKNEG_CLKNEGDATA__M) ==
|
||||
IQM_AF_CLKNEG_CLKNEGDATA_CLK_ADC_DATA_POS) {
|
||||
clkNeg &= (~(IQM_AF_CLKNEG_CLKNEGDATA__M));
|
||||
clkNeg |=
|
||||
|
|
@ -5361,7 +5388,7 @@ static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
|
|||
SCU_RAM_COMMAND_CMD_DEMOD_GET_LOCK, 0, NULL, 2,
|
||||
Result);
|
||||
if (status < 0)
|
||||
printk(KERN_ERR "drxk: %s status = %08x\n", __func__, status);
|
||||
printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
|
||||
|
||||
if (Result[1] < SCU_RAM_QAM_LOCKED_LOCKED_DEMOD_LOCKED) {
|
||||
/* 0x0000 NOT LOCKED */
|
||||
|
|
@ -5388,12 +5415,67 @@ static int GetQAMLockStatus(struct drxk_state *state, u32 *pLockStatus)
|
|||
#define QAM_LOCKRANGE__M 0x10
|
||||
#define QAM_LOCKRANGE_NORMAL 0x10
|
||||
|
||||
static int QAMDemodulatorCommand(struct drxk_state *state,
|
||||
int numberOfParameters)
|
||||
{
|
||||
int status;
|
||||
u16 cmdResult;
|
||||
u16 setParamParameters[4] = { 0, 0, 0, 0 };
|
||||
|
||||
setParamParameters[0] = state->m_Constellation; /* modulation */
|
||||
setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
|
||||
|
||||
if (numberOfParameters == 2) {
|
||||
u16 setEnvParameters[1] = { 0 };
|
||||
|
||||
if (state->m_OperationMode == OM_QAM_ITU_C)
|
||||
setEnvParameters[0] = QAM_TOP_ANNEX_C;
|
||||
else
|
||||
setEnvParameters[0] = QAM_TOP_ANNEX_A;
|
||||
|
||||
status = scu_command(state,
|
||||
SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV,
|
||||
1, setEnvParameters, 1, &cmdResult);
|
||||
if (status < 0)
|
||||
goto error;
|
||||
|
||||
status = scu_command(state,
|
||||
SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
|
||||
numberOfParameters, setParamParameters,
|
||||
1, &cmdResult);
|
||||
} else if (numberOfParameters == 4) {
|
||||
if (state->m_OperationMode == OM_QAM_ITU_C)
|
||||
setParamParameters[2] = QAM_TOP_ANNEX_C;
|
||||
else
|
||||
setParamParameters[2] = QAM_TOP_ANNEX_A;
|
||||
|
||||
setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
|
||||
/* Env parameters */
|
||||
/* check for LOCKRANGE Extented */
|
||||
/* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
|
||||
|
||||
status = scu_command(state,
|
||||
SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM,
|
||||
numberOfParameters, setParamParameters,
|
||||
1, &cmdResult);
|
||||
} else {
|
||||
printk(KERN_WARNING "drxk: Unknown QAM demodulator parameter "
|
||||
"count %d\n", numberOfParameters);
|
||||
}
|
||||
|
||||
error:
|
||||
if (status < 0)
|
||||
printk(KERN_WARNING "drxk: Warning %d on %s\n",
|
||||
status, __func__);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
|
||||
s32 tunerFreqOffset)
|
||||
{
|
||||
int status;
|
||||
u16 setParamParameters[4] = { 0, 0, 0, 0 };
|
||||
u16 cmdResult;
|
||||
int qamDemodParamCount = state->qam_demod_parameter_count;
|
||||
|
||||
dprintk(1, "\n");
|
||||
/*
|
||||
|
|
@ -5445,34 +5527,42 @@ static int SetQAM(struct drxk_state *state, u16 IntermediateFreqkHz,
|
|||
}
|
||||
if (status < 0)
|
||||
goto error;
|
||||
setParamParameters[0] = state->m_Constellation; /* modulation */
|
||||
setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
|
||||
if (state->m_OperationMode == OM_QAM_ITU_C)
|
||||
setParamParameters[2] = QAM_TOP_ANNEX_C;
|
||||
else
|
||||
setParamParameters[2] = QAM_TOP_ANNEX_A;
|
||||
setParamParameters[3] |= (QAM_MIRROR_AUTO_ON);
|
||||
/* Env parameters */
|
||||
/* check for LOCKRANGE Extented */
|
||||
/* setParamParameters[3] |= QAM_LOCKRANGE_NORMAL; */
|
||||
|
||||
status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 4, setParamParameters, 1, &cmdResult);
|
||||
if (status < 0) {
|
||||
/* Fall-back to the simpler call */
|
||||
if (state->m_OperationMode == OM_QAM_ITU_C)
|
||||
setParamParameters[0] = QAM_TOP_ANNEX_C;
|
||||
else
|
||||
setParamParameters[0] = QAM_TOP_ANNEX_A;
|
||||
status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_ENV, 1, setParamParameters, 1, &cmdResult);
|
||||
if (status < 0)
|
||||
goto error;
|
||||
|
||||
setParamParameters[0] = state->m_Constellation; /* modulation */
|
||||
setParamParameters[1] = DRXK_QAM_I12_J17; /* interleave mode */
|
||||
status = scu_command(state, SCU_RAM_COMMAND_STANDARD_QAM | SCU_RAM_COMMAND_CMD_DEMOD_SET_PARAM, 2, setParamParameters, 1, &cmdResult);
|
||||
/* Use the 4-parameter if it's requested or we're probing for
|
||||
* the correct command. */
|
||||
if (state->qam_demod_parameter_count == 4
|
||||
|| !state->qam_demod_parameter_count) {
|
||||
qamDemodParamCount = 4;
|
||||
status = QAMDemodulatorCommand(state, qamDemodParamCount);
|
||||
}
|
||||
if (status < 0)
|
||||
|
||||
/* Use the 2-parameter command if it was requested or if we're
|
||||
* probing for the correct command and the 4-parameter command
|
||||
* failed. */
|
||||
if (state->qam_demod_parameter_count == 2
|
||||
|| (!state->qam_demod_parameter_count && status < 0)) {
|
||||
qamDemodParamCount = 2;
|
||||
status = QAMDemodulatorCommand(state, qamDemodParamCount);
|
||||
}
|
||||
|
||||
if (status < 0) {
|
||||
dprintk(1, "Could not set demodulator parameters. Make "
|
||||
"sure qam_demod_parameter_count (%d) is correct for "
|
||||
"your firmware (%s).\n",
|
||||
state->qam_demod_parameter_count,
|
||||
state->microcode_name);
|
||||
goto error;
|
||||
} else if (!state->qam_demod_parameter_count) {
|
||||
dprintk(1, "Auto-probing the correct QAM demodulator command "
|
||||
"parameters was successful - using %d parameters.\n",
|
||||
qamDemodParamCount);
|
||||
|
||||
/*
|
||||
* One of our commands was successful. We don't need to
|
||||
* auto-probe anymore, now that we got the correct command.
|
||||
*/
|
||||
state->qam_demod_parameter_count = qamDemodParamCount;
|
||||
}
|
||||
|
||||
/*
|
||||
* STEP 3: enable the system in a mode where the ADC provides valid
|
||||
|
|
@ -5968,34 +6058,15 @@ error:
|
|||
return status;
|
||||
}
|
||||
|
||||
static int load_microcode(struct drxk_state *state, const char *mc_name)
|
||||
{
|
||||
const struct firmware *fw = NULL;
|
||||
int err = 0;
|
||||
|
||||
dprintk(1, "\n");
|
||||
|
||||
err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
|
||||
if (err < 0) {
|
||||
printk(KERN_ERR
|
||||
"drxk: Could not load firmware file %s.\n", mc_name);
|
||||
printk(KERN_INFO
|
||||
"drxk: Copy %s to your hotplug directory!\n", mc_name);
|
||||
return err;
|
||||
}
|
||||
err = DownloadMicrocode(state, fw->data, fw->size);
|
||||
release_firmware(fw);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int init_drxk(struct drxk_state *state)
|
||||
{
|
||||
int status = 0;
|
||||
int status = 0, n = 0;
|
||||
enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
|
||||
u16 driverVersion;
|
||||
|
||||
dprintk(1, "\n");
|
||||
if ((state->m_DrxkState == DRXK_UNINITIALIZED)) {
|
||||
drxk_i2c_lock(state);
|
||||
status = PowerUpDevice(state);
|
||||
if (status < 0)
|
||||
goto error;
|
||||
|
|
@ -6073,8 +6144,12 @@ static int init_drxk(struct drxk_state *state)
|
|||
if (status < 0)
|
||||
goto error;
|
||||
|
||||
if (state->microcode_name)
|
||||
load_microcode(state, state->microcode_name);
|
||||
if (state->fw) {
|
||||
status = DownloadMicrocode(state, state->fw->data,
|
||||
state->fw->size);
|
||||
if (status < 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* disable token-ring bus through OFDM block for possible ucode upload */
|
||||
status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
|
||||
|
|
@ -6167,19 +6242,71 @@ static int init_drxk(struct drxk_state *state)
|
|||
state->m_DrxkState = DRXK_POWERED_DOWN;
|
||||
} else
|
||||
state->m_DrxkState = DRXK_STOPPED;
|
||||
|
||||
/* Initialize the supported delivery systems */
|
||||
n = 0;
|
||||
if (state->m_hasDVBC) {
|
||||
state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
|
||||
state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
|
||||
strlcat(state->frontend.ops.info.name, " DVB-C",
|
||||
sizeof(state->frontend.ops.info.name));
|
||||
}
|
||||
if (state->m_hasDVBT) {
|
||||
state->frontend.ops.delsys[n++] = SYS_DVBT;
|
||||
strlcat(state->frontend.ops.info.name, " DVB-T",
|
||||
sizeof(state->frontend.ops.info.name));
|
||||
}
|
||||
drxk_i2c_unlock(state);
|
||||
}
|
||||
error:
|
||||
if (status < 0)
|
||||
if (status < 0) {
|
||||
state->m_DrxkState = DRXK_NO_DEV;
|
||||
drxk_i2c_unlock(state);
|
||||
printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void load_firmware_cb(const struct firmware *fw,
|
||||
void *context)
|
||||
{
|
||||
struct drxk_state *state = context;
|
||||
|
||||
dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
|
||||
if (!fw) {
|
||||
printk(KERN_ERR
|
||||
"drxk: Could not load firmware file %s.\n",
|
||||
state->microcode_name);
|
||||
printk(KERN_INFO
|
||||
"drxk: Copy %s to your hotplug directory!\n",
|
||||
state->microcode_name);
|
||||
state->microcode_name = NULL;
|
||||
|
||||
/*
|
||||
* As firmware is now load asynchronous, it is not possible
|
||||
* anymore to fail at frontend attach. We might silently
|
||||
* return here, and hope that the driver won't crash.
|
||||
* We might also change all DVB callbacks to return -ENODEV
|
||||
* if the device is not initialized.
|
||||
* As the DRX-K devices have their own internal firmware,
|
||||
* let's just hope that it will match a firmware revision
|
||||
* compatible with this driver and proceed.
|
||||
*/
|
||||
}
|
||||
state->fw = fw;
|
||||
|
||||
init_drxk(state);
|
||||
}
|
||||
|
||||
static void drxk_release(struct dvb_frontend *fe)
|
||||
{
|
||||
struct drxk_state *state = fe->demodulator_priv;
|
||||
|
||||
dprintk(1, "\n");
|
||||
if (state->fw)
|
||||
release_firmware(state->fw);
|
||||
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
|
|
@ -6188,6 +6315,12 @@ static int drxk_sleep(struct dvb_frontend *fe)
|
|||
struct drxk_state *state = fe->demodulator_priv;
|
||||
|
||||
dprintk(1, "\n");
|
||||
|
||||
if (state->m_DrxkState == DRXK_NO_DEV)
|
||||
return -ENODEV;
|
||||
if (state->m_DrxkState == DRXK_UNINITIALIZED)
|
||||
return 0;
|
||||
|
||||
ShutDown(state);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -6196,7 +6329,11 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable)
|
|||
{
|
||||
struct drxk_state *state = fe->demodulator_priv;
|
||||
|
||||
dprintk(1, "%s\n", enable ? "enable" : "disable");
|
||||
dprintk(1, ": %s\n", enable ? "enable" : "disable");
|
||||
|
||||
if (state->m_DrxkState == DRXK_NO_DEV)
|
||||
return -ENODEV;
|
||||
|
||||
return ConfigureI2CBridge(state, enable ? true : false);
|
||||
}
|
||||
|
||||
|
|
@ -6209,6 +6346,12 @@ static int drxk_set_parameters(struct dvb_frontend *fe)
|
|||
|
||||
dprintk(1, "\n");
|
||||
|
||||
if (state->m_DrxkState == DRXK_NO_DEV)
|
||||
return -ENODEV;
|
||||
|
||||
if (state->m_DrxkState == DRXK_UNINITIALIZED)
|
||||
return -EAGAIN;
|
||||
|
||||
if (!fe->ops.tuner_ops.get_if_frequency) {
|
||||
printk(KERN_ERR
|
||||
"drxk: Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
|
||||
|
|
@ -6262,6 +6405,12 @@ static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
|
|||
u32 stat;
|
||||
|
||||
dprintk(1, "\n");
|
||||
|
||||
if (state->m_DrxkState == DRXK_NO_DEV)
|
||||
return -ENODEV;
|
||||
if (state->m_DrxkState == DRXK_UNINITIALIZED)
|
||||
return -EAGAIN;
|
||||
|
||||
*status = 0;
|
||||
GetLockStatus(state, &stat, 0);
|
||||
if (stat == MPEG_LOCK)
|
||||
|
|
@ -6275,8 +6424,15 @@ static int drxk_read_status(struct dvb_frontend *fe, fe_status_t *status)
|
|||
|
||||
static int drxk_read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
{
|
||||
struct drxk_state *state = fe->demodulator_priv;
|
||||
|
||||
dprintk(1, "\n");
|
||||
|
||||
if (state->m_DrxkState == DRXK_NO_DEV)
|
||||
return -ENODEV;
|
||||
if (state->m_DrxkState == DRXK_UNINITIALIZED)
|
||||
return -EAGAIN;
|
||||
|
||||
*ber = 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -6288,6 +6444,12 @@ static int drxk_read_signal_strength(struct dvb_frontend *fe,
|
|||
u32 val = 0;
|
||||
|
||||
dprintk(1, "\n");
|
||||
|
||||
if (state->m_DrxkState == DRXK_NO_DEV)
|
||||
return -ENODEV;
|
||||
if (state->m_DrxkState == DRXK_UNINITIALIZED)
|
||||
return -EAGAIN;
|
||||
|
||||
ReadIFAgc(state, &val);
|
||||
*strength = val & 0xffff;
|
||||
return 0;
|
||||
|
|
@ -6299,6 +6461,12 @@ static int drxk_read_snr(struct dvb_frontend *fe, u16 *snr)
|
|||
s32 snr2;
|
||||
|
||||
dprintk(1, "\n");
|
||||
|
||||
if (state->m_DrxkState == DRXK_NO_DEV)
|
||||
return -ENODEV;
|
||||
if (state->m_DrxkState == DRXK_UNINITIALIZED)
|
||||
return -EAGAIN;
|
||||
|
||||
GetSignalToNoise(state, &snr2);
|
||||
*snr = snr2 & 0xffff;
|
||||
return 0;
|
||||
|
|
@ -6310,6 +6478,12 @@ static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
|
|||
u16 err;
|
||||
|
||||
dprintk(1, "\n");
|
||||
|
||||
if (state->m_DrxkState == DRXK_NO_DEV)
|
||||
return -ENODEV;
|
||||
if (state->m_DrxkState == DRXK_UNINITIALIZED)
|
||||
return -EAGAIN;
|
||||
|
||||
DVBTQAMGetAccPktErr(state, &err);
|
||||
*ucblocks = (u32) err;
|
||||
return 0;
|
||||
|
|
@ -6318,9 +6492,16 @@ static int drxk_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
|
|||
static int drxk_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings
|
||||
*sets)
|
||||
{
|
||||
struct drxk_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
|
||||
dprintk(1, "\n");
|
||||
|
||||
if (state->m_DrxkState == DRXK_NO_DEV)
|
||||
return -ENODEV;
|
||||
if (state->m_DrxkState == DRXK_UNINITIALIZED)
|
||||
return -EAGAIN;
|
||||
|
||||
switch (p->delivery_system) {
|
||||
case SYS_DVBC_ANNEX_A:
|
||||
case SYS_DVBC_ANNEX_C:
|
||||
|
|
@ -6371,10 +6552,9 @@ static struct dvb_frontend_ops drxk_ops = {
|
|||
struct dvb_frontend *drxk_attach(const struct drxk_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
int n;
|
||||
|
||||
struct drxk_state *state = NULL;
|
||||
u8 adr = config->adr;
|
||||
int status;
|
||||
|
||||
dprintk(1, "\n");
|
||||
state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
|
||||
|
|
@ -6385,6 +6565,7 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config,
|
|||
state->demod_address = adr;
|
||||
state->single_master = config->single_master;
|
||||
state->microcode_name = config->microcode_name;
|
||||
state->qam_demod_parameter_count = config->qam_demod_parameter_count;
|
||||
state->no_i2c_bridge = config->no_i2c_bridge;
|
||||
state->antenna_gpio = config->antenna_gpio;
|
||||
state->antenna_dvbt = config->antenna_dvbt;
|
||||
|
|
@ -6425,22 +6606,21 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config,
|
|||
state->frontend.demodulator_priv = state;
|
||||
|
||||
init_state(state);
|
||||
if (init_drxk(state) < 0)
|
||||
goto error;
|
||||
|
||||
/* Initialize the supported delivery systems */
|
||||
n = 0;
|
||||
if (state->m_hasDVBC) {
|
||||
state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
|
||||
state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
|
||||
strlcat(state->frontend.ops.info.name, " DVB-C",
|
||||
sizeof(state->frontend.ops.info.name));
|
||||
}
|
||||
if (state->m_hasDVBT) {
|
||||
state->frontend.ops.delsys[n++] = SYS_DVBT;
|
||||
strlcat(state->frontend.ops.info.name, " DVB-T",
|
||||
sizeof(state->frontend.ops.info.name));
|
||||
}
|
||||
/* Load firmware and initialize DRX-K */
|
||||
if (state->microcode_name) {
|
||||
status = request_firmware_nowait(THIS_MODULE, 1,
|
||||
state->microcode_name,
|
||||
state->i2c->dev.parent,
|
||||
GFP_KERNEL,
|
||||
state, load_firmware_cb);
|
||||
if (status < 0) {
|
||||
printk(KERN_ERR
|
||||
"drxk: failed to request a firmware\n");
|
||||
return NULL;
|
||||
}
|
||||
} else if (init_drxk(state) < 0)
|
||||
goto error;
|
||||
|
||||
printk(KERN_INFO "drxk: frontend initialized.\n");
|
||||
return &state->frontend;
|
||||
|
|
|
|||
|
|
@ -94,7 +94,15 @@ enum DRXPowerMode {
|
|||
|
||||
|
||||
enum AGC_CTRL_MODE { DRXK_AGC_CTRL_AUTO = 0, DRXK_AGC_CTRL_USER, DRXK_AGC_CTRL_OFF };
|
||||
enum EDrxkState { DRXK_UNINITIALIZED = 0, DRXK_STOPPED, DRXK_DTV_STARTED, DRXK_ATV_STARTED, DRXK_POWERED_DOWN };
|
||||
enum EDrxkState {
|
||||
DRXK_UNINITIALIZED = 0,
|
||||
DRXK_STOPPED,
|
||||
DRXK_DTV_STARTED,
|
||||
DRXK_ATV_STARTED,
|
||||
DRXK_POWERED_DOWN,
|
||||
DRXK_NO_DEV /* If drxk init failed */
|
||||
};
|
||||
|
||||
enum EDrxkCoefArrayIndex {
|
||||
DRXK_COEF_IDX_MN = 0,
|
||||
DRXK_COEF_IDX_FM ,
|
||||
|
|
@ -325,6 +333,9 @@ struct drxk_state {
|
|||
|
||||
enum DRXPowerMode m_currentPowerMode;
|
||||
|
||||
/* when true, avoids other devices to use the I2C bus */
|
||||
bool drxk_i2c_exclusive_lock;
|
||||
|
||||
/*
|
||||
* Configurable parameters at the driver. They stores the values found
|
||||
* at struct drxk_config.
|
||||
|
|
@ -338,7 +349,11 @@ struct drxk_state {
|
|||
bool antenna_dvbt;
|
||||
u16 antenna_gpio;
|
||||
|
||||
/* Firmware */
|
||||
const char *microcode_name;
|
||||
struct completion fw_wait_load;
|
||||
const struct firmware *fw;
|
||||
int qam_demod_parameter_count;
|
||||
};
|
||||
|
||||
#define NEVER_LOCK 0
|
||||
|
|
|
|||
789
drivers/media/dvb/frontends/rtl2832.c
Normal file
789
drivers/media/dvb/frontends/rtl2832.c
Normal file
|
|
@ -0,0 +1,789 @@
|
|||
/*
|
||||
* Realtek RTL2832 DVB-T demodulator driver
|
||||
*
|
||||
* Copyright (C) 2012 Thomas Mair <thomas.mair86@gmail.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, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "rtl2832_priv.h"
|
||||
#include <linux/bitops.h>
|
||||
|
||||
int rtl2832_debug;
|
||||
module_param_named(debug, rtl2832_debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
|
||||
|
||||
#define REG_MASK(b) (BIT(b + 1) - 1)
|
||||
|
||||
static const struct rtl2832_reg_entry registers[] = {
|
||||
[DVBT_SOFT_RST] = {0x1, 0x1, 2, 2},
|
||||
[DVBT_IIC_REPEAT] = {0x1, 0x1, 3, 3},
|
||||
[DVBT_TR_WAIT_MIN_8K] = {0x1, 0x88, 11, 2},
|
||||
[DVBT_RSD_BER_FAIL_VAL] = {0x1, 0x8f, 15, 0},
|
||||
[DVBT_EN_BK_TRK] = {0x1, 0xa6, 7, 7},
|
||||
[DVBT_AD_EN_REG] = {0x0, 0x8, 7, 7},
|
||||
[DVBT_AD_EN_REG1] = {0x0, 0x8, 6, 6},
|
||||
[DVBT_EN_BBIN] = {0x1, 0xb1, 0, 0},
|
||||
[DVBT_MGD_THD0] = {0x1, 0x95, 7, 0},
|
||||
[DVBT_MGD_THD1] = {0x1, 0x96, 7, 0},
|
||||
[DVBT_MGD_THD2] = {0x1, 0x97, 7, 0},
|
||||
[DVBT_MGD_THD3] = {0x1, 0x98, 7, 0},
|
||||
[DVBT_MGD_THD4] = {0x1, 0x99, 7, 0},
|
||||
[DVBT_MGD_THD5] = {0x1, 0x9a, 7, 0},
|
||||
[DVBT_MGD_THD6] = {0x1, 0x9b, 7, 0},
|
||||
[DVBT_MGD_THD7] = {0x1, 0x9c, 7, 0},
|
||||
[DVBT_EN_CACQ_NOTCH] = {0x1, 0x61, 4, 4},
|
||||
[DVBT_AD_AV_REF] = {0x0, 0x9, 6, 0},
|
||||
[DVBT_REG_PI] = {0x0, 0xa, 2, 0},
|
||||
[DVBT_PIP_ON] = {0x0, 0x21, 3, 3},
|
||||
[DVBT_SCALE1_B92] = {0x2, 0x92, 7, 0},
|
||||
[DVBT_SCALE1_B93] = {0x2, 0x93, 7, 0},
|
||||
[DVBT_SCALE1_BA7] = {0x2, 0xa7, 7, 0},
|
||||
[DVBT_SCALE1_BA9] = {0x2, 0xa9, 7, 0},
|
||||
[DVBT_SCALE1_BAA] = {0x2, 0xaa, 7, 0},
|
||||
[DVBT_SCALE1_BAB] = {0x2, 0xab, 7, 0},
|
||||
[DVBT_SCALE1_BAC] = {0x2, 0xac, 7, 0},
|
||||
[DVBT_SCALE1_BB0] = {0x2, 0xb0, 7, 0},
|
||||
[DVBT_SCALE1_BB1] = {0x2, 0xb1, 7, 0},
|
||||
[DVBT_KB_P1] = {0x1, 0x64, 3, 1},
|
||||
[DVBT_KB_P2] = {0x1, 0x64, 6, 4},
|
||||
[DVBT_KB_P3] = {0x1, 0x65, 2, 0},
|
||||
[DVBT_OPT_ADC_IQ] = {0x0, 0x6, 5, 4},
|
||||
[DVBT_AD_AVI] = {0x0, 0x9, 1, 0},
|
||||
[DVBT_AD_AVQ] = {0x0, 0x9, 3, 2},
|
||||
[DVBT_K1_CR_STEP12] = {0x2, 0xad, 9, 4},
|
||||
[DVBT_TRK_KS_P2] = {0x1, 0x6f, 2, 0},
|
||||
[DVBT_TRK_KS_I2] = {0x1, 0x70, 5, 3},
|
||||
[DVBT_TR_THD_SET2] = {0x1, 0x72, 3, 0},
|
||||
[DVBT_TRK_KC_P2] = {0x1, 0x73, 5, 3},
|
||||
[DVBT_TRK_KC_I2] = {0x1, 0x75, 2, 0},
|
||||
[DVBT_CR_THD_SET2] = {0x1, 0x76, 7, 6},
|
||||
[DVBT_PSET_IFFREQ] = {0x1, 0x19, 21, 0},
|
||||
[DVBT_SPEC_INV] = {0x1, 0x15, 0, 0},
|
||||
[DVBT_RSAMP_RATIO] = {0x1, 0x9f, 27, 2},
|
||||
[DVBT_CFREQ_OFF_RATIO] = {0x1, 0x9d, 23, 4},
|
||||
[DVBT_FSM_STAGE] = {0x3, 0x51, 6, 3},
|
||||
[DVBT_RX_CONSTEL] = {0x3, 0x3c, 3, 2},
|
||||
[DVBT_RX_HIER] = {0x3, 0x3c, 6, 4},
|
||||
[DVBT_RX_C_RATE_LP] = {0x3, 0x3d, 2, 0},
|
||||
[DVBT_RX_C_RATE_HP] = {0x3, 0x3d, 5, 3},
|
||||
[DVBT_GI_IDX] = {0x3, 0x51, 1, 0},
|
||||
[DVBT_FFT_MODE_IDX] = {0x3, 0x51, 2, 2},
|
||||
[DVBT_RSD_BER_EST] = {0x3, 0x4e, 15, 0},
|
||||
[DVBT_CE_EST_EVM] = {0x4, 0xc, 15, 0},
|
||||
[DVBT_RF_AGC_VAL] = {0x3, 0x5b, 13, 0},
|
||||
[DVBT_IF_AGC_VAL] = {0x3, 0x59, 13, 0},
|
||||
[DVBT_DAGC_VAL] = {0x3, 0x5, 7, 0},
|
||||
[DVBT_SFREQ_OFF] = {0x3, 0x18, 13, 0},
|
||||
[DVBT_CFREQ_OFF] = {0x3, 0x5f, 17, 0},
|
||||
[DVBT_POLAR_RF_AGC] = {0x0, 0xe, 1, 1},
|
||||
[DVBT_POLAR_IF_AGC] = {0x0, 0xe, 0, 0},
|
||||
[DVBT_AAGC_HOLD] = {0x1, 0x4, 5, 5},
|
||||
[DVBT_EN_RF_AGC] = {0x1, 0x4, 6, 6},
|
||||
[DVBT_EN_IF_AGC] = {0x1, 0x4, 7, 7},
|
||||
[DVBT_IF_AGC_MIN] = {0x1, 0x8, 7, 0},
|
||||
[DVBT_IF_AGC_MAX] = {0x1, 0x9, 7, 0},
|
||||
[DVBT_RF_AGC_MIN] = {0x1, 0xa, 7, 0},
|
||||
[DVBT_RF_AGC_MAX] = {0x1, 0xb, 7, 0},
|
||||
[DVBT_IF_AGC_MAN] = {0x1, 0xc, 6, 6},
|
||||
[DVBT_IF_AGC_MAN_VAL] = {0x1, 0xc, 13, 0},
|
||||
[DVBT_RF_AGC_MAN] = {0x1, 0xe, 6, 6},
|
||||
[DVBT_RF_AGC_MAN_VAL] = {0x1, 0xe, 13, 0},
|
||||
[DVBT_DAGC_TRG_VAL] = {0x1, 0x12, 7, 0},
|
||||
[DVBT_AGC_TARG_VAL_0] = {0x1, 0x2, 0, 0},
|
||||
[DVBT_AGC_TARG_VAL_8_1] = {0x1, 0x3, 7, 0},
|
||||
[DVBT_AAGC_LOOP_GAIN] = {0x1, 0xc7, 5, 1},
|
||||
[DVBT_LOOP_GAIN2_3_0] = {0x1, 0x4, 4, 1},
|
||||
[DVBT_LOOP_GAIN2_4] = {0x1, 0x5, 7, 7},
|
||||
[DVBT_LOOP_GAIN3] = {0x1, 0xc8, 4, 0},
|
||||
[DVBT_VTOP1] = {0x1, 0x6, 5, 0},
|
||||
[DVBT_VTOP2] = {0x1, 0xc9, 5, 0},
|
||||
[DVBT_VTOP3] = {0x1, 0xca, 5, 0},
|
||||
[DVBT_KRF1] = {0x1, 0xcb, 7, 0},
|
||||
[DVBT_KRF2] = {0x1, 0x7, 7, 0},
|
||||
[DVBT_KRF3] = {0x1, 0xcd, 7, 0},
|
||||
[DVBT_KRF4] = {0x1, 0xce, 7, 0},
|
||||
[DVBT_EN_GI_PGA] = {0x1, 0xe5, 0, 0},
|
||||
[DVBT_THD_LOCK_UP] = {0x1, 0xd9, 8, 0},
|
||||
[DVBT_THD_LOCK_DW] = {0x1, 0xdb, 8, 0},
|
||||
[DVBT_THD_UP1] = {0x1, 0xdd, 7, 0},
|
||||
[DVBT_THD_DW1] = {0x1, 0xde, 7, 0},
|
||||
[DVBT_INTER_CNT_LEN] = {0x1, 0xd8, 3, 0},
|
||||
[DVBT_GI_PGA_STATE] = {0x1, 0xe6, 3, 3},
|
||||
[DVBT_EN_AGC_PGA] = {0x1, 0xd7, 0, 0},
|
||||
[DVBT_CKOUTPAR] = {0x1, 0x7b, 5, 5},
|
||||
[DVBT_CKOUT_PWR] = {0x1, 0x7b, 6, 6},
|
||||
[DVBT_SYNC_DUR] = {0x1, 0x7b, 7, 7},
|
||||
[DVBT_ERR_DUR] = {0x1, 0x7c, 0, 0},
|
||||
[DVBT_SYNC_LVL] = {0x1, 0x7c, 1, 1},
|
||||
[DVBT_ERR_LVL] = {0x1, 0x7c, 2, 2},
|
||||
[DVBT_VAL_LVL] = {0x1, 0x7c, 3, 3},
|
||||
[DVBT_SERIAL] = {0x1, 0x7c, 4, 4},
|
||||
[DVBT_SER_LSB] = {0x1, 0x7c, 5, 5},
|
||||
[DVBT_CDIV_PH0] = {0x1, 0x7d, 3, 0},
|
||||
[DVBT_CDIV_PH1] = {0x1, 0x7d, 7, 4},
|
||||
[DVBT_MPEG_IO_OPT_2_2] = {0x0, 0x6, 7, 7},
|
||||
[DVBT_MPEG_IO_OPT_1_0] = {0x0, 0x7, 7, 6},
|
||||
[DVBT_CKOUTPAR_PIP] = {0x0, 0xb7, 4, 4},
|
||||
[DVBT_CKOUT_PWR_PIP] = {0x0, 0xb7, 3, 3},
|
||||
[DVBT_SYNC_LVL_PIP] = {0x0, 0xb7, 2, 2},
|
||||
[DVBT_ERR_LVL_PIP] = {0x0, 0xb7, 1, 1},
|
||||
[DVBT_VAL_LVL_PIP] = {0x0, 0xb7, 0, 0},
|
||||
[DVBT_CKOUTPAR_PID] = {0x0, 0xb9, 4, 4},
|
||||
[DVBT_CKOUT_PWR_PID] = {0x0, 0xb9, 3, 3},
|
||||
[DVBT_SYNC_LVL_PID] = {0x0, 0xb9, 2, 2},
|
||||
[DVBT_ERR_LVL_PID] = {0x0, 0xb9, 1, 1},
|
||||
[DVBT_VAL_LVL_PID] = {0x0, 0xb9, 0, 0},
|
||||
[DVBT_SM_PASS] = {0x1, 0x93, 11, 0},
|
||||
[DVBT_AD7_SETTING] = {0x0, 0x11, 15, 0},
|
||||
[DVBT_RSSI_R] = {0x3, 0x1, 6, 0},
|
||||
[DVBT_ACI_DET_IND] = {0x3, 0x12, 0, 0},
|
||||
[DVBT_REG_MON] = {0x0, 0xd, 1, 0},
|
||||
[DVBT_REG_MONSEL] = {0x0, 0xd, 2, 2},
|
||||
[DVBT_REG_GPE] = {0x0, 0xd, 7, 7},
|
||||
[DVBT_REG_GPO] = {0x0, 0x10, 0, 0},
|
||||
[DVBT_REG_4MSEL] = {0x0, 0x13, 0, 0},
|
||||
};
|
||||
|
||||
/* write multiple hardware registers */
|
||||
static int rtl2832_wr(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
|
||||
{
|
||||
int ret;
|
||||
u8 buf[1+len];
|
||||
struct i2c_msg msg[1] = {
|
||||
{
|
||||
.addr = priv->cfg.i2c_addr,
|
||||
.flags = 0,
|
||||
.len = 1+len,
|
||||
.buf = buf,
|
||||
}
|
||||
};
|
||||
|
||||
buf[0] = reg;
|
||||
memcpy(&buf[1], val, len);
|
||||
|
||||
ret = i2c_transfer(priv->i2c, msg, 1);
|
||||
if (ret == 1) {
|
||||
ret = 0;
|
||||
} else {
|
||||
warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
|
||||
ret = -EREMOTEIO;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* read multiple hardware registers */
|
||||
static int rtl2832_rd(struct rtl2832_priv *priv, u8 reg, u8 *val, int len)
|
||||
{
|
||||
int ret;
|
||||
struct i2c_msg msg[2] = {
|
||||
{
|
||||
.addr = priv->cfg.i2c_addr,
|
||||
.flags = 0,
|
||||
.len = 1,
|
||||
.buf = ®,
|
||||
}, {
|
||||
.addr = priv->cfg.i2c_addr,
|
||||
.flags = I2C_M_RD,
|
||||
.len = len,
|
||||
.buf = val,
|
||||
}
|
||||
};
|
||||
|
||||
ret = i2c_transfer(priv->i2c, msg, 2);
|
||||
if (ret == 2) {
|
||||
ret = 0;
|
||||
} else {
|
||||
warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
|
||||
ret = -EREMOTEIO;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* write multiple registers */
|
||||
static int rtl2832_wr_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
|
||||
int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
/* switch bank if needed */
|
||||
if (page != priv->page) {
|
||||
ret = rtl2832_wr(priv, 0x00, &page, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->page = page;
|
||||
}
|
||||
|
||||
return rtl2832_wr(priv, reg, val, len);
|
||||
}
|
||||
|
||||
/* read multiple registers */
|
||||
static int rtl2832_rd_regs(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val,
|
||||
int len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* switch bank if needed */
|
||||
if (page != priv->page) {
|
||||
ret = rtl2832_wr(priv, 0x00, &page, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->page = page;
|
||||
}
|
||||
|
||||
return rtl2832_rd(priv, reg, val, len);
|
||||
}
|
||||
|
||||
#if 0 /* currently not used */
|
||||
/* write single register */
|
||||
static int rtl2832_wr_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 val)
|
||||
{
|
||||
return rtl2832_wr_regs(priv, reg, page, &val, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* read single register */
|
||||
static int rtl2832_rd_reg(struct rtl2832_priv *priv, u8 reg, u8 page, u8 *val)
|
||||
{
|
||||
return rtl2832_rd_regs(priv, reg, page, val, 1);
|
||||
}
|
||||
|
||||
int rtl2832_rd_demod_reg(struct rtl2832_priv *priv, int reg, u32 *val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
u8 reg_start_addr;
|
||||
u8 msb, lsb;
|
||||
u8 page;
|
||||
u8 reading[4];
|
||||
u32 reading_tmp;
|
||||
int i;
|
||||
|
||||
u8 len;
|
||||
u32 mask;
|
||||
|
||||
reg_start_addr = registers[reg].start_address;
|
||||
msb = registers[reg].msb;
|
||||
lsb = registers[reg].lsb;
|
||||
page = registers[reg].page;
|
||||
|
||||
len = (msb >> 3) + 1;
|
||||
mask = REG_MASK(msb - lsb);
|
||||
|
||||
ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
reading_tmp = 0;
|
||||
for (i = 0; i < len; i++)
|
||||
reading_tmp |= reading[i] << ((len - 1 - i) * 8);
|
||||
|
||||
*val = (reading_tmp >> lsb) & mask;
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int rtl2832_wr_demod_reg(struct rtl2832_priv *priv, int reg, u32 val)
|
||||
{
|
||||
int ret, i;
|
||||
u8 len;
|
||||
u8 reg_start_addr;
|
||||
u8 msb, lsb;
|
||||
u8 page;
|
||||
u32 mask;
|
||||
|
||||
|
||||
u8 reading[4];
|
||||
u8 writing[4];
|
||||
u32 reading_tmp;
|
||||
u32 writing_tmp;
|
||||
|
||||
|
||||
reg_start_addr = registers[reg].start_address;
|
||||
msb = registers[reg].msb;
|
||||
lsb = registers[reg].lsb;
|
||||
page = registers[reg].page;
|
||||
|
||||
len = (msb >> 3) + 1;
|
||||
mask = REG_MASK(msb - lsb);
|
||||
|
||||
|
||||
ret = rtl2832_rd_regs(priv, reg_start_addr, page, &reading[0], len);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
reading_tmp = 0;
|
||||
for (i = 0; i < len; i++)
|
||||
reading_tmp |= reading[i] << ((len - 1 - i) * 8);
|
||||
|
||||
writing_tmp = reading_tmp & ~(mask << lsb);
|
||||
writing_tmp |= ((val & mask) << lsb);
|
||||
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
writing[i] = (writing_tmp >> ((len - 1 - i) * 8)) & 0xff;
|
||||
|
||||
ret = rtl2832_wr_regs(priv, reg_start_addr, page, &writing[0], len);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int rtl2832_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
|
||||
{
|
||||
int ret;
|
||||
struct rtl2832_priv *priv = fe->demodulator_priv;
|
||||
|
||||
dbg("%s: enable=%d", __func__, enable);
|
||||
|
||||
/* gate already open or close */
|
||||
if (priv->i2c_gate_state == enable)
|
||||
return 0;
|
||||
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_IIC_REPEAT, (enable ? 0x1 : 0x0));
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
priv->i2c_gate_state = enable;
|
||||
|
||||
return ret;
|
||||
err:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int rtl2832_init(struct dvb_frontend *fe)
|
||||
{
|
||||
struct rtl2832_priv *priv = fe->demodulator_priv;
|
||||
int i, ret;
|
||||
|
||||
u8 en_bbin;
|
||||
u64 pset_iffreq;
|
||||
|
||||
/* initialization values for the demodulator registers */
|
||||
struct rtl2832_reg_value rtl2832_initial_regs[] = {
|
||||
{DVBT_AD_EN_REG, 0x1},
|
||||
{DVBT_AD_EN_REG1, 0x1},
|
||||
{DVBT_RSD_BER_FAIL_VAL, 0x2800},
|
||||
{DVBT_MGD_THD0, 0x10},
|
||||
{DVBT_MGD_THD1, 0x20},
|
||||
{DVBT_MGD_THD2, 0x20},
|
||||
{DVBT_MGD_THD3, 0x40},
|
||||
{DVBT_MGD_THD4, 0x22},
|
||||
{DVBT_MGD_THD5, 0x32},
|
||||
{DVBT_MGD_THD6, 0x37},
|
||||
{DVBT_MGD_THD7, 0x39},
|
||||
{DVBT_EN_BK_TRK, 0x0},
|
||||
{DVBT_EN_CACQ_NOTCH, 0x0},
|
||||
{DVBT_AD_AV_REF, 0x2a},
|
||||
{DVBT_REG_PI, 0x6},
|
||||
{DVBT_PIP_ON, 0x0},
|
||||
{DVBT_CDIV_PH0, 0x8},
|
||||
{DVBT_CDIV_PH1, 0x8},
|
||||
{DVBT_SCALE1_B92, 0x4},
|
||||
{DVBT_SCALE1_B93, 0xb0},
|
||||
{DVBT_SCALE1_BA7, 0x78},
|
||||
{DVBT_SCALE1_BA9, 0x28},
|
||||
{DVBT_SCALE1_BAA, 0x59},
|
||||
{DVBT_SCALE1_BAB, 0x83},
|
||||
{DVBT_SCALE1_BAC, 0xd4},
|
||||
{DVBT_SCALE1_BB0, 0x65},
|
||||
{DVBT_SCALE1_BB1, 0x43},
|
||||
{DVBT_KB_P1, 0x1},
|
||||
{DVBT_KB_P2, 0x4},
|
||||
{DVBT_KB_P3, 0x7},
|
||||
{DVBT_K1_CR_STEP12, 0xa},
|
||||
{DVBT_REG_GPE, 0x1},
|
||||
{DVBT_SERIAL, 0x0},
|
||||
{DVBT_CDIV_PH0, 0x9},
|
||||
{DVBT_CDIV_PH1, 0x9},
|
||||
{DVBT_MPEG_IO_OPT_2_2, 0x0},
|
||||
{DVBT_MPEG_IO_OPT_1_0, 0x0},
|
||||
{DVBT_TRK_KS_P2, 0x4},
|
||||
{DVBT_TRK_KS_I2, 0x7},
|
||||
{DVBT_TR_THD_SET2, 0x6},
|
||||
{DVBT_TRK_KC_I2, 0x5},
|
||||
{DVBT_CR_THD_SET2, 0x1},
|
||||
{DVBT_SPEC_INV, 0x0},
|
||||
{DVBT_DAGC_TRG_VAL, 0x5a},
|
||||
{DVBT_AGC_TARG_VAL_0, 0x0},
|
||||
{DVBT_AGC_TARG_VAL_8_1, 0x5a},
|
||||
{DVBT_AAGC_LOOP_GAIN, 0x16},
|
||||
{DVBT_LOOP_GAIN2_3_0, 0x6},
|
||||
{DVBT_LOOP_GAIN2_4, 0x1},
|
||||
{DVBT_LOOP_GAIN3, 0x16},
|
||||
{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, 0xe9bf},
|
||||
{DVBT_EN_GI_PGA, 0x0},
|
||||
{DVBT_THD_LOCK_UP, 0x0},
|
||||
{DVBT_THD_LOCK_DW, 0x0},
|
||||
{DVBT_THD_UP1, 0x11},
|
||||
{DVBT_THD_DW1, 0xef},
|
||||
{DVBT_INTER_CNT_LEN, 0xc},
|
||||
{DVBT_GI_PGA_STATE, 0x0},
|
||||
{DVBT_EN_AGC_PGA, 0x1},
|
||||
{DVBT_IF_AGC_MAN, 0x0},
|
||||
};
|
||||
|
||||
|
||||
dbg("%s", __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);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* if frequency settings */
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_EN_BBIN, en_bbin);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_PSET_IFFREQ, pset_iffreq);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
priv->sleeping = false;
|
||||
|
||||
return ret;
|
||||
|
||||
err:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtl2832_sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
struct rtl2832_priv *priv = fe->demodulator_priv;
|
||||
|
||||
dbg("%s", __func__);
|
||||
priv->sleeping = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtl2832_get_tune_settings(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_tune_settings *s)
|
||||
{
|
||||
dbg("%s", __func__);
|
||||
s->min_delay_ms = 1000;
|
||||
s->step_size = fe->ops.info.frequency_stepsize * 2;
|
||||
s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl2832_set_frontend(struct dvb_frontend *fe)
|
||||
{
|
||||
struct rtl2832_priv *priv = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||
int ret, i, j;
|
||||
u64 bw_mode, num, num2;
|
||||
u32 resamp_ratio, cfreq_off_ratio;
|
||||
|
||||
|
||||
static u8 bw_params[3][32] = {
|
||||
/* 6 MHz bandwidth */
|
||||
{
|
||||
0xf5, 0xff, 0x15, 0x38, 0x5d, 0x6d, 0x52, 0x07, 0xfa, 0x2f,
|
||||
0x53, 0xf5, 0x3f, 0xca, 0x0b, 0x91, 0xea, 0x30, 0x63, 0xb2,
|
||||
0x13, 0xda, 0x0b, 0xc4, 0x18, 0x7e, 0x16, 0x66, 0x08, 0x67,
|
||||
0x19, 0xe0,
|
||||
},
|
||||
|
||||
/* 7 MHz bandwidth */
|
||||
{
|
||||
0xe7, 0xcc, 0xb5, 0xba, 0xe8, 0x2f, 0x67, 0x61, 0x00, 0xaf,
|
||||
0x86, 0xf2, 0xbf, 0x59, 0x04, 0x11, 0xb6, 0x33, 0xa4, 0x30,
|
||||
0x15, 0x10, 0x0a, 0x42, 0x18, 0xf8, 0x17, 0xd9, 0x07, 0x22,
|
||||
0x19, 0x10,
|
||||
},
|
||||
|
||||
/* 8 MHz bandwidth */
|
||||
{
|
||||
0x09, 0xf6, 0xd2, 0xa7, 0x9a, 0xc9, 0x27, 0x77, 0x06, 0xbf,
|
||||
0xec, 0xf4, 0x4f, 0x0b, 0xfc, 0x01, 0x63, 0x35, 0x54, 0xa7,
|
||||
0x16, 0x66, 0x08, 0xb4, 0x19, 0x6e, 0x19, 0x65, 0x05, 0xc8,
|
||||
0x19, 0xe0,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
dbg("%s: frequency=%d bandwidth_hz=%d inversion=%d", __func__,
|
||||
c->frequency, c->bandwidth_hz, c->inversion);
|
||||
|
||||
|
||||
/* program tuner */
|
||||
if (fe->ops.tuner_ops.set_params)
|
||||
fe->ops.tuner_ops.set_params(fe);
|
||||
|
||||
|
||||
switch (c->bandwidth_hz) {
|
||||
case 6000000:
|
||||
i = 0;
|
||||
bw_mode = 48000000;
|
||||
break;
|
||||
case 7000000:
|
||||
i = 1;
|
||||
bw_mode = 56000000;
|
||||
break;
|
||||
case 8000000:
|
||||
i = 2;
|
||||
bw_mode = 64000000;
|
||||
break;
|
||||
default:
|
||||
dbg("invalid bandwidth");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (j = 0; j < sizeof(bw_params[j]); j++) {
|
||||
ret = rtl2832_wr_regs(priv, 0x1c+j, 1, &bw_params[i][j], 1);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* calculate and set resample ratio
|
||||
* RSAMP_RATIO = floor(CrystalFreqHz * 7 * pow(2, 22)
|
||||
* / ConstWithBandwidthMode)
|
||||
*/
|
||||
num = priv->cfg.xtal * 7;
|
||||
num *= 0x400000;
|
||||
num = div_u64(num, bw_mode);
|
||||
resamp_ratio = num & 0x3ffffff;
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_RSAMP_RATIO, resamp_ratio);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* calculate and set cfreq off ratio
|
||||
* CFREQ_OFF_RATIO = - floor(ConstWithBandwidthMode * pow(2, 20)
|
||||
* / (CrystalFreqHz * 7))
|
||||
*/
|
||||
num = bw_mode << 20;
|
||||
num2 = priv->cfg.xtal * 7;
|
||||
num = div_u64(num, num2);
|
||||
num = -num;
|
||||
cfreq_off_ratio = num & 0xfffff;
|
||||
ret = rtl2832_wr_demod_reg(priv, DVBT_CFREQ_OFF_RATIO, cfreq_off_ratio);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
return ret;
|
||||
err:
|
||||
info("%s: failed=%d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtl2832_read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
{
|
||||
struct rtl2832_priv *priv = fe->demodulator_priv;
|
||||
int ret;
|
||||
u32 tmp;
|
||||
*status = 0;
|
||||
|
||||
|
||||
dbg("%s", __func__);
|
||||
if (priv->sleeping)
|
||||
return 0;
|
||||
|
||||
ret = rtl2832_rd_demod_reg(priv, DVBT_FSM_STAGE, &tmp);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (tmp == 11) {
|
||||
*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
|
||||
FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
|
||||
}
|
||||
/* TODO find out if this is also true for rtl2832? */
|
||||
/*else if (tmp == 10) {
|
||||
*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
|
||||
FE_HAS_VITERBI;
|
||||
}*/
|
||||
|
||||
return ret;
|
||||
err:
|
||||
info("%s: failed=%d", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rtl2832_read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||
{
|
||||
*snr = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl2832_read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
{
|
||||
*ber = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl2832_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
|
||||
{
|
||||
*ucblocks = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int rtl2832_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
{
|
||||
*strength = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dvb_frontend_ops rtl2832_ops;
|
||||
|
||||
static void rtl2832_release(struct dvb_frontend *fe)
|
||||
{
|
||||
struct rtl2832_priv *priv = fe->demodulator_priv;
|
||||
|
||||
dbg("%s", __func__);
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
struct dvb_frontend *rtl2832_attach(const struct rtl2832_config *cfg,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
struct rtl2832_priv *priv = NULL;
|
||||
int ret = 0;
|
||||
u8 tmp;
|
||||
|
||||
dbg("%s", __func__);
|
||||
|
||||
/* allocate memory for the internal state */
|
||||
priv = kzalloc(sizeof(struct rtl2832_priv), GFP_KERNEL);
|
||||
if (priv == NULL)
|
||||
goto err;
|
||||
|
||||
/* setup the priv */
|
||||
priv->i2c = i2c;
|
||||
priv->tuner = cfg->tuner;
|
||||
memcpy(&priv->cfg, cfg, sizeof(struct rtl2832_config));
|
||||
|
||||
/* check if the demod is there */
|
||||
ret = rtl2832_rd_reg(priv, 0x00, 0x0, &tmp);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* create dvb_frontend */
|
||||
memcpy(&priv->fe.ops, &rtl2832_ops, sizeof(struct dvb_frontend_ops));
|
||||
priv->fe.demodulator_priv = priv;
|
||||
|
||||
/* TODO implement sleep mode */
|
||||
priv->sleeping = true;
|
||||
|
||||
return &priv->fe;
|
||||
err:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
kfree(priv);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(rtl2832_attach);
|
||||
|
||||
static struct dvb_frontend_ops rtl2832_ops = {
|
||||
.delsys = { SYS_DVBT },
|
||||
.info = {
|
||||
.name = "Realtek RTL2832 (DVB-T)",
|
||||
.frequency_min = 174000000,
|
||||
.frequency_max = 862000000,
|
||||
.frequency_stepsize = 166667,
|
||||
.caps = 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 |
|
||||
FE_CAN_QAM_AUTO |
|
||||
FE_CAN_TRANSMISSION_MODE_AUTO |
|
||||
FE_CAN_GUARD_INTERVAL_AUTO |
|
||||
FE_CAN_HIERARCHY_AUTO |
|
||||
FE_CAN_RECOVER |
|
||||
FE_CAN_MUTE_TS
|
||||
},
|
||||
|
||||
.release = rtl2832_release,
|
||||
|
||||
.init = rtl2832_init,
|
||||
.sleep = rtl2832_sleep,
|
||||
|
||||
.get_tune_settings = rtl2832_get_tune_settings,
|
||||
|
||||
.set_frontend = rtl2832_set_frontend,
|
||||
|
||||
.read_status = rtl2832_read_status,
|
||||
.read_snr = rtl2832_read_snr,
|
||||
.read_ber = rtl2832_read_ber,
|
||||
.read_ucblocks = rtl2832_read_ucblocks,
|
||||
.read_signal_strength = rtl2832_read_signal_strength,
|
||||
.i2c_gate_ctrl = rtl2832_i2c_gate_ctrl,
|
||||
};
|
||||
|
||||
MODULE_AUTHOR("Thomas Mair <[email protected]>");
|
||||
MODULE_DESCRIPTION("Realtek RTL2832 DVB-T demodulator driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION("0.5");
|
||||
74
drivers/media/dvb/frontends/rtl2832.h
Normal file
74
drivers/media/dvb/frontends/rtl2832.h
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Realtek RTL2832 DVB-T demodulator driver
|
||||
*
|
||||
* Copyright (C) 2012 Thomas Mair <thomas.mair86@gmail.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, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef RTL2832_H
|
||||
#define RTL2832_H
|
||||
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
struct rtl2832_config {
|
||||
/*
|
||||
* Demodulator I2C address.
|
||||
*/
|
||||
u8 i2c_addr;
|
||||
|
||||
/*
|
||||
* Xtal frequency.
|
||||
* Hz
|
||||
* 4000000, 16000000, 25000000, 28800000
|
||||
*/
|
||||
u32 xtal;
|
||||
|
||||
/*
|
||||
* IFs for all used modes.
|
||||
* Hz
|
||||
* 4570000, 4571429, 36000000, 36125000, 36166667, 44000000
|
||||
*/
|
||||
u32 if_dvbt;
|
||||
|
||||
/*
|
||||
*/
|
||||
u8 tuner;
|
||||
};
|
||||
|
||||
|
||||
#if defined(CONFIG_DVB_RTL2832) || \
|
||||
(defined(CONFIG_DVB_RTL2832_MODULE) && defined(MODULE))
|
||||
extern struct dvb_frontend *rtl2832_attach(
|
||||
const struct rtl2832_config *cfg,
|
||||
struct i2c_adapter *i2c
|
||||
);
|
||||
|
||||
extern struct i2c_adapter *rtl2832_get_tuner_i2c_adapter(
|
||||
struct dvb_frontend *fe
|
||||
);
|
||||
#else
|
||||
static inline struct dvb_frontend *rtl2832_attach(
|
||||
const struct rtl2832_config *config,
|
||||
struct i2c_adapter *i2c
|
||||
)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* RTL2832_H */
|
||||
260
drivers/media/dvb/frontends/rtl2832_priv.h
Normal file
260
drivers/media/dvb/frontends/rtl2832_priv.h
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
* Realtek RTL2832 DVB-T demodulator driver
|
||||
*
|
||||
* Copyright (C) 2012 Thomas Mair <thomas.mair86@gmail.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, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef RTL2832_PRIV_H
|
||||
#define RTL2832_PRIV_H
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
#include "rtl2832.h"
|
||||
|
||||
#define LOG_PREFIX "rtl2832"
|
||||
|
||||
#undef dbg
|
||||
#define dbg(f, arg...) \
|
||||
do { \
|
||||
if (rtl2832_debug) \
|
||||
printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg); \
|
||||
} while (0)
|
||||
#undef err
|
||||
#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
|
||||
#undef info
|
||||
#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
|
||||
#undef warn
|
||||
#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
|
||||
|
||||
struct rtl2832_priv {
|
||||
struct i2c_adapter *i2c;
|
||||
struct dvb_frontend fe;
|
||||
struct rtl2832_config cfg;
|
||||
|
||||
bool i2c_gate_state;
|
||||
bool sleeping;
|
||||
|
||||
u8 tuner;
|
||||
u8 page; /* active register page */
|
||||
};
|
||||
|
||||
struct rtl2832_reg_entry {
|
||||
u8 page;
|
||||
u8 start_address;
|
||||
u8 msb;
|
||||
u8 lsb;
|
||||
};
|
||||
|
||||
struct rtl2832_reg_value {
|
||||
int reg;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
|
||||
/* Demod register bit names */
|
||||
enum DVBT_REG_BIT_NAME {
|
||||
DVBT_SOFT_RST,
|
||||
DVBT_IIC_REPEAT,
|
||||
DVBT_TR_WAIT_MIN_8K,
|
||||
DVBT_RSD_BER_FAIL_VAL,
|
||||
DVBT_EN_BK_TRK,
|
||||
DVBT_REG_PI,
|
||||
DVBT_REG_PFREQ_1_0,
|
||||
DVBT_PD_DA8,
|
||||
DVBT_LOCK_TH,
|
||||
DVBT_BER_PASS_SCAL,
|
||||
DVBT_CE_FFSM_BYPASS,
|
||||
DVBT_ALPHAIIR_N,
|
||||
DVBT_ALPHAIIR_DIF,
|
||||
DVBT_EN_TRK_SPAN,
|
||||
DVBT_LOCK_TH_LEN,
|
||||
DVBT_CCI_THRE,
|
||||
DVBT_CCI_MON_SCAL,
|
||||
DVBT_CCI_M0,
|
||||
DVBT_CCI_M1,
|
||||
DVBT_CCI_M2,
|
||||
DVBT_CCI_M3,
|
||||
DVBT_SPEC_INIT_0,
|
||||
DVBT_SPEC_INIT_1,
|
||||
DVBT_SPEC_INIT_2,
|
||||
DVBT_AD_EN_REG,
|
||||
DVBT_AD_EN_REG1,
|
||||
DVBT_EN_BBIN,
|
||||
DVBT_MGD_THD0,
|
||||
DVBT_MGD_THD1,
|
||||
DVBT_MGD_THD2,
|
||||
DVBT_MGD_THD3,
|
||||
DVBT_MGD_THD4,
|
||||
DVBT_MGD_THD5,
|
||||
DVBT_MGD_THD6,
|
||||
DVBT_MGD_THD7,
|
||||
DVBT_EN_CACQ_NOTCH,
|
||||
DVBT_AD_AV_REF,
|
||||
DVBT_PIP_ON,
|
||||
DVBT_SCALE1_B92,
|
||||
DVBT_SCALE1_B93,
|
||||
DVBT_SCALE1_BA7,
|
||||
DVBT_SCALE1_BA9,
|
||||
DVBT_SCALE1_BAA,
|
||||
DVBT_SCALE1_BAB,
|
||||
DVBT_SCALE1_BAC,
|
||||
DVBT_SCALE1_BB0,
|
||||
DVBT_SCALE1_BB1,
|
||||
DVBT_KB_P1,
|
||||
DVBT_KB_P2,
|
||||
DVBT_KB_P3,
|
||||
DVBT_OPT_ADC_IQ,
|
||||
DVBT_AD_AVI,
|
||||
DVBT_AD_AVQ,
|
||||
DVBT_K1_CR_STEP12,
|
||||
DVBT_TRK_KS_P2,
|
||||
DVBT_TRK_KS_I2,
|
||||
DVBT_TR_THD_SET2,
|
||||
DVBT_TRK_KC_P2,
|
||||
DVBT_TRK_KC_I2,
|
||||
DVBT_CR_THD_SET2,
|
||||
DVBT_PSET_IFFREQ,
|
||||
DVBT_SPEC_INV,
|
||||
DVBT_BW_INDEX,
|
||||
DVBT_RSAMP_RATIO,
|
||||
DVBT_CFREQ_OFF_RATIO,
|
||||
DVBT_FSM_STAGE,
|
||||
DVBT_RX_CONSTEL,
|
||||
DVBT_RX_HIER,
|
||||
DVBT_RX_C_RATE_LP,
|
||||
DVBT_RX_C_RATE_HP,
|
||||
DVBT_GI_IDX,
|
||||
DVBT_FFT_MODE_IDX,
|
||||
DVBT_RSD_BER_EST,
|
||||
DVBT_CE_EST_EVM,
|
||||
DVBT_RF_AGC_VAL,
|
||||
DVBT_IF_AGC_VAL,
|
||||
DVBT_DAGC_VAL,
|
||||
DVBT_SFREQ_OFF,
|
||||
DVBT_CFREQ_OFF,
|
||||
DVBT_POLAR_RF_AGC,
|
||||
DVBT_POLAR_IF_AGC,
|
||||
DVBT_AAGC_HOLD,
|
||||
DVBT_EN_RF_AGC,
|
||||
DVBT_EN_IF_AGC,
|
||||
DVBT_IF_AGC_MIN,
|
||||
DVBT_IF_AGC_MAX,
|
||||
DVBT_RF_AGC_MIN,
|
||||
DVBT_RF_AGC_MAX,
|
||||
DVBT_IF_AGC_MAN,
|
||||
DVBT_IF_AGC_MAN_VAL,
|
||||
DVBT_RF_AGC_MAN,
|
||||
DVBT_RF_AGC_MAN_VAL,
|
||||
DVBT_DAGC_TRG_VAL,
|
||||
DVBT_AGC_TARG_VAL,
|
||||
DVBT_LOOP_GAIN_3_0,
|
||||
DVBT_LOOP_GAIN_4,
|
||||
DVBT_VTOP,
|
||||
DVBT_KRF,
|
||||
DVBT_AGC_TARG_VAL_0,
|
||||
DVBT_AGC_TARG_VAL_8_1,
|
||||
DVBT_AAGC_LOOP_GAIN,
|
||||
DVBT_LOOP_GAIN2_3_0,
|
||||
DVBT_LOOP_GAIN2_4,
|
||||
DVBT_LOOP_GAIN3,
|
||||
DVBT_VTOP1,
|
||||
DVBT_VTOP2,
|
||||
DVBT_VTOP3,
|
||||
DVBT_KRF1,
|
||||
DVBT_KRF2,
|
||||
DVBT_KRF3,
|
||||
DVBT_KRF4,
|
||||
DVBT_EN_GI_PGA,
|
||||
DVBT_THD_LOCK_UP,
|
||||
DVBT_THD_LOCK_DW,
|
||||
DVBT_THD_UP1,
|
||||
DVBT_THD_DW1,
|
||||
DVBT_INTER_CNT_LEN,
|
||||
DVBT_GI_PGA_STATE,
|
||||
DVBT_EN_AGC_PGA,
|
||||
DVBT_CKOUTPAR,
|
||||
DVBT_CKOUT_PWR,
|
||||
DVBT_SYNC_DUR,
|
||||
DVBT_ERR_DUR,
|
||||
DVBT_SYNC_LVL,
|
||||
DVBT_ERR_LVL,
|
||||
DVBT_VAL_LVL,
|
||||
DVBT_SERIAL,
|
||||
DVBT_SER_LSB,
|
||||
DVBT_CDIV_PH0,
|
||||
DVBT_CDIV_PH1,
|
||||
DVBT_MPEG_IO_OPT_2_2,
|
||||
DVBT_MPEG_IO_OPT_1_0,
|
||||
DVBT_CKOUTPAR_PIP,
|
||||
DVBT_CKOUT_PWR_PIP,
|
||||
DVBT_SYNC_LVL_PIP,
|
||||
DVBT_ERR_LVL_PIP,
|
||||
DVBT_VAL_LVL_PIP,
|
||||
DVBT_CKOUTPAR_PID,
|
||||
DVBT_CKOUT_PWR_PID,
|
||||
DVBT_SYNC_LVL_PID,
|
||||
DVBT_ERR_LVL_PID,
|
||||
DVBT_VAL_LVL_PID,
|
||||
DVBT_SM_PASS,
|
||||
DVBT_UPDATE_REG_2,
|
||||
DVBT_BTHD_P3,
|
||||
DVBT_BTHD_D3,
|
||||
DVBT_FUNC4_REG0,
|
||||
DVBT_FUNC4_REG1,
|
||||
DVBT_FUNC4_REG2,
|
||||
DVBT_FUNC4_REG3,
|
||||
DVBT_FUNC4_REG4,
|
||||
DVBT_FUNC4_REG5,
|
||||
DVBT_FUNC4_REG6,
|
||||
DVBT_FUNC4_REG7,
|
||||
DVBT_FUNC4_REG8,
|
||||
DVBT_FUNC4_REG9,
|
||||
DVBT_FUNC4_REG10,
|
||||
DVBT_FUNC5_REG0,
|
||||
DVBT_FUNC5_REG1,
|
||||
DVBT_FUNC5_REG2,
|
||||
DVBT_FUNC5_REG3,
|
||||
DVBT_FUNC5_REG4,
|
||||
DVBT_FUNC5_REG5,
|
||||
DVBT_FUNC5_REG6,
|
||||
DVBT_FUNC5_REG7,
|
||||
DVBT_FUNC5_REG8,
|
||||
DVBT_FUNC5_REG9,
|
||||
DVBT_FUNC5_REG10,
|
||||
DVBT_FUNC5_REG11,
|
||||
DVBT_FUNC5_REG12,
|
||||
DVBT_FUNC5_REG13,
|
||||
DVBT_FUNC5_REG14,
|
||||
DVBT_FUNC5_REG15,
|
||||
DVBT_FUNC5_REG16,
|
||||
DVBT_FUNC5_REG17,
|
||||
DVBT_FUNC5_REG18,
|
||||
DVBT_AD7_SETTING,
|
||||
DVBT_RSSI_R,
|
||||
DVBT_ACI_DET_IND,
|
||||
DVBT_REG_MON,
|
||||
DVBT_REG_MONSEL,
|
||||
DVBT_REG_GPE,
|
||||
DVBT_REG_GPO,
|
||||
DVBT_REG_4MSEL,
|
||||
DVBT_TEST_REG_1,
|
||||
DVBT_TEST_REG_2,
|
||||
DVBT_TEST_REG_3,
|
||||
DVBT_TEST_REG_4,
|
||||
DVBT_REG_BIT_NAME_ITEM_TERMINATOR,
|
||||
};
|
||||
|
||||
#endif /* RTL2832_PRIV_H */
|
||||
|
|
@ -634,7 +634,6 @@ static int s5h1420_set_frontend(struct dvb_frontend *fe)
|
|||
struct s5h1420_state* state = fe->demodulator_priv;
|
||||
int frequency_delta;
|
||||
struct dvb_frontend_tune_settings fesettings;
|
||||
uint8_t clock_setting;
|
||||
|
||||
dprintk("enter %s\n", __func__);
|
||||
|
||||
|
|
@ -679,25 +678,6 @@ static int s5h1420_set_frontend(struct dvb_frontend *fe)
|
|||
else
|
||||
state->fclk = 44000000;
|
||||
|
||||
/* Clock */
|
||||
switch (state->fclk) {
|
||||
default:
|
||||
case 88000000:
|
||||
clock_setting = 80;
|
||||
break;
|
||||
case 86000000:
|
||||
clock_setting = 78;
|
||||
break;
|
||||
case 80000000:
|
||||
clock_setting = 72;
|
||||
break;
|
||||
case 59000000:
|
||||
clock_setting = 51;
|
||||
break;
|
||||
case 44000000:
|
||||
clock_setting = 36;
|
||||
break;
|
||||
}
|
||||
dprintk("pll01: %d, ToneFreq: %d\n", state->fclk/1000000 - 8, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32));
|
||||
s5h1420_writereg(state, PLL01, state->fclk/1000000 - 8);
|
||||
s5h1420_writereg(state, PLL02, 0x40);
|
||||
|
|
|
|||
|
|
@ -1129,7 +1129,6 @@ static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber)
|
|||
struct stb0899_internal *internal = &state->internal;
|
||||
|
||||
u8 lsb, msb;
|
||||
u32 i;
|
||||
|
||||
*ber = 0;
|
||||
|
||||
|
|
@ -1137,14 +1136,9 @@ static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber)
|
|||
case SYS_DVBS:
|
||||
case SYS_DSS:
|
||||
if (internal->lock) {
|
||||
/* average 5 BER values */
|
||||
for (i = 0; i < 5; i++) {
|
||||
msleep(100);
|
||||
lsb = stb0899_read_reg(state, STB0899_ECNT1L);
|
||||
msb = stb0899_read_reg(state, STB0899_ECNT1M);
|
||||
*ber += MAKEWORD16(msb, lsb);
|
||||
}
|
||||
*ber /= 5;
|
||||
lsb = stb0899_read_reg(state, STB0899_ECNT1L);
|
||||
msb = stb0899_read_reg(state, STB0899_ECNT1M);
|
||||
*ber = MAKEWORD16(msb, lsb);
|
||||
/* Viterbi Check */
|
||||
if (STB0899_GETFIELD(VSTATUS_PRFVIT, internal->v_status)) {
|
||||
/* Error Rate */
|
||||
|
|
@ -1157,13 +1151,9 @@ static int stb0899_read_ber(struct dvb_frontend *fe, u32 *ber)
|
|||
break;
|
||||
case SYS_DVBS2:
|
||||
if (internal->lock) {
|
||||
/* Average 5 PER values */
|
||||
for (i = 0; i < 5; i++) {
|
||||
msleep(100);
|
||||
lsb = stb0899_read_reg(state, STB0899_ECNT1L);
|
||||
msb = stb0899_read_reg(state, STB0899_ECNT1M);
|
||||
*ber += MAKEWORD16(msb, lsb);
|
||||
}
|
||||
lsb = stb0899_read_reg(state, STB0899_ECNT1L);
|
||||
msb = stb0899_read_reg(state, STB0899_ECNT1M);
|
||||
*ber = MAKEWORD16(msb, lsb);
|
||||
/* ber = ber * 10 ^ 7 */
|
||||
*ber *= 10000000;
|
||||
*ber /= (-1 + (1 << (4 + 2 * STB0899_GETFIELD(NOE, internal->err_ctrl))));
|
||||
|
|
|
|||
|
|
@ -1584,7 +1584,7 @@ static int stv0367ter_algo(struct dvb_frontend *fe)
|
|||
struct stv0367ter_state *ter_state = state->ter_state;
|
||||
int offset = 0, tempo = 0;
|
||||
u8 u_var;
|
||||
u8 /*constell,*/ counter, tps_rcvd[2];
|
||||
u8 /*constell,*/ counter;
|
||||
s8 step;
|
||||
s32 timing_offset = 0;
|
||||
u32 trl_nomrate = 0, InternalFreq = 0, temp = 0;
|
||||
|
|
@ -1709,9 +1709,6 @@ static int stv0367ter_algo(struct dvb_frontend *fe)
|
|||
return 0;
|
||||
|
||||
ter_state->state = FE_TER_LOCKOK;
|
||||
/* update results */
|
||||
tps_rcvd[0] = stv0367_readreg(state, R367TER_TPS_RCVD2);
|
||||
tps_rcvd[1] = stv0367_readreg(state, R367TER_TPS_RCVD3);
|
||||
|
||||
ter_state->mode = stv0367_readbits(state, F367TER_SYR_MODE);
|
||||
ter_state->guard = stv0367_readbits(state, F367TER_SYR_GUARD);
|
||||
|
|
|
|||
|
|
@ -3172,7 +3172,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
|
|||
enum stv090x_signal_state signal_state = STV090x_NOCARRIER;
|
||||
u32 reg;
|
||||
s32 agc1_power, power_iq = 0, i;
|
||||
int lock = 0, low_sr = 0, no_signal = 0;
|
||||
int lock = 0, low_sr = 0;
|
||||
|
||||
reg = STV090x_READ_DEMOD(state, TSCFGH);
|
||||
STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 1); /* Stop path 1 stream merger */
|
||||
|
|
@ -3413,7 +3413,7 @@ static enum stv090x_signal_state stv090x_algo(struct stv090x_state *state)
|
|||
goto err;
|
||||
} else {
|
||||
signal_state = STV090x_NODATA;
|
||||
no_signal = stv090x_chk_signal(state);
|
||||
stv090x_chk_signal(state);
|
||||
}
|
||||
}
|
||||
return signal_state;
|
||||
|
|
|
|||
|
|
@ -20,10 +20,6 @@
|
|||
|
||||
#include "tda10071_priv.h"
|
||||
|
||||
int tda10071_debug;
|
||||
module_param_named(debug, tda10071_debug, int, 0644);
|
||||
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
|
||||
|
||||
static struct dvb_frontend_ops tda10071_ops;
|
||||
|
||||
/* write multiple registers */
|
||||
|
|
@ -48,7 +44,8 @@ static int tda10071_wr_regs(struct tda10071_priv *priv, u8 reg, u8 *val,
|
|||
if (ret == 1) {
|
||||
ret = 0;
|
||||
} else {
|
||||
warn("i2c wr failed=%d reg=%02x len=%d", ret, reg, len);
|
||||
dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
|
||||
"len=%d\n", KBUILD_MODNAME, ret, reg, len);
|
||||
ret = -EREMOTEIO;
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -79,7 +76,8 @@ static int tda10071_rd_regs(struct tda10071_priv *priv, u8 reg, u8 *val,
|
|||
memcpy(val, buf, len);
|
||||
ret = 0;
|
||||
} else {
|
||||
warn("i2c rd failed=%d reg=%02x len=%d", ret, reg, len);
|
||||
dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
|
||||
"len=%d\n", KBUILD_MODNAME, ret, reg, len);
|
||||
ret = -EREMOTEIO;
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -170,7 +168,7 @@ static int tda10071_cmd_execute(struct tda10071_priv *priv,
|
|||
usleep_range(200, 5000);
|
||||
}
|
||||
|
||||
dbg("%s: loop=%d", __func__, i);
|
||||
dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
|
||||
|
||||
if (i == 0) {
|
||||
ret = -ETIMEDOUT;
|
||||
|
|
@ -179,7 +177,7 @@ static int tda10071_cmd_execute(struct tda10071_priv *priv,
|
|||
|
||||
return ret;
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -196,7 +194,8 @@ static int tda10071_set_tone(struct dvb_frontend *fe,
|
|||
goto error;
|
||||
}
|
||||
|
||||
dbg("%s: tone_mode=%d", __func__, fe_sec_tone_mode);
|
||||
dev_dbg(&priv->i2c->dev, "%s: tone_mode=%d\n", __func__,
|
||||
fe_sec_tone_mode);
|
||||
|
||||
switch (fe_sec_tone_mode) {
|
||||
case SEC_TONE_ON:
|
||||
|
|
@ -206,24 +205,25 @@ static int tda10071_set_tone(struct dvb_frontend *fe,
|
|||
tone = 0;
|
||||
break;
|
||||
default:
|
||||
dbg("%s: invalid fe_sec_tone_mode", __func__);
|
||||
dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_tone_mode\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
cmd.args[0x00] = CMD_LNB_PCB_CONFIG;
|
||||
cmd.args[0x01] = 0;
|
||||
cmd.args[0x02] = 0x00;
|
||||
cmd.args[0x03] = 0x00;
|
||||
cmd.args[0x04] = tone;
|
||||
cmd.len = 0x05;
|
||||
cmd.args[0] = CMD_LNB_PCB_CONFIG;
|
||||
cmd.args[1] = 0;
|
||||
cmd.args[2] = 0x00;
|
||||
cmd.args[3] = 0x00;
|
||||
cmd.args[4] = tone;
|
||||
cmd.len = 5;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
return ret;
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +240,7 @@ static int tda10071_set_voltage(struct dvb_frontend *fe,
|
|||
goto error;
|
||||
}
|
||||
|
||||
dbg("%s: voltage=%d", __func__, fe_sec_voltage);
|
||||
dev_dbg(&priv->i2c->dev, "%s: voltage=%d\n", __func__, fe_sec_voltage);
|
||||
|
||||
switch (fe_sec_voltage) {
|
||||
case SEC_VOLTAGE_13:
|
||||
|
|
@ -253,22 +253,23 @@ static int tda10071_set_voltage(struct dvb_frontend *fe,
|
|||
voltage = 0;
|
||||
break;
|
||||
default:
|
||||
dbg("%s: invalid fe_sec_voltage", __func__);
|
||||
dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_voltage\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
};
|
||||
|
||||
cmd.args[0x00] = CMD_LNB_SET_DC_LEVEL;
|
||||
cmd.args[0x01] = 0;
|
||||
cmd.args[0x02] = voltage;
|
||||
cmd.len = 0x03;
|
||||
cmd.args[0] = CMD_LNB_SET_DC_LEVEL;
|
||||
cmd.args[1] = 0;
|
||||
cmd.args[2] = voltage;
|
||||
cmd.len = 3;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
return ret;
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -285,9 +286,10 @@ static int tda10071_diseqc_send_master_cmd(struct dvb_frontend *fe,
|
|||
goto error;
|
||||
}
|
||||
|
||||
dbg("%s: msg_len=%d", __func__, diseqc_cmd->msg_len);
|
||||
dev_dbg(&priv->i2c->dev, "%s: msg_len=%d\n", __func__,
|
||||
diseqc_cmd->msg_len);
|
||||
|
||||
if (diseqc_cmd->msg_len < 3 || diseqc_cmd->msg_len > 16) {
|
||||
if (diseqc_cmd->msg_len < 3 || diseqc_cmd->msg_len > 6) {
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -301,7 +303,7 @@ static int tda10071_diseqc_send_master_cmd(struct dvb_frontend *fe,
|
|||
usleep_range(10000, 20000);
|
||||
}
|
||||
|
||||
dbg("%s: loop=%d", __func__, i);
|
||||
dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
|
||||
|
||||
if (i == 0) {
|
||||
ret = -ETIMEDOUT;
|
||||
|
|
@ -312,22 +314,22 @@ static int tda10071_diseqc_send_master_cmd(struct dvb_frontend *fe,
|
|||
if (ret)
|
||||
goto error;
|
||||
|
||||
cmd.args[0x00] = CMD_LNB_SEND_DISEQC;
|
||||
cmd.args[0x01] = 0;
|
||||
cmd.args[0x02] = 0;
|
||||
cmd.args[0x03] = 0;
|
||||
cmd.args[0x04] = 2;
|
||||
cmd.args[0x05] = 0;
|
||||
cmd.args[0x06] = diseqc_cmd->msg_len;
|
||||
memcpy(&cmd.args[0x07], diseqc_cmd->msg, diseqc_cmd->msg_len);
|
||||
cmd.len = 0x07 + diseqc_cmd->msg_len;
|
||||
cmd.args[0] = CMD_LNB_SEND_DISEQC;
|
||||
cmd.args[1] = 0;
|
||||
cmd.args[2] = 0;
|
||||
cmd.args[3] = 0;
|
||||
cmd.args[4] = 2;
|
||||
cmd.args[5] = 0;
|
||||
cmd.args[6] = diseqc_cmd->msg_len;
|
||||
memcpy(&cmd.args[7], diseqc_cmd->msg, diseqc_cmd->msg_len);
|
||||
cmd.len = 7 + diseqc_cmd->msg_len;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
return ret;
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -344,7 +346,7 @@ static int tda10071_diseqc_recv_slave_reply(struct dvb_frontend *fe,
|
|||
goto error;
|
||||
}
|
||||
|
||||
dbg("%s:", __func__);
|
||||
dev_dbg(&priv->i2c->dev, "%s:\n", __func__);
|
||||
|
||||
/* wait LNB RX */
|
||||
for (i = 500, tmp = 0; i && !tmp; i--) {
|
||||
|
|
@ -355,7 +357,7 @@ static int tda10071_diseqc_recv_slave_reply(struct dvb_frontend *fe,
|
|||
usleep_range(10000, 20000);
|
||||
}
|
||||
|
||||
dbg("%s: loop=%d", __func__, i);
|
||||
dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
|
||||
|
||||
if (i == 0) {
|
||||
ret = -ETIMEDOUT;
|
||||
|
|
@ -372,9 +374,9 @@ static int tda10071_diseqc_recv_slave_reply(struct dvb_frontend *fe,
|
|||
reply->msg_len = sizeof(reply->msg); /* truncate API max */
|
||||
|
||||
/* read reply */
|
||||
cmd.args[0x00] = CMD_LNB_UPDATE_REPLY;
|
||||
cmd.args[0x01] = 0;
|
||||
cmd.len = 0x02;
|
||||
cmd.args[0] = CMD_LNB_UPDATE_REPLY;
|
||||
cmd.args[1] = 0;
|
||||
cmd.len = 2;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
|
@ -385,7 +387,7 @@ static int tda10071_diseqc_recv_slave_reply(struct dvb_frontend *fe,
|
|||
|
||||
return ret;
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -402,7 +404,8 @@ static int tda10071_diseqc_send_burst(struct dvb_frontend *fe,
|
|||
goto error;
|
||||
}
|
||||
|
||||
dbg("%s: fe_sec_mini_cmd=%d", __func__, fe_sec_mini_cmd);
|
||||
dev_dbg(&priv->i2c->dev, "%s: fe_sec_mini_cmd=%d\n", __func__,
|
||||
fe_sec_mini_cmd);
|
||||
|
||||
switch (fe_sec_mini_cmd) {
|
||||
case SEC_MINI_A:
|
||||
|
|
@ -412,7 +415,8 @@ static int tda10071_diseqc_send_burst(struct dvb_frontend *fe,
|
|||
burst = 1;
|
||||
break;
|
||||
default:
|
||||
dbg("%s: invalid fe_sec_mini_cmd", __func__);
|
||||
dev_dbg(&priv->i2c->dev, "%s: invalid fe_sec_mini_cmd\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -426,7 +430,7 @@ static int tda10071_diseqc_send_burst(struct dvb_frontend *fe,
|
|||
usleep_range(10000, 20000);
|
||||
}
|
||||
|
||||
dbg("%s: loop=%d", __func__, i);
|
||||
dev_dbg(&priv->i2c->dev, "%s: loop=%d\n", __func__, i);
|
||||
|
||||
if (i == 0) {
|
||||
ret = -ETIMEDOUT;
|
||||
|
|
@ -437,17 +441,17 @@ static int tda10071_diseqc_send_burst(struct dvb_frontend *fe,
|
|||
if (ret)
|
||||
goto error;
|
||||
|
||||
cmd.args[0x00] = CMD_LNB_SEND_TONEBURST;
|
||||
cmd.args[0x01] = 0;
|
||||
cmd.args[0x02] = burst;
|
||||
cmd.len = 0x03;
|
||||
cmd.args[0] = CMD_LNB_SEND_TONEBURST;
|
||||
cmd.args[1] = 0;
|
||||
cmd.args[2] = burst;
|
||||
cmd.len = 3;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
return ret;
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -481,7 +485,7 @@ static int tda10071_read_status(struct dvb_frontend *fe, fe_status_t *status)
|
|||
|
||||
return ret;
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -506,7 +510,7 @@ static int tda10071_read_snr(struct dvb_frontend *fe, u16 *snr)
|
|||
|
||||
return ret;
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -523,9 +527,9 @@ static int tda10071_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
|||
goto error;
|
||||
}
|
||||
|
||||
cmd.args[0x00] = CMD_GET_AGCACC;
|
||||
cmd.args[0x01] = 0;
|
||||
cmd.len = 0x02;
|
||||
cmd.args[0] = CMD_GET_AGCACC;
|
||||
cmd.args[1] = 0;
|
||||
cmd.len = 2;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
|
@ -545,7 +549,7 @@ static int tda10071_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
|||
|
||||
return ret;
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -583,17 +587,18 @@ static int tda10071_read_ber(struct dvb_frontend *fe, u32 *ber)
|
|||
goto error;
|
||||
|
||||
if (priv->meas_count[i] == tmp) {
|
||||
dbg("%s: meas not ready=%02x", __func__, tmp);
|
||||
dev_dbg(&priv->i2c->dev, "%s: meas not ready=%02x\n", __func__,
|
||||
tmp);
|
||||
*ber = priv->ber;
|
||||
return 0;
|
||||
} else {
|
||||
priv->meas_count[i] = tmp;
|
||||
}
|
||||
|
||||
cmd.args[0x00] = CMD_BER_UPDATE_COUNTERS;
|
||||
cmd.args[0x01] = 0;
|
||||
cmd.args[0x02] = i;
|
||||
cmd.len = 0x03;
|
||||
cmd.args[0] = CMD_BER_UPDATE_COUNTERS;
|
||||
cmd.args[1] = 0;
|
||||
cmd.args[2] = i;
|
||||
cmd.len = 3;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
|
@ -612,7 +617,7 @@ static int tda10071_read_ber(struct dvb_frontend *fe, u32 *ber)
|
|||
|
||||
return ret;
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -632,7 +637,7 @@ static int tda10071_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
|
|||
|
||||
return ret;
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -644,10 +649,11 @@ static int tda10071_set_frontend(struct dvb_frontend *fe)
|
|||
int ret, i;
|
||||
u8 mode, rolloff, pilot, inversion, div;
|
||||
|
||||
dbg("%s: delivery_system=%d modulation=%d frequency=%d " \
|
||||
"symbol_rate=%d inversion=%d pilot=%d rolloff=%d", __func__,
|
||||
c->delivery_system, c->modulation, c->frequency,
|
||||
c->symbol_rate, c->inversion, c->pilot, c->rolloff);
|
||||
dev_dbg(&priv->i2c->dev, "%s: delivery_system=%d modulation=%d " \
|
||||
"frequency=%d symbol_rate=%d inversion=%d pilot=%d " \
|
||||
"rolloff=%d\n", __func__, c->delivery_system, c->modulation,
|
||||
c->frequency, c->symbol_rate, c->inversion, c->pilot,
|
||||
c->rolloff);
|
||||
|
||||
priv->delivery_system = SYS_UNDEFINED;
|
||||
|
||||
|
|
@ -669,7 +675,7 @@ static int tda10071_set_frontend(struct dvb_frontend *fe)
|
|||
inversion = 3;
|
||||
break;
|
||||
default:
|
||||
dbg("%s: invalid inversion", __func__);
|
||||
dev_dbg(&priv->i2c->dev, "%s: invalid inversion\n", __func__);
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -692,7 +698,8 @@ static int tda10071_set_frontend(struct dvb_frontend *fe)
|
|||
break;
|
||||
case ROLLOFF_AUTO:
|
||||
default:
|
||||
dbg("%s: invalid rolloff", __func__);
|
||||
dev_dbg(&priv->i2c->dev, "%s: invalid rolloff\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -708,13 +715,15 @@ static int tda10071_set_frontend(struct dvb_frontend *fe)
|
|||
pilot = 2;
|
||||
break;
|
||||
default:
|
||||
dbg("%s: invalid pilot", __func__);
|
||||
dev_dbg(&priv->i2c->dev, "%s: invalid pilot\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dbg("%s: invalid delivery_system", __func__);
|
||||
dev_dbg(&priv->i2c->dev, "%s: invalid delivery_system\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -724,13 +733,15 @@ static int tda10071_set_frontend(struct dvb_frontend *fe)
|
|||
c->modulation == TDA10071_MODCOD[i].modulation &&
|
||||
c->fec_inner == TDA10071_MODCOD[i].fec) {
|
||||
mode = TDA10071_MODCOD[i].val;
|
||||
dbg("%s: mode found=%02x", __func__, mode);
|
||||
dev_dbg(&priv->i2c->dev, "%s: mode found=%02x\n",
|
||||
__func__, mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == 0xff) {
|
||||
dbg("%s: invalid parameter combination", __func__);
|
||||
dev_dbg(&priv->i2c->dev, "%s: invalid parameter combination\n",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -748,22 +759,22 @@ static int tda10071_set_frontend(struct dvb_frontend *fe)
|
|||
if (ret)
|
||||
goto error;
|
||||
|
||||
cmd.args[0x00] = CMD_CHANGE_CHANNEL;
|
||||
cmd.args[0x01] = 0;
|
||||
cmd.args[0x02] = mode;
|
||||
cmd.args[0x03] = (c->frequency >> 16) & 0xff;
|
||||
cmd.args[0x04] = (c->frequency >> 8) & 0xff;
|
||||
cmd.args[0x05] = (c->frequency >> 0) & 0xff;
|
||||
cmd.args[0x06] = ((c->symbol_rate / 1000) >> 8) & 0xff;
|
||||
cmd.args[0x07] = ((c->symbol_rate / 1000) >> 0) & 0xff;
|
||||
cmd.args[0x08] = (tda10071_ops.info.frequency_tolerance >> 8) & 0xff;
|
||||
cmd.args[0x09] = (tda10071_ops.info.frequency_tolerance >> 0) & 0xff;
|
||||
cmd.args[0x0a] = rolloff;
|
||||
cmd.args[0x0b] = inversion;
|
||||
cmd.args[0x0c] = pilot;
|
||||
cmd.args[0x0d] = 0x00;
|
||||
cmd.args[0x0e] = 0x00;
|
||||
cmd.len = 0x0f;
|
||||
cmd.args[0] = CMD_CHANGE_CHANNEL;
|
||||
cmd.args[1] = 0;
|
||||
cmd.args[2] = mode;
|
||||
cmd.args[3] = (c->frequency >> 16) & 0xff;
|
||||
cmd.args[4] = (c->frequency >> 8) & 0xff;
|
||||
cmd.args[5] = (c->frequency >> 0) & 0xff;
|
||||
cmd.args[6] = ((c->symbol_rate / 1000) >> 8) & 0xff;
|
||||
cmd.args[7] = ((c->symbol_rate / 1000) >> 0) & 0xff;
|
||||
cmd.args[8] = (tda10071_ops.info.frequency_tolerance >> 8) & 0xff;
|
||||
cmd.args[9] = (tda10071_ops.info.frequency_tolerance >> 0) & 0xff;
|
||||
cmd.args[10] = rolloff;
|
||||
cmd.args[11] = inversion;
|
||||
cmd.args[12] = pilot;
|
||||
cmd.args[13] = 0x00;
|
||||
cmd.args[14] = 0x00;
|
||||
cmd.len = 15;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
|
@ -772,7 +783,7 @@ static int tda10071_set_frontend(struct dvb_frontend *fe)
|
|||
|
||||
return ret;
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -829,7 +840,7 @@ static int tda10071_get_frontend(struct dvb_frontend *fe)
|
|||
|
||||
return ret;
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -915,10 +926,10 @@ static int tda10071_init(struct dvb_frontend *fe)
|
|||
goto error;
|
||||
}
|
||||
|
||||
cmd.args[0x00] = CMD_SET_SLEEP_MODE;
|
||||
cmd.args[0x01] = 0;
|
||||
cmd.args[0x02] = 0;
|
||||
cmd.len = 0x03;
|
||||
cmd.args[0] = CMD_SET_SLEEP_MODE;
|
||||
cmd.args[1] = 0;
|
||||
cmd.args[2] = 0;
|
||||
cmd.len = 3;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
|
@ -929,10 +940,11 @@ static int tda10071_init(struct dvb_frontend *fe)
|
|||
/* request the firmware, this will block and timeout */
|
||||
ret = request_firmware(&fw, fw_file, priv->i2c->dev.parent);
|
||||
if (ret) {
|
||||
err("did not find the firmware file. (%s) "
|
||||
"Please see linux/Documentation/dvb/ for more" \
|
||||
" details on firmware-problems. (%d)",
|
||||
fw_file, ret);
|
||||
dev_err(&priv->i2c->dev, "%s: did not find the " \
|
||||
"firmware file. (%s) Please see " \
|
||||
"linux/Documentation/dvb/ for more " \
|
||||
"details on firmware-problems. (%d)\n",
|
||||
KBUILD_MODNAME, fw_file, ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
@ -961,10 +973,11 @@ static int tda10071_init(struct dvb_frontend *fe)
|
|||
if (ret)
|
||||
goto error_release_firmware;
|
||||
|
||||
info("found a '%s' in cold state, will try to load a firmware",
|
||||
tda10071_ops.info.name);
|
||||
|
||||
info("downloading firmware from file '%s'", fw_file);
|
||||
dev_info(&priv->i2c->dev, "%s: found a '%s' in cold state, " \
|
||||
"will try to load a firmware\n", KBUILD_MODNAME,
|
||||
tda10071_ops.info.name);
|
||||
dev_info(&priv->i2c->dev, "%s: downloading firmware from " \
|
||||
"file '%s'\n", KBUILD_MODNAME, fw_file);
|
||||
|
||||
/* do not download last byte */
|
||||
fw_size = fw->size - 1;
|
||||
|
|
@ -978,7 +991,9 @@ static int tda10071_init(struct dvb_frontend *fe)
|
|||
ret = tda10071_wr_regs(priv, 0xfa,
|
||||
(u8 *) &fw->data[fw_size - remaining], len);
|
||||
if (ret) {
|
||||
err("firmware download failed=%d", ret);
|
||||
dev_err(&priv->i2c->dev, "%s: firmware " \
|
||||
"download failed=%d\n",
|
||||
KBUILD_MODNAME, ret);
|
||||
if (ret)
|
||||
goto error_release_firmware;
|
||||
}
|
||||
|
|
@ -1002,15 +1017,16 @@ static int tda10071_init(struct dvb_frontend *fe)
|
|||
goto error;
|
||||
|
||||
if (tmp) {
|
||||
info("firmware did not run");
|
||||
dev_info(&priv->i2c->dev, "%s: firmware did not run\n",
|
||||
KBUILD_MODNAME);
|
||||
ret = -EFAULT;
|
||||
goto error;
|
||||
} else {
|
||||
priv->warm = 1;
|
||||
}
|
||||
|
||||
cmd.args[0x00] = CMD_GET_FW_VERSION;
|
||||
cmd.len = 0x01;
|
||||
cmd.args[0] = CMD_GET_FW_VERSION;
|
||||
cmd.len = 1;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
|
@ -1019,54 +1035,55 @@ static int tda10071_init(struct dvb_frontend *fe)
|
|||
if (ret)
|
||||
goto error;
|
||||
|
||||
info("firmware version %d.%d.%d.%d",
|
||||
buf[0], buf[1], buf[2], buf[3]);
|
||||
info("found a '%s' in warm state.", tda10071_ops.info.name);
|
||||
dev_info(&priv->i2c->dev, "%s: firmware version %d.%d.%d.%d\n",
|
||||
KBUILD_MODNAME, buf[0], buf[1], buf[2], buf[3]);
|
||||
dev_info(&priv->i2c->dev, "%s: found a '%s' in warm state\n",
|
||||
KBUILD_MODNAME, tda10071_ops.info.name);
|
||||
|
||||
ret = tda10071_rd_regs(priv, 0x81, buf, 2);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
cmd.args[0x00] = CMD_DEMOD_INIT;
|
||||
cmd.args[0x01] = ((priv->cfg.xtal / 1000) >> 8) & 0xff;
|
||||
cmd.args[0x02] = ((priv->cfg.xtal / 1000) >> 0) & 0xff;
|
||||
cmd.args[0x03] = buf[0];
|
||||
cmd.args[0x04] = buf[1];
|
||||
cmd.args[0x05] = priv->cfg.pll_multiplier;
|
||||
cmd.args[0x06] = priv->cfg.spec_inv;
|
||||
cmd.args[0x07] = 0x00;
|
||||
cmd.len = 0x08;
|
||||
cmd.args[0] = CMD_DEMOD_INIT;
|
||||
cmd.args[1] = ((priv->cfg.xtal / 1000) >> 8) & 0xff;
|
||||
cmd.args[2] = ((priv->cfg.xtal / 1000) >> 0) & 0xff;
|
||||
cmd.args[3] = buf[0];
|
||||
cmd.args[4] = buf[1];
|
||||
cmd.args[5] = priv->cfg.pll_multiplier;
|
||||
cmd.args[6] = priv->cfg.spec_inv;
|
||||
cmd.args[7] = 0x00;
|
||||
cmd.len = 8;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
cmd.args[0x00] = CMD_TUNER_INIT;
|
||||
cmd.args[0x01] = 0x00;
|
||||
cmd.args[0x02] = 0x00;
|
||||
cmd.args[0x03] = 0x00;
|
||||
cmd.args[0x04] = 0x00;
|
||||
cmd.args[0x05] = 0x14;
|
||||
cmd.args[0x06] = 0x00;
|
||||
cmd.args[0x07] = 0x03;
|
||||
cmd.args[0x08] = 0x02;
|
||||
cmd.args[0x09] = 0x02;
|
||||
cmd.args[0x0a] = 0x00;
|
||||
cmd.args[0x0b] = 0x00;
|
||||
cmd.args[0x0c] = 0x00;
|
||||
cmd.args[0x0d] = 0x00;
|
||||
cmd.args[0x0e] = 0x00;
|
||||
cmd.len = 0x0f;
|
||||
cmd.args[0] = CMD_TUNER_INIT;
|
||||
cmd.args[1] = 0x00;
|
||||
cmd.args[2] = 0x00;
|
||||
cmd.args[3] = 0x00;
|
||||
cmd.args[4] = 0x00;
|
||||
cmd.args[5] = 0x14;
|
||||
cmd.args[6] = 0x00;
|
||||
cmd.args[7] = 0x03;
|
||||
cmd.args[8] = 0x02;
|
||||
cmd.args[9] = 0x02;
|
||||
cmd.args[10] = 0x00;
|
||||
cmd.args[11] = 0x00;
|
||||
cmd.args[12] = 0x00;
|
||||
cmd.args[13] = 0x00;
|
||||
cmd.args[14] = 0x00;
|
||||
cmd.len = 15;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
cmd.args[0x00] = CMD_MPEG_CONFIG;
|
||||
cmd.args[0x01] = 0;
|
||||
cmd.args[0x02] = priv->cfg.ts_mode;
|
||||
cmd.args[0x03] = 0x00;
|
||||
cmd.args[0x04] = 0x04;
|
||||
cmd.args[0x05] = 0x00;
|
||||
cmd.len = 0x06;
|
||||
cmd.args[0] = CMD_MPEG_CONFIG;
|
||||
cmd.args[1] = 0;
|
||||
cmd.args[2] = priv->cfg.ts_mode;
|
||||
cmd.args[3] = 0x00;
|
||||
cmd.args[4] = 0x04;
|
||||
cmd.args[5] = 0x00;
|
||||
cmd.len = 6;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
|
@ -1075,27 +1092,27 @@ static int tda10071_init(struct dvb_frontend *fe)
|
|||
if (ret)
|
||||
goto error;
|
||||
|
||||
cmd.args[0x00] = CMD_LNB_CONFIG;
|
||||
cmd.args[0x01] = 0;
|
||||
cmd.args[0x02] = 150;
|
||||
cmd.args[0x03] = 3;
|
||||
cmd.args[0x04] = 22;
|
||||
cmd.args[0x05] = 1;
|
||||
cmd.args[0x06] = 1;
|
||||
cmd.args[0x07] = 30;
|
||||
cmd.args[0x08] = 30;
|
||||
cmd.args[0x09] = 30;
|
||||
cmd.args[0x0a] = 30;
|
||||
cmd.len = 0x0b;
|
||||
cmd.args[0] = CMD_LNB_CONFIG;
|
||||
cmd.args[1] = 0;
|
||||
cmd.args[2] = 150;
|
||||
cmd.args[3] = 3;
|
||||
cmd.args[4] = 22;
|
||||
cmd.args[5] = 1;
|
||||
cmd.args[6] = 1;
|
||||
cmd.args[7] = 30;
|
||||
cmd.args[8] = 30;
|
||||
cmd.args[9] = 30;
|
||||
cmd.args[10] = 30;
|
||||
cmd.len = 11;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
cmd.args[0x00] = CMD_BER_CONTROL;
|
||||
cmd.args[0x01] = 0;
|
||||
cmd.args[0x02] = 14;
|
||||
cmd.args[0x03] = 14;
|
||||
cmd.len = 0x04;
|
||||
cmd.args[0] = CMD_BER_CONTROL;
|
||||
cmd.args[1] = 0;
|
||||
cmd.args[2] = 14;
|
||||
cmd.args[3] = 14;
|
||||
cmd.len = 4;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
|
@ -1105,7 +1122,7 @@ static int tda10071_init(struct dvb_frontend *fe)
|
|||
error_release_firmware:
|
||||
release_firmware(fw);
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1132,10 +1149,10 @@ static int tda10071_sleep(struct dvb_frontend *fe)
|
|||
goto error;
|
||||
}
|
||||
|
||||
cmd.args[0x00] = CMD_SET_SLEEP_MODE;
|
||||
cmd.args[0x01] = 0;
|
||||
cmd.args[0x02] = 1;
|
||||
cmd.len = 0x03;
|
||||
cmd.args[0] = CMD_SET_SLEEP_MODE;
|
||||
cmd.args[1] = 0;
|
||||
cmd.args[2] = 1;
|
||||
cmd.len = 3;
|
||||
ret = tda10071_cmd_execute(priv, &cmd);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
|
@ -1149,7 +1166,7 @@ static int tda10071_sleep(struct dvb_frontend *fe)
|
|||
|
||||
return ret;
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1208,7 +1225,7 @@ struct dvb_frontend *tda10071_attach(const struct tda10071_config *config,
|
|||
|
||||
return &priv->fe;
|
||||
error:
|
||||
dbg("%s: failed=%d", __func__, ret);
|
||||
dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
|
||||
kfree(priv);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,19 +25,6 @@
|
|||
#include "tda10071.h"
|
||||
#include <linux/firmware.h>
|
||||
|
||||
#define LOG_PREFIX "tda10071"
|
||||
|
||||
#undef dbg
|
||||
#define dbg(f, arg...) \
|
||||
if (tda10071_debug) \
|
||||
printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
|
||||
#undef err
|
||||
#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
|
||||
#undef info
|
||||
#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
|
||||
#undef warn
|
||||
#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
|
||||
|
||||
struct tda10071_priv {
|
||||
struct i2c_adapter *i2c;
|
||||
struct dvb_frontend fe;
|
||||
|
|
@ -112,7 +99,7 @@ struct tda10071_reg_val_mask {
|
|||
#define CMD_BER_UPDATE_COUNTERS 0x3f
|
||||
|
||||
/* firmare command struct */
|
||||
#define TDA10071_ARGLEN 0x1e
|
||||
#define TDA10071_ARGLEN 30
|
||||
struct tda10071_cmd {
|
||||
u8 args[TDA10071_ARGLEN];
|
||||
u8 len;
|
||||
|
|
|
|||
|
|
@ -217,6 +217,7 @@ static int demod_attach_drxk(struct ngene_channel *chan,
|
|||
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.microcode_name = "drxk_a3.mc";
|
||||
config.qam_demod_parameter_count = 4;
|
||||
config.adr = 0x29 + (chan->number ^ 2);
|
||||
|
||||
chan->fe = dvb_attach(drxk_attach, &config, i2c);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
menuconfig RADIO_ADAPTERS
|
||||
bool "Radio Adapters"
|
||||
depends on VIDEO_V4L2
|
||||
depends on MEDIA_RADIO_SUPPORT
|
||||
default y
|
||||
---help---
|
||||
Say Y here to enable selecting AM/FM radio adapters.
|
||||
|
|
|
|||
43
drivers/media/radio/lm7000.h
Normal file
43
drivers/media/radio/lm7000.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef __LM7000_H
|
||||
#define __LM7000_H
|
||||
|
||||
/* Sanyo LM7000 tuner chip control
|
||||
*
|
||||
* Copyright 2012 Ondrej Zary <linux@rainbow-software.org>
|
||||
* based on radio-aimslab.c by M. Kirkwood
|
||||
* and radio-sf16fmi.c by M. Kirkwood and Petr Vandrovec
|
||||
*/
|
||||
|
||||
#define LM7000_DATA (1 << 0)
|
||||
#define LM7000_CLK (1 << 1)
|
||||
#define LM7000_CE (1 << 2)
|
||||
|
||||
#define LM7000_FM_100 (0 << 20)
|
||||
#define LM7000_FM_50 (1 << 20)
|
||||
#define LM7000_FM_25 (2 << 20)
|
||||
#define LM7000_BIT_FM (1 << 23)
|
||||
|
||||
static inline void lm7000_set_freq(u32 freq, void *handle,
|
||||
void (*set_pins)(void *handle, u8 pins))
|
||||
{
|
||||
int i;
|
||||
u8 data;
|
||||
u32 val;
|
||||
|
||||
freq += 171200; /* Add 10.7 MHz IF */
|
||||
freq /= 400; /* Convert to 25 kHz units */
|
||||
val = freq | LM7000_FM_25 | LM7000_BIT_FM;
|
||||
/* write the 24-bit register, starting with LSB */
|
||||
for (i = 0; i < 24; i++) {
|
||||
data = val & (1 << i) ? LM7000_DATA : 0;
|
||||
set_pins(handle, data | LM7000_CE);
|
||||
udelay(2);
|
||||
set_pins(handle, data | LM7000_CE | LM7000_CLK);
|
||||
udelay(2);
|
||||
set_pins(handle, data | LM7000_CE);
|
||||
udelay(2);
|
||||
}
|
||||
set_pins(handle, 0);
|
||||
}
|
||||
|
||||
#endif /* __LM7000_H */
|
||||
|
|
@ -37,6 +37,7 @@
|
|||
#include <media/v4l2-ioctl.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
#include "radio-isa.h"
|
||||
#include "lm7000.h"
|
||||
|
||||
MODULE_AUTHOR("M. Kirkwood");
|
||||
MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card.");
|
||||
|
|
@ -72,55 +73,38 @@ static struct radio_isa_card *rtrack_alloc(void)
|
|||
return rt ? &rt->isa : NULL;
|
||||
}
|
||||
|
||||
/* The 128+64 on these outb's is to keep the volume stable while tuning.
|
||||
* Without them, the volume _will_ creep up with each frequency change
|
||||
* and bit 4 (+16) is to keep the signal strength meter enabled.
|
||||
*/
|
||||
#define AIMS_BIT_TUN_CE (1 << 0)
|
||||
#define AIMS_BIT_TUN_CLK (1 << 1)
|
||||
#define AIMS_BIT_TUN_DATA (1 << 2)
|
||||
#define AIMS_BIT_VOL_CE (1 << 3)
|
||||
#define AIMS_BIT_TUN_STRQ (1 << 4)
|
||||
/* bit 5 is not connected */
|
||||
#define AIMS_BIT_VOL_UP (1 << 6) /* active low */
|
||||
#define AIMS_BIT_VOL_DN (1 << 7) /* active low */
|
||||
|
||||
static void send_0_byte(struct radio_isa_card *isa, int on)
|
||||
void rtrack_set_pins(void *handle, u8 pins)
|
||||
{
|
||||
outb_p(128+64+16+on+1, isa->io); /* wr-enable + data low */
|
||||
outb_p(128+64+16+on+2+1, isa->io); /* clock */
|
||||
msleep(1);
|
||||
}
|
||||
struct radio_isa_card *isa = handle;
|
||||
struct rtrack *rt = container_of(isa, struct rtrack, isa);
|
||||
u8 bits = AIMS_BIT_VOL_DN | AIMS_BIT_VOL_UP | AIMS_BIT_TUN_STRQ;
|
||||
|
||||
static void send_1_byte(struct radio_isa_card *isa, int on)
|
||||
{
|
||||
outb_p(128+64+16+on+4+1, isa->io); /* wr-enable+data high */
|
||||
outb_p(128+64+16+on+4+2+1, isa->io); /* clock */
|
||||
msleep(1);
|
||||
if (!v4l2_ctrl_g_ctrl(rt->isa.mute))
|
||||
bits |= AIMS_BIT_VOL_CE;
|
||||
|
||||
if (pins & LM7000_DATA)
|
||||
bits |= AIMS_BIT_TUN_DATA;
|
||||
if (pins & LM7000_CLK)
|
||||
bits |= AIMS_BIT_TUN_CLK;
|
||||
if (pins & LM7000_CE)
|
||||
bits |= AIMS_BIT_TUN_CE;
|
||||
|
||||
outb_p(bits, rt->isa.io);
|
||||
}
|
||||
|
||||
static int rtrack_s_frequency(struct radio_isa_card *isa, u32 freq)
|
||||
{
|
||||
int on = v4l2_ctrl_g_ctrl(isa->mute) ? 0 : 8;
|
||||
int i;
|
||||
lm7000_set_freq(freq, isa, rtrack_set_pins);
|
||||
|
||||
freq += 171200; /* Add 10.7 MHz IF */
|
||||
freq /= 800; /* Convert to 50 kHz units */
|
||||
|
||||
send_0_byte(isa, on); /* 0: LSB of frequency */
|
||||
|
||||
for (i = 0; i < 13; i++) /* : frequency bits (1-13) */
|
||||
if (freq & (1 << i))
|
||||
send_1_byte(isa, on);
|
||||
else
|
||||
send_0_byte(isa, on);
|
||||
|
||||
send_0_byte(isa, on); /* 14: test bit - always 0 */
|
||||
send_0_byte(isa, on); /* 15: test bit - always 0 */
|
||||
|
||||
send_0_byte(isa, on); /* 16: band data 0 - always 0 */
|
||||
send_0_byte(isa, on); /* 17: band data 1 - always 0 */
|
||||
send_0_byte(isa, on); /* 18: band data 2 - always 0 */
|
||||
send_0_byte(isa, on); /* 19: time base - always 0 */
|
||||
|
||||
send_0_byte(isa, on); /* 20: spacing (0 = 25 kHz) */
|
||||
send_1_byte(isa, on); /* 21: spacing (1 = 25 kHz) */
|
||||
send_0_byte(isa, on); /* 22: spacing (0 = 25 kHz) */
|
||||
send_1_byte(isa, on); /* 23: AM/FM (FM = 1, always) */
|
||||
|
||||
outb(0xd0 + on, isa->io); /* volume steady + sigstr */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -295,7 +295,8 @@ static int vidioc_g_tuner(struct file *file, void *priv,
|
|||
v->type = V4L2_TUNER_RADIO;
|
||||
v->rangelow = FREQ_MIN * FREQ_MUL;
|
||||
v->rangehigh = FREQ_MAX * FREQ_MUL;
|
||||
v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
|
||||
v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
|
||||
V4L2_TUNER_CAP_HWSEEK_WRAP;
|
||||
v->rxsubchans = is_stereo ? V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
|
||||
v->audmode = radio->stereo ?
|
||||
V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO;
|
||||
|
|
@ -372,7 +373,7 @@ static int vidioc_s_hw_freq_seek(struct file *file, void *priv,
|
|||
timeout = jiffies + msecs_to_jiffies(30000);
|
||||
for (;;) {
|
||||
if (time_after(jiffies, timeout)) {
|
||||
retval = -EAGAIN;
|
||||
retval = -ENODATA;
|
||||
break;
|
||||
}
|
||||
if (schedule_timeout_interruptible(msecs_to_jiffies(10))) {
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <linux/io.h> /* outb, outb_p */
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
#include "lm7000.h"
|
||||
|
||||
MODULE_AUTHOR("Petr Vandrovec, [email protected] and M. Kirkwood");
|
||||
MODULE_DESCRIPTION("A driver for the SF16-FMI, SF16-FMP and SF16-FMD radio.");
|
||||
|
|
@ -54,31 +55,33 @@ static struct fmi fmi_card;
|
|||
static struct pnp_dev *dev;
|
||||
bool pnp_attached;
|
||||
|
||||
/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
|
||||
/* It is only useful to give freq in interval of 800 (=0.05Mhz),
|
||||
* other bits will be truncated, e.g 92.7400016 -> 92.7, but
|
||||
* 92.7400017 -> 92.75
|
||||
*/
|
||||
#define RSF16_ENCODE(x) ((x) / 800 + 214)
|
||||
#define RSF16_MINFREQ (87 * 16000)
|
||||
#define RSF16_MAXFREQ (108 * 16000)
|
||||
|
||||
static void outbits(int bits, unsigned int data, int io)
|
||||
#define FMI_BIT_TUN_CE (1 << 0)
|
||||
#define FMI_BIT_TUN_CLK (1 << 1)
|
||||
#define FMI_BIT_TUN_DATA (1 << 2)
|
||||
#define FMI_BIT_VOL_SW (1 << 3)
|
||||
#define FMI_BIT_TUN_STRQ (1 << 4)
|
||||
|
||||
void fmi_set_pins(void *handle, u8 pins)
|
||||
{
|
||||
while (bits--) {
|
||||
if (data & 1) {
|
||||
outb(5, io);
|
||||
udelay(6);
|
||||
outb(7, io);
|
||||
udelay(6);
|
||||
} else {
|
||||
outb(1, io);
|
||||
udelay(6);
|
||||
outb(3, io);
|
||||
udelay(6);
|
||||
}
|
||||
data >>= 1;
|
||||
}
|
||||
struct fmi *fmi = handle;
|
||||
u8 bits = FMI_BIT_TUN_STRQ;
|
||||
|
||||
if (!fmi->mute)
|
||||
bits |= FMI_BIT_VOL_SW;
|
||||
|
||||
if (pins & LM7000_DATA)
|
||||
bits |= FMI_BIT_TUN_DATA;
|
||||
if (pins & LM7000_CLK)
|
||||
bits |= FMI_BIT_TUN_CLK;
|
||||
if (pins & LM7000_CE)
|
||||
bits |= FMI_BIT_TUN_CE;
|
||||
|
||||
mutex_lock(&fmi->lock);
|
||||
outb_p(bits, fmi->io);
|
||||
mutex_unlock(&fmi->lock);
|
||||
}
|
||||
|
||||
static inline void fmi_mute(struct fmi *fmi)
|
||||
|
|
@ -95,20 +98,6 @@ static inline void fmi_unmute(struct fmi *fmi)
|
|||
mutex_unlock(&fmi->lock);
|
||||
}
|
||||
|
||||
static inline int fmi_setfreq(struct fmi *fmi, unsigned long freq)
|
||||
{
|
||||
mutex_lock(&fmi->lock);
|
||||
fmi->curfreq = freq;
|
||||
|
||||
outbits(16, RSF16_ENCODE(freq), fmi->io);
|
||||
outbits(8, 0xC0, fmi->io);
|
||||
msleep(143); /* was schedule_timeout(HZ/7) */
|
||||
mutex_unlock(&fmi->lock);
|
||||
if (!fmi->mute)
|
||||
fmi_unmute(fmi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int fmi_getsigstr(struct fmi *fmi)
|
||||
{
|
||||
int val;
|
||||
|
|
@ -173,7 +162,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
|
|||
return -EINVAL;
|
||||
/* rounding in steps of 800 to match the freq
|
||||
that will be used */
|
||||
fmi_setfreq(fmi, (f->frequency / 800) * 800);
|
||||
lm7000_set_freq((f->frequency / 800) * 800, fmi, fmi_set_pins);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1514,7 +1514,8 @@ static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
|
|||
tuner->rangehigh = WL1273_FREQ(WL1273_BAND_OTHER_HIGH);
|
||||
|
||||
tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_RDS |
|
||||
V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS_BLOCK_IO;
|
||||
V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS_BLOCK_IO |
|
||||
V4L2_TUNER_CAP_HWSEEK_BOUNDED | V4L2_TUNER_CAP_HWSEEK_WRAP;
|
||||
|
||||
if (radio->stereo)
|
||||
tuner->audmode = V4L2_TUNER_MODE_STEREO;
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ stop:
|
|||
|
||||
/* try again, if timed out */
|
||||
if (retval == 0 && timed_out)
|
||||
return -EAGAIN;
|
||||
return -ENODATA;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -596,7 +596,9 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
|
|||
strcpy(tuner->name, "FM");
|
||||
tuner->type = V4L2_TUNER_RADIO;
|
||||
tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
|
||||
V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO;
|
||||
V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO |
|
||||
V4L2_TUNER_CAP_HWSEEK_BOUNDED |
|
||||
V4L2_TUNER_CAP_HWSEEK_WRAP;
|
||||
|
||||
/* range limits */
|
||||
switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
|
||||
|
|
|
|||
|
|
@ -251,7 +251,7 @@ again:
|
|||
if (!timeleft) {
|
||||
fmerr("Timeout(%d sec),didn't get tune ended int\n",
|
||||
jiffies_to_msecs(FM_DRV_RX_SEEK_TIMEOUT) / 1000);
|
||||
return -ETIMEDOUT;
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
int_reason = fmdev->irq_info.flag & (FM_TUNE_COMPLETE | FM_BAND_LIMIT);
|
||||
|
|
|
|||
|
|
@ -285,7 +285,9 @@ static int fm_v4l2_vidioc_g_tuner(struct file *file, void *priv,
|
|||
tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO |
|
||||
((fmdev->rx.rds.flag == FM_RDS_ENABLE) ? V4L2_TUNER_SUB_RDS : 0);
|
||||
tuner->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS |
|
||||
V4L2_TUNER_CAP_LOW;
|
||||
V4L2_TUNER_CAP_LOW |
|
||||
V4L2_TUNER_CAP_HWSEEK_BOUNDED |
|
||||
V4L2_TUNER_CAP_HWSEEK_WRAP;
|
||||
tuner->audmode = (stereo_mono_mode ?
|
||||
V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,21 @@
|
|||
menuconfig RC_CORE
|
||||
tristate "Remote Controller adapters"
|
||||
depends on INPUT
|
||||
default INPUT
|
||||
---help---
|
||||
Enable support for Remote Controllers on Linux. This is
|
||||
needed in order to support several video capture adapters,
|
||||
standalone IR receivers/transmitters, and RF receivers.
|
||||
|
||||
Enable this option if you have a video capture board even
|
||||
if you don't need IR, as otherwise, you may not be able to
|
||||
compile the driver for your adapter.
|
||||
|
||||
if RC_CORE
|
||||
|
||||
config LIRC
|
||||
config RC_CORE
|
||||
tristate
|
||||
depends on MEDIA_RC_SUPPORT
|
||||
depends on INPUT
|
||||
default y
|
||||
|
||||
source "drivers/media/rc/keymaps/Kconfig"
|
||||
|
||||
menuconfig RC_DECODERS
|
||||
bool "Remote controller decoders"
|
||||
depends on RC_CORE
|
||||
default y
|
||||
|
||||
if RC_DECODERS
|
||||
config LIRC
|
||||
tristate "LIRC interface driver"
|
||||
depends on RC_CORE
|
||||
|
||||
---help---
|
||||
Enable this option to build the Linux Infrared Remote
|
||||
Control (LIRC) core device interface driver. The LIRC
|
||||
|
|
@ -24,7 +23,16 @@ config LIRC
|
|||
LIRC daemon handles protocol decoding for IR reception and
|
||||
encoding for IR transmitting (aka "blasting").
|
||||
|
||||
source "drivers/media/rc/keymaps/Kconfig"
|
||||
config IR_LIRC_CODEC
|
||||
tristate "Enable IR to LIRC bridge"
|
||||
depends on RC_CORE
|
||||
depends on LIRC
|
||||
default y
|
||||
|
||||
---help---
|
||||
Enable this option to pass raw IR to and from userspace via
|
||||
the LIRC interface.
|
||||
|
||||
|
||||
config IR_NEC_DECODER
|
||||
tristate "Enable IR raw decoder for the NEC protocol"
|
||||
|
|
@ -108,16 +116,13 @@ config IR_MCE_KBD_DECODER
|
|||
Enable this option if you have a Microsoft Remote Keyboard for
|
||||
Windows Media Center Edition, which you would like to use with
|
||||
a raw IR receiver in your system.
|
||||
endif #RC_DECODERS
|
||||
|
||||
config IR_LIRC_CODEC
|
||||
tristate "Enable IR to LIRC bridge"
|
||||
menuconfig RC_DEVICES
|
||||
bool "Remote Controller devices"
|
||||
depends on RC_CORE
|
||||
depends on LIRC
|
||||
default y
|
||||
|
||||
---help---
|
||||
Enable this option to pass raw IR to and from userspace via
|
||||
the LIRC interface.
|
||||
if RC_DEVICES
|
||||
|
||||
config RC_ATI_REMOTE
|
||||
tristate "ATI / X10 based USB RF remote controls"
|
||||
|
|
@ -276,4 +281,4 @@ config IR_GPIO_CIR
|
|||
To compile this driver as a module, choose M here: the module will
|
||||
be called gpio-ir-recv.
|
||||
|
||||
endif #RC_CORE
|
||||
endif #RC_DEVICES
|
||||
|
|
|
|||
|
|
@ -1018,6 +1018,8 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
|
|||
|
||||
spin_lock_init(&dev->hw_lock);
|
||||
|
||||
dev->hw_io = pnp_port_start(pnp_dev, 0);
|
||||
|
||||
pnp_set_drvdata(pnp_dev, dev);
|
||||
dev->pnp_dev = pnp_dev;
|
||||
|
||||
|
|
@ -1072,7 +1074,6 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
|
|||
|
||||
/* claim the resources */
|
||||
error = -EBUSY;
|
||||
dev->hw_io = pnp_port_start(pnp_dev, 0);
|
||||
if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) {
|
||||
dev->hw_io = -1;
|
||||
dev->irq = -1;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
* USA
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pnp.h>
|
||||
|
|
@ -110,30 +112,32 @@ static u8 fintek_cir_reg_read(struct fintek_dev *fintek, u8 offset)
|
|||
return val;
|
||||
}
|
||||
|
||||
#define pr_reg(text, ...) \
|
||||
printk(KERN_INFO KBUILD_MODNAME ": " text, ## __VA_ARGS__)
|
||||
|
||||
/* dump current cir register contents */
|
||||
static void cir_dump_regs(struct fintek_dev *fintek)
|
||||
{
|
||||
fintek_config_mode_enable(fintek);
|
||||
fintek_select_logical_dev(fintek, fintek->logical_dev_cir);
|
||||
|
||||
pr_reg("%s: Dump CIR logical device registers:\n", FINTEK_DRIVER_NAME);
|
||||
pr_reg(" * CR CIR BASE ADDR: 0x%x\n",
|
||||
(fintek_cr_read(fintek, CIR_CR_BASE_ADDR_HI) << 8) |
|
||||
pr_info("%s: Dump CIR logical device registers:\n", FINTEK_DRIVER_NAME);
|
||||
pr_info(" * CR CIR BASE ADDR: 0x%x\n",
|
||||
(fintek_cr_read(fintek, CIR_CR_BASE_ADDR_HI) << 8) |
|
||||
fintek_cr_read(fintek, CIR_CR_BASE_ADDR_LO));
|
||||
pr_reg(" * CR CIR IRQ NUM: 0x%x\n",
|
||||
fintek_cr_read(fintek, CIR_CR_IRQ_SEL));
|
||||
pr_info(" * CR CIR IRQ NUM: 0x%x\n",
|
||||
fintek_cr_read(fintek, CIR_CR_IRQ_SEL));
|
||||
|
||||
fintek_config_mode_disable(fintek);
|
||||
|
||||
pr_reg("%s: Dump CIR registers:\n", FINTEK_DRIVER_NAME);
|
||||
pr_reg(" * STATUS: 0x%x\n", fintek_cir_reg_read(fintek, CIR_STATUS));
|
||||
pr_reg(" * CONTROL: 0x%x\n", fintek_cir_reg_read(fintek, CIR_CONTROL));
|
||||
pr_reg(" * RX_DATA: 0x%x\n", fintek_cir_reg_read(fintek, CIR_RX_DATA));
|
||||
pr_reg(" * TX_CONTROL: 0x%x\n", fintek_cir_reg_read(fintek, CIR_TX_CONTROL));
|
||||
pr_reg(" * TX_DATA: 0x%x\n", fintek_cir_reg_read(fintek, CIR_TX_DATA));
|
||||
pr_info("%s: Dump CIR registers:\n", FINTEK_DRIVER_NAME);
|
||||
pr_info(" * STATUS: 0x%x\n",
|
||||
fintek_cir_reg_read(fintek, CIR_STATUS));
|
||||
pr_info(" * CONTROL: 0x%x\n",
|
||||
fintek_cir_reg_read(fintek, CIR_CONTROL));
|
||||
pr_info(" * RX_DATA: 0x%x\n",
|
||||
fintek_cir_reg_read(fintek, CIR_RX_DATA));
|
||||
pr_info(" * TX_CONTROL: 0x%x\n",
|
||||
fintek_cir_reg_read(fintek, CIR_TX_CONTROL));
|
||||
pr_info(" * TX_DATA: 0x%x\n",
|
||||
fintek_cir_reg_read(fintek, CIR_TX_DATA));
|
||||
}
|
||||
|
||||
/* detect hardware features */
|
||||
|
|
|
|||
|
|
@ -82,12 +82,21 @@ static int __devinit gpio_ir_recv_probe(struct platform_device *pdev)
|
|||
goto err_allocate_device;
|
||||
}
|
||||
|
||||
rcdev->priv = gpio_dev;
|
||||
rcdev->driver_type = RC_DRIVER_IR_RAW;
|
||||
rcdev->allowed_protos = RC_TYPE_ALL;
|
||||
rcdev->input_name = GPIO_IR_DEVICE_NAME;
|
||||
rcdev->input_phys = GPIO_IR_DEVICE_NAME "/input0";
|
||||
rcdev->input_id.bustype = BUS_HOST;
|
||||
rcdev->input_id.vendor = 0x0001;
|
||||
rcdev->input_id.product = 0x0001;
|
||||
rcdev->input_id.version = 0x0100;
|
||||
rcdev->dev.parent = &pdev->dev;
|
||||
rcdev->driver_name = GPIO_IR_DRIVER_NAME;
|
||||
rcdev->map_name = RC_MAP_EMPTY;
|
||||
if (pdata->allowed_protos)
|
||||
rcdev->allowed_protos = pdata->allowed_protos;
|
||||
else
|
||||
rcdev->allowed_protos = RC_TYPE_ALL;
|
||||
rcdev->map_name = pdata->map_name ?: RC_MAP_EMPTY;
|
||||
|
||||
gpio_dev->rcdev = rcdev;
|
||||
gpio_dev->gpio_nr = pdata->gpio_nr;
|
||||
|
|
@ -188,18 +197,7 @@ static struct platform_driver gpio_ir_recv_driver = {
|
|||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
static int __init gpio_ir_recv_init(void)
|
||||
{
|
||||
return platform_driver_register(&gpio_ir_recv_driver);
|
||||
}
|
||||
module_init(gpio_ir_recv_init);
|
||||
|
||||
static void __exit gpio_ir_recv_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&gpio_ir_recv_driver);
|
||||
}
|
||||
module_exit(gpio_ir_recv_exit);
|
||||
module_platform_driver(gpio_ir_recv_driver);
|
||||
|
||||
MODULE_DESCRIPTION("GPIO IR Receiver driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
* USA
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pnp.h>
|
||||
|
|
@ -123,43 +125,40 @@ static u8 nvt_cir_wake_reg_read(struct nvt_dev *nvt, u8 offset)
|
|||
return val;
|
||||
}
|
||||
|
||||
#define pr_reg(text, ...) \
|
||||
printk(KERN_INFO KBUILD_MODNAME ": " text, ## __VA_ARGS__)
|
||||
|
||||
/* dump current cir register contents */
|
||||
static void cir_dump_regs(struct nvt_dev *nvt)
|
||||
{
|
||||
nvt_efm_enable(nvt);
|
||||
nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR);
|
||||
|
||||
pr_reg("%s: Dump CIR logical device registers:\n", NVT_DRIVER_NAME);
|
||||
pr_reg(" * CR CIR ACTIVE : 0x%x\n",
|
||||
nvt_cr_read(nvt, CR_LOGICAL_DEV_EN));
|
||||
pr_reg(" * CR CIR BASE ADDR: 0x%x\n",
|
||||
(nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) |
|
||||
pr_info("%s: Dump CIR logical device registers:\n", NVT_DRIVER_NAME);
|
||||
pr_info(" * CR CIR ACTIVE : 0x%x\n",
|
||||
nvt_cr_read(nvt, CR_LOGICAL_DEV_EN));
|
||||
pr_info(" * CR CIR BASE ADDR: 0x%x\n",
|
||||
(nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) |
|
||||
nvt_cr_read(nvt, CR_CIR_BASE_ADDR_LO));
|
||||
pr_reg(" * CR CIR IRQ NUM: 0x%x\n",
|
||||
nvt_cr_read(nvt, CR_CIR_IRQ_RSRC));
|
||||
pr_info(" * CR CIR IRQ NUM: 0x%x\n",
|
||||
nvt_cr_read(nvt, CR_CIR_IRQ_RSRC));
|
||||
|
||||
nvt_efm_disable(nvt);
|
||||
|
||||
pr_reg("%s: Dump CIR registers:\n", NVT_DRIVER_NAME);
|
||||
pr_reg(" * IRCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRCON));
|
||||
pr_reg(" * IRSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRSTS));
|
||||
pr_reg(" * IREN: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IREN));
|
||||
pr_reg(" * RXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_RXFCONT));
|
||||
pr_reg(" * CP: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CP));
|
||||
pr_reg(" * CC: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CC));
|
||||
pr_reg(" * SLCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCH));
|
||||
pr_reg(" * SLCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCL));
|
||||
pr_reg(" * FIFOCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FIFOCON));
|
||||
pr_reg(" * IRFIFOSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFIFOSTS));
|
||||
pr_reg(" * SRXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SRXFIFO));
|
||||
pr_reg(" * TXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_TXFCONT));
|
||||
pr_reg(" * STXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_STXFIFO));
|
||||
pr_reg(" * FCCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCH));
|
||||
pr_reg(" * FCCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCL));
|
||||
pr_reg(" * IRFSM: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFSM));
|
||||
pr_info("%s: Dump CIR registers:\n", NVT_DRIVER_NAME);
|
||||
pr_info(" * IRCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRCON));
|
||||
pr_info(" * IRSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRSTS));
|
||||
pr_info(" * IREN: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IREN));
|
||||
pr_info(" * RXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_RXFCONT));
|
||||
pr_info(" * CP: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CP));
|
||||
pr_info(" * CC: 0x%x\n", nvt_cir_reg_read(nvt, CIR_CC));
|
||||
pr_info(" * SLCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCH));
|
||||
pr_info(" * SLCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SLCL));
|
||||
pr_info(" * FIFOCON: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FIFOCON));
|
||||
pr_info(" * IRFIFOSTS: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFIFOSTS));
|
||||
pr_info(" * SRXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_SRXFIFO));
|
||||
pr_info(" * TXFCONT: 0x%x\n", nvt_cir_reg_read(nvt, CIR_TXFCONT));
|
||||
pr_info(" * STXFIFO: 0x%x\n", nvt_cir_reg_read(nvt, CIR_STXFIFO));
|
||||
pr_info(" * FCCH: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCH));
|
||||
pr_info(" * FCCL: 0x%x\n", nvt_cir_reg_read(nvt, CIR_FCCL));
|
||||
pr_info(" * IRFSM: 0x%x\n", nvt_cir_reg_read(nvt, CIR_IRFSM));
|
||||
}
|
||||
|
||||
/* dump current cir wake register contents */
|
||||
|
|
@ -170,59 +169,59 @@ static void cir_wake_dump_regs(struct nvt_dev *nvt)
|
|||
nvt_efm_enable(nvt);
|
||||
nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR_WAKE);
|
||||
|
||||
pr_reg("%s: Dump CIR WAKE logical device registers:\n",
|
||||
NVT_DRIVER_NAME);
|
||||
pr_reg(" * CR CIR WAKE ACTIVE : 0x%x\n",
|
||||
nvt_cr_read(nvt, CR_LOGICAL_DEV_EN));
|
||||
pr_reg(" * CR CIR WAKE BASE ADDR: 0x%x\n",
|
||||
(nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) |
|
||||
pr_info("%s: Dump CIR WAKE logical device registers:\n",
|
||||
NVT_DRIVER_NAME);
|
||||
pr_info(" * CR CIR WAKE ACTIVE : 0x%x\n",
|
||||
nvt_cr_read(nvt, CR_LOGICAL_DEV_EN));
|
||||
pr_info(" * CR CIR WAKE BASE ADDR: 0x%x\n",
|
||||
(nvt_cr_read(nvt, CR_CIR_BASE_ADDR_HI) << 8) |
|
||||
nvt_cr_read(nvt, CR_CIR_BASE_ADDR_LO));
|
||||
pr_reg(" * CR CIR WAKE IRQ NUM: 0x%x\n",
|
||||
nvt_cr_read(nvt, CR_CIR_IRQ_RSRC));
|
||||
pr_info(" * CR CIR WAKE IRQ NUM: 0x%x\n",
|
||||
nvt_cr_read(nvt, CR_CIR_IRQ_RSRC));
|
||||
|
||||
nvt_efm_disable(nvt);
|
||||
|
||||
pr_reg("%s: Dump CIR WAKE registers\n", NVT_DRIVER_NAME);
|
||||
pr_reg(" * IRCON: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRCON));
|
||||
pr_reg(" * IRSTS: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRSTS));
|
||||
pr_reg(" * IREN: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_IREN));
|
||||
pr_reg(" * FIFO CMP DEEP: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_DEEP));
|
||||
pr_reg(" * FIFO CMP TOL: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_TOL));
|
||||
pr_reg(" * FIFO COUNT: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_COUNT));
|
||||
pr_reg(" * SLCH: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCH));
|
||||
pr_reg(" * SLCL: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCL));
|
||||
pr_reg(" * FIFOCON: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFOCON));
|
||||
pr_reg(" * SRXFSTS: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_SRXFSTS));
|
||||
pr_reg(" * SAMPLE RX FIFO: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_SAMPLE_RX_FIFO));
|
||||
pr_reg(" * WR FIFO DATA: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_WR_FIFO_DATA));
|
||||
pr_reg(" * RD FIFO ONLY: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY));
|
||||
pr_reg(" * RD FIFO ONLY IDX: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY_IDX));
|
||||
pr_reg(" * FIFO IGNORE: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_IGNORE));
|
||||
pr_reg(" * IRFSM: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRFSM));
|
||||
pr_info("%s: Dump CIR WAKE registers\n", NVT_DRIVER_NAME);
|
||||
pr_info(" * IRCON: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRCON));
|
||||
pr_info(" * IRSTS: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRSTS));
|
||||
pr_info(" * IREN: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_IREN));
|
||||
pr_info(" * FIFO CMP DEEP: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_DEEP));
|
||||
pr_info(" * FIFO CMP TOL: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_CMP_TOL));
|
||||
pr_info(" * FIFO COUNT: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_COUNT));
|
||||
pr_info(" * SLCH: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCH));
|
||||
pr_info(" * SLCL: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_SLCL));
|
||||
pr_info(" * FIFOCON: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFOCON));
|
||||
pr_info(" * SRXFSTS: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_SRXFSTS));
|
||||
pr_info(" * SAMPLE RX FIFO: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_SAMPLE_RX_FIFO));
|
||||
pr_info(" * WR FIFO DATA: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_WR_FIFO_DATA));
|
||||
pr_info(" * RD FIFO ONLY: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY));
|
||||
pr_info(" * RD FIFO ONLY IDX: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY_IDX));
|
||||
pr_info(" * FIFO IGNORE: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_IGNORE));
|
||||
pr_info(" * IRFSM: 0x%x\n",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRFSM));
|
||||
|
||||
fifo_len = nvt_cir_wake_reg_read(nvt, CIR_WAKE_FIFO_COUNT);
|
||||
pr_reg("%s: Dump CIR WAKE FIFO (len %d)\n", NVT_DRIVER_NAME, fifo_len);
|
||||
pr_reg("* Contents = ");
|
||||
pr_info("%s: Dump CIR WAKE FIFO (len %d)\n", NVT_DRIVER_NAME, fifo_len);
|
||||
pr_info("* Contents =");
|
||||
for (i = 0; i < fifo_len; i++)
|
||||
printk(KERN_CONT "%02x ",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY));
|
||||
printk(KERN_CONT "\n");
|
||||
pr_cont(" %02x",
|
||||
nvt_cir_wake_reg_read(nvt, CIR_WAKE_RD_FIFO_ONLY));
|
||||
pr_cont("\n");
|
||||
}
|
||||
|
||||
/* detect hardware features */
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
config VIDEO_V4L2
|
||||
tristate
|
||||
depends on VIDEO_DEV && VIDEO_V4L2_COMMON
|
||||
default VIDEO_DEV && VIDEO_V4L2_COMMON
|
||||
default y
|
||||
|
||||
config VIDEOBUF_GEN
|
||||
tristate
|
||||
|
|
@ -73,6 +73,7 @@ config VIDEOBUF2_DMA_SG
|
|||
menuconfig VIDEO_CAPTURE_DRIVERS
|
||||
bool "Video capture adapters"
|
||||
depends on VIDEO_V4L2
|
||||
depends on MEDIA_CAMERA_SUPPORT || MEDIA_ANALOG_TV_SUPPORT
|
||||
default y
|
||||
---help---
|
||||
Say Y here to enable selecting the video adapters for
|
||||
|
|
@ -461,6 +462,15 @@ config VIDEO_ADV7343
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called adv7343.
|
||||
|
||||
config VIDEO_ADV7393
|
||||
tristate "ADV7393 video encoder"
|
||||
depends on I2C
|
||||
help
|
||||
Support for Analog Devices I2C bus based ADV7393 encoder.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called adv7393.
|
||||
|
||||
config VIDEO_AK881X
|
||||
tristate "AK8813/AK8814 video encoders"
|
||||
depends on I2C
|
||||
|
|
@ -478,6 +488,7 @@ config VIDEO_SMIAPP_PLL
|
|||
config VIDEO_OV7670
|
||||
tristate "OmniVision OV7670 sensor support"
|
||||
depends on I2C && VIDEO_V4L2
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
---help---
|
||||
This is a Video4Linux2 sensor-level driver for the OmniVision
|
||||
OV7670 VGA camera. It currently only works with the M88ALP01
|
||||
|
|
@ -486,6 +497,7 @@ config VIDEO_OV7670
|
|||
config VIDEO_VS6624
|
||||
tristate "ST VS6624 sensor support"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
---help---
|
||||
This is a Video4Linux2 sensor-level driver for the ST VS6624
|
||||
camera.
|
||||
|
|
@ -496,6 +508,7 @@ config VIDEO_VS6624
|
|||
config VIDEO_MT9M032
|
||||
tristate "MT9M032 camera sensor support"
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
select VIDEO_APTINA_PLL
|
||||
---help---
|
||||
This driver supports MT9M032 camera sensors from Aptina, monochrome
|
||||
|
|
@ -504,6 +517,7 @@ config VIDEO_MT9M032
|
|||
config VIDEO_MT9P031
|
||||
tristate "Aptina MT9P031 support"
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
select VIDEO_APTINA_PLL
|
||||
---help---
|
||||
This is a Video4Linux2 sensor-level driver for the Aptina
|
||||
|
|
@ -512,6 +526,7 @@ config VIDEO_MT9P031
|
|||
config VIDEO_MT9T001
|
||||
tristate "Aptina MT9T001 support"
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
---help---
|
||||
This is a Video4Linux2 sensor-level driver for the Aptina
|
||||
(Micron) mt0t001 3 Mpixel camera.
|
||||
|
|
@ -519,6 +534,7 @@ config VIDEO_MT9T001
|
|||
config VIDEO_MT9V011
|
||||
tristate "Micron mt9v011 sensor support"
|
||||
depends on I2C && VIDEO_V4L2
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
---help---
|
||||
This is a Video4Linux2 sensor-level driver for the Micron
|
||||
mt0v011 1.3 Mpixel camera. It currently only works with the
|
||||
|
|
@ -527,6 +543,7 @@ config VIDEO_MT9V011
|
|||
config VIDEO_MT9V032
|
||||
tristate "Micron MT9V032 sensor support"
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
---help---
|
||||
This is a Video4Linux2 sensor-level driver for the Micron
|
||||
MT9V032 752x480 CMOS sensor.
|
||||
|
|
@ -534,6 +551,7 @@ config VIDEO_MT9V032
|
|||
config VIDEO_TCM825X
|
||||
tristate "TCM825x camera sensor support"
|
||||
depends on I2C && VIDEO_V4L2
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
---help---
|
||||
This is a driver for the Toshiba TCM825x VGA camera sensor.
|
||||
It is used for example in Nokia N800.
|
||||
|
|
@ -541,12 +559,14 @@ config VIDEO_TCM825X
|
|||
config VIDEO_SR030PC30
|
||||
tristate "Siliconfile SR030PC30 sensor support"
|
||||
depends on I2C && VIDEO_V4L2
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
---help---
|
||||
This driver supports SR030PC30 VGA camera from Siliconfile
|
||||
|
||||
config VIDEO_NOON010PC30
|
||||
tristate "Siliconfile NOON010PC30 sensor support"
|
||||
depends on I2C && VIDEO_V4L2 && EXPERIMENTAL && VIDEO_V4L2_SUBDEV_API
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
---help---
|
||||
This driver supports NOON010PC30 CIF camera from Siliconfile
|
||||
|
||||
|
|
@ -554,6 +574,7 @@ source "drivers/media/video/m5mols/Kconfig"
|
|||
|
||||
config VIDEO_S5K6AA
|
||||
tristate "Samsung S5K6AAFX sensor support"
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
---help---
|
||||
This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M
|
||||
|
|
@ -566,6 +587,7 @@ comment "Flash devices"
|
|||
config VIDEO_ADP1653
|
||||
tristate "ADP1653 flash support"
|
||||
depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
---help---
|
||||
This is a driver for the ADP1653 flash controller. It is used for
|
||||
example in Nokia N900.
|
||||
|
|
@ -573,6 +595,7 @@ config VIDEO_ADP1653
|
|||
config VIDEO_AS3645A
|
||||
tristate "AS3645A flash driver support"
|
||||
depends on I2C && VIDEO_V4L2 && MEDIA_CONTROLLER
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
---help---
|
||||
This is a driver for the AS3645A and LM3555 flash controllers. It has
|
||||
build in control for flash, torch and indicator LEDs.
|
||||
|
|
@ -647,30 +670,14 @@ menuconfig V4L_USB_DRIVERS
|
|||
depends on USB
|
||||
default y
|
||||
|
||||
if V4L_USB_DRIVERS
|
||||
if V4L_USB_DRIVERS && MEDIA_CAMERA_SUPPORT
|
||||
|
||||
source "drivers/media/video/au0828/Kconfig"
|
||||
comment "Webcam devices"
|
||||
|
||||
source "drivers/media/video/uvc/Kconfig"
|
||||
|
||||
source "drivers/media/video/gspca/Kconfig"
|
||||
|
||||
source "drivers/media/video/pvrusb2/Kconfig"
|
||||
|
||||
source "drivers/media/video/hdpvr/Kconfig"
|
||||
|
||||
source "drivers/media/video/em28xx/Kconfig"
|
||||
|
||||
source "drivers/media/video/tlg2300/Kconfig"
|
||||
|
||||
source "drivers/media/video/cx231xx/Kconfig"
|
||||
|
||||
source "drivers/media/video/tm6000/Kconfig"
|
||||
|
||||
source "drivers/media/video/usbvision/Kconfig"
|
||||
|
||||
source "drivers/media/video/sn9c102/Kconfig"
|
||||
|
||||
source "drivers/media/video/pwc/Kconfig"
|
||||
|
||||
source "drivers/media/video/cpia2/Kconfig"
|
||||
|
|
@ -711,15 +718,46 @@ config USB_S2255
|
|||
Say Y here if you want support for the Sensoray 2255 USB device.
|
||||
This driver can be compiled as a module, called s2255drv.
|
||||
|
||||
source "drivers/media/video/sn9c102/Kconfig"
|
||||
|
||||
endif # V4L_USB_DRIVERS && MEDIA_CAMERA_SUPPORT
|
||||
|
||||
if V4L_USB_DRIVERS
|
||||
|
||||
comment "Webcam and/or TV USB devices"
|
||||
|
||||
source "drivers/media/video/em28xx/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
if V4L_USB_DRIVERS && MEDIA_ANALOG_TV_SUPPORT
|
||||
|
||||
comment "TV USB devices"
|
||||
|
||||
source "drivers/media/video/au0828/Kconfig"
|
||||
|
||||
source "drivers/media/video/pvrusb2/Kconfig"
|
||||
|
||||
source "drivers/media/video/hdpvr/Kconfig"
|
||||
|
||||
source "drivers/media/video/tlg2300/Kconfig"
|
||||
|
||||
source "drivers/media/video/cx231xx/Kconfig"
|
||||
|
||||
source "drivers/media/video/tm6000/Kconfig"
|
||||
|
||||
source "drivers/media/video/usbvision/Kconfig"
|
||||
|
||||
endif # V4L_USB_DRIVERS
|
||||
|
||||
#
|
||||
# PCI drivers configuration
|
||||
# PCI drivers configuration - No devices here are for webcams
|
||||
#
|
||||
|
||||
menuconfig V4L_PCI_DRIVERS
|
||||
bool "V4L PCI(e) devices"
|
||||
depends on PCI
|
||||
depends on MEDIA_ANALOG_TV_SUPPORT
|
||||
default y
|
||||
---help---
|
||||
Say Y here to enable support for these PCI(e) drivers.
|
||||
|
|
@ -814,11 +852,13 @@ endif # V4L_PCI_DRIVERS
|
|||
|
||||
#
|
||||
# ISA & parallel port drivers configuration
|
||||
# All devices here are webcam or grabber devices
|
||||
#
|
||||
|
||||
menuconfig V4L_ISA_PARPORT_DRIVERS
|
||||
bool "V4L ISA and parallel port devices"
|
||||
depends on ISA || PARPORT
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
default n
|
||||
---help---
|
||||
Say Y here to enable support for these ISA and parallel port drivers.
|
||||
|
|
@ -871,8 +911,13 @@ config VIDEO_W9966
|
|||
|
||||
endif # V4L_ISA_PARPORT_DRIVERS
|
||||
|
||||
#
|
||||
# Platform drivers
|
||||
# All drivers here are currently for webcam support
|
||||
|
||||
menuconfig V4L_PLATFORM_DRIVERS
|
||||
bool "V4L platform devices"
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
default n
|
||||
---help---
|
||||
Say Y here to enable support for platform-specific V4L drivers.
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
|
|||
obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o
|
||||
obj-$(CONFIG_VIDEO_ADV7183) += adv7183.o
|
||||
obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o
|
||||
obj-$(CONFIG_VIDEO_ADV7393) += adv7393.o
|
||||
obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
|
||||
obj-$(CONFIG_VIDEO_VS6624) += vs6624.o
|
||||
obj-$(CONFIG_VIDEO_BT819) += bt819.o
|
||||
|
|
|
|||
487
drivers/media/video/adv7393.c
Normal file
487
drivers/media/video/adv7393.c
Normal file
|
|
@ -0,0 +1,487 @@
|
|||
/*
|
||||
* adv7393 - ADV7393 Video Encoder Driver
|
||||
*
|
||||
* The encoder hardware does not support SECAM.
|
||||
*
|
||||
* Copyright (C) 2010-2012 ADVANSEE - http://www.advansee.com/
|
||||
* Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
|
||||
*
|
||||
* Based on ADV7343 driver,
|
||||
*
|
||||
* Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.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 version 2.
|
||||
*
|
||||
* This program is distributed .as is. WITHOUT ANY WARRANTY of any
|
||||
* kind, whether express or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <media/adv7393.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-chip-ident.h>
|
||||
#include <media/v4l2-ctrls.h>
|
||||
|
||||
#include "adv7393_regs.h"
|
||||
|
||||
MODULE_DESCRIPTION("ADV7393 video encoder driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static bool debug;
|
||||
module_param(debug, bool, 0644);
|
||||
MODULE_PARM_DESC(debug, "Debug level 0-1");
|
||||
|
||||
struct adv7393_state {
|
||||
struct v4l2_subdev sd;
|
||||
struct v4l2_ctrl_handler hdl;
|
||||
u8 reg00;
|
||||
u8 reg01;
|
||||
u8 reg02;
|
||||
u8 reg35;
|
||||
u8 reg80;
|
||||
u8 reg82;
|
||||
u32 output;
|
||||
v4l2_std_id std;
|
||||
};
|
||||
|
||||
static inline struct adv7393_state *to_state(struct v4l2_subdev *sd)
|
||||
{
|
||||
return container_of(sd, struct adv7393_state, sd);
|
||||
}
|
||||
|
||||
static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
return &container_of(ctrl->handler, struct adv7393_state, hdl)->sd;
|
||||
}
|
||||
|
||||
static inline int adv7393_write(struct v4l2_subdev *sd, u8 reg, u8 value)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
|
||||
return i2c_smbus_write_byte_data(client, reg, value);
|
||||
}
|
||||
|
||||
static const u8 adv7393_init_reg_val[] = {
|
||||
ADV7393_SOFT_RESET, ADV7393_SOFT_RESET_DEFAULT,
|
||||
ADV7393_POWER_MODE_REG, ADV7393_POWER_MODE_REG_DEFAULT,
|
||||
|
||||
ADV7393_HD_MODE_REG1, ADV7393_HD_MODE_REG1_DEFAULT,
|
||||
ADV7393_HD_MODE_REG2, ADV7393_HD_MODE_REG2_DEFAULT,
|
||||
ADV7393_HD_MODE_REG3, ADV7393_HD_MODE_REG3_DEFAULT,
|
||||
ADV7393_HD_MODE_REG4, ADV7393_HD_MODE_REG4_DEFAULT,
|
||||
ADV7393_HD_MODE_REG5, ADV7393_HD_MODE_REG5_DEFAULT,
|
||||
ADV7393_HD_MODE_REG6, ADV7393_HD_MODE_REG6_DEFAULT,
|
||||
ADV7393_HD_MODE_REG7, ADV7393_HD_MODE_REG7_DEFAULT,
|
||||
|
||||
ADV7393_SD_MODE_REG1, ADV7393_SD_MODE_REG1_DEFAULT,
|
||||
ADV7393_SD_MODE_REG2, ADV7393_SD_MODE_REG2_DEFAULT,
|
||||
ADV7393_SD_MODE_REG3, ADV7393_SD_MODE_REG3_DEFAULT,
|
||||
ADV7393_SD_MODE_REG4, ADV7393_SD_MODE_REG4_DEFAULT,
|
||||
ADV7393_SD_MODE_REG5, ADV7393_SD_MODE_REG5_DEFAULT,
|
||||
ADV7393_SD_MODE_REG6, ADV7393_SD_MODE_REG6_DEFAULT,
|
||||
ADV7393_SD_MODE_REG7, ADV7393_SD_MODE_REG7_DEFAULT,
|
||||
ADV7393_SD_MODE_REG8, ADV7393_SD_MODE_REG8_DEFAULT,
|
||||
|
||||
ADV7393_SD_TIMING_REG0, ADV7393_SD_TIMING_REG0_DEFAULT,
|
||||
|
||||
ADV7393_SD_HUE_ADJUST, ADV7393_SD_HUE_ADJUST_DEFAULT,
|
||||
ADV7393_SD_CGMS_WSS0, ADV7393_SD_CGMS_WSS0_DEFAULT,
|
||||
ADV7393_SD_BRIGHTNESS_WSS, ADV7393_SD_BRIGHTNESS_WSS_DEFAULT,
|
||||
};
|
||||
|
||||
/*
|
||||
* 2^32
|
||||
* FSC(reg) = FSC (HZ) * --------
|
||||
* 27000000
|
||||
*/
|
||||
static const struct adv7393_std_info stdinfo[] = {
|
||||
{
|
||||
/* FSC(Hz) = 4,433,618.75 Hz */
|
||||
SD_STD_NTSC, 705268427, V4L2_STD_NTSC_443,
|
||||
}, {
|
||||
/* FSC(Hz) = 3,579,545.45 Hz */
|
||||
SD_STD_NTSC, 569408542, V4L2_STD_NTSC,
|
||||
}, {
|
||||
/* FSC(Hz) = 3,575,611.00 Hz */
|
||||
SD_STD_PAL_M, 568782678, V4L2_STD_PAL_M,
|
||||
}, {
|
||||
/* FSC(Hz) = 3,582,056.00 Hz */
|
||||
SD_STD_PAL_N, 569807903, V4L2_STD_PAL_Nc,
|
||||
}, {
|
||||
/* FSC(Hz) = 4,433,618.75 Hz */
|
||||
SD_STD_PAL_N, 705268427, V4L2_STD_PAL_N,
|
||||
}, {
|
||||
/* FSC(Hz) = 4,433,618.75 Hz */
|
||||
SD_STD_PAL_M, 705268427, V4L2_STD_PAL_60,
|
||||
}, {
|
||||
/* FSC(Hz) = 4,433,618.75 Hz */
|
||||
SD_STD_PAL_BDGHI, 705268427, V4L2_STD_PAL,
|
||||
},
|
||||
};
|
||||
|
||||
static int adv7393_setstd(struct v4l2_subdev *sd, v4l2_std_id std)
|
||||
{
|
||||
struct adv7393_state *state = to_state(sd);
|
||||
const struct adv7393_std_info *std_info;
|
||||
int num_std;
|
||||
u8 reg;
|
||||
u32 val;
|
||||
int err = 0;
|
||||
int i;
|
||||
|
||||
num_std = ARRAY_SIZE(stdinfo);
|
||||
|
||||
for (i = 0; i < num_std; i++) {
|
||||
if (stdinfo[i].stdid & std)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == num_std) {
|
||||
v4l2_dbg(1, debug, sd,
|
||||
"Invalid std or std is not supported: %llx\n",
|
||||
(unsigned long long)std);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
std_info = &stdinfo[i];
|
||||
|
||||
/* Set the standard */
|
||||
val = state->reg80 & ~SD_STD_MASK;
|
||||
val |= std_info->standard_val3;
|
||||
err = adv7393_write(sd, ADV7393_SD_MODE_REG1, val);
|
||||
if (err < 0)
|
||||
goto setstd_exit;
|
||||
|
||||
state->reg80 = val;
|
||||
|
||||
/* Configure the input mode register */
|
||||
val = state->reg01 & ~INPUT_MODE_MASK;
|
||||
val |= SD_INPUT_MODE;
|
||||
err = adv7393_write(sd, ADV7393_MODE_SELECT_REG, val);
|
||||
if (err < 0)
|
||||
goto setstd_exit;
|
||||
|
||||
state->reg01 = val;
|
||||
|
||||
/* Program the sub carrier frequency registers */
|
||||
val = std_info->fsc_val;
|
||||
for (reg = ADV7393_FSC_REG0; reg <= ADV7393_FSC_REG3; reg++) {
|
||||
err = adv7393_write(sd, reg, val);
|
||||
if (err < 0)
|
||||
goto setstd_exit;
|
||||
val >>= 8;
|
||||
}
|
||||
|
||||
val = state->reg82;
|
||||
|
||||
/* Pedestal settings */
|
||||
if (std & (V4L2_STD_NTSC | V4L2_STD_NTSC_443))
|
||||
val |= SD_PEDESTAL_EN;
|
||||
else
|
||||
val &= SD_PEDESTAL_DI;
|
||||
|
||||
err = adv7393_write(sd, ADV7393_SD_MODE_REG2, val);
|
||||
if (err < 0)
|
||||
goto setstd_exit;
|
||||
|
||||
state->reg82 = val;
|
||||
|
||||
setstd_exit:
|
||||
if (err != 0)
|
||||
v4l2_err(sd, "Error setting std, write failed\n");
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int adv7393_setoutput(struct v4l2_subdev *sd, u32 output_type)
|
||||
{
|
||||
struct adv7393_state *state = to_state(sd);
|
||||
u8 val;
|
||||
int err = 0;
|
||||
|
||||
if (output_type > ADV7393_SVIDEO_ID) {
|
||||
v4l2_dbg(1, debug, sd,
|
||||
"Invalid output type or output type not supported:%d\n",
|
||||
output_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Enable Appropriate DAC */
|
||||
val = state->reg00 & 0x03;
|
||||
|
||||
if (output_type == ADV7393_COMPOSITE_ID)
|
||||
val |= ADV7393_COMPOSITE_POWER_VALUE;
|
||||
else if (output_type == ADV7393_COMPONENT_ID)
|
||||
val |= ADV7393_COMPONENT_POWER_VALUE;
|
||||
else
|
||||
val |= ADV7393_SVIDEO_POWER_VALUE;
|
||||
|
||||
err = adv7393_write(sd, ADV7393_POWER_MODE_REG, val);
|
||||
if (err < 0)
|
||||
goto setoutput_exit;
|
||||
|
||||
state->reg00 = val;
|
||||
|
||||
/* Enable YUV output */
|
||||
val = state->reg02 | YUV_OUTPUT_SELECT;
|
||||
err = adv7393_write(sd, ADV7393_MODE_REG0, val);
|
||||
if (err < 0)
|
||||
goto setoutput_exit;
|
||||
|
||||
state->reg02 = val;
|
||||
|
||||
/* configure SD DAC Output 1 bit */
|
||||
val = state->reg82;
|
||||
if (output_type == ADV7393_COMPONENT_ID)
|
||||
val &= SD_DAC_OUT1_DI;
|
||||
else
|
||||
val |= SD_DAC_OUT1_EN;
|
||||
err = adv7393_write(sd, ADV7393_SD_MODE_REG2, val);
|
||||
if (err < 0)
|
||||
goto setoutput_exit;
|
||||
|
||||
state->reg82 = val;
|
||||
|
||||
/* configure ED/HD Color DAC Swap bit to zero */
|
||||
val = state->reg35 & HD_DAC_SWAP_DI;
|
||||
err = adv7393_write(sd, ADV7393_HD_MODE_REG6, val);
|
||||
if (err < 0)
|
||||
goto setoutput_exit;
|
||||
|
||||
state->reg35 = val;
|
||||
|
||||
setoutput_exit:
|
||||
if (err != 0)
|
||||
v4l2_err(sd, "Error setting output, write failed\n");
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int adv7393_log_status(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct adv7393_state *state = to_state(sd);
|
||||
|
||||
v4l2_info(sd, "Standard: %llx\n", (unsigned long long)state->std);
|
||||
v4l2_info(sd, "Output: %s\n", (state->output == 0) ? "Composite" :
|
||||
((state->output == 1) ? "Component" : "S-Video"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int adv7393_s_ctrl(struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct v4l2_subdev *sd = to_sd(ctrl);
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_BRIGHTNESS:
|
||||
return adv7393_write(sd, ADV7393_SD_BRIGHTNESS_WSS,
|
||||
ctrl->val & SD_BRIGHTNESS_VALUE_MASK);
|
||||
|
||||
case V4L2_CID_HUE:
|
||||
return adv7393_write(sd, ADV7393_SD_HUE_ADJUST,
|
||||
ctrl->val - ADV7393_HUE_MIN);
|
||||
|
||||
case V4L2_CID_GAIN:
|
||||
return adv7393_write(sd, ADV7393_DAC123_OUTPUT_LEVEL,
|
||||
ctrl->val);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int adv7393_g_chip_ident(struct v4l2_subdev *sd,
|
||||
struct v4l2_dbg_chip_ident *chip)
|
||||
{
|
||||
struct i2c_client *client = v4l2_get_subdevdata(sd);
|
||||
|
||||
return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7393, 0);
|
||||
}
|
||||
|
||||
static const struct v4l2_ctrl_ops adv7393_ctrl_ops = {
|
||||
.s_ctrl = adv7393_s_ctrl,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_core_ops adv7393_core_ops = {
|
||||
.log_status = adv7393_log_status,
|
||||
.g_chip_ident = adv7393_g_chip_ident,
|
||||
.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
|
||||
.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
|
||||
.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
|
||||
.g_ctrl = v4l2_subdev_g_ctrl,
|
||||
.s_ctrl = v4l2_subdev_s_ctrl,
|
||||
.queryctrl = v4l2_subdev_queryctrl,
|
||||
.querymenu = v4l2_subdev_querymenu,
|
||||
};
|
||||
|
||||
static int adv7393_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
|
||||
{
|
||||
struct adv7393_state *state = to_state(sd);
|
||||
int err = 0;
|
||||
|
||||
if (state->std == std)
|
||||
return 0;
|
||||
|
||||
err = adv7393_setstd(sd, std);
|
||||
if (!err)
|
||||
state->std = std;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int adv7393_s_routing(struct v4l2_subdev *sd,
|
||||
u32 input, u32 output, u32 config)
|
||||
{
|
||||
struct adv7393_state *state = to_state(sd);
|
||||
int err = 0;
|
||||
|
||||
if (state->output == output)
|
||||
return 0;
|
||||
|
||||
err = adv7393_setoutput(sd, output);
|
||||
if (!err)
|
||||
state->output = output;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct v4l2_subdev_video_ops adv7393_video_ops = {
|
||||
.s_std_output = adv7393_s_std_output,
|
||||
.s_routing = adv7393_s_routing,
|
||||
};
|
||||
|
||||
static const struct v4l2_subdev_ops adv7393_ops = {
|
||||
.core = &adv7393_core_ops,
|
||||
.video = &adv7393_video_ops,
|
||||
};
|
||||
|
||||
static int adv7393_initialize(struct v4l2_subdev *sd)
|
||||
{
|
||||
struct adv7393_state *state = to_state(sd);
|
||||
int err = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(adv7393_init_reg_val); i += 2) {
|
||||
|
||||
err = adv7393_write(sd, adv7393_init_reg_val[i],
|
||||
adv7393_init_reg_val[i+1]);
|
||||
if (err) {
|
||||
v4l2_err(sd, "Error initializing\n");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure for default video standard */
|
||||
err = adv7393_setoutput(sd, state->output);
|
||||
if (err < 0) {
|
||||
v4l2_err(sd, "Error setting output during init\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = adv7393_setstd(sd, state->std);
|
||||
if (err < 0) {
|
||||
v4l2_err(sd, "Error setting std during init\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int adv7393_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct adv7393_state *state;
|
||||
int err;
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
||||
return -ENODEV;
|
||||
|
||||
v4l_info(client, "chip found @ 0x%x (%s)\n",
|
||||
client->addr << 1, client->adapter->name);
|
||||
|
||||
state = kzalloc(sizeof(struct adv7393_state), GFP_KERNEL);
|
||||
if (state == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
state->reg00 = ADV7393_POWER_MODE_REG_DEFAULT;
|
||||
state->reg01 = 0x00;
|
||||
state->reg02 = 0x20;
|
||||
state->reg35 = ADV7393_HD_MODE_REG6_DEFAULT;
|
||||
state->reg80 = ADV7393_SD_MODE_REG1_DEFAULT;
|
||||
state->reg82 = ADV7393_SD_MODE_REG2_DEFAULT;
|
||||
|
||||
state->output = ADV7393_COMPOSITE_ID;
|
||||
state->std = V4L2_STD_NTSC;
|
||||
|
||||
v4l2_i2c_subdev_init(&state->sd, client, &adv7393_ops);
|
||||
|
||||
v4l2_ctrl_handler_init(&state->hdl, 3);
|
||||
v4l2_ctrl_new_std(&state->hdl, &adv7393_ctrl_ops,
|
||||
V4L2_CID_BRIGHTNESS, ADV7393_BRIGHTNESS_MIN,
|
||||
ADV7393_BRIGHTNESS_MAX, 1,
|
||||
ADV7393_BRIGHTNESS_DEF);
|
||||
v4l2_ctrl_new_std(&state->hdl, &adv7393_ctrl_ops,
|
||||
V4L2_CID_HUE, ADV7393_HUE_MIN,
|
||||
ADV7393_HUE_MAX, 1,
|
||||
ADV7393_HUE_DEF);
|
||||
v4l2_ctrl_new_std(&state->hdl, &adv7393_ctrl_ops,
|
||||
V4L2_CID_GAIN, ADV7393_GAIN_MIN,
|
||||
ADV7393_GAIN_MAX, 1,
|
||||
ADV7393_GAIN_DEF);
|
||||
state->sd.ctrl_handler = &state->hdl;
|
||||
if (state->hdl.error) {
|
||||
int err = state->hdl.error;
|
||||
|
||||
v4l2_ctrl_handler_free(&state->hdl);
|
||||
kfree(state);
|
||||
return err;
|
||||
}
|
||||
v4l2_ctrl_handler_setup(&state->hdl);
|
||||
|
||||
err = adv7393_initialize(&state->sd);
|
||||
if (err) {
|
||||
v4l2_ctrl_handler_free(&state->hdl);
|
||||
kfree(state);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int adv7393_remove(struct i2c_client *client)
|
||||
{
|
||||
struct v4l2_subdev *sd = i2c_get_clientdata(client);
|
||||
struct adv7393_state *state = to_state(sd);
|
||||
|
||||
v4l2_device_unregister_subdev(sd);
|
||||
v4l2_ctrl_handler_free(&state->hdl);
|
||||
kfree(state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id adv7393_id[] = {
|
||||
{"adv7393", 0},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, adv7393_id);
|
||||
|
||||
static struct i2c_driver adv7393_driver = {
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "adv7393",
|
||||
},
|
||||
.probe = adv7393_probe,
|
||||
.remove = adv7393_remove,
|
||||
.id_table = adv7393_id,
|
||||
};
|
||||
module_i2c_driver(adv7393_driver);
|
||||
188
drivers/media/video/adv7393_regs.h
Normal file
188
drivers/media/video/adv7393_regs.h
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
* ADV7393 encoder related structure and register definitions
|
||||
*
|
||||
* Copyright (C) 2010-2012 ADVANSEE - http://www.advansee.com/
|
||||
* Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
|
||||
*
|
||||
* Based on ADV7343 driver,
|
||||
*
|
||||
* Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.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 version 2.
|
||||
*
|
||||
* This program is distributed .as is. WITHOUT ANY WARRANTY of any
|
||||
* kind, whether express or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef ADV7393_REGS_H
|
||||
#define ADV7393_REGS_H
|
||||
|
||||
struct adv7393_std_info {
|
||||
u32 standard_val3;
|
||||
u32 fsc_val;
|
||||
v4l2_std_id stdid;
|
||||
};
|
||||
|
||||
/* Register offset macros */
|
||||
#define ADV7393_POWER_MODE_REG (0x00)
|
||||
#define ADV7393_MODE_SELECT_REG (0x01)
|
||||
#define ADV7393_MODE_REG0 (0x02)
|
||||
|
||||
#define ADV7393_DAC123_OUTPUT_LEVEL (0x0B)
|
||||
|
||||
#define ADV7393_SOFT_RESET (0x17)
|
||||
|
||||
#define ADV7393_HD_MODE_REG1 (0x30)
|
||||
#define ADV7393_HD_MODE_REG2 (0x31)
|
||||
#define ADV7393_HD_MODE_REG3 (0x32)
|
||||
#define ADV7393_HD_MODE_REG4 (0x33)
|
||||
#define ADV7393_HD_MODE_REG5 (0x34)
|
||||
#define ADV7393_HD_MODE_REG6 (0x35)
|
||||
|
||||
#define ADV7393_HD_MODE_REG7 (0x39)
|
||||
|
||||
#define ADV7393_SD_MODE_REG1 (0x80)
|
||||
#define ADV7393_SD_MODE_REG2 (0x82)
|
||||
#define ADV7393_SD_MODE_REG3 (0x83)
|
||||
#define ADV7393_SD_MODE_REG4 (0x84)
|
||||
#define ADV7393_SD_MODE_REG5 (0x86)
|
||||
#define ADV7393_SD_MODE_REG6 (0x87)
|
||||
#define ADV7393_SD_MODE_REG7 (0x88)
|
||||
#define ADV7393_SD_MODE_REG8 (0x89)
|
||||
|
||||
#define ADV7393_SD_TIMING_REG0 (0x8A)
|
||||
|
||||
#define ADV7393_FSC_REG0 (0x8C)
|
||||
#define ADV7393_FSC_REG1 (0x8D)
|
||||
#define ADV7393_FSC_REG2 (0x8E)
|
||||
#define ADV7393_FSC_REG3 (0x8F)
|
||||
|
||||
#define ADV7393_SD_CGMS_WSS0 (0x99)
|
||||
|
||||
#define ADV7393_SD_HUE_ADJUST (0xA0)
|
||||
#define ADV7393_SD_BRIGHTNESS_WSS (0xA1)
|
||||
|
||||
/* Default values for the registers */
|
||||
#define ADV7393_POWER_MODE_REG_DEFAULT (0x10)
|
||||
#define ADV7393_HD_MODE_REG1_DEFAULT (0x3C) /* Changed Default
|
||||
720p EAV/SAV code*/
|
||||
#define ADV7393_HD_MODE_REG2_DEFAULT (0x01) /* Changed Pixel data
|
||||
valid */
|
||||
#define ADV7393_HD_MODE_REG3_DEFAULT (0x00) /* Color delay 0 clks */
|
||||
#define ADV7393_HD_MODE_REG4_DEFAULT (0xEC) /* Changed */
|
||||
#define ADV7393_HD_MODE_REG5_DEFAULT (0x08)
|
||||
#define ADV7393_HD_MODE_REG6_DEFAULT (0x00)
|
||||
#define ADV7393_HD_MODE_REG7_DEFAULT (0x00)
|
||||
#define ADV7393_SOFT_RESET_DEFAULT (0x02)
|
||||
#define ADV7393_COMPOSITE_POWER_VALUE (0x10)
|
||||
#define ADV7393_COMPONENT_POWER_VALUE (0x1C)
|
||||
#define ADV7393_SVIDEO_POWER_VALUE (0x0C)
|
||||
#define ADV7393_SD_HUE_ADJUST_DEFAULT (0x80)
|
||||
#define ADV7393_SD_BRIGHTNESS_WSS_DEFAULT (0x00)
|
||||
|
||||
#define ADV7393_SD_CGMS_WSS0_DEFAULT (0x10)
|
||||
|
||||
#define ADV7393_SD_MODE_REG1_DEFAULT (0x10)
|
||||
#define ADV7393_SD_MODE_REG2_DEFAULT (0xC9)
|
||||
#define ADV7393_SD_MODE_REG3_DEFAULT (0x00)
|
||||
#define ADV7393_SD_MODE_REG4_DEFAULT (0x00)
|
||||
#define ADV7393_SD_MODE_REG5_DEFAULT (0x02)
|
||||
#define ADV7393_SD_MODE_REG6_DEFAULT (0x8C)
|
||||
#define ADV7393_SD_MODE_REG7_DEFAULT (0x14)
|
||||
#define ADV7393_SD_MODE_REG8_DEFAULT (0x00)
|
||||
|
||||
#define ADV7393_SD_TIMING_REG0_DEFAULT (0x0C)
|
||||
|
||||
/* Bit masks for Mode Select Register */
|
||||
#define INPUT_MODE_MASK (0x70)
|
||||
#define SD_INPUT_MODE (0x00)
|
||||
#define HD_720P_INPUT_MODE (0x10)
|
||||
#define HD_1080I_INPUT_MODE (0x10)
|
||||
|
||||
/* Bit masks for Mode Register 0 */
|
||||
#define TEST_PATTERN_BLACK_BAR_EN (0x04)
|
||||
#define YUV_OUTPUT_SELECT (0x20)
|
||||
#define RGB_OUTPUT_SELECT (0xDF)
|
||||
|
||||
/* Bit masks for SD brightness/WSS */
|
||||
#define SD_BRIGHTNESS_VALUE_MASK (0x7F)
|
||||
#define SD_BLANK_WSS_DATA_MASK (0x80)
|
||||
|
||||
/* Bit masks for soft reset register */
|
||||
#define SOFT_RESET (0x02)
|
||||
|
||||
/* Bit masks for HD Mode Register 1 */
|
||||
#define OUTPUT_STD_MASK (0x03)
|
||||
#define OUTPUT_STD_SHIFT (0)
|
||||
#define OUTPUT_STD_EIA0_2 (0x00)
|
||||
#define OUTPUT_STD_EIA0_1 (0x01)
|
||||
#define OUTPUT_STD_FULL (0x02)
|
||||
#define EMBEDDED_SYNC (0x04)
|
||||
#define EXTERNAL_SYNC (0xFB)
|
||||
#define STD_MODE_MASK (0x1F)
|
||||
#define STD_MODE_SHIFT (3)
|
||||
#define STD_MODE_720P (0x05)
|
||||
#define STD_MODE_720P_25 (0x08)
|
||||
#define STD_MODE_720P_30 (0x07)
|
||||
#define STD_MODE_720P_50 (0x06)
|
||||
#define STD_MODE_1080I (0x0D)
|
||||
#define STD_MODE_1080I_25 (0x0E)
|
||||
#define STD_MODE_1080P_24 (0x11)
|
||||
#define STD_MODE_1080P_25 (0x10)
|
||||
#define STD_MODE_1080P_30 (0x0F)
|
||||
#define STD_MODE_525P (0x00)
|
||||
#define STD_MODE_625P (0x03)
|
||||
|
||||
/* Bit masks for SD Mode Register 1 */
|
||||
#define SD_STD_MASK (0x03)
|
||||
#define SD_STD_NTSC (0x00)
|
||||
#define SD_STD_PAL_BDGHI (0x01)
|
||||
#define SD_STD_PAL_M (0x02)
|
||||
#define SD_STD_PAL_N (0x03)
|
||||
#define SD_LUMA_FLTR_MASK (0x07)
|
||||
#define SD_LUMA_FLTR_SHIFT (2)
|
||||
#define SD_CHROMA_FLTR_MASK (0x07)
|
||||
#define SD_CHROMA_FLTR_SHIFT (5)
|
||||
|
||||
/* Bit masks for SD Mode Register 2 */
|
||||
#define SD_PRPB_SSAF_EN (0x01)
|
||||
#define SD_PRPB_SSAF_DI (0xFE)
|
||||
#define SD_DAC_OUT1_EN (0x02)
|
||||
#define SD_DAC_OUT1_DI (0xFD)
|
||||
#define SD_PEDESTAL_EN (0x08)
|
||||
#define SD_PEDESTAL_DI (0xF7)
|
||||
#define SD_SQUARE_PIXEL_EN (0x10)
|
||||
#define SD_SQUARE_PIXEL_DI (0xEF)
|
||||
#define SD_PIXEL_DATA_VALID (0x40)
|
||||
#define SD_ACTIVE_EDGE_EN (0x80)
|
||||
#define SD_ACTIVE_EDGE_DI (0x7F)
|
||||
|
||||
/* Bit masks for HD Mode Register 6 */
|
||||
#define HD_PRPB_SYNC_EN (0x04)
|
||||
#define HD_PRPB_SYNC_DI (0xFB)
|
||||
#define HD_DAC_SWAP_EN (0x08)
|
||||
#define HD_DAC_SWAP_DI (0xF7)
|
||||
#define HD_GAMMA_CURVE_A (0xEF)
|
||||
#define HD_GAMMA_CURVE_B (0x10)
|
||||
#define HD_GAMMA_EN (0x20)
|
||||
#define HD_GAMMA_DI (0xDF)
|
||||
#define HD_ADPT_FLTR_MODEA (0xBF)
|
||||
#define HD_ADPT_FLTR_MODEB (0x40)
|
||||
#define HD_ADPT_FLTR_EN (0x80)
|
||||
#define HD_ADPT_FLTR_DI (0x7F)
|
||||
|
||||
#define ADV7393_BRIGHTNESS_MAX (63)
|
||||
#define ADV7393_BRIGHTNESS_MIN (-64)
|
||||
#define ADV7393_BRIGHTNESS_DEF (0)
|
||||
#define ADV7393_HUE_MAX (127)
|
||||
#define ADV7393_HUE_MIN (-128)
|
||||
#define ADV7393_HUE_DEF (0)
|
||||
#define ADV7393_GAIN_MAX (64)
|
||||
#define ADV7393_GAIN_MIN (-64)
|
||||
#define ADV7393_GAIN_DEF (0)
|
||||
|
||||
#endif
|
||||
|
|
@ -676,6 +676,7 @@ struct tvcard bttv_tvcards[] = {
|
|||
.tuner_type = UNSET,
|
||||
.tuner_addr = ADDR_UNSET,
|
||||
.has_remote = 1,
|
||||
.has_radio = 1, /* not every card has radio */
|
||||
},
|
||||
[BTTV_BOARD_VOBIS_BOOSTAR] = {
|
||||
.name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
|
||||
|
|
|
|||
|
|
@ -557,12 +557,6 @@ static const struct bttv_format formats[] = {
|
|||
.btformat = BT848_COLOR_FMT_YUY2,
|
||||
.depth = 16,
|
||||
.flags = FORMAT_FLAGS_PACKED,
|
||||
},{
|
||||
.name = "4:2:2, packed, YUYV",
|
||||
.fourcc = V4L2_PIX_FMT_YUYV,
|
||||
.btformat = BT848_COLOR_FMT_YUY2,
|
||||
.depth = 16,
|
||||
.flags = FORMAT_FLAGS_PACKED,
|
||||
},{
|
||||
.name = "4:2:2, packed, UYVY",
|
||||
.fourcc = V4L2_PIX_FMT_UYVY,
|
||||
|
|
|
|||
|
|
@ -932,7 +932,7 @@ static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
|
|||
buf->sequence = cam->buffers[buf->index].seq;
|
||||
buf->m.offset = cam->buffers[buf->index].data - cam->frame_buffer;
|
||||
buf->length = cam->frame_size;
|
||||
buf->input = 0;
|
||||
buf->reserved2 = 0;
|
||||
buf->reserved = 0;
|
||||
memset(&buf->timecode, 0, sizeof(buf->timecode));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,50 +0,0 @@
|
|||
/* cs8420.h - cs8420 initializations
|
||||
Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
#ifndef __CS8420_H__
|
||||
#define __CS8420_H__
|
||||
|
||||
/* Initialization Sequence */
|
||||
|
||||
static __u8 init8420[] = {
|
||||
1, 0x01, 2, 0x02, 3, 0x00, 4, 0x46,
|
||||
5, 0x24, 6, 0x84, 18, 0x18, 19, 0x13,
|
||||
};
|
||||
|
||||
#define INIT8420LEN (sizeof(init8420)/2)
|
||||
|
||||
static __u8 mode8420pro[] = { /* professional output mode */
|
||||
32, 0xa1, 33, 0x00, 34, 0x00, 35, 0x00,
|
||||
36, 0x00, 37, 0x00, 38, 0x00, 39, 0x00,
|
||||
40, 0x00, 41, 0x00, 42, 0x00, 43, 0x00,
|
||||
44, 0x00, 45, 0x00, 46, 0x00, 47, 0x00,
|
||||
48, 0x00, 49, 0x00, 50, 0x00, 51, 0x00,
|
||||
52, 0x00, 53, 0x00, 54, 0x00, 55, 0x00,
|
||||
};
|
||||
#define MODE8420LEN (sizeof(mode8420pro)/2)
|
||||
|
||||
static __u8 mode8420con[] = { /* consumer output mode */
|
||||
32, 0x20, 33, 0x00, 34, 0x00, 35, 0x48,
|
||||
36, 0x00, 37, 0x00, 38, 0x00, 39, 0x00,
|
||||
40, 0x00, 41, 0x00, 42, 0x00, 43, 0x00,
|
||||
44, 0x00, 45, 0x00, 46, 0x00, 47, 0x00,
|
||||
48, 0x00, 49, 0x00, 50, 0x00, 51, 0x00,
|
||||
52, 0x00, 53, 0x00, 54, 0x00, 55, 0x00,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1142,24 +1142,6 @@ static long cx18_default(struct file *file, void *fh, bool valid_prio,
|
|||
return 0;
|
||||
}
|
||||
|
||||
long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct video_device *vfd = video_devdata(filp);
|
||||
struct cx18_open_id *id = file2id(filp);
|
||||
struct cx18 *cx = id->cx;
|
||||
long res;
|
||||
|
||||
mutex_lock(&cx->serialize_lock);
|
||||
|
||||
if (cx18_debug & CX18_DBGFLG_IOCTL)
|
||||
vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
|
||||
res = video_ioctl2(filp, cmd, arg);
|
||||
vfd->debug = 0;
|
||||
mutex_unlock(&cx->serialize_lock);
|
||||
return res;
|
||||
}
|
||||
|
||||
static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
|
||||
.vidioc_querycap = cx18_querycap,
|
||||
.vidioc_s_audio = cx18_s_audio,
|
||||
|
|
|
|||
|
|
@ -29,5 +29,3 @@ void cx18_set_funcs(struct video_device *vdev);
|
|||
int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std);
|
||||
int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
|
||||
int cx18_s_input(struct file *file, void *fh, unsigned int inp);
|
||||
long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
|
|
|
|||
|
|
@ -40,8 +40,7 @@ static struct v4l2_file_operations cx18_v4l2_enc_fops = {
|
|||
.owner = THIS_MODULE,
|
||||
.read = cx18_v4l2_read,
|
||||
.open = cx18_v4l2_open,
|
||||
/* FIXME change to video_ioctl2 if serialization lock can be removed */
|
||||
.unlocked_ioctl = cx18_v4l2_ioctl,
|
||||
.unlocked_ioctl = video_ioctl2,
|
||||
.release = cx18_v4l2_close,
|
||||
.poll = cx18_v4l2_enc_poll,
|
||||
.mmap = cx18_v4l2_mmap,
|
||||
|
|
@ -376,6 +375,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
|
|||
s->video_dev->fops = &cx18_v4l2_enc_fops;
|
||||
s->video_dev->release = video_device_release;
|
||||
s->video_dev->tvnorms = V4L2_STD_ALL;
|
||||
s->video_dev->lock = &cx->serialize_lock;
|
||||
set_bit(V4L2_FL_USE_FH_PRIO, &s->video_dev->flags);
|
||||
cx18_set_funcs(s->video_dev);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ void initGPIO(struct cx231xx *dev)
|
|||
verve_read_byte(dev, 0x07, &val);
|
||||
cx231xx_info(" verve_read_byte address0x07=0x%x\n", val);
|
||||
|
||||
cx231xx_capture_start(dev, 1, 2);
|
||||
cx231xx_capture_start(dev, 1, Vbi);
|
||||
|
||||
cx231xx_mode_register(dev, EP_MODE_SET, 0x0500FE00);
|
||||
cx231xx_mode_register(dev, GBULK_BIT_EN, 0xFFFDFFFF);
|
||||
|
|
@ -99,7 +99,7 @@ void uninitGPIO(struct cx231xx *dev)
|
|||
{
|
||||
u8 value[4] = { 0, 0, 0, 0 };
|
||||
|
||||
cx231xx_capture_start(dev, 0, 2);
|
||||
cx231xx_capture_start(dev, 0, Vbi);
|
||||
verve_write_byte(dev, 0x07, 0x14);
|
||||
cx231xx_write_ctrl_reg(dev, VRT_SET_REGISTER,
|
||||
0x68, value, 4);
|
||||
|
|
@ -2516,29 +2516,29 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type)
|
|||
|
||||
if (dev->udev->speed == USB_SPEED_HIGH) {
|
||||
switch (media_type) {
|
||||
case 81: /* audio */
|
||||
case Audio:
|
||||
cx231xx_info("%s: Audio enter HANC\n", __func__);
|
||||
status =
|
||||
cx231xx_mode_register(dev, TS_MODE_REG, 0x9300);
|
||||
break;
|
||||
|
||||
case 2: /* vbi */
|
||||
case Vbi:
|
||||
cx231xx_info("%s: set vanc registers\n", __func__);
|
||||
status = cx231xx_mode_register(dev, TS_MODE_REG, 0x300);
|
||||
break;
|
||||
|
||||
case 3: /* sliced cc */
|
||||
case Sliced_cc:
|
||||
cx231xx_info("%s: set hanc registers\n", __func__);
|
||||
status =
|
||||
cx231xx_mode_register(dev, TS_MODE_REG, 0x1300);
|
||||
break;
|
||||
|
||||
case 0: /* video */
|
||||
case Raw_Video:
|
||||
cx231xx_info("%s: set video registers\n", __func__);
|
||||
status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100);
|
||||
break;
|
||||
|
||||
case 4: /* ts1 */
|
||||
case TS1_serial_mode:
|
||||
cx231xx_info("%s: set ts1 registers", __func__);
|
||||
|
||||
if (dev->board.has_417) {
|
||||
|
|
@ -2569,7 +2569,7 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type)
|
|||
}
|
||||
break;
|
||||
|
||||
case 6: /* ts1 parallel mode */
|
||||
case TS1_parallel_mode:
|
||||
cx231xx_info("%s: set ts1 parallel mode registers\n",
|
||||
__func__);
|
||||
status = cx231xx_mode_register(dev, TS_MODE_REG, 0x100);
|
||||
|
|
@ -2592,52 +2592,28 @@ int cx231xx_capture_start(struct cx231xx *dev, int start, u8 media_type)
|
|||
/* get EP for media type */
|
||||
pcb_config = (struct pcb_config *)&dev->current_pcb_config;
|
||||
|
||||
if (pcb_config->config_num == 1) {
|
||||
if (pcb_config->config_num) {
|
||||
switch (media_type) {
|
||||
case 0: /* Video */
|
||||
case Raw_Video:
|
||||
ep_mask = ENABLE_EP4; /* ep4 [00:1000] */
|
||||
break;
|
||||
case 1: /* Audio */
|
||||
case Audio:
|
||||
ep_mask = ENABLE_EP3; /* ep3 [00:0100] */
|
||||
break;
|
||||
case 2: /* Vbi */
|
||||
case Vbi:
|
||||
ep_mask = ENABLE_EP5; /* ep5 [01:0000] */
|
||||
break;
|
||||
case 3: /* Sliced_cc */
|
||||
case Sliced_cc:
|
||||
ep_mask = ENABLE_EP6; /* ep6 [10:0000] */
|
||||
break;
|
||||
case 4: /* ts1 */
|
||||
case 6: /* ts1 parallel mode */
|
||||
case TS1_serial_mode:
|
||||
case TS1_parallel_mode:
|
||||
ep_mask = ENABLE_EP1; /* ep1 [00:0001] */
|
||||
break;
|
||||
case 5: /* ts2 */
|
||||
case TS2:
|
||||
ep_mask = ENABLE_EP2; /* ep2 [00:0010] */
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (pcb_config->config_num > 1) {
|
||||
switch (media_type) {
|
||||
case 0: /* Video */
|
||||
ep_mask = ENABLE_EP4; /* ep4 [00:1000] */
|
||||
break;
|
||||
case 1: /* Audio */
|
||||
ep_mask = ENABLE_EP3; /* ep3 [00:0100] */
|
||||
break;
|
||||
case 2: /* Vbi */
|
||||
ep_mask = ENABLE_EP5; /* ep5 [01:0000] */
|
||||
break;
|
||||
case 3: /* Sliced_cc */
|
||||
ep_mask = ENABLE_EP6; /* ep6 [10:0000] */
|
||||
break;
|
||||
case 4: /* ts1 */
|
||||
case 6: /* ts1 parallel mode */
|
||||
ep_mask = ENABLE_EP1; /* ep1 [00:0001] */
|
||||
break;
|
||||
case 5: /* ts2 */
|
||||
ep_mask = ENABLE_EP2; /* ep2 [00:0010] */
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (start) {
|
||||
|
|
|
|||
|
|
@ -1023,7 +1023,6 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
|
|||
int nr = 0, ifnum;
|
||||
int i, isoc_pipe = 0;
|
||||
char *speed;
|
||||
char descr[255] = "";
|
||||
struct usb_interface_assoc_descriptor *assoc_desc;
|
||||
|
||||
udev = usb_get_dev(interface_to_usbdev(interface));
|
||||
|
|
@ -1098,20 +1097,10 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
|
|||
speed = "unknown";
|
||||
}
|
||||
|
||||
if (udev->manufacturer)
|
||||
strlcpy(descr, udev->manufacturer, sizeof(descr));
|
||||
|
||||
if (udev->product) {
|
||||
if (*descr)
|
||||
strlcat(descr, " ", sizeof(descr));
|
||||
strlcat(descr, udev->product, sizeof(descr));
|
||||
}
|
||||
if (*descr)
|
||||
strlcat(descr, " ", sizeof(descr));
|
||||
|
||||
cx231xx_info("New device %s@ %s Mbps "
|
||||
cx231xx_info("New device %s %s @ %s Mbps "
|
||||
"(%04x:%04x) with %d interfaces\n",
|
||||
descr,
|
||||
udev->manufacturer ? udev->manufacturer : "",
|
||||
udev->product ? udev->product : "",
|
||||
speed,
|
||||
le16_to_cpu(udev->descriptor.idVendor),
|
||||
le16_to_cpu(udev->descriptor.idProduct),
|
||||
|
|
|
|||
|
|
@ -585,13 +585,10 @@ static void snd_cx88_wm8775_volume_put(struct snd_kcontrol *kcontrol,
|
|||
{
|
||||
snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
struct cx88_core *core = chip->core;
|
||||
struct v4l2_control client_ctl;
|
||||
int left = value->value.integer.value[0];
|
||||
int right = value->value.integer.value[1];
|
||||
int v, b;
|
||||
|
||||
memset(&client_ctl, 0, sizeof(client_ctl));
|
||||
|
||||
/* Pass volume & balance onto any WM8775 */
|
||||
if (left >= right) {
|
||||
v = left << 10;
|
||||
|
|
@ -600,13 +597,8 @@ static void snd_cx88_wm8775_volume_put(struct snd_kcontrol *kcontrol,
|
|||
v = right << 10;
|
||||
b = right ? 0xffff - (0x8000 * left) / right : 0x8000;
|
||||
}
|
||||
client_ctl.value = v;
|
||||
client_ctl.id = V4L2_CID_AUDIO_VOLUME;
|
||||
call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
|
||||
|
||||
client_ctl.value = b;
|
||||
client_ctl.id = V4L2_CID_AUDIO_BALANCE;
|
||||
call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
|
||||
wm8775_s_ctrl(core, V4L2_CID_AUDIO_VOLUME, v);
|
||||
wm8775_s_ctrl(core, V4L2_CID_AUDIO_BALANCE, b);
|
||||
}
|
||||
|
||||
/* OK - TODO: test it */
|
||||
|
|
@ -687,14 +679,8 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
|
|||
cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol);
|
||||
/* Pass mute onto any WM8775 */
|
||||
if ((core->board.audio_chip == V4L2_IDENT_WM8775) &&
|
||||
((1<<6) == bit)) {
|
||||
struct v4l2_control client_ctl;
|
||||
|
||||
memset(&client_ctl, 0, sizeof(client_ctl));
|
||||
client_ctl.value = 0 != (vol & bit);
|
||||
client_ctl.id = V4L2_CID_AUDIO_MUTE;
|
||||
call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
|
||||
}
|
||||
((1<<6) == bit))
|
||||
wm8775_s_ctrl(core, V4L2_CID_AUDIO_MUTE, 0 != (vol & bit));
|
||||
ret = 1;
|
||||
}
|
||||
spin_unlock_irq(&chip->reg_lock);
|
||||
|
|
@ -724,13 +710,10 @@ static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol,
|
|||
{
|
||||
snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
|
||||
struct cx88_core *core = chip->core;
|
||||
struct v4l2_control client_ctl;
|
||||
|
||||
memset(&client_ctl, 0, sizeof(client_ctl));
|
||||
client_ctl.id = V4L2_CID_AUDIO_LOUDNESS;
|
||||
call_hw(core, WM8775_GID, core, g_ctrl, &client_ctl);
|
||||
value->value.integer.value[0] = client_ctl.value ? 1 : 0;
|
||||
s32 val;
|
||||
|
||||
val = wm8775_g_ctrl(core, V4L2_CID_AUDIO_LOUDNESS);
|
||||
value->value.integer.value[0] = val ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include <linux/firmware.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
#include <media/v4l2-event.h>
|
||||
#include <media/cx2341x.h>
|
||||
|
||||
#include "cx88.h"
|
||||
|
|
@ -523,11 +524,10 @@ static void blackbird_codec_settings(struct cx8802_dev *dev)
|
|||
blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
|
||||
dev->height, dev->width);
|
||||
|
||||
dev->params.width = dev->width;
|
||||
dev->params.height = dev->height;
|
||||
dev->params.is_50hz = (dev->core->tvnorm & V4L2_STD_625_50) != 0;
|
||||
|
||||
cx2341x_update(dev, blackbird_mbox_func, NULL, &dev->params);
|
||||
dev->cxhdl.width = dev->width;
|
||||
dev->cxhdl.height = dev->height;
|
||||
cx2341x_handler_set_50hz(&dev->cxhdl, dev->core->tvnorm & V4L2_STD_625_50);
|
||||
cx2341x_handler_setup(&dev->cxhdl);
|
||||
}
|
||||
|
||||
static int blackbird_initialize_codec(struct cx8802_dev *dev)
|
||||
|
|
@ -618,6 +618,8 @@ static int blackbird_start_codec(struct file *file, void *priv)
|
|||
/* initialize the video input */
|
||||
blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
|
||||
|
||||
cx2341x_handler_set_busy(&dev->cxhdl, 1);
|
||||
|
||||
/* start capturing to the host interface */
|
||||
blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0,
|
||||
BLACKBIRD_MPEG_CAPTURE,
|
||||
|
|
@ -636,6 +638,8 @@ static int blackbird_stop_codec(struct cx8802_dev *dev)
|
|||
BLACKBIRD_RAW_BITS_NONE
|
||||
);
|
||||
|
||||
cx2341x_handler_set_busy(&dev->cxhdl, 0);
|
||||
|
||||
dev->mpeg_active = 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -685,58 +689,15 @@ static struct videobuf_queue_ops blackbird_qops = {
|
|||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static const u32 *ctrl_classes[] = {
|
||||
cx88_user_ctrls,
|
||||
cx2341x_mpeg_ctrls,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int blackbird_queryctrl(struct cx8802_dev *dev, struct v4l2_queryctrl *qctrl)
|
||||
{
|
||||
qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
|
||||
if (qctrl->id == 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Standard V4L2 controls */
|
||||
if (cx8800_ctrl_query(dev->core, qctrl) == 0)
|
||||
return 0;
|
||||
|
||||
/* MPEG V4L2 controls */
|
||||
if (cx2341x_ctrl_query(&dev->params, qctrl))
|
||||
qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* IOCTL Handlers */
|
||||
|
||||
static int vidioc_querymenu (struct file *file, void *priv,
|
||||
struct v4l2_querymenu *qmenu)
|
||||
{
|
||||
struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev;
|
||||
struct v4l2_queryctrl qctrl;
|
||||
|
||||
qctrl.id = qmenu->id;
|
||||
blackbird_queryctrl(dev, &qctrl);
|
||||
return v4l2_ctrl_query_menu(qmenu, &qctrl,
|
||||
cx2341x_ctrl_get_menu(&dev->params, qmenu->id));
|
||||
}
|
||||
|
||||
static int vidioc_querycap (struct file *file, void *priv,
|
||||
static int vidioc_querycap(struct file *file, void *priv,
|
||||
struct v4l2_capability *cap)
|
||||
{
|
||||
struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev;
|
||||
struct cx88_core *core = dev->core;
|
||||
|
||||
strcpy(cap->driver, "cx88_blackbird");
|
||||
strlcpy(cap->card, core->board.name, sizeof(cap->card));
|
||||
sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
|
||||
cap->capabilities =
|
||||
V4L2_CAP_VIDEO_CAPTURE |
|
||||
V4L2_CAP_READWRITE |
|
||||
V4L2_CAP_STREAMING;
|
||||
if (UNSET != core->board.tuner_type)
|
||||
cap->capabilities |= V4L2_CAP_TUNER;
|
||||
sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
|
||||
cx88_querycap(file, core, cap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -748,6 +709,7 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
|
|||
|
||||
strlcpy(f->description, "MPEG", sizeof(f->description));
|
||||
f->pixelformat = V4L2_PIX_FMT_MPEG;
|
||||
f->flags = V4L2_FMT_FLAG_COMPRESSED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -759,12 +721,12 @@ static int vidioc_g_fmt_vid_cap (struct file *file, void *priv,
|
|||
|
||||
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
|
||||
f->fmt.pix.bytesperline = 0;
|
||||
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */
|
||||
f->fmt.pix.colorspace = 0;
|
||||
f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */;
|
||||
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
|
||||
f->fmt.pix.width = dev->width;
|
||||
f->fmt.pix.height = dev->height;
|
||||
f->fmt.pix.field = fh->mpegq.field;
|
||||
dprintk(0,"VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
|
||||
dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n",
|
||||
dev->width, dev->height, fh->mpegq.field );
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -777,9 +739,9 @@ static int vidioc_try_fmt_vid_cap (struct file *file, void *priv,
|
|||
|
||||
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
|
||||
f->fmt.pix.bytesperline = 0;
|
||||
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
|
||||
f->fmt.pix.colorspace = 0;
|
||||
dprintk(0,"VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
|
||||
f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */;
|
||||
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
|
||||
dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
|
||||
dev->width, dev->height, fh->mpegq.field );
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -793,15 +755,15 @@ static int vidioc_s_fmt_vid_cap (struct file *file, void *priv,
|
|||
|
||||
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
|
||||
f->fmt.pix.bytesperline = 0;
|
||||
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
|
||||
f->fmt.pix.colorspace = 0;
|
||||
f->fmt.pix.sizeimage = 188 * 4 * mpegbufs; /* 188 * 4 * 1024; */;
|
||||
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
|
||||
dev->width = f->fmt.pix.width;
|
||||
dev->height = f->fmt.pix.height;
|
||||
fh->mpegq.field = f->fmt.pix.field;
|
||||
cx88_set_scale(core, f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
|
||||
blackbird_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
|
||||
f->fmt.pix.height, f->fmt.pix.width);
|
||||
dprintk(0,"VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
|
||||
dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
|
||||
f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field );
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -834,60 +796,21 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p)
|
|||
static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
|
||||
{
|
||||
struct cx8802_fh *fh = priv;
|
||||
struct cx8802_dev *dev = fh->dev;
|
||||
|
||||
if (!dev->mpeg_active)
|
||||
blackbird_start_codec(file, fh);
|
||||
return videobuf_streamon(&fh->mpegq);
|
||||
}
|
||||
|
||||
static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
|
||||
{
|
||||
struct cx8802_fh *fh = priv;
|
||||
return videobuf_streamoff(&fh->mpegq);
|
||||
}
|
||||
|
||||
static int vidioc_g_ext_ctrls (struct file *file, void *priv,
|
||||
struct v4l2_ext_controls *f)
|
||||
{
|
||||
struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev;
|
||||
|
||||
if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
|
||||
return -EINVAL;
|
||||
return cx2341x_ext_ctrls(&dev->params, 0, f, VIDIOC_G_EXT_CTRLS);
|
||||
}
|
||||
|
||||
static int vidioc_s_ext_ctrls (struct file *file, void *priv,
|
||||
struct v4l2_ext_controls *f)
|
||||
{
|
||||
struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev;
|
||||
struct cx2341x_mpeg_params p;
|
||||
int err;
|
||||
|
||||
if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
|
||||
return -EINVAL;
|
||||
struct cx8802_dev *dev = fh->dev;
|
||||
|
||||
if (dev->mpeg_active)
|
||||
blackbird_stop_codec(dev);
|
||||
|
||||
p = dev->params;
|
||||
err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS);
|
||||
if (!err) {
|
||||
err = cx2341x_update(dev, blackbird_mbox_func, &dev->params, &p);
|
||||
dev->params = p;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int vidioc_try_ext_ctrls (struct file *file, void *priv,
|
||||
struct v4l2_ext_controls *f)
|
||||
{
|
||||
struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev;
|
||||
struct cx2341x_mpeg_params p;
|
||||
int err;
|
||||
|
||||
if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
|
||||
return -EINVAL;
|
||||
p = dev->params;
|
||||
err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS);
|
||||
|
||||
return err;
|
||||
return videobuf_streamoff(&fh->mpegq);
|
||||
}
|
||||
|
||||
static int vidioc_s_frequency (struct file *file, void *priv,
|
||||
|
|
@ -897,6 +820,10 @@ static int vidioc_s_frequency (struct file *file, void *priv,
|
|||
struct cx8802_dev *dev = fh->dev;
|
||||
struct cx88_core *core = dev->core;
|
||||
|
||||
if (unlikely(UNSET == core->board.tuner_type))
|
||||
return -EINVAL;
|
||||
if (unlikely(f->tuner != 0))
|
||||
return -EINVAL;
|
||||
if (dev->mpeg_active)
|
||||
blackbird_stop_codec(dev);
|
||||
|
||||
|
|
@ -914,29 +841,11 @@ static int vidioc_log_status (struct file *file, void *priv)
|
|||
char name[32 + 2];
|
||||
|
||||
snprintf(name, sizeof(name), "%s/2", core->name);
|
||||
printk("%s/2: ============ START LOG STATUS ============\n",
|
||||
core->name);
|
||||
call_all(core, core, log_status);
|
||||
cx2341x_log_status(&dev->params, name);
|
||||
printk("%s/2: ============= END LOG STATUS =============\n",
|
||||
core->name);
|
||||
v4l2_ctrl_handler_log_status(&dev->cxhdl.hdl, name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_queryctrl (struct file *file, void *priv,
|
||||
struct v4l2_queryctrl *qctrl)
|
||||
{
|
||||
struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev;
|
||||
|
||||
if (blackbird_queryctrl(dev, qctrl) == 0)
|
||||
return 0;
|
||||
|
||||
qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
|
||||
if (unlikely(qctrl->id == 0))
|
||||
return -EINVAL;
|
||||
return cx8800_ctrl_query(dev->core, qctrl);
|
||||
}
|
||||
|
||||
static int vidioc_enum_input (struct file *file, void *priv,
|
||||
struct v4l2_input *i)
|
||||
{
|
||||
|
|
@ -944,22 +853,6 @@ static int vidioc_enum_input (struct file *file, void *priv,
|
|||
return cx88_enum_input (core,i);
|
||||
}
|
||||
|
||||
static int vidioc_g_ctrl (struct file *file, void *priv,
|
||||
struct v4l2_control *ctl)
|
||||
{
|
||||
struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
|
||||
return
|
||||
cx88_get_control(core,ctl);
|
||||
}
|
||||
|
||||
static int vidioc_s_ctrl (struct file *file, void *priv,
|
||||
struct v4l2_control *ctl)
|
||||
{
|
||||
struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
|
||||
return
|
||||
cx88_set_control(core,ctl);
|
||||
}
|
||||
|
||||
static int vidioc_g_frequency (struct file *file, void *priv,
|
||||
struct v4l2_frequency *f)
|
||||
{
|
||||
|
|
@ -968,8 +861,9 @@ static int vidioc_g_frequency (struct file *file, void *priv,
|
|||
|
||||
if (unlikely(UNSET == core->board.tuner_type))
|
||||
return -EINVAL;
|
||||
if (unlikely(f->tuner != 0))
|
||||
return -EINVAL;
|
||||
|
||||
f->type = V4L2_TUNER_ANALOG_TV;
|
||||
f->frequency = core->freq;
|
||||
call_all(core, tuner, g_frequency, f);
|
||||
|
||||
|
|
@ -990,6 +884,8 @@ static int vidioc_s_input (struct file *file, void *priv, unsigned int i)
|
|||
|
||||
if (i >= 4)
|
||||
return -EINVAL;
|
||||
if (0 == INPUT(i).type)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&core->lock);
|
||||
cx88_newstation(core);
|
||||
|
|
@ -1010,9 +906,9 @@ static int vidioc_g_tuner (struct file *file, void *priv,
|
|||
return -EINVAL;
|
||||
|
||||
strcpy(t->name, "Television");
|
||||
t->type = V4L2_TUNER_ANALOG_TV;
|
||||
t->capability = V4L2_TUNER_CAP_NORM;
|
||||
t->rangehigh = 0xffffffffUL;
|
||||
call_all(core, tuner, g_tuner, t);
|
||||
|
||||
cx88_get_stereo(core ,t);
|
||||
reg = cx_read(MO_DEVICE_STATUS);
|
||||
|
|
@ -1034,6 +930,14 @@ static int vidioc_s_tuner (struct file *file, void *priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorm)
|
||||
{
|
||||
struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
|
||||
|
||||
*tvnorm = core->tvnorm;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id)
|
||||
{
|
||||
struct cx88_core *core = ((struct cx8802_fh *)priv)->dev->core;
|
||||
|
|
@ -1087,6 +991,7 @@ static int mpeg_open(struct file *file)
|
|||
mutex_unlock(&dev->core->lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
v4l2_fh_init(&fh->fh, vdev);
|
||||
file->private_data = fh;
|
||||
fh->dev = dev;
|
||||
|
||||
|
|
@ -1103,6 +1008,7 @@ static int mpeg_open(struct file *file)
|
|||
|
||||
dev->core->mpeg_users++;
|
||||
mutex_unlock(&dev->core->lock);
|
||||
v4l2_fh_add(&fh->fh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1123,6 +1029,8 @@ static int mpeg_release(struct file *file)
|
|||
|
||||
videobuf_mmap_free(&fh->mpegq);
|
||||
|
||||
v4l2_fh_del(&fh->fh);
|
||||
v4l2_fh_exit(&fh->fh);
|
||||
file->private_data = NULL;
|
||||
kfree(fh);
|
||||
|
||||
|
|
@ -1155,13 +1063,14 @@ mpeg_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
|
|||
static unsigned int
|
||||
mpeg_poll(struct file *file, struct poll_table_struct *wait)
|
||||
{
|
||||
unsigned long req_events = poll_requested_events(wait);
|
||||
struct cx8802_fh *fh = file->private_data;
|
||||
struct cx8802_dev *dev = fh->dev;
|
||||
|
||||
if (!dev->mpeg_active)
|
||||
if (!dev->mpeg_active && (req_events & (POLLIN | POLLRDNORM)))
|
||||
blackbird_start_codec(file, fh);
|
||||
|
||||
return videobuf_poll_stream(file, &fh->mpegq, wait);
|
||||
return v4l2_ctrl_poll(file, wait) | videobuf_poll_stream(file, &fh->mpegq, wait);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -1180,11 +1089,10 @@ static const struct v4l2_file_operations mpeg_fops =
|
|||
.read = mpeg_read,
|
||||
.poll = mpeg_poll,
|
||||
.mmap = mpeg_mmap,
|
||||
.ioctl = video_ioctl2,
|
||||
.unlocked_ioctl = video_ioctl2,
|
||||
};
|
||||
|
||||
static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
|
||||
.vidioc_querymenu = vidioc_querymenu,
|
||||
.vidioc_querycap = vidioc_querycap,
|
||||
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
|
||||
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
|
||||
|
|
@ -1196,21 +1104,18 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
|
|||
.vidioc_dqbuf = vidioc_dqbuf,
|
||||
.vidioc_streamon = vidioc_streamon,
|
||||
.vidioc_streamoff = vidioc_streamoff,
|
||||
.vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
|
||||
.vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
|
||||
.vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
|
||||
.vidioc_s_frequency = vidioc_s_frequency,
|
||||
.vidioc_log_status = vidioc_log_status,
|
||||
.vidioc_queryctrl = vidioc_queryctrl,
|
||||
.vidioc_enum_input = vidioc_enum_input,
|
||||
.vidioc_g_ctrl = vidioc_g_ctrl,
|
||||
.vidioc_s_ctrl = vidioc_s_ctrl,
|
||||
.vidioc_g_frequency = vidioc_g_frequency,
|
||||
.vidioc_g_input = vidioc_g_input,
|
||||
.vidioc_s_input = vidioc_s_input,
|
||||
.vidioc_g_tuner = vidioc_g_tuner,
|
||||
.vidioc_s_tuner = vidioc_s_tuner,
|
||||
.vidioc_g_std = vidioc_g_std,
|
||||
.vidioc_s_std = vidioc_s_std,
|
||||
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
|
||||
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
|
||||
};
|
||||
|
||||
static struct video_device cx8802_mpeg_template = {
|
||||
|
|
@ -1218,7 +1123,6 @@ static struct video_device cx8802_mpeg_template = {
|
|||
.fops = &mpeg_fops,
|
||||
.ioctl_ops = &mpeg_ioctl_ops,
|
||||
.tvnorms = CX88_NORMS,
|
||||
.current_norm = V4L2_STD_NTSC_M,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
|
@ -1286,6 +1190,7 @@ static int blackbird_register_video(struct cx8802_dev *dev)
|
|||
|
||||
dev->mpeg_dev = cx88_vdev_init(dev->core,dev->pci,
|
||||
&cx8802_mpeg_template,"mpeg");
|
||||
dev->mpeg_dev->ctrl_handler = &dev->cxhdl.hdl;
|
||||
video_set_drvdata(dev->mpeg_dev, dev);
|
||||
err = video_register_device(dev->mpeg_dev,VFL_TYPE_GRABBER, -1);
|
||||
if (err < 0) {
|
||||
|
|
@ -1318,17 +1223,20 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
|
|||
goto fail_core;
|
||||
|
||||
dev->width = 720;
|
||||
dev->height = 576;
|
||||
cx2341x_fill_defaults(&dev->params);
|
||||
dev->params.port = CX2341X_PORT_STREAMING;
|
||||
|
||||
cx8802_mpeg_template.current_norm = core->tvnorm;
|
||||
|
||||
if (core->tvnorm & V4L2_STD_525_60) {
|
||||
dev->height = 480;
|
||||
} else {
|
||||
dev->height = 576;
|
||||
}
|
||||
dev->cxhdl.port = CX2341X_PORT_STREAMING;
|
||||
dev->cxhdl.width = dev->width;
|
||||
dev->cxhdl.height = dev->height;
|
||||
dev->cxhdl.func = blackbird_mbox_func;
|
||||
dev->cxhdl.priv = dev;
|
||||
err = cx2341x_handler_init(&dev->cxhdl, 36);
|
||||
if (err)
|
||||
goto fail_core;
|
||||
v4l2_ctrl_add_handler(&dev->cxhdl.hdl, &core->video_hdl);
|
||||
|
||||
/* blackbird stuff */
|
||||
printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n",
|
||||
|
|
@ -1336,12 +1244,14 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
|
|||
host_setup(dev->core);
|
||||
|
||||
blackbird_initialize_codec(dev);
|
||||
blackbird_register_video(dev);
|
||||
|
||||
/* initial device configuration: needed ? */
|
||||
// init_controls(core);
|
||||
cx88_set_tvnorm(core,core->tvnorm);
|
||||
cx88_video_mux(core,0);
|
||||
cx2341x_handler_set_50hz(&dev->cxhdl, dev->height == 576);
|
||||
cx2341x_handler_setup(&dev->cxhdl);
|
||||
blackbird_register_video(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
@ -1351,8 +1261,12 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
|
|||
|
||||
static int cx8802_blackbird_remove(struct cx8802_driver *drv)
|
||||
{
|
||||
struct cx88_core *core = drv->core;
|
||||
struct cx8802_dev *dev = core->dvbdev;
|
||||
|
||||
/* blackbird */
|
||||
blackbird_unregister_video(drv->core->dvbdev);
|
||||
v4l2_ctrl_handler_free(&dev->cxhdl.hdl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3693,7 +3693,22 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (v4l2_ctrl_handler_init(&core->video_hdl, 13)) {
|
||||
v4l2_device_unregister(&core->v4l2_dev);
|
||||
kfree(core);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (v4l2_ctrl_handler_init(&core->audio_hdl, 13)) {
|
||||
v4l2_ctrl_handler_free(&core->video_hdl);
|
||||
v4l2_device_unregister(&core->v4l2_dev);
|
||||
kfree(core);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (0 != cx88_get_resources(core, pci)) {
|
||||
v4l2_ctrl_handler_free(&core->video_hdl);
|
||||
v4l2_ctrl_handler_free(&core->audio_hdl);
|
||||
v4l2_device_unregister(&core->v4l2_dev);
|
||||
kfree(core);
|
||||
return NULL;
|
||||
|
|
@ -3706,6 +3721,11 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
|
|||
core->bmmio = (u8 __iomem *)core->lmmio;
|
||||
|
||||
if (core->lmmio == NULL) {
|
||||
release_mem_region(pci_resource_start(pci, 0),
|
||||
pci_resource_len(pci, 0));
|
||||
v4l2_ctrl_handler_free(&core->video_hdl);
|
||||
v4l2_ctrl_handler_free(&core->audio_hdl);
|
||||
v4l2_device_unregister(&core->v4l2_dev);
|
||||
kfree(core);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1012,6 +1012,9 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
|
|||
// tell i2c chips
|
||||
call_all(core, core, s_std, norm);
|
||||
|
||||
/* The chroma_agc control should be inaccessible if the video format is SECAM */
|
||||
v4l2_ctrl_grab(core->chroma_agc, cxiformat == VideoFormatSECAM);
|
||||
|
||||
// done
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1030,10 +1033,10 @@ struct video_device *cx88_vdev_init(struct cx88_core *core,
|
|||
return NULL;
|
||||
*vfd = *template_;
|
||||
vfd->v4l2_dev = &core->v4l2_dev;
|
||||
vfd->parent = &pci->dev;
|
||||
vfd->release = video_device_release;
|
||||
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
|
||||
core->name, type, core->board.name);
|
||||
set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
|
||||
return vfd;
|
||||
}
|
||||
|
||||
|
|
@ -1086,6 +1089,8 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
|
|||
iounmap(core->lmmio);
|
||||
cx88_devcount--;
|
||||
mutex_unlock(&devlist);
|
||||
v4l2_ctrl_handler_free(&core->video_hdl);
|
||||
v4l2_ctrl_handler_free(&core->audio_hdl);
|
||||
v4l2_device_unregister(&core->v4l2_dev);
|
||||
kfree(core);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -26,6 +26,7 @@
|
|||
#include <linux/kdev_t.h>
|
||||
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-fh.h>
|
||||
#include <media/tuner.h>
|
||||
#include <media/tveeprom.h>
|
||||
#include <media/videobuf-dma-sg.h>
|
||||
|
|
@ -115,15 +116,6 @@ struct cx8800_fmt {
|
|||
u32 cxformat;
|
||||
};
|
||||
|
||||
struct cx88_ctrl {
|
||||
struct v4l2_queryctrl v;
|
||||
u32 off;
|
||||
u32 reg;
|
||||
u32 sreg;
|
||||
u32 mask;
|
||||
u32 shift;
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------- */
|
||||
/* SRAM memory management data (see cx88-core.c) */
|
||||
|
||||
|
|
@ -359,6 +351,10 @@ struct cx88_core {
|
|||
|
||||
/* config info -- analog */
|
||||
struct v4l2_device v4l2_dev;
|
||||
struct v4l2_ctrl_handler video_hdl;
|
||||
struct v4l2_ctrl *chroma_agc;
|
||||
struct v4l2_ctrl_handler audio_hdl;
|
||||
struct v4l2_subdev *sd_wm8775;
|
||||
struct i2c_client *i2c_rtc;
|
||||
unsigned int boardnr;
|
||||
struct cx88_board board;
|
||||
|
|
@ -409,8 +405,6 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev)
|
|||
return container_of(v4l2_dev, struct cx88_core, v4l2_dev);
|
||||
}
|
||||
|
||||
#define WM8775_GID (1 << 0)
|
||||
|
||||
#define call_hw(core, grpid, o, f, args...) \
|
||||
do { \
|
||||
if (!core->i2c_rc) { \
|
||||
|
|
@ -424,6 +418,36 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev)
|
|||
|
||||
#define call_all(core, o, f, args...) call_hw(core, 0, o, f, ##args)
|
||||
|
||||
#define WM8775_GID (1 << 0)
|
||||
|
||||
#define wm8775_s_ctrl(core, id, val) \
|
||||
do { \
|
||||
struct v4l2_ctrl *ctrl_ = \
|
||||
v4l2_ctrl_find(core->sd_wm8775->ctrl_handler, id); \
|
||||
if (ctrl_ && !core->i2c_rc) { \
|
||||
if (core->gate_ctrl) \
|
||||
core->gate_ctrl(core, 1); \
|
||||
v4l2_ctrl_s_ctrl(ctrl_, val); \
|
||||
if (core->gate_ctrl) \
|
||||
core->gate_ctrl(core, 0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define wm8775_g_ctrl(core, id) \
|
||||
({ \
|
||||
struct v4l2_ctrl *ctrl_ = \
|
||||
v4l2_ctrl_find(core->sd_wm8775->ctrl_handler, id); \
|
||||
s32 val = 0; \
|
||||
if (ctrl_ && !core->i2c_rc) { \
|
||||
if (core->gate_ctrl) \
|
||||
core->gate_ctrl(core, 1); \
|
||||
val = v4l2_ctrl_g_ctrl(ctrl_); \
|
||||
if (core->gate_ctrl) \
|
||||
core->gate_ctrl(core, 0); \
|
||||
} \
|
||||
val; \
|
||||
})
|
||||
|
||||
struct cx8800_dev;
|
||||
struct cx8802_dev;
|
||||
|
||||
|
|
@ -431,19 +455,11 @@ struct cx8802_dev;
|
|||
/* function 0: video stuff */
|
||||
|
||||
struct cx8800_fh {
|
||||
struct v4l2_fh fh;
|
||||
struct cx8800_dev *dev;
|
||||
enum v4l2_buf_type type;
|
||||
int radio;
|
||||
unsigned int resources;
|
||||
|
||||
/* video overlay */
|
||||
struct v4l2_window win;
|
||||
struct v4l2_clip *clips;
|
||||
unsigned int nclips;
|
||||
|
||||
/* video capture */
|
||||
const struct cx8800_fmt *fmt;
|
||||
unsigned int width,height;
|
||||
struct videobuf_queue vidq;
|
||||
|
||||
/* vbi capture */
|
||||
|
|
@ -468,6 +484,8 @@ struct cx8800_dev {
|
|||
struct pci_dev *pci;
|
||||
unsigned char pci_rev,pci_lat;
|
||||
|
||||
const struct cx8800_fmt *fmt;
|
||||
unsigned int width, height;
|
||||
|
||||
/* capture queues */
|
||||
struct cx88_dmaqueue vidq;
|
||||
|
|
@ -488,6 +506,7 @@ struct cx8800_dev {
|
|||
/* function 2: mpeg stuff */
|
||||
|
||||
struct cx8802_fh {
|
||||
struct v4l2_fh fh;
|
||||
struct cx8802_dev *dev;
|
||||
struct videobuf_queue mpegq;
|
||||
};
|
||||
|
|
@ -552,7 +571,7 @@ struct cx8802_dev {
|
|||
unsigned char mpeg_active; /* nonzero if mpeg encoder is active */
|
||||
|
||||
/* mpeg params */
|
||||
struct cx2341x_mpeg_params params;
|
||||
struct cx2341x_handler cxhdl;
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
|
||||
|
|
@ -722,11 +741,8 @@ void cx8802_cancel_buffers(struct cx8802_dev *dev);
|
|||
|
||||
/* ----------------------------------------------------------- */
|
||||
/* cx88-video.c*/
|
||||
extern const u32 cx88_user_ctrls[];
|
||||
extern int cx8800_ctrl_query(struct cx88_core *core,
|
||||
struct v4l2_queryctrl *qctrl);
|
||||
int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i);
|
||||
int cx88_set_freq (struct cx88_core *core,struct v4l2_frequency *f);
|
||||
int cx88_get_control(struct cx88_core *core, struct v4l2_control *ctl);
|
||||
int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl);
|
||||
int cx88_video_mux(struct cx88_core *core, unsigned int input);
|
||||
void cx88_querycap(struct file *file, struct cx88_core *core,
|
||||
struct v4l2_capability *cap);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include <sound/initval.h>
|
||||
#include <sound/control.h>
|
||||
#include <sound/tlv.h>
|
||||
#include <sound/ac97_codec.h>
|
||||
#include <media/v4l2-common.h>
|
||||
#include "em28xx.h"
|
||||
|
||||
|
|
@ -679,19 +680,19 @@ static int em28xx_audio_init(struct em28xx *dev)
|
|||
INIT_WORK(&dev->wq_trigger, audio_trigger);
|
||||
|
||||
if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
|
||||
em28xx_cvol_new(card, dev, "Video", AC97_VIDEO_VOL);
|
||||
em28xx_cvol_new(card, dev, "Line In", AC97_LINEIN_VOL);
|
||||
em28xx_cvol_new(card, dev, "Phone", AC97_PHONE_VOL);
|
||||
em28xx_cvol_new(card, dev, "Microphone", AC97_PHONE_VOL);
|
||||
em28xx_cvol_new(card, dev, "CD", AC97_CD_VOL);
|
||||
em28xx_cvol_new(card, dev, "AUX", AC97_AUX_VOL);
|
||||
em28xx_cvol_new(card, dev, "PCM", AC97_PCM_OUT_VOL);
|
||||
em28xx_cvol_new(card, dev, "Video", AC97_VIDEO);
|
||||
em28xx_cvol_new(card, dev, "Line In", AC97_LINE);
|
||||
em28xx_cvol_new(card, dev, "Phone", AC97_PHONE);
|
||||
em28xx_cvol_new(card, dev, "Microphone", AC97_MIC);
|
||||
em28xx_cvol_new(card, dev, "CD", AC97_CD);
|
||||
em28xx_cvol_new(card, dev, "AUX", AC97_AUX);
|
||||
em28xx_cvol_new(card, dev, "PCM", AC97_PCM);
|
||||
|
||||
em28xx_cvol_new(card, dev, "Master", AC97_MASTER_VOL);
|
||||
em28xx_cvol_new(card, dev, "Line", AC97_LINE_LEVEL_VOL);
|
||||
em28xx_cvol_new(card, dev, "Mono", AC97_MASTER_MONO_VOL);
|
||||
em28xx_cvol_new(card, dev, "LFE", AC97_LFE_MASTER_VOL);
|
||||
em28xx_cvol_new(card, dev, "Surround", AC97_SURR_MASTER_VOL);
|
||||
em28xx_cvol_new(card, dev, "Master", AC97_MASTER);
|
||||
em28xx_cvol_new(card, dev, "Line", AC97_HEADPHONE);
|
||||
em28xx_cvol_new(card, dev, "Mono", AC97_MASTER_MONO);
|
||||
em28xx_cvol_new(card, dev, "LFE", AC97_CENTER_LFE_MASTER);
|
||||
em28xx_cvol_new(card, dev, "Surround", AC97_SURROUND_MASTER);
|
||||
}
|
||||
|
||||
err = snd_card_register(card);
|
||||
|
|
|
|||
|
|
@ -975,12 +975,7 @@ struct em28xx_board em28xx_boards[] = {
|
|||
.name = "Terratec Cinergy HTC Stick",
|
||||
.has_dvb = 1,
|
||||
.ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS,
|
||||
#if 0
|
||||
.tuner_type = TUNER_PHILIPS_TDA8290,
|
||||
.tuner_addr = 0x41,
|
||||
.dvb_gpio = terratec_h5_digital, /* FIXME: probably wrong */
|
||||
.tuner_gpio = terratec_h5_gpio,
|
||||
#endif
|
||||
.tuner_type = TUNER_ABSENT,
|
||||
.i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT |
|
||||
EM28XX_I2C_CLK_WAIT_ENABLE |
|
||||
EM28XX_I2C_FREQ_400_KHZ,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <sound/ac97_codec.h>
|
||||
#include <media/v4l2-common.h>
|
||||
|
||||
#include "em28xx.h"
|
||||
|
|
@ -326,13 +327,13 @@ struct em28xx_vol_itable {
|
|||
};
|
||||
|
||||
static struct em28xx_vol_itable inputs[] = {
|
||||
{ EM28XX_AMUX_VIDEO, AC97_VIDEO_VOL },
|
||||
{ EM28XX_AMUX_LINE_IN, AC97_LINEIN_VOL },
|
||||
{ EM28XX_AMUX_PHONE, AC97_PHONE_VOL },
|
||||
{ EM28XX_AMUX_MIC, AC97_MIC_VOL },
|
||||
{ EM28XX_AMUX_CD, AC97_CD_VOL },
|
||||
{ EM28XX_AMUX_AUX, AC97_AUX_VOL },
|
||||
{ EM28XX_AMUX_PCM_OUT, AC97_PCM_OUT_VOL },
|
||||
{ EM28XX_AMUX_VIDEO, AC97_VIDEO },
|
||||
{ EM28XX_AMUX_LINE_IN, AC97_LINE },
|
||||
{ EM28XX_AMUX_PHONE, AC97_PHONE },
|
||||
{ EM28XX_AMUX_MIC, AC97_MIC },
|
||||
{ EM28XX_AMUX_CD, AC97_CD },
|
||||
{ EM28XX_AMUX_AUX, AC97_AUX },
|
||||
{ EM28XX_AMUX_PCM_OUT, AC97_PCM },
|
||||
};
|
||||
|
||||
static int set_ac97_input(struct em28xx *dev)
|
||||
|
|
@ -415,11 +416,11 @@ struct em28xx_vol_otable {
|
|||
};
|
||||
|
||||
static const struct em28xx_vol_otable outputs[] = {
|
||||
{ EM28XX_AOUT_MASTER, AC97_MASTER_VOL },
|
||||
{ EM28XX_AOUT_LINE, AC97_LINE_LEVEL_VOL },
|
||||
{ EM28XX_AOUT_MONO, AC97_MASTER_MONO_VOL },
|
||||
{ EM28XX_AOUT_LFE, AC97_LFE_MASTER_VOL },
|
||||
{ EM28XX_AOUT_SURR, AC97_SURR_MASTER_VOL },
|
||||
{ EM28XX_AOUT_MASTER, AC97_MASTER },
|
||||
{ EM28XX_AOUT_LINE, AC97_HEADPHONE },
|
||||
{ EM28XX_AOUT_MONO, AC97_MASTER_MONO },
|
||||
{ EM28XX_AOUT_LFE, AC97_CENTER_LFE_MASTER },
|
||||
{ EM28XX_AOUT_SURR, AC97_SURROUND_MASTER },
|
||||
};
|
||||
|
||||
int em28xx_audio_analog_set(struct em28xx *dev)
|
||||
|
|
@ -459,9 +460,9 @@ int em28xx_audio_analog_set(struct em28xx *dev)
|
|||
if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
|
||||
int vol;
|
||||
|
||||
em28xx_write_ac97(dev, AC97_POWER_DOWN_CTRL, 0x4200);
|
||||
em28xx_write_ac97(dev, AC97_EXT_AUD_CTRL, 0x0031);
|
||||
em28xx_write_ac97(dev, AC97_PCM_IN_SRATE, 0xbb80);
|
||||
em28xx_write_ac97(dev, AC97_POWERDOWN, 0x4200);
|
||||
em28xx_write_ac97(dev, AC97_EXTENDED_STATUS, 0x0031);
|
||||
em28xx_write_ac97(dev, AC97_PCM_LR_ADC_RATE, 0xbb80);
|
||||
|
||||
/* LSB: left channel - both channels with the same level */
|
||||
vol = (0x1f - dev->volume) | ((0x1f - dev->volume) << 8);
|
||||
|
|
@ -487,7 +488,7 @@ int em28xx_audio_analog_set(struct em28xx *dev)
|
|||
channels */
|
||||
sel |= (sel << 8);
|
||||
|
||||
em28xx_write_ac97(dev, AC97_RECORD_SELECT, sel);
|
||||
em28xx_write_ac97(dev, AC97_REC_SEL, sel);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -310,31 +310,47 @@ static struct drxd_config em28xx_drxd = {
|
|||
.disable_i2c_gate_ctrl = 1,
|
||||
};
|
||||
|
||||
struct drxk_config terratec_h5_drxk = {
|
||||
static struct drxk_config terratec_h5_drxk = {
|
||||
.adr = 0x29,
|
||||
.single_master = 1,
|
||||
.no_i2c_bridge = 1,
|
||||
.microcode_name = "dvb-usb-terratec-h5-drxk.fw",
|
||||
.qam_demod_parameter_count = 2,
|
||||
};
|
||||
|
||||
struct drxk_config hauppauge_930c_drxk = {
|
||||
static struct drxk_config hauppauge_930c_drxk = {
|
||||
.adr = 0x29,
|
||||
.single_master = 1,
|
||||
.no_i2c_bridge = 1,
|
||||
.microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw",
|
||||
.chunk_size = 56,
|
||||
.qam_demod_parameter_count = 2,
|
||||
};
|
||||
|
||||
struct drxk_config maxmedia_ub425_tc_drxk = {
|
||||
struct drxk_config terratec_htc_stick_drxk = {
|
||||
.adr = 0x29,
|
||||
.single_master = 1,
|
||||
.no_i2c_bridge = 1,
|
||||
.microcode_name = "dvb-usb-terratec-htc-stick-drxk.fw",
|
||||
.chunk_size = 54,
|
||||
.qam_demod_parameter_count = 2,
|
||||
/* Required for the antenna_gpio to disable LNA. */
|
||||
.antenna_dvbt = true,
|
||||
/* The windows driver uses the same. This will disable LNA. */
|
||||
.antenna_gpio = 0x6,
|
||||
};
|
||||
|
||||
static struct drxk_config maxmedia_ub425_tc_drxk = {
|
||||
.adr = 0x29,
|
||||
.single_master = 1,
|
||||
.no_i2c_bridge = 1,
|
||||
};
|
||||
|
||||
struct drxk_config pctv_520e_drxk = {
|
||||
static struct drxk_config pctv_520e_drxk = {
|
||||
.adr = 0x29,
|
||||
.single_master = 1,
|
||||
.microcode_name = "dvb-demod-drxk-pctv.fw",
|
||||
.qam_demod_parameter_count = 2,
|
||||
.chunk_size = 58,
|
||||
.antenna_dvbt = true, /* disable LNA */
|
||||
.antenna_gpio = (1 << 2), /* disable LNA */
|
||||
|
|
@ -473,6 +489,57 @@ static void terratec_h5_init(struct em28xx *dev)
|
|||
em28xx_gpio_set(dev, terratec_h5_end);
|
||||
};
|
||||
|
||||
static void terratec_htc_stick_init(struct em28xx *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* GPIO configuration:
|
||||
* 0xff: unknown (does not affect DVB-T).
|
||||
* 0xf6: DRX-K (demodulator).
|
||||
* 0xe6: unknown (does not affect DVB-T).
|
||||
* 0xb6: unknown (does not affect DVB-T).
|
||||
*/
|
||||
struct em28xx_reg_seq terratec_htc_stick_init[] = {
|
||||
{EM28XX_R08_GPIO, 0xff, 0xff, 10},
|
||||
{EM2874_R80_GPIO, 0xf6, 0xff, 100},
|
||||
{EM2874_R80_GPIO, 0xe6, 0xff, 50},
|
||||
{EM2874_R80_GPIO, 0xf6, 0xff, 100},
|
||||
{ -1, -1, -1, -1},
|
||||
};
|
||||
struct em28xx_reg_seq terratec_htc_stick_end[] = {
|
||||
{EM2874_R80_GPIO, 0xb6, 0xff, 100},
|
||||
{EM2874_R80_GPIO, 0xf6, 0xff, 50},
|
||||
{ -1, -1, -1, -1},
|
||||
};
|
||||
|
||||
/* Init the analog decoder? */
|
||||
struct {
|
||||
unsigned char r[4];
|
||||
int len;
|
||||
} regs[] = {
|
||||
{{ 0x06, 0x02, 0x00, 0x31 }, 4},
|
||||
{{ 0x01, 0x02 }, 2},
|
||||
{{ 0x01, 0x02, 0x00, 0xc6 }, 4},
|
||||
{{ 0x01, 0x00 }, 2},
|
||||
{{ 0x01, 0x00, 0xff, 0xaf }, 4},
|
||||
};
|
||||
|
||||
em28xx_gpio_set(dev, terratec_htc_stick_init);
|
||||
|
||||
em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40);
|
||||
msleep(10);
|
||||
em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44);
|
||||
msleep(10);
|
||||
|
||||
dev->i2c_client.addr = 0x82 >> 1;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(regs); i++)
|
||||
i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len);
|
||||
|
||||
em28xx_gpio_set(dev, terratec_htc_stick_end);
|
||||
};
|
||||
|
||||
static void pctv_520e_init(struct em28xx *dev)
|
||||
{
|
||||
/*
|
||||
|
|
@ -944,7 +1011,6 @@ static int em28xx_dvb_init(struct em28xx *dev)
|
|||
break;
|
||||
}
|
||||
case EM2884_BOARD_TERRATEC_H5:
|
||||
case EM2884_BOARD_CINERGY_HTC_STICK:
|
||||
terratec_h5_init(dev);
|
||||
|
||||
dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, &dev->i2c_adap);
|
||||
|
|
@ -1021,6 +1087,25 @@ static int em28xx_dvb_init(struct em28xx *dev)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case EM2884_BOARD_CINERGY_HTC_STICK:
|
||||
terratec_htc_stick_init(dev);
|
||||
|
||||
/* attach demodulator */
|
||||
dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk,
|
||||
&dev->i2c_adap);
|
||||
if (!dvb->fe[0]) {
|
||||
result = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
/* Attach the demodulator. */
|
||||
if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
|
||||
&dev->i2c_adap,
|
||||
&em28xx_cxd2820r_tda18271_config)) {
|
||||
result = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
em28xx_errdev("/2: The frontend of your DVB/ATSC card"
|
||||
" isn't supported yet\n");
|
||||
|
|
|
|||
|
|
@ -475,6 +475,7 @@ static struct i2c_client em28xx_client_template = {
|
|||
*/
|
||||
static char *i2c_devs[128] = {
|
||||
[0x4a >> 1] = "saa7113h",
|
||||
[0x52 >> 1] = "drxk",
|
||||
[0x60 >> 1] = "remote IR sensor",
|
||||
[0x8e >> 1] = "remote IR sensor",
|
||||
[0x86 >> 1] = "tda9887",
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ static void em28xx_ir_stop(struct rc_dev *rc)
|
|||
cancel_delayed_work_sync(&ir->work);
|
||||
}
|
||||
|
||||
int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type)
|
||||
static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type)
|
||||
{
|
||||
int rc = 0;
|
||||
struct em28xx_IR *ir = rc_dev->priv;
|
||||
|
|
|
|||
|
|
@ -211,58 +211,9 @@ enum em28xx_chip_id {
|
|||
};
|
||||
|
||||
/*
|
||||
* Registers used by em202 and other AC97 chips
|
||||
* Registers used by em202
|
||||
*/
|
||||
|
||||
/* Standard AC97 registers */
|
||||
#define AC97_RESET 0x00
|
||||
|
||||
/* Output volumes */
|
||||
#define AC97_MASTER_VOL 0x02
|
||||
#define AC97_LINE_LEVEL_VOL 0x04 /* Some devices use for headphones */
|
||||
#define AC97_MASTER_MONO_VOL 0x06
|
||||
|
||||
/* Input volumes */
|
||||
#define AC97_PC_BEEP_VOL 0x0a
|
||||
#define AC97_PHONE_VOL 0x0c
|
||||
#define AC97_MIC_VOL 0x0e
|
||||
#define AC97_LINEIN_VOL 0x10
|
||||
#define AC97_CD_VOL 0x12
|
||||
#define AC97_VIDEO_VOL 0x14
|
||||
#define AC97_AUX_VOL 0x16
|
||||
#define AC97_PCM_OUT_VOL 0x18
|
||||
|
||||
/* capture registers */
|
||||
#define AC97_RECORD_SELECT 0x1a
|
||||
#define AC97_RECORD_GAIN 0x1c
|
||||
|
||||
/* control registers */
|
||||
#define AC97_GENERAL_PURPOSE 0x20
|
||||
#define AC97_3D_CTRL 0x22
|
||||
#define AC97_AUD_INT_AND_PAG 0x24
|
||||
#define AC97_POWER_DOWN_CTRL 0x26
|
||||
#define AC97_EXT_AUD_ID 0x28
|
||||
#define AC97_EXT_AUD_CTRL 0x2a
|
||||
|
||||
/* Supported rate varies for each AC97 device
|
||||
if write an unsupported value, it will return the closest one
|
||||
*/
|
||||
#define AC97_PCM_OUT_FRONT_SRATE 0x2c
|
||||
#define AC97_PCM_OUT_SURR_SRATE 0x2e
|
||||
#define AC97_PCM_OUT_LFE_SRATE 0x30
|
||||
#define AC97_PCM_IN_SRATE 0x32
|
||||
|
||||
/* For devices with more than 2 channels, extra output volumes */
|
||||
#define AC97_LFE_MASTER_VOL 0x36
|
||||
#define AC97_SURR_MASTER_VOL 0x38
|
||||
|
||||
/* Digital SPDIF output control */
|
||||
#define AC97_SPDIF_OUT_CTRL 0x3a
|
||||
|
||||
/* Vendor ID identifier */
|
||||
#define AC97_VENDOR_ID1 0x7c
|
||||
#define AC97_VENDOR_ID2 0x7e
|
||||
|
||||
/* EMP202 vendor registers */
|
||||
#define EM202_EXT_MODEM_CTRL 0x3e
|
||||
#define EM202_GPIO_CONF 0x4c
|
||||
|
|
|
|||
|
|
@ -1,94 +0,0 @@
|
|||
/* ibmmpeg2.h - IBM MPEGCD21 definitions */
|
||||
|
||||
#ifndef __IBM_MPEG2__
|
||||
#define __IBM_MPEG2__
|
||||
|
||||
/* Define all MPEG Decoder registers */
|
||||
/* Chip Control and Status */
|
||||
#define IBM_MP2_CHIP_CONTROL 0x200*2
|
||||
#define IBM_MP2_CHIP_MODE 0x201*2
|
||||
/* Timer Control and Status */
|
||||
#define IBM_MP2_SYNC_STC2 0x202*2
|
||||
#define IBM_MP2_SYNC_STC1 0x203*2
|
||||
#define IBM_MP2_SYNC_STC0 0x204*2
|
||||
#define IBM_MP2_SYNC_PTS2 0x205*2
|
||||
#define IBM_MP2_SYNC_PTS1 0x206*2
|
||||
#define IBM_MP2_SYNC_PTS0 0x207*2
|
||||
/* Video FIFO Control */
|
||||
#define IBM_MP2_FIFO 0x208*2
|
||||
#define IBM_MP2_FIFOW 0x100*2
|
||||
#define IBM_MP2_FIFO_STAT 0x209*2
|
||||
#define IBM_MP2_RB_THRESHOLD 0x22b*2
|
||||
/* Command buffer */
|
||||
#define IBM_MP2_COMMAND 0x20a*2
|
||||
#define IBM_MP2_CMD_DATA 0x20b*2
|
||||
#define IBM_MP2_CMD_STAT 0x20c*2
|
||||
#define IBM_MP2_CMD_ADDR 0x20d*2
|
||||
/* Internal Processor Control and Status */
|
||||
#define IBM_MP2_PROC_IADDR 0x20e*2
|
||||
#define IBM_MP2_PROC_IDATA 0x20f*2
|
||||
#define IBM_MP2_WR_PROT 0x235*2
|
||||
/* DRAM Access */
|
||||
#define IBM_MP2_DRAM_ADDR 0x210*2
|
||||
#define IBM_MP2_DRAM_DATA 0x212*2
|
||||
#define IBM_MP2_DRAM_CMD_STAT 0x213*2
|
||||
#define IBM_MP2_BLOCK_SIZE 0x23b*2
|
||||
#define IBM_MP2_SRC_ADDR 0x23c*2
|
||||
/* Onscreen Display */
|
||||
#define IBM_MP2_OSD_ADDR 0x214*2
|
||||
#define IBM_MP2_OSD_DATA 0x215*2
|
||||
#define IBM_MP2_OSD_MODE 0x217*2
|
||||
#define IBM_MP2_OSD_LINK_ADDR 0x229*2
|
||||
#define IBM_MP2_OSD_SIZE 0x22a*2
|
||||
/* Interrupt Control */
|
||||
#define IBM_MP2_HOST_INT 0x218*2
|
||||
#define IBM_MP2_MASK0 0x219*2
|
||||
#define IBM_MP2_HOST_INT1 0x23e*2
|
||||
#define IBM_MP2_MASK1 0x23f*2
|
||||
/* Audio Control */
|
||||
#define IBM_MP2_AUD_IADDR 0x21a*2
|
||||
#define IBM_MP2_AUD_IDATA 0x21b*2
|
||||
#define IBM_MP2_AUD_FIFO 0x21c*2
|
||||
#define IBM_MP2_AUD_FIFOW 0x101*2
|
||||
#define IBM_MP2_AUD_CTL 0x21d*2
|
||||
#define IBM_MP2_BEEP_CTL 0x21e*2
|
||||
#define IBM_MP2_FRNT_ATTEN 0x22d*2
|
||||
/* Display Control */
|
||||
#define IBM_MP2_DISP_MODE 0x220*2
|
||||
#define IBM_MP2_DISP_DLY 0x221*2
|
||||
#define IBM_MP2_VBI_CTL 0x222*2
|
||||
#define IBM_MP2_DISP_LBOR 0x223*2
|
||||
#define IBM_MP2_DISP_TBOR 0x224*2
|
||||
/* Polarity Control */
|
||||
#define IBM_MP2_INFC_CTL 0x22c*2
|
||||
|
||||
/* control commands */
|
||||
#define IBM_MP2_PLAY 0
|
||||
#define IBM_MP2_PAUSE 1
|
||||
#define IBM_MP2_SINGLE_FRAME 2
|
||||
#define IBM_MP2_FAST_FORWARD 3
|
||||
#define IBM_MP2_SLOW_MOTION 4
|
||||
#define IBM_MP2_IMED_NORM_PLAY 5
|
||||
#define IBM_MP2_RESET_WINDOW 6
|
||||
#define IBM_MP2_FREEZE_FRAME 7
|
||||
#define IBM_MP2_RESET_VID_RATE 8
|
||||
#define IBM_MP2_CONFIG_DECODER 9
|
||||
#define IBM_MP2_CHANNEL_SWITCH 10
|
||||
#define IBM_MP2_RESET_AUD_RATE 11
|
||||
#define IBM_MP2_PRE_OP_CHN_SW 12
|
||||
#define IBM_MP2_SET_STILL_MODE 14
|
||||
|
||||
/* Define Xilinx FPGA Internal Registers */
|
||||
|
||||
/* general control register 0 */
|
||||
#define XILINX_CTL0 0x600
|
||||
/* genlock delay resister 1 */
|
||||
#define XILINX_GLDELAY 0x602
|
||||
/* send 16 bits to CS3310 port */
|
||||
#define XILINX_CS3310 0x604
|
||||
/* send 16 bits to CS3310 and complete */
|
||||
#define XILINX_CS3310_CMPLT 0x60c
|
||||
/* pulse width modulator control */
|
||||
#define XILINX_PWM 0x606
|
||||
|
||||
#endif
|
||||
|
|
@ -1830,18 +1830,6 @@ static long ivtv_default(struct file *file, void *fh, bool valid_prio,
|
|||
return 0;
|
||||
}
|
||||
|
||||
long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct video_device *vfd = video_devdata(filp);
|
||||
long ret;
|
||||
|
||||
if (ivtv_debug & IVTV_DBGFLG_IOCTL)
|
||||
vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
|
||||
ret = video_ioctl2(filp, cmd, arg);
|
||||
vfd->debug = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
|
||||
.vidioc_querycap = ivtv_querycap,
|
||||
.vidioc_s_audio = ivtv_s_audio,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,5 @@ void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std);
|
|||
void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std);
|
||||
int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
|
||||
int ivtv_s_input(struct file *file, void *fh, unsigned int inp);
|
||||
long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ static const struct v4l2_file_operations ivtv_v4l2_enc_fops = {
|
|||
.read = ivtv_v4l2_read,
|
||||
.write = ivtv_v4l2_write,
|
||||
.open = ivtv_v4l2_open,
|
||||
.unlocked_ioctl = ivtv_v4l2_ioctl,
|
||||
.unlocked_ioctl = video_ioctl2,
|
||||
.release = ivtv_v4l2_close,
|
||||
.poll = ivtv_v4l2_enc_poll,
|
||||
};
|
||||
|
|
@ -60,7 +60,7 @@ static const struct v4l2_file_operations ivtv_v4l2_dec_fops = {
|
|||
.read = ivtv_v4l2_read,
|
||||
.write = ivtv_v4l2_write,
|
||||
.open = ivtv_v4l2_open,
|
||||
.unlocked_ioctl = ivtv_v4l2_ioctl,
|
||||
.unlocked_ioctl = video_ioctl2,
|
||||
.release = ivtv_v4l2_close,
|
||||
.poll = ivtv_v4l2_dec_poll,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
config VIDEO_M5MOLS
|
||||
tristate "Fujitsu M-5MOLS 8MP sensor support"
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
---help---
|
||||
This driver supports Fujitsu M-5MOLS camera sensor with ISP
|
||||
|
|
|
|||
|
|
@ -60,6 +60,10 @@ MODULE_VERSION("0.1.1");
|
|||
#define MEM2MEM_COLOR_STEP (0xff >> 4)
|
||||
#define MEM2MEM_NUM_TILES 8
|
||||
|
||||
/* Flags that indicate processing mode */
|
||||
#define MEM2MEM_HFLIP (1 << 0)
|
||||
#define MEM2MEM_VFLIP (1 << 1)
|
||||
|
||||
#define dprintk(dev, fmt, arg...) \
|
||||
v4l2_dbg(1, 1, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
|
||||
|
||||
|
|
@ -115,6 +119,24 @@ enum {
|
|||
|
||||
static struct v4l2_queryctrl m2mtest_ctrls[] = {
|
||||
{
|
||||
.id = V4L2_CID_HFLIP,
|
||||
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
||||
.name = "Mirror",
|
||||
.minimum = 0,
|
||||
.maximum = 1,
|
||||
.step = 1,
|
||||
.default_value = 0,
|
||||
.flags = 0,
|
||||
}, {
|
||||
.id = V4L2_CID_VFLIP,
|
||||
.type = V4L2_CTRL_TYPE_BOOLEAN,
|
||||
.name = "Vertical Mirror",
|
||||
.minimum = 0,
|
||||
.maximum = 1,
|
||||
.step = 1,
|
||||
.default_value = 0,
|
||||
.flags = 0,
|
||||
}, {
|
||||
.id = V4L2_CID_TRANS_TIME_MSEC,
|
||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||
.name = "Transaction time (msec)",
|
||||
|
|
@ -181,6 +203,9 @@ struct m2mtest_ctx {
|
|||
/* Abort requested by m2m */
|
||||
int aborting;
|
||||
|
||||
/* Processing mode */
|
||||
int mode;
|
||||
|
||||
struct v4l2_m2m_ctx *m2m_ctx;
|
||||
|
||||
/* Source and destination queue data */
|
||||
|
|
@ -249,19 +274,84 @@ static int device_process(struct m2mtest_ctx *ctx,
|
|||
bytes_left = bytesperline - tile_w * MEM2MEM_NUM_TILES;
|
||||
w = 0;
|
||||
|
||||
for (y = 0; y < height; ++y) {
|
||||
for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
|
||||
if (w & 0x1) {
|
||||
for (x = 0; x < tile_w; ++x)
|
||||
*p_out++ = *p_in++ + MEM2MEM_COLOR_STEP;
|
||||
} else {
|
||||
for (x = 0; x < tile_w; ++x)
|
||||
*p_out++ = *p_in++ - MEM2MEM_COLOR_STEP;
|
||||
switch (ctx->mode) {
|
||||
case MEM2MEM_HFLIP | MEM2MEM_VFLIP:
|
||||
p_out += bytesperline * height - bytes_left;
|
||||
for (y = 0; y < height; ++y) {
|
||||
for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
|
||||
if (w & 0x1) {
|
||||
for (x = 0; x < tile_w; ++x)
|
||||
*--p_out = *p_in++ +
|
||||
MEM2MEM_COLOR_STEP;
|
||||
} else {
|
||||
for (x = 0; x < tile_w; ++x)
|
||||
*--p_out = *p_in++ -
|
||||
MEM2MEM_COLOR_STEP;
|
||||
}
|
||||
++w;
|
||||
}
|
||||
++w;
|
||||
p_in += bytes_left;
|
||||
p_out -= bytes_left;
|
||||
}
|
||||
break;
|
||||
|
||||
case MEM2MEM_HFLIP:
|
||||
for (y = 0; y < height; ++y) {
|
||||
p_out += MEM2MEM_NUM_TILES * tile_w;
|
||||
for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
|
||||
if (w & 0x01) {
|
||||
for (x = 0; x < tile_w; ++x)
|
||||
*--p_out = *p_in++ +
|
||||
MEM2MEM_COLOR_STEP;
|
||||
} else {
|
||||
for (x = 0; x < tile_w; ++x)
|
||||
*--p_out = *p_in++ -
|
||||
MEM2MEM_COLOR_STEP;
|
||||
}
|
||||
++w;
|
||||
}
|
||||
p_in += bytes_left;
|
||||
p_out += bytesperline;
|
||||
}
|
||||
break;
|
||||
|
||||
case MEM2MEM_VFLIP:
|
||||
p_out += bytesperline * (height - 1);
|
||||
for (y = 0; y < height; ++y) {
|
||||
for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
|
||||
if (w & 0x1) {
|
||||
for (x = 0; x < tile_w; ++x)
|
||||
*p_out++ = *p_in++ +
|
||||
MEM2MEM_COLOR_STEP;
|
||||
} else {
|
||||
for (x = 0; x < tile_w; ++x)
|
||||
*p_out++ = *p_in++ -
|
||||
MEM2MEM_COLOR_STEP;
|
||||
}
|
||||
++w;
|
||||
}
|
||||
p_in += bytes_left;
|
||||
p_out += bytes_left - 2 * bytesperline;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
for (y = 0; y < height; ++y) {
|
||||
for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
|
||||
if (w & 0x1) {
|
||||
for (x = 0; x < tile_w; ++x)
|
||||
*p_out++ = *p_in++ +
|
||||
MEM2MEM_COLOR_STEP;
|
||||
} else {
|
||||
for (x = 0; x < tile_w; ++x)
|
||||
*p_out++ = *p_in++ -
|
||||
MEM2MEM_COLOR_STEP;
|
||||
}
|
||||
++w;
|
||||
}
|
||||
p_in += bytes_left;
|
||||
p_out += bytes_left;
|
||||
}
|
||||
p_in += bytes_left;
|
||||
p_out += bytes_left;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -648,6 +738,14 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
|
|||
struct m2mtest_ctx *ctx = priv;
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_HFLIP:
|
||||
ctrl->value = (ctx->mode & MEM2MEM_HFLIP) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case V4L2_CID_VFLIP:
|
||||
ctrl->value = (ctx->mode & MEM2MEM_VFLIP) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case V4L2_CID_TRANS_TIME_MSEC:
|
||||
ctrl->value = ctx->transtime;
|
||||
break;
|
||||
|
|
@ -691,6 +789,20 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
|
|||
return ret;
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_HFLIP:
|
||||
if (ctrl->value)
|
||||
ctx->mode |= MEM2MEM_HFLIP;
|
||||
else
|
||||
ctx->mode &= ~MEM2MEM_HFLIP;
|
||||
break;
|
||||
|
||||
case V4L2_CID_VFLIP:
|
||||
if (ctrl->value)
|
||||
ctx->mode |= MEM2MEM_VFLIP;
|
||||
else
|
||||
ctx->mode &= ~MEM2MEM_VFLIP;
|
||||
break;
|
||||
|
||||
case V4L2_CID_TRANS_TIME_MSEC:
|
||||
ctx->transtime = ctrl->value;
|
||||
break;
|
||||
|
|
@ -861,6 +973,7 @@ static int m2mtest_open(struct file *file)
|
|||
ctx->translen = MEM2MEM_DEF_TRANSLEN;
|
||||
ctx->transtime = MEM2MEM_DEF_TRANSTIME;
|
||||
ctx->num_processed = 0;
|
||||
ctx->mode = 0;
|
||||
|
||||
ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0];
|
||||
ctx->q_data[V4L2_M2M_DST].fmt = &formats[0];
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
/*
|
||||
* mt9m001 i2c address 0x5d
|
||||
* The platform has to define ctruct i2c_board_info objects and link to them
|
||||
* The platform has to define struct i2c_board_info objects and link to them
|
||||
* from struct soc_camera_link
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -688,11 +688,17 @@ static const struct v4l2_subdev_ops mt9m032_ops = {
|
|||
static int mt9m032_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *devid)
|
||||
{
|
||||
struct mt9m032_platform_data *pdata = client->dev.platform_data;
|
||||
struct i2c_adapter *adapter = client->adapter;
|
||||
struct mt9m032 *sensor;
|
||||
int chip_version;
|
||||
int ret;
|
||||
|
||||
if (pdata == NULL) {
|
||||
dev_err(&client->dev, "No platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
|
||||
dev_warn(&client->dev,
|
||||
"I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
|
||||
|
|
@ -708,7 +714,7 @@ static int mt9m032_probe(struct i2c_client *client,
|
|||
|
||||
mutex_init(&sensor->lock);
|
||||
|
||||
sensor->pdata = client->dev.platform_data;
|
||||
sensor->pdata = pdata;
|
||||
|
||||
v4l2_i2c_subdev_init(&sensor->subdev, client, &mt9m032_ops);
|
||||
sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
|
||||
|
|
@ -738,7 +744,7 @@ static int mt9m032_probe(struct i2c_client *client,
|
|||
sensor->format.field = V4L2_FIELD_NONE;
|
||||
sensor->format.colorspace = V4L2_COLORSPACE_SRGB;
|
||||
|
||||
v4l2_ctrl_handler_init(&sensor->ctrls, 4);
|
||||
v4l2_ctrl_handler_init(&sensor->ctrls, 5);
|
||||
|
||||
v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
|
||||
V4L2_CID_GAIN, 0, 127, 1, 64);
|
||||
|
|
@ -754,6 +760,9 @@ static int mt9m032_probe(struct i2c_client *client,
|
|||
V4L2_CID_EXPOSURE, MT9M032_SHUTTER_WIDTH_MIN,
|
||||
MT9M032_SHUTTER_WIDTH_MAX, 1,
|
||||
MT9M032_SHUTTER_WIDTH_DEF);
|
||||
v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
|
||||
V4L2_CID_PIXEL_RATE, pdata->pix_clock,
|
||||
pdata->pix_clock, 1, pdata->pix_clock);
|
||||
|
||||
if (sensor->ctrls.error) {
|
||||
ret = sensor->ctrls.error;
|
||||
|
|
|
|||
|
|
@ -214,7 +214,6 @@ struct mt9m111 {
|
|||
int power_count;
|
||||
const struct mt9m111_datafmt *fmt;
|
||||
int lastpage; /* PageMap cache value */
|
||||
unsigned char datawidth;
|
||||
};
|
||||
|
||||
/* Find a data format by a pixel code */
|
||||
|
|
|
|||
|
|
@ -950,7 +950,7 @@ static int mt9p031_probe(struct i2c_client *client,
|
|||
mt9p031->model = did->driver_data;
|
||||
mt9p031->reset = -1;
|
||||
|
||||
v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 4);
|
||||
v4l2_ctrl_handler_init(&mt9p031->ctrls, ARRAY_SIZE(mt9p031_ctrls) + 5);
|
||||
|
||||
v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
|
||||
V4L2_CID_EXPOSURE, MT9P031_SHUTTER_WIDTH_MIN,
|
||||
|
|
@ -963,6 +963,9 @@ static int mt9p031_probe(struct i2c_client *client,
|
|||
V4L2_CID_HFLIP, 0, 1, 1, 0);
|
||||
v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
|
||||
V4L2_CID_VFLIP, 0, 1, 1, 0);
|
||||
v4l2_ctrl_new_std(&mt9p031->ctrls, &mt9p031_ctrl_ops,
|
||||
V4L2_CID_PIXEL_RATE, pdata->target_freq,
|
||||
pdata->target_freq, 1, pdata->target_freq);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mt9p031_ctrls); ++i)
|
||||
v4l2_ctrl_new_custom(&mt9p031->ctrls, &mt9p031_ctrls[i], NULL);
|
||||
|
|
|
|||
|
|
@ -691,7 +691,7 @@ static int mt9t001_video_probe(struct i2c_client *client)
|
|||
return ret;
|
||||
|
||||
/* Configure the pixel clock polarity */
|
||||
if (pdata && pdata->clk_pol) {
|
||||
if (pdata->clk_pol) {
|
||||
ret = mt9t001_write(client, MT9T001_PIXEL_CLOCK,
|
||||
MT9T001_PIXEL_CLOCK_INVERT);
|
||||
if (ret < 0)
|
||||
|
|
@ -715,10 +715,16 @@ static int mt9t001_video_probe(struct i2c_client *client)
|
|||
static int mt9t001_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *did)
|
||||
{
|
||||
struct mt9t001_platform_data *pdata = client->dev.platform_data;
|
||||
struct mt9t001 *mt9t001;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
if (pdata == NULL) {
|
||||
dev_err(&client->dev, "No platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!i2c_check_functionality(client->adapter,
|
||||
I2C_FUNC_SMBUS_WORD_DATA)) {
|
||||
dev_warn(&client->adapter->dev,
|
||||
|
|
@ -735,7 +741,7 @@ static int mt9t001_probe(struct i2c_client *client,
|
|||
return -ENOMEM;
|
||||
|
||||
v4l2_ctrl_handler_init(&mt9t001->ctrls, ARRAY_SIZE(mt9t001_ctrls) +
|
||||
ARRAY_SIZE(mt9t001_gains) + 2);
|
||||
ARRAY_SIZE(mt9t001_gains) + 3);
|
||||
|
||||
v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops,
|
||||
V4L2_CID_EXPOSURE, MT9T001_SHUTTER_WIDTH_MIN,
|
||||
|
|
@ -743,6 +749,9 @@ static int mt9t001_probe(struct i2c_client *client,
|
|||
MT9T001_SHUTTER_WIDTH_DEF);
|
||||
v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops,
|
||||
V4L2_CID_BLACK_LEVEL, 1, 1, 1, 1);
|
||||
v4l2_ctrl_new_std(&mt9t001->ctrls, &mt9t001_ctrl_ops,
|
||||
V4L2_CID_PIXEL_RATE, pdata->ext_clk, pdata->ext_clk,
|
||||
1, pdata->ext_clk);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(mt9t001_ctrls); ++i)
|
||||
v4l2_ctrl_new_custom(&mt9t001->ctrls, &mt9t001_ctrls[i], NULL);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
/*
|
||||
* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
|
||||
* The platform has to define ctruct i2c_board_info objects and link to them
|
||||
* The platform has to define struct i2c_board_info objects and link to them
|
||||
* from struct soc_camera_link
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -2014,7 +2014,7 @@ static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
|
|||
return -EINVAL;
|
||||
|
||||
switch (sel->target) {
|
||||
case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS:
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
sel->r.left = 0;
|
||||
sel->r.top = 0;
|
||||
sel->r.width = INT_MAX;
|
||||
|
|
@ -2024,7 +2024,7 @@ static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
|
|||
ccdc_try_crop(ccdc, format, &sel->r);
|
||||
break;
|
||||
|
||||
case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
|
||||
case V4L2_SEL_TGT_CROP:
|
||||
sel->r = *__ccdc_get_crop(ccdc, fh, sel->which);
|
||||
break;
|
||||
|
||||
|
|
@ -2052,7 +2052,7 @@ static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
|
|||
struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
|
||||
struct v4l2_mbus_framefmt *format;
|
||||
|
||||
if (sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL ||
|
||||
if (sel->target != V4L2_SEL_TGT_CROP ||
|
||||
sel->pad != CCDC_PAD_SOURCE_OF)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -2064,7 +2064,7 @@ static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
|
|||
* pad. If the KEEP_CONFIG flag is set, just return the current crop
|
||||
* rectangle.
|
||||
*/
|
||||
if (sel->flags & V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG) {
|
||||
if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) {
|
||||
sel->r = *__ccdc_get_crop(ccdc, fh, sel->which);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1949,7 +1949,7 @@ static int preview_get_selection(struct v4l2_subdev *sd,
|
|||
return -EINVAL;
|
||||
|
||||
switch (sel->target) {
|
||||
case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS:
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
sel->r.left = 0;
|
||||
sel->r.top = 0;
|
||||
sel->r.width = INT_MAX;
|
||||
|
|
@ -1960,7 +1960,7 @@ static int preview_get_selection(struct v4l2_subdev *sd,
|
|||
preview_try_crop(prev, format, &sel->r);
|
||||
break;
|
||||
|
||||
case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
|
||||
case V4L2_SEL_TGT_CROP:
|
||||
sel->r = *__preview_get_crop(prev, fh, sel->which);
|
||||
break;
|
||||
|
||||
|
|
@ -1988,7 +1988,7 @@ static int preview_set_selection(struct v4l2_subdev *sd,
|
|||
struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
|
||||
struct v4l2_mbus_framefmt *format;
|
||||
|
||||
if (sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL ||
|
||||
if (sel->target != V4L2_SEL_TGT_CROP ||
|
||||
sel->pad != PREV_PAD_SINK)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -2000,7 +2000,7 @@ static int preview_set_selection(struct v4l2_subdev *sd,
|
|||
* pad. If the KEEP_CONFIG flag is set, just return the current crop
|
||||
* rectangle.
|
||||
*/
|
||||
if (sel->flags & V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG) {
|
||||
if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) {
|
||||
sel->r = *__preview_get_crop(prev, fh, sel->which);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1249,7 +1249,7 @@ static int resizer_get_selection(struct v4l2_subdev *sd,
|
|||
sel->which);
|
||||
|
||||
switch (sel->target) {
|
||||
case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS:
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
sel->r.left = 0;
|
||||
sel->r.top = 0;
|
||||
sel->r.width = INT_MAX;
|
||||
|
|
@ -1259,7 +1259,7 @@ static int resizer_get_selection(struct v4l2_subdev *sd,
|
|||
resizer_calc_ratios(res, &sel->r, format_source, &ratio);
|
||||
break;
|
||||
|
||||
case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
|
||||
case V4L2_SEL_TGT_CROP:
|
||||
sel->r = *__resizer_get_crop(res, fh, sel->which);
|
||||
resizer_calc_ratios(res, &sel->r, format_source, &ratio);
|
||||
break;
|
||||
|
|
@ -1293,7 +1293,7 @@ static int resizer_set_selection(struct v4l2_subdev *sd,
|
|||
struct v4l2_mbus_framefmt *format_sink, *format_source;
|
||||
struct resizer_ratio ratio;
|
||||
|
||||
if (sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL ||
|
||||
if (sel->target != V4L2_SEL_TGT_CROP ||
|
||||
sel->pad != RESZ_PAD_SINK)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
config VIDEO_PVRUSB2
|
||||
tristate "Hauppauge WinTV-PVR USB2 support"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
depends on VIDEO_MEDIA # Avoids pvrusb = Y / DVB = M
|
||||
select VIDEO_TUNER
|
||||
select VIDEO_TVEEPROM
|
||||
select VIDEO_CX2341X
|
||||
|
|
|
|||
|
|
@ -226,13 +226,11 @@ static int pvr2_enum_input(struct file *file, void *priv, struct v4l2_input *vi)
|
|||
struct v4l2_input tmp;
|
||||
unsigned int cnt;
|
||||
int val;
|
||||
int ret;
|
||||
|
||||
cptr = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
|
||||
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
tmp.index = vi->index;
|
||||
ret = 0;
|
||||
if (vi->index >= fh->input_cnt)
|
||||
return -EINVAL;
|
||||
val = fh->input_map[vi->index];
|
||||
|
|
@ -556,9 +554,7 @@ static int pvr2_queryctrl(struct file *file, void *priv,
|
|||
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
|
||||
struct pvr2_ctrl *cptr;
|
||||
int val;
|
||||
int ret;
|
||||
|
||||
ret = 0;
|
||||
if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) {
|
||||
cptr = pvr2_hdw_get_ctrl_nextv4l(
|
||||
hdw, (vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL));
|
||||
|
|
@ -705,11 +701,9 @@ static int pvr2_try_ext_ctrls(struct file *file, void *priv,
|
|||
struct v4l2_ext_control *ctrl;
|
||||
struct pvr2_ctrl *pctl;
|
||||
unsigned int idx;
|
||||
int ret;
|
||||
|
||||
/* For the moment just validate that the requested control
|
||||
actually exists. */
|
||||
ret = 0;
|
||||
for (idx = 0; idx < ctls->count; idx++) {
|
||||
ctrl = ctls->controls + idx;
|
||||
pctl = pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id);
|
||||
|
|
@ -770,12 +764,10 @@ static int pvr2_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
|
|||
{
|
||||
struct pvr2_v4l2_fh *fh = file->private_data;
|
||||
struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
|
||||
struct v4l2_cropcap cap;
|
||||
int ret;
|
||||
|
||||
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
return -EINVAL;
|
||||
cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
ret = pvr2_ctrl_set_value(
|
||||
pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL),
|
||||
crop->c.left);
|
||||
|
|
@ -965,7 +957,7 @@ static long pvr2_v4l2_ioctl(struct file *file,
|
|||
long ret = -EINVAL;
|
||||
|
||||
if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL)
|
||||
v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw), cmd);
|
||||
v4l_printk_ioctl(pvr2_hdw_get_driver_name(hdw), cmd);
|
||||
|
||||
if (!pvr2_hdw_dev_ok(hdw)) {
|
||||
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
|
||||
|
|
@ -998,7 +990,7 @@ static long pvr2_v4l2_ioctl(struct file *file,
|
|||
pvr2_trace(PVR2_TRACE_V4LIOCTL,
|
||||
"pvr2_v4l2_do_ioctl failure, ret=%ld"
|
||||
" command was:", ret);
|
||||
v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),
|
||||
v4l_printk_ioctl(pvr2_hdw_get_driver_name(hdw),
|
||||
cmd);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,19 +136,13 @@ static int leds[2] = { 100, 0 };
|
|||
|
||||
/***/
|
||||
|
||||
static int pwc_video_close(struct file *file);
|
||||
static ssize_t pwc_video_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos);
|
||||
static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
|
||||
static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma);
|
||||
|
||||
static const struct v4l2_file_operations pwc_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = v4l2_fh_open,
|
||||
.release = pwc_video_close,
|
||||
.read = pwc_video_read,
|
||||
.poll = pwc_video_poll,
|
||||
.mmap = pwc_video_mmap,
|
||||
.release = vb2_fop_release,
|
||||
.read = vb2_fop_read,
|
||||
.poll = vb2_fop_poll,
|
||||
.mmap = vb2_fop_mmap,
|
||||
.unlocked_ioctl = video_ioctl2,
|
||||
};
|
||||
static struct video_device pwc_template = {
|
||||
|
|
@ -562,17 +556,6 @@ static const char *pwc_sensor_type_to_string(unsigned int sensor_type)
|
|||
/***************************************************************************/
|
||||
/* Video4Linux functions */
|
||||
|
||||
int pwc_test_n_set_capt_file(struct pwc_device *pdev, struct file *file)
|
||||
{
|
||||
if (pdev->capt_file != NULL &&
|
||||
pdev->capt_file != file)
|
||||
return -EBUSY;
|
||||
|
||||
pdev->capt_file = file;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pwc_video_release(struct v4l2_device *v)
|
||||
{
|
||||
struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
|
||||
|
|
@ -583,113 +566,6 @@ static void pwc_video_release(struct v4l2_device *v)
|
|||
kfree(pdev);
|
||||
}
|
||||
|
||||
static int pwc_video_close(struct file *file)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
|
||||
/*
|
||||
* If we're still streaming vb2_queue_release will call stream_stop
|
||||
* so we must take both the v4l2_lock and the vb_queue_lock.
|
||||
*/
|
||||
if (mutex_lock_interruptible(&pdev->v4l2_lock))
|
||||
return -ERESTARTSYS;
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock)) {
|
||||
mutex_unlock(&pdev->v4l2_lock);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
|
||||
if (pdev->capt_file == file) {
|
||||
vb2_queue_release(&pdev->vb_queue);
|
||||
pdev->capt_file = NULL;
|
||||
}
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
mutex_unlock(&pdev->v4l2_lock);
|
||||
|
||||
return v4l2_fh_release(file);
|
||||
}
|
||||
|
||||
static ssize_t pwc_video_read(struct file *file, char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int lock_v4l2 = 0;
|
||||
ssize_t ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* stream_start will get called so we must take the v4l2_lock */
|
||||
if (pdev->vb_queue.fileio == NULL)
|
||||
lock_v4l2 = 1;
|
||||
|
||||
/* Use try_lock, since we're taking the locks in the *wrong* order! */
|
||||
if (lock_v4l2 && !mutex_trylock(&pdev->v4l2_lock)) {
|
||||
ret = -ERESTARTSYS;
|
||||
goto out;
|
||||
}
|
||||
ret = vb2_read(&pdev->vb_queue, buf, count, ppos,
|
||||
file->f_flags & O_NONBLOCK);
|
||||
if (lock_v4l2)
|
||||
mutex_unlock(&pdev->v4l2_lock);
|
||||
out:
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
struct vb2_queue *q = &pdev->vb_queue;
|
||||
unsigned long req_events = poll_requested_events(wait);
|
||||
unsigned int ret = POLL_ERR;
|
||||
int lock_v4l2 = 0;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return POLL_ERR;
|
||||
|
||||
/* Will this start fileio and thus call start_stream? */
|
||||
if ((req_events & (POLLIN | POLLRDNORM)) &&
|
||||
q->num_buffers == 0 && !q->streaming && q->fileio == NULL) {
|
||||
if (pwc_test_n_set_capt_file(pdev, file))
|
||||
goto out;
|
||||
lock_v4l2 = 1;
|
||||
}
|
||||
|
||||
/* Use try_lock, since we're taking the locks in the *wrong* order! */
|
||||
if (lock_v4l2 && !mutex_trylock(&pdev->v4l2_lock))
|
||||
goto out;
|
||||
ret = vb2_poll(&pdev->vb_queue, file, wait);
|
||||
if (lock_v4l2)
|
||||
mutex_unlock(&pdev->v4l2_lock);
|
||||
|
||||
out:
|
||||
if (!pdev->udev)
|
||||
ret |= POLLHUP;
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret == 0)
|
||||
ret = vb2_mmap(&pdev->vb_queue, vma);
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* Videobuf2 operations */
|
||||
|
||||
|
|
@ -782,6 +658,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
|
|||
if (!pdev->udev)
|
||||
return -ENODEV;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->v4l2_lock))
|
||||
return -ERESTARTSYS;
|
||||
/* Turn on camera and set LEDS on */
|
||||
pwc_camera_power(pdev, 1);
|
||||
pwc_set_leds(pdev, leds[0], leds[1]);
|
||||
|
|
@ -794,6 +672,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count)
|
|||
/* And cleanup any queued bufs!! */
|
||||
pwc_cleanup_queued_bufs(pdev);
|
||||
}
|
||||
mutex_unlock(&pdev->v4l2_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
@ -802,6 +681,8 @@ static int stop_streaming(struct vb2_queue *vq)
|
|||
{
|
||||
struct pwc_device *pdev = vb2_get_drv_priv(vq);
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->v4l2_lock))
|
||||
return -ERESTARTSYS;
|
||||
if (pdev->udev) {
|
||||
pwc_set_leds(pdev, 0, 0);
|
||||
pwc_camera_power(pdev, 0);
|
||||
|
|
@ -809,22 +690,11 @@ static int stop_streaming(struct vb2_queue *vq)
|
|||
}
|
||||
|
||||
pwc_cleanup_queued_bufs(pdev);
|
||||
mutex_unlock(&pdev->v4l2_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wait_prepare(struct vb2_queue *vq)
|
||||
{
|
||||
struct pwc_device *pdev = vb2_get_drv_priv(vq);
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
}
|
||||
|
||||
static void wait_finish(struct vb2_queue *vq)
|
||||
{
|
||||
struct pwc_device *pdev = vb2_get_drv_priv(vq);
|
||||
mutex_lock(&pdev->vb_queue_lock);
|
||||
}
|
||||
|
||||
static struct vb2_ops pwc_vb_queue_ops = {
|
||||
.queue_setup = queue_setup,
|
||||
.buf_init = buffer_init,
|
||||
|
|
@ -834,8 +704,8 @@ static struct vb2_ops pwc_vb_queue_ops = {
|
|||
.buf_queue = buffer_queue,
|
||||
.start_streaming = start_streaming,
|
||||
.stop_streaming = stop_streaming,
|
||||
.wait_prepare = wait_prepare,
|
||||
.wait_finish = wait_finish,
|
||||
.wait_prepare = vb2_ops_wait_prepare,
|
||||
.wait_finish = vb2_ops_wait_finish,
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
|
@ -1136,6 +1006,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
|||
/* Init video_device structure */
|
||||
memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template));
|
||||
strcpy(pdev->vdev.name, name);
|
||||
pdev->vdev.queue = &pdev->vb_queue;
|
||||
pdev->vdev.queue->lock = &pdev->vb_queue_lock;
|
||||
set_bit(V4L2_FL_USE_FH_PRIO, &pdev->vdev.flags);
|
||||
video_set_drvdata(&pdev->vdev, pdev);
|
||||
|
||||
|
|
@ -1190,15 +1062,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
|
|||
pdev->vdev.v4l2_dev = &pdev->v4l2_dev;
|
||||
pdev->vdev.lock = &pdev->v4l2_lock;
|
||||
|
||||
/*
|
||||
* Don't take v4l2_lock for these ioctls. This improves latency if
|
||||
* v4l2_lock is taken for a long time, e.g. when changing a control
|
||||
* value, and a new frame is ready to be dequeued.
|
||||
*/
|
||||
v4l2_disable_ioctl_locking(&pdev->vdev, VIDIOC_DQBUF);
|
||||
v4l2_disable_ioctl_locking(&pdev->vdev, VIDIOC_QBUF);
|
||||
v4l2_disable_ioctl_locking(&pdev->vdev, VIDIOC_QUERYBUF);
|
||||
|
||||
rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1);
|
||||
if (rc < 0) {
|
||||
PWC_ERROR("Failed to register as video device (%d).\n", rc);
|
||||
|
|
@ -1253,20 +1116,18 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
|
|||
struct v4l2_device *v = usb_get_intfdata(intf);
|
||||
struct pwc_device *pdev = container_of(v, struct pwc_device, v4l2_dev);
|
||||
|
||||
mutex_lock(&pdev->v4l2_lock);
|
||||
|
||||
mutex_lock(&pdev->vb_queue_lock);
|
||||
mutex_lock(&pdev->v4l2_lock);
|
||||
/* No need to keep the urbs around after disconnection */
|
||||
if (pdev->vb_queue.streaming)
|
||||
pwc_isoc_cleanup(pdev);
|
||||
pdev->udev = NULL;
|
||||
pwc_cleanup_queued_bufs(pdev);
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
|
||||
v4l2_device_disconnect(&pdev->v4l2_dev);
|
||||
video_unregister_device(&pdev->vdev);
|
||||
|
||||
mutex_unlock(&pdev->v4l2_lock);
|
||||
mutex_unlock(pdev->vb_queue.lock);
|
||||
|
||||
#ifdef CONFIG_USB_PWC_INPUT_EVDEV
|
||||
if (pdev->button_dev)
|
||||
|
|
|
|||
|
|
@ -405,6 +405,7 @@ static void pwc_vidioc_fill_fmt(struct v4l2_format *f,
|
|||
f->fmt.pix.pixelformat = pixfmt;
|
||||
f->fmt.pix.bytesperline = f->fmt.pix.width;
|
||||
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.width * 3 / 2;
|
||||
f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
|
||||
PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() "
|
||||
"width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n",
|
||||
f->fmt.pix.width,
|
||||
|
|
@ -468,17 +469,8 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret)
|
||||
goto leave;
|
||||
|
||||
if (pdev->vb_queue.streaming) {
|
||||
ret = -EBUSY;
|
||||
goto leave;
|
||||
}
|
||||
if (vb2_is_busy(&pdev->vb_queue))
|
||||
return -EBUSY;
|
||||
|
||||
pixelformat = f->fmt.pix.pixelformat;
|
||||
|
||||
|
|
@ -496,8 +488,6 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
|
|||
PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret);
|
||||
|
||||
pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt);
|
||||
leave:
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -508,10 +498,9 @@ static int pwc_querycap(struct file *file, void *fh, struct v4l2_capability *cap
|
|||
strcpy(cap->driver, PWC_NAME);
|
||||
strlcpy(cap->card, pdev->vdev.name, sizeof(cap->card));
|
||||
usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info));
|
||||
cap->capabilities =
|
||||
V4L2_CAP_VIDEO_CAPTURE |
|
||||
V4L2_CAP_STREAMING |
|
||||
V4L2_CAP_READWRITE;
|
||||
cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
|
||||
V4L2_CAP_READWRITE;
|
||||
cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -520,7 +509,8 @@ static int pwc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
|
|||
if (i->index) /* Only one INPUT is supported */
|
||||
return -EINVAL;
|
||||
|
||||
strcpy(i->name, "usb");
|
||||
strlcpy(i->name, "Camera", sizeof(i->name));
|
||||
i->type = V4L2_INPUT_TYPE_CAMERA;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -933,104 +923,6 @@ static int pwc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *
|
|||
return pwc_vidioc_try_fmt(pdev, f);
|
||||
}
|
||||
|
||||
static int pwc_reqbufs(struct file *file, void *fh,
|
||||
struct v4l2_requestbuffers *rb)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret == 0)
|
||||
ret = vb2_reqbufs(&pdev->vb_queue, rb);
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret == 0)
|
||||
ret = vb2_querybuf(&pdev->vb_queue, buf);
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret == 0)
|
||||
ret = vb2_qbuf(&pdev->vb_queue, buf);
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret == 0)
|
||||
ret = vb2_dqbuf(&pdev->vb_queue, buf,
|
||||
file->f_flags & O_NONBLOCK);
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret == 0)
|
||||
ret = vb2_streamon(&pdev->vb_queue, i);
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
|
||||
{
|
||||
struct pwc_device *pdev = video_drvdata(file);
|
||||
int ret;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret == 0)
|
||||
ret = vb2_streamoff(&pdev->vb_queue, i);
|
||||
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int pwc_enum_framesizes(struct file *file, void *fh,
|
||||
struct v4l2_frmsizeenum *fsize)
|
||||
{
|
||||
|
|
@ -1112,32 +1004,27 @@ static int pwc_s_parm(struct file *file, void *fh,
|
|||
int compression = 0;
|
||||
int ret, fps;
|
||||
|
||||
if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
|
||||
parm->parm.capture.timeperframe.numerator == 0)
|
||||
if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
|
||||
return -EINVAL;
|
||||
|
||||
fps = parm->parm.capture.timeperframe.denominator /
|
||||
parm->parm.capture.timeperframe.numerator;
|
||||
/* If timeperframe == 0, then reset the framerate to the nominal value.
|
||||
We pick a high framerate here, and let pwc_set_video_mode() figure
|
||||
out the best match. */
|
||||
if (parm->parm.capture.timeperframe.numerator == 0 ||
|
||||
parm->parm.capture.timeperframe.denominator == 0)
|
||||
fps = 30;
|
||||
else
|
||||
fps = parm->parm.capture.timeperframe.denominator /
|
||||
parm->parm.capture.timeperframe.numerator;
|
||||
|
||||
if (mutex_lock_interruptible(&pdev->vb_queue_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
ret = pwc_test_n_set_capt_file(pdev, file);
|
||||
if (ret)
|
||||
goto leave;
|
||||
|
||||
if (pdev->vb_queue.streaming) {
|
||||
ret = -EBUSY;
|
||||
goto leave;
|
||||
}
|
||||
if (vb2_is_busy(&pdev->vb_queue))
|
||||
return -EBUSY;
|
||||
|
||||
ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, pdev->pixfmt,
|
||||
fps, &compression, 0);
|
||||
|
||||
pwc_g_parm(file, fh, parm);
|
||||
|
||||
leave:
|
||||
mutex_unlock(&pdev->vb_queue_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1150,12 +1037,12 @@ const struct v4l2_ioctl_ops pwc_ioctl_ops = {
|
|||
.vidioc_g_fmt_vid_cap = pwc_g_fmt_vid_cap,
|
||||
.vidioc_s_fmt_vid_cap = pwc_s_fmt_vid_cap,
|
||||
.vidioc_try_fmt_vid_cap = pwc_try_fmt_vid_cap,
|
||||
.vidioc_reqbufs = pwc_reqbufs,
|
||||
.vidioc_querybuf = pwc_querybuf,
|
||||
.vidioc_qbuf = pwc_qbuf,
|
||||
.vidioc_dqbuf = pwc_dqbuf,
|
||||
.vidioc_streamon = pwc_streamon,
|
||||
.vidioc_streamoff = pwc_streamoff,
|
||||
.vidioc_reqbufs = vb2_ioctl_reqbufs,
|
||||
.vidioc_querybuf = vb2_ioctl_querybuf,
|
||||
.vidioc_qbuf = vb2_ioctl_qbuf,
|
||||
.vidioc_dqbuf = vb2_ioctl_dqbuf,
|
||||
.vidioc_streamon = vb2_ioctl_streamon,
|
||||
.vidioc_streamoff = vb2_ioctl_streamoff,
|
||||
.vidioc_log_status = v4l2_ctrl_log_status,
|
||||
.vidioc_enum_framesizes = pwc_enum_framesizes,
|
||||
.vidioc_enum_frameintervals = pwc_enum_frameintervals,
|
||||
|
|
|
|||
|
|
@ -239,7 +239,6 @@ struct pwc_device
|
|||
int features; /* feature bits */
|
||||
|
||||
/*** Video data ***/
|
||||
struct file *capt_file; /* file doing video capture */
|
||||
int vendpoint; /* video isoc endpoint */
|
||||
int vcinterface; /* video control interface */
|
||||
int valternate; /* alternate interface needed */
|
||||
|
|
@ -355,8 +354,6 @@ struct pwc_device
|
|||
extern int pwc_trace;
|
||||
#endif
|
||||
|
||||
int pwc_test_n_set_capt_file(struct pwc_device *pdev, struct file *file);
|
||||
|
||||
/** Functions in pwc-misc.c */
|
||||
/* sizes in pixels */
|
||||
extern const int pwc_image_sizes[PSZ_MAX][2];
|
||||
|
|
|
|||
|
|
@ -658,7 +658,7 @@ static void fimc_capture_try_selection(struct fimc_ctx *ctx,
|
|||
r->left = r->top = 0;
|
||||
return;
|
||||
}
|
||||
if (target == V4L2_SEL_TGT_COMPOSE_ACTIVE) {
|
||||
if (target == V4L2_SEL_TGT_COMPOSE) {
|
||||
if (ctx->rotation != 90 && ctx->rotation != 270)
|
||||
align_h = 1;
|
||||
max_sc_h = min(SCALER_MAX_HRATIO, 1 << (ffs(sink->width) - 3));
|
||||
|
|
@ -685,7 +685,7 @@ static void fimc_capture_try_selection(struct fimc_ctx *ctx,
|
|||
rotate ? sink->f_height : sink->f_width);
|
||||
max_h = min_t(u32, FIMC_CAMIF_MAX_HEIGHT, sink->f_height);
|
||||
|
||||
if (target == V4L2_SEL_TGT_COMPOSE_ACTIVE) {
|
||||
if (target == V4L2_SEL_TGT_COMPOSE) {
|
||||
min_w = min_t(u32, max_w, sink->f_width / max_sc_h);
|
||||
min_h = min_t(u32, max_h, sink->f_height / max_sc_v);
|
||||
if (rotate) {
|
||||
|
|
@ -1146,9 +1146,9 @@ static int fimc_cap_g_selection(struct file *file, void *fh,
|
|||
s->r.height = f->o_height;
|
||||
return 0;
|
||||
|
||||
case V4L2_SEL_TGT_COMPOSE_ACTIVE:
|
||||
case V4L2_SEL_TGT_COMPOSE:
|
||||
f = &ctx->d_frame;
|
||||
case V4L2_SEL_TGT_CROP_ACTIVE:
|
||||
case V4L2_SEL_TGT_CROP:
|
||||
s->r.left = f->offs_h;
|
||||
s->r.top = f->offs_v;
|
||||
s->r.width = f->width;
|
||||
|
|
@ -1160,7 +1160,7 @@ static int fimc_cap_g_selection(struct file *file, void *fh,
|
|||
}
|
||||
|
||||
/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
|
||||
int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
|
||||
static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
|
||||
{
|
||||
if (a->left < b->left || a->top < b->top)
|
||||
return 0;
|
||||
|
|
@ -1184,9 +1184,9 @@ static int fimc_cap_s_selection(struct file *file, void *fh,
|
|||
if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
|
||||
return -EINVAL;
|
||||
|
||||
if (s->target == V4L2_SEL_TGT_COMPOSE_ACTIVE)
|
||||
if (s->target == V4L2_SEL_TGT_COMPOSE)
|
||||
f = &ctx->d_frame;
|
||||
else if (s->target == V4L2_SEL_TGT_CROP_ACTIVE)
|
||||
else if (s->target == V4L2_SEL_TGT_CROP)
|
||||
f = &ctx->s_frame;
|
||||
else
|
||||
return -EINVAL;
|
||||
|
|
@ -1428,9 +1428,9 @@ static int fimc_subdev_get_selection(struct v4l2_subdev *sd,
|
|||
mutex_lock(&fimc->lock);
|
||||
|
||||
switch (sel->target) {
|
||||
case V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS:
|
||||
case V4L2_SEL_TGT_COMPOSE_BOUNDS:
|
||||
f = &ctx->d_frame;
|
||||
case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS:
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
r->width = f->o_width;
|
||||
r->height = f->o_height;
|
||||
r->left = 0;
|
||||
|
|
@ -1438,10 +1438,10 @@ static int fimc_subdev_get_selection(struct v4l2_subdev *sd,
|
|||
mutex_unlock(&fimc->lock);
|
||||
return 0;
|
||||
|
||||
case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
|
||||
case V4L2_SEL_TGT_CROP:
|
||||
try_sel = v4l2_subdev_get_try_crop(fh, sel->pad);
|
||||
break;
|
||||
case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL:
|
||||
case V4L2_SEL_TGT_COMPOSE:
|
||||
try_sel = v4l2_subdev_get_try_compose(fh, sel->pad);
|
||||
f = &ctx->d_frame;
|
||||
break;
|
||||
|
|
@ -1482,12 +1482,12 @@ static int fimc_subdev_set_selection(struct v4l2_subdev *sd,
|
|||
return -EINVAL;
|
||||
|
||||
mutex_lock(&fimc->lock);
|
||||
fimc_capture_try_selection(ctx, r, V4L2_SEL_TGT_CROP_ACTIVE);
|
||||
fimc_capture_try_selection(ctx, r, V4L2_SEL_TGT_CROP);
|
||||
|
||||
switch (sel->target) {
|
||||
case V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS:
|
||||
case V4L2_SEL_TGT_COMPOSE_BOUNDS:
|
||||
f = &ctx->d_frame;
|
||||
case V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS:
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
r->width = f->o_width;
|
||||
r->height = f->o_height;
|
||||
r->left = 0;
|
||||
|
|
@ -1495,10 +1495,10 @@ static int fimc_subdev_set_selection(struct v4l2_subdev *sd,
|
|||
mutex_unlock(&fimc->lock);
|
||||
return 0;
|
||||
|
||||
case V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL:
|
||||
case V4L2_SEL_TGT_CROP:
|
||||
try_sel = v4l2_subdev_get_try_crop(fh, sel->pad);
|
||||
break;
|
||||
case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL:
|
||||
case V4L2_SEL_TGT_COMPOSE:
|
||||
try_sel = v4l2_subdev_get_try_compose(fh, sel->pad);
|
||||
f = &ctx->d_frame;
|
||||
break;
|
||||
|
|
@ -1514,7 +1514,7 @@ static int fimc_subdev_set_selection(struct v4l2_subdev *sd,
|
|||
set_frame_crop(f, r->left, r->top, r->width, r->height);
|
||||
set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
|
||||
spin_unlock_irqrestore(&fimc->slock, flags);
|
||||
if (sel->target == V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTUAL)
|
||||
if (sel->target == V4L2_SEL_TGT_COMPOSE)
|
||||
ctx->state |= FIMC_COMPOSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -463,7 +463,7 @@ void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
|
|||
f->fmt->color, f->dma_offset.y_h, f->dma_offset.y_v);
|
||||
}
|
||||
|
||||
int fimc_set_color_effect(struct fimc_ctx *ctx, enum v4l2_colorfx colorfx)
|
||||
static int fimc_set_color_effect(struct fimc_ctx *ctx, enum v4l2_colorfx colorfx)
|
||||
{
|
||||
struct fimc_effect *effect = &ctx->effect;
|
||||
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ void flite_hw_set_camera_bus(struct fimc_lite *dev,
|
|||
flite_hw_set_camera_port(dev, s_info->mux_id);
|
||||
}
|
||||
|
||||
void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f)
|
||||
static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f)
|
||||
{
|
||||
static const u32 pixcode[4][2] = {
|
||||
{ V4L2_MBUS_FMT_YUYV8_2X8, FLITE_REG_CIODMAFMT_YCBYCR },
|
||||
|
|
|
|||
|
|
@ -902,7 +902,7 @@ static int fimc_lite_g_selection(struct file *file, void *fh,
|
|||
sel->r.height = f->f_height;
|
||||
return 0;
|
||||
|
||||
case V4L2_SEL_TGT_COMPOSE_ACTIVE:
|
||||
case V4L2_SEL_TGT_COMPOSE:
|
||||
sel->r = f->rect;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -919,7 +919,7 @@ static int fimc_lite_s_selection(struct file *file, void *fh,
|
|||
unsigned long flags;
|
||||
|
||||
if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
|
||||
sel->target != V4L2_SEL_TGT_COMPOSE_ACTIVE)
|
||||
sel->target != V4L2_SEL_TGT_COMPOSE)
|
||||
return -EINVAL;
|
||||
|
||||
fimc_lite_try_compose(fimc, &rect);
|
||||
|
|
@ -1117,9 +1117,9 @@ static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd,
|
|||
struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
|
||||
struct flite_frame *f = &fimc->inp_frame;
|
||||
|
||||
if ((sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL &&
|
||||
sel->target != V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS) ||
|
||||
sel->pad != FLITE_SD_PAD_SINK)
|
||||
if ((sel->target != V4L2_SEL_TGT_CROP &&
|
||||
sel->target != V4L2_SEL_TGT_CROP_BOUNDS) ||
|
||||
sel->pad != FLITE_SD_PAD_SINK)
|
||||
return -EINVAL;
|
||||
|
||||
if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
|
||||
|
|
@ -1128,7 +1128,7 @@ static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd,
|
|||
}
|
||||
|
||||
mutex_lock(&fimc->lock);
|
||||
if (sel->target == V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL) {
|
||||
if (sel->target == V4L2_SEL_TGT_CROP) {
|
||||
sel->r = f->rect;
|
||||
} else {
|
||||
sel->r.left = 0;
|
||||
|
|
@ -1153,8 +1153,7 @@ static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd,
|
|||
struct flite_frame *f = &fimc->inp_frame;
|
||||
int ret = 0;
|
||||
|
||||
if (sel->target != V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL ||
|
||||
sel->pad != FLITE_SD_PAD_SINK)
|
||||
if (sel->target != V4L2_SEL_TGT_CROP || sel->pad != FLITE_SD_PAD_SINK)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&fimc->lock);
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ EXPORT_SYMBOL_GPL(fimc_pipeline_initialize);
|
|||
* sensor clock.
|
||||
* Called with the graph mutex held.
|
||||
*/
|
||||
int __fimc_pipeline_shutdown(struct fimc_pipeline *p)
|
||||
static int __fimc_pipeline_shutdown(struct fimc_pipeline *p)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
|
@ -1010,7 +1010,7 @@ static struct platform_driver fimc_md_driver = {
|
|||
}
|
||||
};
|
||||
|
||||
int __init fimc_md_init(void)
|
||||
static int __init fimc_md_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
|
@ -1021,7 +1021,8 @@ int __init fimc_md_init(void)
|
|||
|
||||
return platform_driver_register(&fimc_md_driver);
|
||||
}
|
||||
void __exit fimc_md_exit(void)
|
||||
|
||||
static void __exit fimc_md_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&fimc_md_driver);
|
||||
fimc_unregister_driver();
|
||||
|
|
|
|||
|
|
@ -824,10 +824,10 @@ static int s5p_jpeg_g_selection(struct file *file, void *priv,
|
|||
|
||||
/* For JPEG blob active == default == bounds */
|
||||
switch (s->target) {
|
||||
case V4L2_SEL_TGT_CROP_ACTIVE:
|
||||
case V4L2_SEL_TGT_CROP:
|
||||
case V4L2_SEL_TGT_CROP_BOUNDS:
|
||||
case V4L2_SEL_TGT_CROP_DEFAULT:
|
||||
case V4L2_SEL_TGT_COMPOSE_ACTIVE:
|
||||
case V4L2_SEL_TGT_COMPOSE:
|
||||
case V4L2_SEL_TGT_COMPOSE_DEFAULT:
|
||||
s->r.width = ctx->out_q.w;
|
||||
s->r.height = ctx->out_q.h;
|
||||
|
|
@ -1503,29 +1503,7 @@ static struct platform_driver s5p_jpeg_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init
|
||||
s5p_jpeg_register(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pr_info("S5P JPEG V4L2 Driver, (c) 2011 Samsung Electronics\n");
|
||||
|
||||
ret = platform_driver_register(&s5p_jpeg_driver);
|
||||
|
||||
if (ret)
|
||||
pr_err("%s: failed to register jpeg driver\n", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit
|
||||
s5p_jpeg_unregister(void)
|
||||
{
|
||||
platform_driver_unregister(&s5p_jpeg_driver);
|
||||
}
|
||||
|
||||
module_init(s5p_jpeg_register);
|
||||
module_exit(s5p_jpeg_unregister);
|
||||
module_platform_driver(s5p_jpeg_driver);
|
||||
|
||||
MODULE_AUTHOR("Andrzej Pietrasiewicz <[email protected]>");
|
||||
MODULE_DESCRIPTION("Samsung JPEG codec driver");
|
||||
|
|
|
|||
|
|
@ -367,7 +367,7 @@ static int mxr_g_selection(struct file *file, void *fh,
|
|||
return -EINVAL;
|
||||
|
||||
switch (s->target) {
|
||||
case V4L2_SEL_TGT_CROP_ACTIVE:
|
||||
case V4L2_SEL_TGT_CROP:
|
||||
s->r.left = geo->src.x_offset;
|
||||
s->r.top = geo->src.y_offset;
|
||||
s->r.width = geo->src.width;
|
||||
|
|
@ -380,7 +380,7 @@ static int mxr_g_selection(struct file *file, void *fh,
|
|||
s->r.width = geo->src.full_width;
|
||||
s->r.height = geo->src.full_height;
|
||||
break;
|
||||
case V4L2_SEL_TGT_COMPOSE_ACTIVE:
|
||||
case V4L2_SEL_TGT_COMPOSE:
|
||||
case V4L2_SEL_TGT_COMPOSE_PADDED:
|
||||
s->r.left = geo->dst.x_offset;
|
||||
s->r.top = geo->dst.y_offset;
|
||||
|
|
@ -449,11 +449,11 @@ static int mxr_s_selection(struct file *file, void *fh,
|
|||
res.height = geo->dst.full_height;
|
||||
break;
|
||||
|
||||
case V4L2_SEL_TGT_CROP_ACTIVE:
|
||||
case V4L2_SEL_TGT_CROP:
|
||||
target = &geo->src;
|
||||
stage = MXR_GEOMETRY_CROP;
|
||||
break;
|
||||
case V4L2_SEL_TGT_COMPOSE_ACTIVE:
|
||||
case V4L2_SEL_TGT_COMPOSE:
|
||||
case V4L2_SEL_TGT_COMPOSE_PADDED:
|
||||
target = &geo->dst;
|
||||
stage = MXR_GEOMETRY_COMPOSE;
|
||||
|
|
|
|||
|
|
@ -419,14 +419,4 @@ static struct i2c_driver sii9234_driver = {
|
|||
.id_table = sii9234_id,
|
||||
};
|
||||
|
||||
static int __init sii9234_init(void)
|
||||
{
|
||||
return i2c_add_driver(&sii9234_driver);
|
||||
}
|
||||
module_init(sii9234_init);
|
||||
|
||||
static void __exit sii9234_exit(void)
|
||||
{
|
||||
i2c_del_driver(&sii9234_driver);
|
||||
}
|
||||
module_exit(sii9234_exit);
|
||||
module_i2c_driver(sii9234_driver);
|
||||
|
|
|
|||
|
|
@ -1,132 +0,0 @@
|
|||
/* saa7121.h - saa7121 initializations
|
||||
Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
#ifndef __SAA7121_H__
|
||||
#define __SAA7121_H__
|
||||
|
||||
#define NTSC_BURST_START 0x19 /* 28 */
|
||||
#define NTSC_BURST_END 0x1d /* 29 */
|
||||
#define NTSC_CHROMA_PHASE 0x67 /* 5a */
|
||||
#define NTSC_GAINU 0x76 /* 5b */
|
||||
#define NTSC_GAINV 0xa5 /* 5c */
|
||||
#define NTSC_BLACK_LEVEL 0x2a /* 5d */
|
||||
#define NTSC_BLANKING_LEVEL 0x2e /* 5e */
|
||||
#define NTSC_VBI_BLANKING 0x2e /* 5f */
|
||||
#define NTSC_DAC_CONTROL 0x11 /* 61 */
|
||||
#define NTSC_BURST_AMP 0x3f /* 62 */
|
||||
#define NTSC_SUBC3 0x1f /* 63 */
|
||||
#define NTSC_SUBC2 0x7c /* 64 */
|
||||
#define NTSC_SUBC1 0xf0 /* 65 */
|
||||
#define NTSC_SUBC0 0x21 /* 66 */
|
||||
#define NTSC_HTRIG 0x72 /* 6c */
|
||||
#define NTSC_VTRIG 0x00 /* 6c */
|
||||
#define NTSC_MULTI 0x30 /* 6e */
|
||||
#define NTSC_CCTTX 0x11 /* 6f */
|
||||
#define NTSC_FIRST_ACTIVE 0x12 /* 7a */
|
||||
#define NTSC_LAST_ACTIVE 0x02 /* 7b */
|
||||
#define NTSC_MSB_VERTICAL 0x40 /* 7c */
|
||||
|
||||
#define PAL_BURST_START 0x21 /* 28 */
|
||||
#define PAL_BURST_END 0x1d /* 29 */
|
||||
#define PAL_CHROMA_PHASE 0x3f /* 5a */
|
||||
#define PAL_GAINU 0x7d /* 5b */
|
||||
#define PAL_GAINV 0xaf /* 5c */
|
||||
#define PAL_BLACK_LEVEL 0x23 /* 5d */
|
||||
#define PAL_BLANKING_LEVEL 0x35 /* 5e */
|
||||
#define PAL_VBI_BLANKING 0x35 /* 5f */
|
||||
#define PAL_DAC_CONTROL 0x02 /* 61 */
|
||||
#define PAL_BURST_AMP 0x2f /* 62 */
|
||||
#define PAL_SUBC3 0xcb /* 63 */
|
||||
#define PAL_SUBC2 0x8a /* 64 */
|
||||
#define PAL_SUBC1 0x09 /* 65 */
|
||||
#define PAL_SUBC0 0x2a /* 66 */
|
||||
#define PAL_HTRIG 0x86 /* 6c */
|
||||
#define PAL_VTRIG 0x04 /* 6d */
|
||||
#define PAL_MULTI 0x20 /* 6e */
|
||||
#define PAL_CCTTX 0x15 /* 6f */
|
||||
#define PAL_FIRST_ACTIVE 0x16 /* 7a */
|
||||
#define PAL_LAST_ACTIVE 0x36 /* 7b */
|
||||
#define PAL_MSB_VERTICAL 0x40 /* 7c */
|
||||
|
||||
/* Initialization Sequence */
|
||||
|
||||
static __u8 init7121ntsc[] = {
|
||||
0x26, 0x0, 0x27, 0x0,
|
||||
0x28, NTSC_BURST_START, 0x29, NTSC_BURST_END,
|
||||
0x2a, 0x0, 0x2b, 0x0, 0x2c, 0x0, 0x2d, 0x0,
|
||||
0x2e, 0x0, 0x2f, 0x0, 0x30, 0x0, 0x31, 0x0,
|
||||
0x32, 0x0, 0x33, 0x0, 0x34, 0x0, 0x35, 0x0,
|
||||
0x36, 0x0, 0x37, 0x0, 0x38, 0x0, 0x39, 0x0,
|
||||
0x3a, 0x03, 0x3b, 0x0, 0x3c, 0x0, 0x3d, 0x0,
|
||||
0x3e, 0x0, 0x3f, 0x0, 0x40, 0x0, 0x41, 0x0,
|
||||
0x42, 0x0, 0x43, 0x0, 0x44, 0x0, 0x45, 0x0,
|
||||
0x46, 0x0, 0x47, 0x0, 0x48, 0x0, 0x49, 0x0,
|
||||
0x4a, 0x0, 0x4b, 0x0, 0x4c, 0x0, 0x4d, 0x0,
|
||||
0x4e, 0x0, 0x4f, 0x0, 0x50, 0x0, 0x51, 0x0,
|
||||
0x52, 0x0, 0x53, 0x0, 0x54, 0x0, 0x55, 0x0,
|
||||
0x56, 0x0, 0x57, 0x0, 0x58, 0x0, 0x59, 0x0,
|
||||
0x5a, NTSC_CHROMA_PHASE, 0x5b, NTSC_GAINU,
|
||||
0x5c, NTSC_GAINV, 0x5d, NTSC_BLACK_LEVEL,
|
||||
0x5e, NTSC_BLANKING_LEVEL, 0x5f, NTSC_VBI_BLANKING,
|
||||
0x60, 0x0, 0x61, NTSC_DAC_CONTROL,
|
||||
0x62, NTSC_BURST_AMP, 0x63, NTSC_SUBC3,
|
||||
0x64, NTSC_SUBC2, 0x65, NTSC_SUBC1,
|
||||
0x66, NTSC_SUBC0, 0x67, 0x80, 0x68, 0x80,
|
||||
0x69, 0x80, 0x6a, 0x80, 0x6b, 0x29,
|
||||
0x6c, NTSC_HTRIG, 0x6d, NTSC_VTRIG,
|
||||
0x6e, NTSC_MULTI, 0x6f, NTSC_CCTTX,
|
||||
0x70, 0xc9, 0x71, 0x68, 0x72, 0x60, 0x73, 0x0,
|
||||
0x74, 0x0, 0x75, 0x0, 0x76, 0x0, 0x77, 0x0,
|
||||
0x78, 0x0, 0x79, 0x0, 0x7a, NTSC_FIRST_ACTIVE,
|
||||
0x7b, NTSC_LAST_ACTIVE, 0x7c, NTSC_MSB_VERTICAL,
|
||||
0x7d, 0x0, 0x7e, 0x0, 0x7f, 0x0
|
||||
};
|
||||
#define INIT7121LEN (sizeof(init7121ntsc)/2)
|
||||
|
||||
static __u8 init7121pal[] = {
|
||||
0x26, 0x0, 0x27, 0x0,
|
||||
0x28, PAL_BURST_START, 0x29, PAL_BURST_END,
|
||||
0x2a, 0x0, 0x2b, 0x0, 0x2c, 0x0, 0x2d, 0x0,
|
||||
0x2e, 0x0, 0x2f, 0x0, 0x30, 0x0, 0x31, 0x0,
|
||||
0x32, 0x0, 0x33, 0x0, 0x34, 0x0, 0x35, 0x0,
|
||||
0x36, 0x0, 0x37, 0x0, 0x38, 0x0, 0x39, 0x0,
|
||||
0x3a, 0x03, 0x3b, 0x0, 0x3c, 0x0, 0x3d, 0x0,
|
||||
0x3e, 0x0, 0x3f, 0x0, 0x40, 0x0, 0x41, 0x0,
|
||||
0x42, 0x0, 0x43, 0x0, 0x44, 0x0, 0x45, 0x0,
|
||||
0x46, 0x0, 0x47, 0x0, 0x48, 0x0, 0x49, 0x0,
|
||||
0x4a, 0x0, 0x4b, 0x0, 0x4c, 0x0, 0x4d, 0x0,
|
||||
0x4e, 0x0, 0x4f, 0x0, 0x50, 0x0, 0x51, 0x0,
|
||||
0x52, 0x0, 0x53, 0x0, 0x54, 0x0, 0x55, 0x0,
|
||||
0x56, 0x0, 0x57, 0x0, 0x58, 0x0, 0x59, 0x0,
|
||||
0x5a, PAL_CHROMA_PHASE, 0x5b, PAL_GAINU,
|
||||
0x5c, PAL_GAINV, 0x5d, PAL_BLACK_LEVEL,
|
||||
0x5e, PAL_BLANKING_LEVEL, 0x5f, PAL_VBI_BLANKING,
|
||||
0x60, 0x0, 0x61, PAL_DAC_CONTROL,
|
||||
0x62, PAL_BURST_AMP, 0x63, PAL_SUBC3,
|
||||
0x64, PAL_SUBC2, 0x65, PAL_SUBC1,
|
||||
0x66, PAL_SUBC0, 0x67, 0x80, 0x68, 0x80,
|
||||
0x69, 0x80, 0x6a, 0x80, 0x6b, 0x29,
|
||||
0x6c, PAL_HTRIG, 0x6d, PAL_VTRIG,
|
||||
0x6e, PAL_MULTI, 0x6f, PAL_CCTTX,
|
||||
0x70, 0xc9, 0x71, 0x68, 0x72, 0x60, 0x73, 0x0,
|
||||
0x74, 0x0, 0x75, 0x0, 0x76, 0x0, 0x77, 0x0,
|
||||
0x78, 0x0, 0x79, 0x0, 0x7a, PAL_FIRST_ACTIVE,
|
||||
0x7b, PAL_LAST_ACTIVE, 0x7c, PAL_MSB_VERTICAL,
|
||||
0x7d, 0x0, 0x7e, 0x0, 0x7f, 0x0
|
||||
};
|
||||
#endif
|
||||
|
|
@ -1282,7 +1282,7 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS:
|
||||
if (configure_tda827x_fe(dev, &tda827x_lifeview_config,
|
||||
&tda827x_cfg_0) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_PHILIPS_EUROPA:
|
||||
case SAA7134_BOARD_VIDEOMATE_DVBT_300:
|
||||
|
|
@ -1322,7 +1322,7 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
case SAA7134_BOARD_KWORLD_DVBT_210:
|
||||
if (configure_tda827x_fe(dev, &kworld_dvb_t_210_config,
|
||||
&tda827x_cfg_2) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_HAUPPAUGE_HVR1120:
|
||||
fe0->dvb.frontend = dvb_attach(tda10048_attach,
|
||||
|
|
@ -1340,17 +1340,17 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
case SAA7134_BOARD_PHILIPS_TIGER:
|
||||
if (configure_tda827x_fe(dev, &philips_tiger_config,
|
||||
&tda827x_cfg_0) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_PINNACLE_PCTV_310i:
|
||||
if (configure_tda827x_fe(dev, &pinnacle_pctv_310i_config,
|
||||
&tda827x_cfg_1) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_HAUPPAUGE_HVR1110:
|
||||
if (configure_tda827x_fe(dev, &hauppauge_hvr_1110_config,
|
||||
&tda827x_cfg_1) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_HAUPPAUGE_HVR1150:
|
||||
fe0->dvb.frontend = dvb_attach(lgdt3305_attach,
|
||||
|
|
@ -1368,30 +1368,30 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
|
||||
if (configure_tda827x_fe(dev, &asus_p7131_dual_config,
|
||||
&tda827x_cfg_0) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_FLYDVBT_LR301:
|
||||
if (configure_tda827x_fe(dev, &tda827x_lifeview_config,
|
||||
&tda827x_cfg_0) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_FLYDVB_TRIO:
|
||||
if (!use_frontend) { /* terrestrial */
|
||||
if (configure_tda827x_fe(dev, &lifeview_trio_config,
|
||||
&tda827x_cfg_0) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
} else { /* satellite */
|
||||
fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
|
||||
if (fe0->dvb.frontend) {
|
||||
if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x63,
|
||||
&dev->i2c_adap, 0) == NULL) {
|
||||
wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap,
|
||||
0x08, 0, 0) == NULL) {
|
||||
wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1407,7 +1407,7 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
&ads_duo_cfg) == NULL) {
|
||||
wprintk("no tda827x tuner found at addr: %02x\n",
|
||||
ads_tech_duo_config.tuner_address);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
} else
|
||||
wprintk("failed to attach tda10046\n");
|
||||
|
|
@ -1415,13 +1415,13 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
case SAA7134_BOARD_TEVION_DVBT_220RF:
|
||||
if (configure_tda827x_fe(dev, &tevion_dvbt220rf_config,
|
||||
&tda827x_cfg_0) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_MEDION_MD8800_QUADRO:
|
||||
if (!use_frontend) { /* terrestrial */
|
||||
if (configure_tda827x_fe(dev, &md8800_dvbt_config,
|
||||
&tda827x_cfg_0) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
} else { /* satellite */
|
||||
fe0->dvb.frontend = dvb_attach(tda10086_attach,
|
||||
&flydvbs, &dev->i2c_adap);
|
||||
|
|
@ -1435,7 +1435,7 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
0x60, &dev->i2c_adap, 0) == NULL) {
|
||||
wprintk("%s: Medion Quadro, no tda826x "
|
||||
"found !\n", __func__);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
if (dev_id != 0x08) {
|
||||
/* we need to open the i2c gate (we know it exists) */
|
||||
|
|
@ -1444,7 +1444,7 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
&dev->i2c_adap, 0x08, 0, 0) == NULL) {
|
||||
wprintk("%s: Medion Quadro, no ISL6405 "
|
||||
"found !\n", __func__);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
if (dev_id == 0x07) {
|
||||
/* fire up the 2nd section of the LNB supply since
|
||||
|
|
@ -1503,12 +1503,12 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60,
|
||||
&dev->i2c_adap, 0) == NULL) {
|
||||
wprintk("%s: No tda826x found!\n", __func__);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
if (dvb_attach(isl6421_attach, fe0->dvb.frontend,
|
||||
&dev->i2c_adap, 0x08, 0, 0) == NULL) {
|
||||
wprintk("%s: No ISL6421 found!\n", __func__);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -1537,37 +1537,37 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
case SAA7134_BOARD_CINERGY_HT_PCMCIA:
|
||||
if (configure_tda827x_fe(dev, &cinergy_ht_config,
|
||||
&tda827x_cfg_0) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_CINERGY_HT_PCI:
|
||||
if (configure_tda827x_fe(dev, &cinergy_ht_pci_config,
|
||||
&tda827x_cfg_0) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_PHILIPS_TIGER_S:
|
||||
if (configure_tda827x_fe(dev, &philips_tiger_s_config,
|
||||
&tda827x_cfg_2) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_ASUS_P7131_4871:
|
||||
if (configure_tda827x_fe(dev, &asus_p7131_4871_config,
|
||||
&tda827x_cfg_2) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_ASUSTeK_P7131_HYBRID_LNA:
|
||||
if (configure_tda827x_fe(dev, &asus_p7131_hybrid_lna_config,
|
||||
&tda827x_cfg_2) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_AVERMEDIA_SUPER_007:
|
||||
if (configure_tda827x_fe(dev, &avermedia_super_007_config,
|
||||
&tda827x_cfg_0) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_TWINHAN_DTV_DVB_3056:
|
||||
if (configure_tda827x_fe(dev, &twinhan_dtv_dvb_3056_config,
|
||||
&tda827x_cfg_2_sw42) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_PHILIPS_SNAKE:
|
||||
fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
|
||||
|
|
@ -1576,24 +1576,24 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60,
|
||||
&dev->i2c_adap, 0) == NULL) {
|
||||
wprintk("%s: No tda826x found!\n", __func__);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
|
||||
&dev->i2c_adap, 0, 0) == NULL) {
|
||||
wprintk("%s: No lnbp21 found!\n", __func__);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SAA7134_BOARD_CREATIX_CTX953:
|
||||
if (configure_tda827x_fe(dev, &md8800_dvbt_config,
|
||||
&tda827x_cfg_0) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_MSI_TVANYWHERE_AD11:
|
||||
if (configure_tda827x_fe(dev, &philips_tiger_s_config,
|
||||
&tda827x_cfg_2) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
|
||||
dprintk("AverMedia E506R dvb setup\n");
|
||||
|
|
@ -1614,7 +1614,7 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
&dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) {
|
||||
wprintk("%s: MD7134 DVB-S, no SD1878 "
|
||||
"found !\n", __func__);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
/* we need to open the i2c gate (we know it exists) */
|
||||
fe = fe0->dvb.frontend;
|
||||
|
|
@ -1623,7 +1623,7 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
&dev->i2c_adap, 0x08, 0, 0) == NULL) {
|
||||
wprintk("%s: MD7134 DVB-S, no ISL6405 "
|
||||
"found !\n", __func__);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
dev->original_set_voltage = fe->ops.set_voltage;
|
||||
|
|
@ -1645,7 +1645,7 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
if (!use_frontend) { /* terrestrial */
|
||||
if (configure_tda827x_fe(dev, &asus_tiger_3in1_config,
|
||||
&tda827x_cfg_2) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
} else { /* satellite */
|
||||
fe0->dvb.frontend = dvb_attach(tda10086_attach,
|
||||
&flydvbs, &dev->i2c_adap);
|
||||
|
|
@ -1655,13 +1655,13 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
&dev->i2c_adap, 0) == NULL) {
|
||||
wprintk("%s: Asus Tiger 3in1, no "
|
||||
"tda826x found!\n", __func__);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
|
||||
&dev->i2c_adap, 0, 0) == NULL) {
|
||||
wprintk("%s: Asus Tiger 3in1, no lnbp21"
|
||||
" found!\n", __func__);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1670,7 +1670,7 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
if (!use_frontend) { /* terrestrial */
|
||||
if (configure_tda827x_fe(dev, &asus_ps3_100_config,
|
||||
&tda827x_cfg_2) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
} else { /* satellite */
|
||||
fe0->dvb.frontend = dvb_attach(tda10086_attach,
|
||||
&flydvbs, &dev->i2c_adap);
|
||||
|
|
@ -1680,13 +1680,13 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
&dev->i2c_adap, 0) == NULL) {
|
||||
wprintk("%s: Asus My Cinema PS3-100, no "
|
||||
"tda826x found!\n", __func__);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
|
||||
&dev->i2c_adap, 0, 0) == NULL) {
|
||||
wprintk("%s: Asus My Cinema PS3-100, no lnbp21"
|
||||
" found!\n", __func__);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1694,7 +1694,7 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
case SAA7134_BOARD_ASUSTeK_TIGER:
|
||||
if (configure_tda827x_fe(dev, &philips_tiger_config,
|
||||
&tda827x_cfg_0) < 0)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
break;
|
||||
case SAA7134_BOARD_BEHOLD_H6:
|
||||
fe0->dvb.frontend = dvb_attach(zl10353_attach,
|
||||
|
|
@ -1830,19 +1830,19 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
};
|
||||
|
||||
if (!fe0->dvb.frontend)
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
|
||||
fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
|
||||
if (!fe) {
|
||||
printk(KERN_ERR "%s/2: xc3028 attach failed\n",
|
||||
dev->name);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == fe0->dvb.frontend) {
|
||||
printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name);
|
||||
goto dettach_frontend;
|
||||
goto detach_frontend;
|
||||
}
|
||||
/* define general-purpose callback pointer */
|
||||
fe0->dvb.frontend->callback = saa7134_tuner_callback;
|
||||
|
|
@ -1864,7 +1864,7 @@ static int dvb_init(struct saa7134_dev *dev)
|
|||
}
|
||||
return ret;
|
||||
|
||||
dettach_frontend:
|
||||
detach_frontend:
|
||||
videobuf_dvb_dealloc_frontends(&dev->frontends);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
saa7146.h - definitions philips saa7146 based cards
|
||||
Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SAA7146__
|
||||
#define __SAA7146__
|
||||
|
||||
#define SAA7146_VERSION_CODE 0x000101
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
#ifndef O_NONCAP
|
||||
#define O_NONCAP O_TRUNC
|
||||
#endif
|
||||
|
||||
#define MAX_GBUFFERS 2
|
||||
#define FBUF_SIZE 0x190000
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
struct saa7146_window
|
||||
{
|
||||
int x, y;
|
||||
ushort width, height;
|
||||
ushort bpp, bpl;
|
||||
ushort swidth, sheight;
|
||||
short cropx, cropy;
|
||||
ushort cropwidth, cropheight;
|
||||
unsigned long vidadr;
|
||||
int color_fmt;
|
||||
ushort depth;
|
||||
};
|
||||
|
||||
/* Per-open data for handling multiple opens on one device */
|
||||
struct device_open
|
||||
{
|
||||
int isopen;
|
||||
int noncapturing;
|
||||
struct saa7146 *dev;
|
||||
};
|
||||
#define MAX_OPENS 3
|
||||
|
||||
struct saa7146
|
||||
{
|
||||
struct video_device video_dev;
|
||||
struct video_picture picture;
|
||||
struct video_audio audio_dev;
|
||||
struct video_info vidinfo;
|
||||
int user;
|
||||
int cap;
|
||||
int capuser;
|
||||
int irqstate; /* irq routine is state driven */
|
||||
int writemode;
|
||||
int playmode;
|
||||
unsigned int nr;
|
||||
unsigned long irq; /* IRQ used by SAA7146 card */
|
||||
unsigned short id;
|
||||
unsigned char revision;
|
||||
unsigned char boardcfg[64]; /* 64 bytes of config from eeprom */
|
||||
unsigned long saa7146_adr; /* bus address of IO mem from PCI BIOS */
|
||||
struct saa7146_window win;
|
||||
unsigned char __iomem *saa7146_mem; /* pointer to mapped IO memory */
|
||||
struct device_open open_data[MAX_OPENS];
|
||||
#define MAX_MARKS 16
|
||||
/* for a/v sync */
|
||||
int endmark[MAX_MARKS], endmarkhead, endmarktail;
|
||||
u32 *dmaRPS1, *pageRPS1, *dmaRPS2, *pageRPS2, *dmavid1, *dmavid2,
|
||||
*dmavid3, *dmaa1in, *dmaa1out, *dmaa2in, *dmaa2out,
|
||||
*pagedebi, *pagevid1, *pagevid2, *pagevid3, *pagea1in,
|
||||
*pagea1out, *pagea2in, *pagea2out;
|
||||
wait_queue_head_t i2cq, debiq, audq, vidq;
|
||||
u8 *vidbuf, *audbuf, *osdbuf, *dmadebi;
|
||||
int audhead, vidhead, osdhead, audtail, vidtail, osdtail;
|
||||
spinlock_t lock; /* the device lock */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef _ALPHA_SAA7146
|
||||
#define saawrite(dat,adr) writel((dat), saa->saa7146_adr+(adr))
|
||||
#define saaread(adr) readl(saa->saa7146_adr+(adr))
|
||||
#else
|
||||
#define saawrite(dat,adr) writel((dat), saa->saa7146_mem+(adr))
|
||||
#define saaread(adr) readl(saa->saa7146_mem+(adr))
|
||||
#endif
|
||||
|
||||
#define saaand(dat,adr) saawrite((dat) & saaread(adr), adr)
|
||||
#define saaor(dat,adr) saawrite((dat) | saaread(adr), adr)
|
||||
#define saaaor(dat,mask,adr) saawrite((dat) | ((mask) & saaread(adr)), adr)
|
||||
|
||||
/* bitmask of attached hardware found */
|
||||
#define SAA7146_UNKNOWN 0x00000000
|
||||
#define SAA7146_SAA7111 0x00000001
|
||||
#define SAA7146_SAA7121 0x00000002
|
||||
#define SAA7146_IBMMPEG 0x00000004
|
||||
|
||||
#endif
|
||||
|
|
@ -1,283 +0,0 @@
|
|||
/*
|
||||
saa7146.h - definitions philips saa7146 based cards
|
||||
Copyright (C) 1999 Nathan Laredo (laredo@gnu.org)
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __SAA7146_REG__
|
||||
#define __SAA7146_REG__
|
||||
#define SAA7146_BASE_ODD1 0x00
|
||||
#define SAA7146_BASE_EVEN1 0x04
|
||||
#define SAA7146_PROT_ADDR1 0x08
|
||||
#define SAA7146_PITCH1 0x0c
|
||||
#define SAA7146_PAGE1 0x10
|
||||
#define SAA7146_NUM_LINE_BYTE1 0x14
|
||||
#define SAA7146_BASE_ODD2 0x18
|
||||
#define SAA7146_BASE_EVEN2 0x1c
|
||||
#define SAA7146_PROT_ADDR2 0x20
|
||||
#define SAA7146_PITCH2 0x24
|
||||
#define SAA7146_PAGE2 0x28
|
||||
#define SAA7146_NUM_LINE_BYTE2 0x2c
|
||||
#define SAA7146_BASE_ODD3 0x30
|
||||
#define SAA7146_BASE_EVEN3 0x34
|
||||
#define SAA7146_PROT_ADDR3 0x38
|
||||
#define SAA7146_PITCH3 0x3c
|
||||
#define SAA7146_PAGE3 0x40
|
||||
#define SAA7146_NUM_LINE_BYTE3 0x44
|
||||
#define SAA7146_PCI_BT_V1 0x48
|
||||
#define SAA7146_PCI_BT_V2 0x49
|
||||
#define SAA7146_PCI_BT_V3 0x4a
|
||||
#define SAA7146_PCI_BT_DEBI 0x4b
|
||||
#define SAA7146_PCI_BT_A 0x4c
|
||||
#define SAA7146_DD1_INIT 0x50
|
||||
#define SAA7146_DD1_STREAM_B 0x54
|
||||
#define SAA7146_DD1_STREAM_A 0x56
|
||||
#define SAA7146_BRS_CTRL 0x58
|
||||
#define SAA7146_HPS_CTRL 0x5c
|
||||
#define SAA7146_HPS_V_SCALE 0x60
|
||||
#define SAA7146_HPS_V_GAIN 0x64
|
||||
#define SAA7146_HPS_H_PRESCALE 0x68
|
||||
#define SAA7146_HPS_H_SCALE 0x6c
|
||||
#define SAA7146_BCS_CTRL 0x70
|
||||
#define SAA7146_CHROMA_KEY_RANGE 0x74
|
||||
#define SAA7146_CLIP_FORMAT_CTRL 0x78
|
||||
#define SAA7146_DEBI_CONFIG 0x7c
|
||||
#define SAA7146_DEBI_COMMAND 0x80
|
||||
#define SAA7146_DEBI_PAGE 0x84
|
||||
#define SAA7146_DEBI_AD 0x88
|
||||
#define SAA7146_I2C_TRANSFER 0x8c
|
||||
#define SAA7146_I2C_STATUS 0x90
|
||||
#define SAA7146_BASE_A1_IN 0x94
|
||||
#define SAA7146_PROT_A1_IN 0x98
|
||||
#define SAA7146_PAGE_A1_IN 0x9C
|
||||
#define SAA7146_BASE_A1_OUT 0xa0
|
||||
#define SAA7146_PROT_A1_OUT 0xa4
|
||||
#define SAA7146_PAGE_A1_OUT 0xa8
|
||||
#define SAA7146_BASE_A2_IN 0xac
|
||||
#define SAA7146_PROT_A2_IN 0xb0
|
||||
#define SAA7146_PAGE_A2_IN 0xb4
|
||||
#define SAA7146_BASE_A2_OUT 0xb8
|
||||
#define SAA7146_PROT_A2_OUT 0xbc
|
||||
#define SAA7146_PAGE_A2_OUT 0xc0
|
||||
#define SAA7146_RPS_PAGE0 0xc4
|
||||
#define SAA7146_RPS_PAGE1 0xc8
|
||||
#define SAA7146_RPS_THRESH0 0xcc
|
||||
#define SAA7146_RPS_THRESH1 0xd0
|
||||
#define SAA7146_RPS_TOV0 0xd4
|
||||
#define SAA7146_RPS_TOV1 0xd8
|
||||
#define SAA7146_IER 0xdc
|
||||
#define SAA7146_GPIO_CTRL 0xe0
|
||||
#define SAA7146_EC1SSR 0xe4
|
||||
#define SAA7146_EC2SSR 0xe8
|
||||
#define SAA7146_ECT1R 0xec
|
||||
#define SAA7146_ECT2R 0xf0
|
||||
#define SAA7146_ACON1 0xf4
|
||||
#define SAA7146_ACON2 0xf8
|
||||
#define SAA7146_MC1 0xfc
|
||||
#define SAA7146_MC2 0x100
|
||||
#define SAA7146_RPS_ADDR0 0x104
|
||||
#define SAA7146_RPS_ADDR1 0x108
|
||||
#define SAA7146_ISR 0x10c
|
||||
#define SAA7146_PSR 0x110
|
||||
#define SAA7146_SSR 0x114
|
||||
#define SAA7146_EC1R 0x118
|
||||
#define SAA7146_EC2R 0x11c
|
||||
#define SAA7146_VDP1 0x120
|
||||
#define SAA7146_VDP2 0x124
|
||||
#define SAA7146_VDP3 0x128
|
||||
#define SAA7146_ADP1 0x12c
|
||||
#define SAA7146_ADP2 0x130
|
||||
#define SAA7146_ADP3 0x134
|
||||
#define SAA7146_ADP4 0x138
|
||||
#define SAA7146_DDP 0x13c
|
||||
#define SAA7146_LEVEL_REP 0x140
|
||||
#define SAA7146_FB_BUFFER1 0x144
|
||||
#define SAA7146_FB_BUFFER2 0x148
|
||||
#define SAA7146_A_TIME_SLOT1 0x180
|
||||
#define SAA7146_A_TIME_SLOT2 0x1C0
|
||||
|
||||
/* bitfield defines */
|
||||
#define MASK_31 0x80000000
|
||||
#define MASK_30 0x40000000
|
||||
#define MASK_29 0x20000000
|
||||
#define MASK_28 0x10000000
|
||||
#define MASK_27 0x08000000
|
||||
#define MASK_26 0x04000000
|
||||
#define MASK_25 0x02000000
|
||||
#define MASK_24 0x01000000
|
||||
#define MASK_23 0x00800000
|
||||
#define MASK_22 0x00400000
|
||||
#define MASK_21 0x00200000
|
||||
#define MASK_20 0x00100000
|
||||
#define MASK_19 0x00080000
|
||||
#define MASK_18 0x00040000
|
||||
#define MASK_17 0x00020000
|
||||
#define MASK_16 0x00010000
|
||||
#define MASK_15 0x00008000
|
||||
#define MASK_14 0x00004000
|
||||
#define MASK_13 0x00002000
|
||||
#define MASK_12 0x00001000
|
||||
#define MASK_11 0x00000800
|
||||
#define MASK_10 0x00000400
|
||||
#define MASK_09 0x00000200
|
||||
#define MASK_08 0x00000100
|
||||
#define MASK_07 0x00000080
|
||||
#define MASK_06 0x00000040
|
||||
#define MASK_05 0x00000020
|
||||
#define MASK_04 0x00000010
|
||||
#define MASK_03 0x00000008
|
||||
#define MASK_02 0x00000004
|
||||
#define MASK_01 0x00000002
|
||||
#define MASK_00 0x00000001
|
||||
#define MASK_B0 0x000000ff
|
||||
#define MASK_B1 0x0000ff00
|
||||
#define MASK_B2 0x00ff0000
|
||||
#define MASK_B3 0xff000000
|
||||
#define MASK_W0 0x0000ffff
|
||||
#define MASK_W1 0xffff0000
|
||||
#define MASK_PA 0xfffffffc
|
||||
#define MASK_PR 0xfffffffe
|
||||
#define MASK_ER 0xffffffff
|
||||
#define MASK_NONE 0x00000000
|
||||
|
||||
#define SAA7146_PAGE_MAP_EN MASK_11
|
||||
/* main control register 1 */
|
||||
#define SAA7146_MC1_MRST_N MASK_15
|
||||
#define SAA7146_MC1_ERPS1 MASK_13
|
||||
#define SAA7146_MC1_ERPS0 MASK_12
|
||||
#define SAA7146_MC1_EDP MASK_11
|
||||
#define SAA7146_MC1_EVP MASK_10
|
||||
#define SAA7146_MC1_EAP MASK_09
|
||||
#define SAA7146_MC1_EI2C MASK_08
|
||||
#define SAA7146_MC1_TR_E_DEBI MASK_07
|
||||
#define SAA7146_MC1_TR_E_1 MASK_06
|
||||
#define SAA7146_MC1_TR_E_2 MASK_05
|
||||
#define SAA7146_MC1_TR_E_3 MASK_04
|
||||
#define SAA7146_MC1_TR_E_A2_OUT MASK_03
|
||||
#define SAA7146_MC1_TR_E_A2_IN MASK_02
|
||||
#define SAA7146_MC1_TR_E_A1_OUT MASK_01
|
||||
#define SAA7146_MC1_TR_E_A1_IN MASK_00
|
||||
/* main control register 2 */
|
||||
#define SAA7146_MC2_RPS_SIG4 MASK_15
|
||||
#define SAA7146_MC2_RPS_SIG3 MASK_14
|
||||
#define SAA7146_MC2_RPS_SIG2 MASK_13
|
||||
#define SAA7146_MC2_RPS_SIG1 MASK_12
|
||||
#define SAA7146_MC2_RPS_SIG0 MASK_11
|
||||
#define SAA7146_MC2_UPLD_D1_B MASK_10
|
||||
#define SAA7146_MC2_UPLD_D1_A MASK_09
|
||||
#define SAA7146_MC2_UPLD_BRS MASK_08
|
||||
#define SAA7146_MC2_UPLD_HPS_H MASK_06
|
||||
#define SAA7146_MC2_UPLD_HPS_V MASK_05
|
||||
#define SAA7146_MC2_UPLD_DMA3 MASK_04
|
||||
#define SAA7146_MC2_UPLD_DMA2 MASK_03
|
||||
#define SAA7146_MC2_UPLD_DMA1 MASK_02
|
||||
#define SAA7146_MC2_UPLD_DEBI MASK_01
|
||||
#define SAA7146_MC2_UPLD_I2C MASK_00
|
||||
/* Primary Status Register and Interrupt Enable/Status Registers */
|
||||
#define SAA7146_PSR_PPEF MASK_31
|
||||
#define SAA7146_PSR_PABO MASK_30
|
||||
#define SAA7146_PSR_PPED MASK_29
|
||||
#define SAA7146_PSR_RPS_I1 MASK_28
|
||||
#define SAA7146_PSR_RPS_I0 MASK_27
|
||||
#define SAA7146_PSR_RPS_LATE1 MASK_26
|
||||
#define SAA7146_PSR_RPS_LATE0 MASK_25
|
||||
#define SAA7146_PSR_RPS_E1 MASK_24
|
||||
#define SAA7146_PSR_RPS_E0 MASK_23
|
||||
#define SAA7146_PSR_RPS_TO1 MASK_22
|
||||
#define SAA7146_PSR_RPS_TO0 MASK_21
|
||||
#define SAA7146_PSR_UPLD MASK_20
|
||||
#define SAA7146_PSR_DEBI_S MASK_19
|
||||
#define SAA7146_PSR_DEBI_E MASK_18
|
||||
#define SAA7146_PSR_I2C_S MASK_17
|
||||
#define SAA7146_PSR_I2C_E MASK_16
|
||||
#define SAA7146_PSR_A2_IN MASK_15
|
||||
#define SAA7146_PSR_A2_OUT MASK_14
|
||||
#define SAA7146_PSR_A1_IN MASK_13
|
||||
#define SAA7146_PSR_A1_OUT MASK_12
|
||||
#define SAA7146_PSR_AFOU MASK_11
|
||||
#define SAA7146_PSR_V_PE MASK_10
|
||||
#define SAA7146_PSR_VFOU MASK_09
|
||||
#define SAA7146_PSR_FIDA MASK_08
|
||||
#define SAA7146_PSR_FIDB MASK_07
|
||||
#define SAA7146_PSR_PIN3 MASK_06
|
||||
#define SAA7146_PSR_PIN2 MASK_05
|
||||
#define SAA7146_PSR_PIN1 MASK_04
|
||||
#define SAA7146_PSR_PIN0 MASK_03
|
||||
#define SAA7146_PSR_ECS MASK_02
|
||||
#define SAA7146_PSR_EC3S MASK_01
|
||||
#define SAA7146_PSR_EC0S MASK_00
|
||||
/* Secondary Status Register */
|
||||
#define SAA7146_SSR_PRQ MASK_31
|
||||
#define SAA7146_SSR_PMA MASK_30
|
||||
#define SAA7146_SSR_RPS_RE1 MASK_29
|
||||
#define SAA7146_SSR_RPS_PE1 MASK_28
|
||||
#define SAA7146_SSR_RPS_A1 MASK_27
|
||||
#define SAA7146_SSR_RPS_RE0 MASK_26
|
||||
#define SAA7146_SSR_RPS_PE0 MASK_25
|
||||
#define SAA7146_SSR_RPS_A0 MASK_24
|
||||
#define SAA7146_SSR_DEBI_TO MASK_23
|
||||
#define SAA7146_SSR_DEBI_EF MASK_22
|
||||
#define SAA7146_SSR_I2C_EA MASK_21
|
||||
#define SAA7146_SSR_I2C_EW MASK_20
|
||||
#define SAA7146_SSR_I2C_ER MASK_19
|
||||
#define SAA7146_SSR_I2C_EL MASK_18
|
||||
#define SAA7146_SSR_I2C_EF MASK_17
|
||||
#define SAA7146_SSR_V3P MASK_16
|
||||
#define SAA7146_SSR_V2P MASK_15
|
||||
#define SAA7146_SSR_V1P MASK_14
|
||||
#define SAA7146_SSR_VF3 MASK_13
|
||||
#define SAA7146_SSR_VF2 MASK_12
|
||||
#define SAA7146_SSR_VF1 MASK_11
|
||||
#define SAA7146_SSR_AF2_IN MASK_10
|
||||
#define SAA7146_SSR_AF2_OUT MASK_09
|
||||
#define SAA7146_SSR_AF1_IN MASK_08
|
||||
#define SAA7146_SSR_AF1_OUT MASK_07
|
||||
#define SAA7146_SSR_VGT MASK_05
|
||||
#define SAA7146_SSR_LNQG MASK_04
|
||||
#define SAA7146_SSR_EC5S MASK_03
|
||||
#define SAA7146_SSR_EC4S MASK_02
|
||||
#define SAA7146_SSR_EC2S MASK_01
|
||||
#define SAA7146_SSR_EC1S MASK_00
|
||||
/* I2C status register */
|
||||
#define SAA7146_I2C_ABORT MASK_07
|
||||
#define SAA7146_I2C_SPERR MASK_06
|
||||
#define SAA7146_I2C_APERR MASK_05
|
||||
#define SAA7146_I2C_DTERR MASK_04
|
||||
#define SAA7146_I2C_DRERR MASK_03
|
||||
#define SAA7146_I2C_AL MASK_02
|
||||
#define SAA7146_I2C_ERR MASK_01
|
||||
#define SAA7146_I2C_BUSY MASK_00
|
||||
/* output formats */
|
||||
#define SAA7146_YUV422 0
|
||||
#define SAA7146_RGB16 0
|
||||
#define SAA7146_YUV444 1
|
||||
#define SAA7146_RGB24 1
|
||||
#define SAA7146_ARGB32 2
|
||||
#define SAA7146_YUV411 3
|
||||
#define SAA7146_ARGB15 3
|
||||
#define SAA7146_YUV2 4
|
||||
#define SAA7146_RGAB15 4
|
||||
#define SAA7146_Y8 6
|
||||
#define SAA7146_YUV8 7
|
||||
#define SAA7146_RGB8 7
|
||||
#define SAA7146_YUV444p 8
|
||||
#define SAA7146_YUV422p 9
|
||||
#define SAA7146_YUV420p 10
|
||||
#define SAA7146_YUV1620 11
|
||||
#define SAA7146_Y1 13
|
||||
#define SAA7146_Y2 14
|
||||
#define SAA7146_YUV1 15
|
||||
#endif
|
||||
|
|
@ -1367,7 +1367,6 @@ int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
|
|||
struct saa7164_dev *dev = bus->dev;
|
||||
u16 len = 0;
|
||||
int unitid;
|
||||
u32 regval;
|
||||
u8 buf[256];
|
||||
int ret;
|
||||
|
||||
|
|
@ -1376,19 +1375,6 @@ int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
|
|||
if (reglen > 4)
|
||||
return -EIO;
|
||||
|
||||
if (reglen == 1)
|
||||
regval = *(reg);
|
||||
else
|
||||
if (reglen == 2)
|
||||
regval = ((*(reg) << 8) || *(reg+1));
|
||||
else
|
||||
if (reglen == 3)
|
||||
regval = ((*(reg) << 16) | (*(reg+1) << 8) | *(reg+2));
|
||||
else
|
||||
if (reglen == 4)
|
||||
regval = ((*(reg) << 24) | (*(reg+1) << 16) |
|
||||
(*(reg+2) << 8) | *(reg+3));
|
||||
|
||||
/* Prepare the send buffer */
|
||||
/* Bytes 00-03 source register length
|
||||
* 04-07 source bytes to read
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
config VIDEO_SMIAPP
|
||||
tristate "SMIA++/SMIA sensor support"
|
||||
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAVE_CLK
|
||||
depends on MEDIA_CAMERA_SUPPORT
|
||||
select VIDEO_SMIAPP_PLL
|
||||
---help---
|
||||
This is a generic driver for SMIA++/SMIA camera modules.
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue