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:
Linus Torvalds 2012-07-30 19:03:41 -07:00
commit 6df419e45d
156 changed files with 7584 additions and 5523 deletions

View file

@ -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"

View file

@ -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.

View file

@ -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);

View file

@ -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__);

View file

@ -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);

View file

@ -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. */

View file

@ -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.

View file

@ -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;
}

View file

@ -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

View file

@ -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");

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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) \

View file

@ -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;

View file

@ -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

View 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 = &reg,
}, {
.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");

View 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 */

View 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 */

View file

@ -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);

View file

@ -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))));

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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);

View file

@ -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.

View 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 */

View file

@ -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;
}

View file

@ -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))) {

View file

@ -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;
}

View file

@ -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;

View file

@ -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) {

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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 */

View file

@ -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");

View file

@ -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 */

View file

@ -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.

View file

@ -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

View 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);

View 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

View file

@ -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",

View file

@ -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,

View file

@ -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));

View file

@ -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

View file

@ -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,

View file

@ -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);

View file

@ -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;

View file

@ -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) {

View file

@ -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),

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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,

View file

@ -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);
}
}

View file

@ -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");

View file

@ -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",

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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,

View file

@ -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

View file

@ -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,
};

View file

@ -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

View file

@ -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];

View file

@ -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
*/

View file

@ -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;

View file

@ -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 */

View file

@ -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);

View file

@ -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);

View file

@ -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
*/

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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

View file

@ -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);
}
}

View file

@ -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)

View file

@ -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,

View file

@ -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];

View file

@ -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;
}

View file

@ -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;

View file

@ -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 },

View file

@ -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);

View file

@ -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();

View file

@ -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");

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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