Commit 58f25071 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb

* git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (98 commits)
  V4L/DVB (8549): mxl5007: Fix an error at include file
  V4L/DVB (8548): pwc: Fix compilation
  V4L/DVB (8546): add tuner-3036 and dpc7146 drivers to feature-removal-schedule.txt
  V4L/DVB (8546): saa7146: fix read from uninitialized memory
  V4L/DVB (8544): gspca: probe/open race.
  V4L/DVB (8543): em28xx: Rename #define for Compro VideoMate ForYou/Stereo
  V4L/DVB (8542): em28xx: AMD ATI TV Wonder HD 600 entry at cards struct is duplicated
  V4L/DVB (8541): em28xx: HVR-950 entry is duplicated.
  V4L/DVB (8540): em28xx-cards: Add Compro VideoMate ForYou/Stereo model
  V4L/DVB (8539): em28xx-cards: New supported IDs for analog models
  V4L/DVB (8538): em28xx-cards: Add GrabBeeX+ USB2800 model
  V4L/DVB (8534): remove select's of FW_LOADER
  V4L/DVB (8522): videodev2: Fix merge conflict
  V4L/DVB (8532): mxl5007t: remove excessive locks
  V4L/DVB (8531): mxl5007t: move i2c gate handling outside of mutex protected code blocks
  V4L/DVB (8530): au0828: add support for new revision of HVR950Q
  V4L/DVB (8529): mxl5007t: enable _init and _sleep power management functionality
  V4L/DVB (8528): add support for MaxLinear MxL5007T silicon tuner
  V4L/DVB (8526): saa7146: fix VIDIOC_ENUM_FMT
  V4L/DVB (8525): fix a few assorted spelling mistakes.
  ...
parents c32f1a34 c2f90e95
......@@ -47,6 +47,30 @@ Who: Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
What: old tuner-3036 i2c driver
When: 2.6.28
Why: This driver is for VERY old i2c-over-parallel port teletext receiver
boxes. Rather then spending effort on converting this driver to V4L2,
and since it is extremely unlikely that anyone still uses one of these
devices, it was decided to drop it.
Who: Hans Verkuil <hverkuil@xs4all.nl>
Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
What: V4L2 dpc7146 driver
When: 2.6.28
Why: Old driver for the dpc7146 demonstration board that is no longer
relevant. The last time this was tested on actual hardware was
probably around 2002. Since this is a driver for a demonstration
board the decision was made to remove it rather than spending a
lot of effort continually updating this driver to stay in sync
with the latest internal V4L2 or I2C API.
Who: Hans Verkuil <hverkuil@xs4all.nl>
Mauro Carvalho Chehab <mchehab@infradead.org>
---------------------------
What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
When: November 2005
Files: drivers/pcmcia/: pcmcia_ioctl.c
......
......@@ -2,3 +2,4 @@
1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008]
2 -> Hauppauge HVR850 (au0828) [2040:7240]
3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620]
4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281]
0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800]
1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2750,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883]
1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883]
2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036]
3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208]
4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201]
5 -> MSI VOX USB 2.0 (em2820/em2840)
6 -> Terratec Cinergy 200 USB (em2800)
7 -> Leadtek Winfast USB II (em2800)
7 -> Leadtek Winfast USB II (em2800) [0413:6023]
8 -> Kworld USB2800 (em2800)
9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a]
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
......@@ -14,7 +14,46 @@
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
15 -> V-Gear PocketTV (em2800)
16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513,2040:6517,2040:651b,2040:651f]
16 -> Hauppauge WinTV HVR 950 (em2883) [2040:6513,2040:6517,2040:651b,2040:651f]
17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227]
18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502]
19 -> PointNix Intra-Oral Camera (em2860)
20 -> AMD ATI TV Wonder HD 600 (em2880) [0438:b002]
21 -> eMPIA Technology, Inc. GrabBeeX+ Video Encoder (em2800) [eb1a:2801]
22 -> Unknown EM2750/EM2751 webcam grabber (em2750) [eb1a:2750,eb1a:2751]
23 -> Huaqi DLCW-130 (em2750)
24 -> D-Link DUB-T210 TV Tuner (em2820/em2840) [2001:f112]
25 -> Gadmei UTV310 (em2820/em2840)
26 -> Hercules Smart TV USB 2.0 (em2820/em2840)
27 -> Pinnacle PCTV USB 2 (Philips FM1216ME) (em2820/em2840)
28 -> Leadtek Winfast USB II Deluxe (em2820/em2840)
29 -> Pinnacle Dazzle DVC 100 (em2820/em2840)
30 -> Videology 20K14XUSB USB2.0 (em2820/em2840)
31 -> Usbgear VD204v9 (em2821)
32 -> Supercomp USB 2.0 TV (em2821)
33 -> SIIG AVTuner-PVR/Prolink PlayTV USB 2.0 (em2821)
34 -> Terratec Cinergy A Hybrid XS (em2860) [0ccd:004f]
35 -> Typhoon DVD Maker (em2860)
36 -> NetGMBH Cam (em2860)
37 -> Gadmei UTV330 (em2860)
38 -> Yakumo MovieMixer (em2861)
39 -> KWorld PVRTV 300U (em2861) [eb1a:e300]
40 -> Plextor ConvertX PX-TV100U (em2861) [093b:a005]
41 -> Kworld 350 U DVB-T (em2870) [eb1a:e350]
42 -> Kworld 355 U DVB-T (em2870) [eb1a:e355,eb1a:e357]
43 -> Terratec Cinergy T XS (em2870) [0ccd:0043]
44 -> Terratec Cinergy T XS (MT2060) (em2870)
45 -> Pinnacle PCTV DVB-T (em2870)
46 -> Compro, VideoMate U3 (em2870) [185b:2870]
47 -> KWorld DVB-T 305U (em2880) [eb1a:e305]
48 -> KWorld DVB-T 310U (em2880)
49 -> MSI DigiVox A/D (em2880) [eb1a:e310]
50 -> MSI DigiVox A/D II (em2880) [eb1a:e320]
51 -> Terratec Hybrid XS Secam (em2880) [0ccd:004c]
52 -> DNT DA2 Hybrid (em2881)
53 -> Pinnacle Hybrid Pro (em2881)
54 -> Kworld VS-DVB-T 323UR (em2882) [eb1a:e323]
55 -> Terratec Hybrid XS (em2882) (em2882) [0ccd:005e]
56 -> Pinnacle Hybrid Pro (2) (em2882) [2304:0226]
57 -> Kworld PlusTV HD Hybrid 330 (em2883) [eb1a:a316]
58 -> Compro VideoMate ForYou/Stereo (em2820/em2840) [185b:2041]
List of the webcams know by gspca.
List of the webcams known by gspca.
The modules are:
gspca_main main driver
......
......@@ -3796,6 +3796,12 @@ P: Ben Nizette
M: bn@niasdigital.com
S: Maintained
SOC-CAMERA V4L2 SUBSYSTEM
P: Guennadi Liakhovetski
M: g.liakhovetski@gmx.de
L: video4linux-list@redhat.com
S: Maintained
SOFTWARE RAID (Multiple Disks) SUPPORT
P: Ingo Molnar
M: mingo@redhat.com
......
......@@ -563,7 +563,7 @@ int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev
DEB_EE(("dev:%p\n",dev));
if( VFL_TYPE_GRABBER == (*vid)->type ) {
if ((*vid)->vfl_type == VFL_TYPE_GRABBER) {
vv->video_minor = -1;
} else {
vv->vbi_minor = -1;
......
......@@ -656,7 +656,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu
/* if we have a user buffer, the first page may not be
aligned to a page boundary. */
pt1->offset = list->offset;
pt1->offset = dma->sglist->offset;
pt2->offset = pt1->offset+o1;
pt3->offset = pt1->offset+o2;
......@@ -958,21 +958,18 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
case VIDIOC_ENUM_FMT:
{
struct v4l2_fmtdesc *f = arg;
int index;
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
case V4L2_BUF_TYPE_VIDEO_OVERLAY: {
index = f->index;
if (index < 0 || index >= NUM_FORMATS) {
case V4L2_BUF_TYPE_VIDEO_OVERLAY:
if (f->index >= NUM_FORMATS)
return -EINVAL;
}
memset(f,0,sizeof(*f));
f->index = index;
strlcpy((char *)f->description,formats[index].name,sizeof(f->description));
f->pixelformat = formats[index].pixelformat;
strlcpy((char *)f->description, formats[f->index].name,
sizeof(f->description));
f->pixelformat = formats[f->index].pixelformat;
f->flags = 0;
memset(f->reserved, 0, sizeof(f->reserved));
break;
}
default:
return -EINVAL;
}
......
......@@ -21,9 +21,8 @@ config MEDIA_TUNER
tristate
default VIDEO_MEDIA && I2C
depends on VIDEO_MEDIA && I2C
select FW_LOADER if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG
select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE
select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE
select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE
select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE
......@@ -138,8 +137,6 @@ config MEDIA_TUNER_QT1010
config MEDIA_TUNER_XC2028
tristate "XCeive xc2028/xc3028 tuners"
depends on VIDEO_MEDIA && I2C
depends on HOTPLUG
select FW_LOADER
default m if MEDIA_TUNER_CUSTOMIZE
help
Say Y here to include support for the xc2028/xc3028 tuners.
......@@ -147,8 +144,6 @@ config MEDIA_TUNER_XC2028
config MEDIA_TUNER_XC5000
tristate "Xceive XC5000 silicon tuner"
depends on VIDEO_MEDIA && I2C
depends on HOTPLUG
select FW_LOADER
default m if DVB_FE_CUSTOMISE
help
A driver for the silicon tuner XC5000 from Xceive.
......@@ -162,4 +157,11 @@ config MEDIA_TUNER_MXL5005S
help
A driver for the silicon tuner MXL5005S from MaxLinear.
config MEDIA_TUNER_MXL5007T
tristate "MaxLinear MxL5007T silicon tuner"
depends on VIDEO_MEDIA && I2C
default m if DVB_FE_CUSTOMISE
help
A driver for the silicon tuner MxL5007T from MaxLinear.
endif # MEDIA_TUNER_CUSTOMIZE
......@@ -21,6 +21,7 @@ obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
......@@ -148,7 +148,8 @@ static int mt2032_compute_freq(struct dvb_frontend *fe,
tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
if(lo1a<0 || lo1a>7 || lo1n<17 ||lo1n>48 || lo2a<0 ||lo2a >7 ||lo2n<17 || lo2n>30) {
if (lo1a > 7 || lo1n < 17 || lo1n > 48 || lo2a > 7 || lo2n < 17 ||
lo2n > 30) {
tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
lo1a, lo1n, lo2a,lo2n);
return(-1);
......
This diff is collapsed.
/*
* mxl5007t.h - driver for the MaxLinear MxL5007T silicon tuner
*
* Copyright (C) 2008 Michael Krufky <mkrufky@linuxtv.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 __MXL5007T_H__
#define __MXL5007T_H__
#include "dvb_frontend.h"
/* ------------------------------------------------------------------------- */
enum mxl5007t_if_freq {
MxL_IF_4_MHZ, /* 4000000 */
MxL_IF_4_5_MHZ, /* 4500000 */
MxL_IF_4_57_MHZ, /* 4570000 */
MxL_IF_5_MHZ, /* 5000000 */
MxL_IF_5_38_MHZ, /* 5380000 */
MxL_IF_6_MHZ, /* 6000000 */
MxL_IF_6_28_MHZ, /* 6280000 */
MxL_IF_9_1915_MHZ, /* 9191500 */
MxL_IF_35_25_MHZ, /* 35250000 */
MxL_IF_36_15_MHZ, /* 36150000 */
MxL_IF_44_MHZ, /* 44000000 */
};
enum mxl5007t_xtal_freq {
MxL_XTAL_16_MHZ, /* 16000000 */
MxL_XTAL_20_MHZ, /* 20000000 */
MxL_XTAL_20_25_MHZ, /* 20250000 */
MxL_XTAL_20_48_MHZ, /* 20480000 */
MxL_XTAL_24_MHZ, /* 24000000 */
MxL_XTAL_25_MHZ, /* 25000000 */
MxL_XTAL_25_14_MHZ, /* 25140000 */
MxL_XTAL_27_MHZ, /* 27000000 */
MxL_XTAL_28_8_MHZ, /* 28800000 */
MxL_XTAL_32_MHZ, /* 32000000 */
MxL_XTAL_40_MHZ, /* 40000000 */
MxL_XTAL_44_MHZ, /* 44000000 */
MxL_XTAL_48_MHZ, /* 48000000 */
MxL_XTAL_49_3811_MHZ, /* 49381100 */
};
enum mxl5007t_clkout_amp {
MxL_CLKOUT_AMP_0_94V = 0,
MxL_CLKOUT_AMP_0_53V = 1,
MxL_CLKOUT_AMP_0_37V = 2,
MxL_CLKOUT_AMP_0_28V = 3,
MxL_CLKOUT_AMP_0_23V = 4,
MxL_CLKOUT_AMP_0_20V = 5,
MxL_CLKOUT_AMP_0_17V = 6,
MxL_CLKOUT_AMP_0_15V = 7,
};
struct mxl5007t_config {
s32 if_diff_out_level;
enum mxl5007t_clkout_amp clk_out_amp;
enum mxl5007t_xtal_freq xtal_freq_hz;
enum mxl5007t_if_freq if_freq_hz;
unsigned int invert_if:1;
unsigned int loop_thru_enable:1;
unsigned int clk_out_enable:1;
};
#if defined(CONFIG_MEDIA_TUNER_MXL5007T) || (defined(CONFIG_MEDIA_TUNER_MXL5007T_MODULE) && defined(MODULE))
extern struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, u8 addr,
struct mxl5007t_config *cfg);
#else
static inline struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
u8 addr,
struct mxl5007t_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
#endif /* __MXL5007T_H__ */
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* ---------------------------------------------------------------------------
* Local variables:
* c-basic-offset: 8
* End:
*/
......@@ -6,7 +6,7 @@
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/videodev.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/tuner.h>
#include "tuner-i2c.h"
......
......@@ -6,7 +6,7 @@
*/
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/videodev.h>
#include <linux/videodev2.h>
#include <media/tuner.h>
#include <media/v4l2-common.h>
#include <media/tuner-types.h>
......
config DVB_BT8XX
tristate "BT8xx based PCI cards"
depends on DVB_CORE && PCI && I2C && VIDEO_BT848
depends on HOTPLUG # due to FW_LOADER
select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_SP887X if !DVB_FE_CUSTOMISE
select DVB_NXT6000 if !DVB_FE_CUSTOMISE
......@@ -10,7 +9,6 @@ config DVB_BT8XX
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_SIMPLE if !DVB_FE_CUSTOMISE
select FW_LOADER
help
Support for PCI cards based on the Bt8xx PCI bridge. Examples are
the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards,
......
config DVB_USB
tristate "Support for various USB DVB devices"
depends on DVB_CORE && USB && I2C && INPUT
depends on HOTPLUG # due to FW_LOADER
select FW_LOADER
help
By enabling this you will be able to choose the various supported
USB1.1 and USB2.0 DVB devices.
......@@ -246,6 +244,14 @@ config DVB_USB_AF9005_REMOTE
Say Y here to support the default remote control decoding for the
Afatech AF9005 based receiver.
config DVB_USB_DW2102
tristate "DvbWorld 2102 DVB-S USB2.0 receiver"
depends on DVB_USB
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_PLL if !DVB_FE_CUSTOMISE
help
Say Y here to support the DvbWorld 2102 DVB-S USB2.0 receiver.
config DVB_USB_ANYSEE
tristate "Anysee DVB-T/C USB2.0 support"
depends on DVB_USB
......
......@@ -64,6 +64,9 @@ obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o
dvb-usb-anysee-objs = anysee.o
obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o
dvb-usb-dw2102-objs = dw2102.o
obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
# due to tuner-xc3028
EXTRA_CFLAGS += -Idrivers/media/common/tuners
......
......@@ -43,7 +43,7 @@ module_param_named(debug, dvb_usb_anysee_debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
struct mutex anysee_usb_mutex;
static struct mutex anysee_usb_mutex;
static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen,
u8 *rbuf, u8 rlen)
......
......@@ -204,5 +204,6 @@
#define USB_PID_ASUS_U3000 0x171f
#define USB_PID_ASUS_U3100 0x173f
#define USB_PID_YUAN_EC372S 0x1edc
#define USB_PID_DW2102 0x2102
#endif
/* DVB USB framework compliant Linux driver for the DVBWorld DVB-S 2102 Card
*
* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
*
* 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.
*
* see Documentation/dvb/README.dvb-usb for more information
*/
#include <linux/version.h>
#include "dw2102.h"
#include "stv0299.h"
#include "z0194a.h"
#ifndef USB_PID_DW2102
#define USB_PID_DW2102 0x2102
#endif
#define DW2102_READ_MSG 0
#define DW2102_WRITE_MSG 1
#define REG_1F_SYMBOLRATE_BYTE0 0x1f
#define REG_20_SYMBOLRATE_BYTE1 0x20
#define REG_21_SYMBOLRATE_BYTE2 0x21
#define DW2102_VOLTAGE_CTRL (0x1800)
#define DW2102_RC_QUERY (0x1a00)
struct dw2102_state {
u32 last_key_pressed;
};
struct dw2102_rc_keys {
u32 keycode;
u32 event;
};
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static int dw2102_op_rw(struct usb_device *dev, u8 request, u16 value,
u8 *data, u16 len, int flags)
{
int ret;
u8 u8buf[len];
unsigned int pipe = (flags == DW2102_READ_MSG) ?
usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
u8 request_type = (flags == DW2102_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
if (flags == DW2102_WRITE_MSG)
memcpy(u8buf, data, len);
ret = usb_control_msg(dev, pipe, request,
request_type | USB_TYPE_VENDOR, value, 0 , u8buf, len, 2000);
if (flags == DW2102_READ_MSG)
memcpy(data, u8buf, len);
return ret;
}
/* I2C */
static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
int num)
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
int i = 0, ret = 0;
u8 buf6[] = {0x2c, 0x05, 0xc0, 0, 0, 0, 0};
u8 request;
u16 value;
if (!d)
return -ENODEV;
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
switch (num) {
case 2:
/* read stv0299 register */
request = 0xb5;
value = msg[0].buf[0];/* register */
for (i = 0; i < msg[1].len; i++) {
value = value + i;
ret = dw2102_op_rw(d->udev, 0xb5,
value, buf6, 2, DW2102_READ_MSG);
msg[1].buf[i] = buf6[0];
}
break;
case 1:
switch (msg[0].addr) {
case 0x68:
/* write to stv0299 register */
buf6[0] = 0x2a;
buf6[1] = msg[0].buf[0];
buf6[2] = msg[0].buf[1];
ret = dw2102_op_rw(d->udev, 0xb2,
0, buf6, 3, DW2102_WRITE_MSG);
break;
case 0x60:
if (msg[0].flags == 0) {
/* write to tuner pll */
buf6[0] = 0x2c;
buf6[1] = 5;
buf6[2] = 0xc0;
buf6[3] = msg[0].buf[0];
buf6[4] = msg[0].buf[1];
buf6[5] = msg[0].buf[2];
buf6[6] = msg[0].buf[3];
ret = dw2102_op_rw(d->udev, 0xb2,
0, buf6, 7, DW2102_WRITE_MSG);
} else {
/* write to tuner pll */
ret = dw2102_op_rw(d->udev, 0xb5,
0, buf6, 1, DW2102_READ_MSG);
msg[0].buf[0] = buf6[0];
}
break;
case (DW2102_RC_QUERY):
ret = dw2102_op_rw(d->udev, 0xb8,
0, buf6, 2, DW2102_READ_MSG);
msg[0].buf[0] = buf6[0];
msg[0].buf[1] = buf6[1];
break;
case (DW2102_VOLTAGE_CTRL):
buf6[0] = 0x30;
buf6[1] = msg[0].buf[0];
ret = dw2102_op_rw(d->udev, 0xb2,
0, buf6, 2, DW2102_WRITE_MSG);
break;
}
break;
}
mutex_unlock(&d->i2c_mutex);
return num;
}
static u32 dw2102_i2c_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C;
}
static struct i2c_algorithm dw2102_i2c_algo = {
.master_xfer = dw2102_i2c_transfer,
.functionality = dw2102_i2c_func,
};
static int dw2102_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
{
static u8 command_13v[1] = {0x00};
static u8 command_18v[1] = {0x01};
struct i2c_msg msg[] = {
{.addr = DW2102_VOLTAGE_CTRL, .flags = 0,
.buf = command_13v, .len = 1},
};
struct dvb_usb_adapter *udev_adap =
(struct dvb_usb_adapter *)(fe->dvb->priv);
if (voltage == SEC_VOLTAGE_18)
msg[0].buf = command_18v;
i2c_transfer(&udev_adap->dev->i2c_adap, msg, 1);
return 0;
}
static int dw2102_frontend_attach(struct dvb_usb_adapter *d)
{
d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config,
&d->dev->i2c_adap);
if (d->fe != NULL) {
d->fe->ops.set_voltage = dw2102_set_voltage;
info("Attached stv0299!\n");
return 0;
}
return -EIO;
}
static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
{
dvb_attach(dvb_pll_attach, adap->fe, 0x60,
&adap->dev->i2c_adap, DVB_PLL_OPERA1);
return 0;
}
static struct dvb_usb_rc_key dw2102_rc_keys[] = {
{ 0xf8, 0x0a, KEY_Q }, /*power*/
{ 0xf8, 0x0c, KEY_M }, /*mute*/
{ 0xf8, 0x11, KEY_1 },
{ 0xf8, 0x12, KEY_2 },
{ 0xf8, 0x13, KEY_3 },
{ 0xf8, 0x14, KEY_4 },
{ 0xf8, 0x15, KEY_5 },
{ 0xf8, 0x16, KEY_6 },
{ 0xf8, 0x17, KEY_7 },
{ 0xf8, 0x18, KEY_8 },
{ 0xf8, 0x19, KEY_9 },
{ 0xf8, 0x10, KEY_0 },
{ 0xf8, 0x1c, KEY_PAGEUP }, /*ch+*/
{ 0xf8, 0x0f, KEY_PAGEDOWN }, /*ch-*/
{ 0xf8, 0x1a, KEY_O }, /*vol+*/
{ 0xf8, 0x0e, KEY_Z }, /*vol-*/
{ 0xf8, 0x04, KEY_R }, /*rec*/
{ 0xf8, 0x09, KEY_D }, /*fav*/
{ 0xf8, 0x08, KEY_BACKSPACE }, /*rewind*/
{ 0xf8, 0x07, KEY_A }, /*fast*/
{ 0xf8, 0x0b, KEY_P }, /*pause*/
{ 0xf8, 0x02, KEY_ESC }, /*cancel*/
{ 0xf8, 0x03, KEY_G }, /*tab*/
{ 0xf8, 0x00, KEY_UP }, /*up*/
{ 0xf8, 0x1f, KEY_ENTER }, /*ok*/
{ 0xf8, 0x01, KEY_DOWN }, /*down*/
{ 0xf8, 0x05, KEY_C }, /*cap*/
{ 0xf8, 0x06, KEY_S }, /*stop*/
{ 0xf8, 0x40, KEY_F }, /*full*/
{ 0xf8, 0x1e, KEY_W }, /*tvmode*/
{ 0xf8, 0x1b, KEY_B }, /*recall*/
};
static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
struct dw2102_state *st = d->priv;
u8 key[2];
struct i2c_msg msg[] = {
{.addr = DW2102_RC_QUERY, .flags = I2C_M_RD, .buf = key,
.len = 2},
};
int i;
*state = REMOTE_NO_KEY_PRESSED;
if (dw2102_i2c_transfer(&d->i2c_adap, msg, 1) == 1) {
for (i = 0; i < ARRAY_SIZE(dw2102_rc_keys); i++) {
if (dw2102_rc_keys[i].data == msg[0].buf[0]) {
*state = REMOTE_KEY_PRESSED;
*event = dw2102_rc_keys[i].event;
st->last_key_pressed =
dw2102_rc_keys[i].event;
break;
}
st->last_key_pressed = 0;
}
}
/* info("key: %x %x\n",key[0],key[1]); */
return 0;
}
static struct usb_device_id dw2102_table[] = {
{USB_DEVICE(USB_VID_CYPRESS, USB_PID_DW2102)},
{USB_DEVICE(USB_VID_CYPRESS, 0x2101)},
{ }
};
MODULE_DEVICE_TABLE(usb, dw2102_table);
static int dw2102_load_firmware(struct usb_device *dev,
const struct firmware *frmwr)
{
u8 *b, *p;
int ret = 0, i;
u8 reset;
u8 reset16 [] = {0, 0, 0, 0, 0, 0, 0};
const struct firmware *fw;
const char *filename = "dvb-usb-dw2101.fw";
switch (dev->descriptor.idProduct) {
case 0x2101:
ret = request_firmware(&fw, filename, &dev->dev);
if (ret != 0) {
err("did not find the firmware file. (%s) "
"Please see linux/Documentation/dvb/ for more details "
"on firmware-problems.", filename);
return ret;
}
break;
case USB_PID_DW2102:
fw = frmwr;
break;
}
info("start downloading DW2102 firmware");
p = kmalloc(fw->size, GFP_KERNEL);
reset = 1;
/*stop the CPU*/
dw2102_op_rw(dev, 0xa0, 0x7f92, &reset, 1, DW2102_WRITE_MSG);
dw2102_op_rw(dev, 0xa0, 0xe600, &reset, 1, DW2102_WRITE_MSG);
if (p != NULL) {
memcpy(p, fw->data, fw->size);
for (i = 0; i < fw->size; i += 0x40) {
b = (u8 *) p + i;
if (dw2102_op_rw
(dev, 0xa0, i, b , 0x40,
DW2102_WRITE_MSG) != 0x40
) {
err("error while transferring firmware");
ret = -EINVAL;
break;
}
}
/* restart the CPU */
reset = 0;
if (ret || dw2102_op_rw
(dev, 0xa0, 0x7f92, &reset, 1,
DW2102_WRITE_MSG) != 1) {
err("could not restart the USB controller CPU.");
ret = -EINVAL;
}
if (ret || dw2102_op_rw
(dev, 0xa0, 0xe600, &reset, 1,
DW2102_WRITE_MSG) != 1) {
err("could not restart the USB controller CPU.");
ret = -EINVAL;
}
/* init registers */
switch (dev->descriptor.idProduct) {
case USB_PID_DW2102:
dw2102_op_rw
(dev, 0xbf, 0x0040, &reset, 0,
DW2102_WRITE_MSG);
dw2102_op_rw
(dev, 0xb9, 0x0000, &reset16[0], 2,
DW2102_READ_MSG);
break;
case 0x2101:
dw2102_op_rw
(dev, 0xbc, 0x0030, &reset16[0], 2,
DW2102_READ_MSG);
dw2102_op_rw
(dev, 0xba, 0x0000, &reset16[0], 7,
DW2102_READ_MSG);
dw2102_op_rw
(dev, 0xba, 0x0000, &reset16[0], 7,
DW2102_READ_MSG);
dw2102_op_rw
(dev, 0xb9, 0x0000, &reset16[0], 2,
DW2102_READ_MSG);
break;
}
kfree(p);
}
return ret;
}
static struct dvb_usb_device_properties dw2102_properties = {
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
.usb_ctrl = DEVICE_SPECIFIC,
.firmware = "dvb-usb-dw2102.fw",
.size_of_priv = sizeof(struct dw2102_state),
.no_reconnect = 1,
.i2c_algo = &dw2102_i2c_algo,
.rc_key_map = dw2102_rc_keys,
.rc_key_map_size = ARRAY_SIZE(dw2102_rc_keys),
.rc_interval = 150,
.rc_query = dw2102_rc_query,
.generic_bulk_ctrl_endpoint = 0x81,
/* parameter for the MPEG2-data transfer */
.num_adapters = 1,
.download_firmware = dw2102_load_firmware,
.adapter = {
{
.frontend_attach = dw2102_frontend_attach,
.streaming_ctrl = NULL,
.tuner_attach = dw2102_tuner_attach,
.stream = {
.type = USB_BULK,
.count = 8,
.endpoint = 0x82,
.u = {
.bulk = {
.buffersize = 4096,
}
}
},
}
},
.num_device_descs = 2,
.devices = {
{"DVBWorld DVB-S 2102 USB2.0",
{&dw2102_table[0], NULL},
{NULL},
},
{"DVBWorld DVB-S 2101 USB2.0",
{&dw2102_table[1], NULL},
{NULL},
},
}
};
static int dw2102_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
return dvb_usb_device_init(intf, &dw2102_properties,
THIS_MODULE, NULL, adapter_nr);
}
static struct usb_driver dw2102_driver = {
.name = "dw2102",
.probe = dw2102_probe,
.disconnect = dvb_usb_device_exit,
.id_table = dw2102_table,
};
static int __init dw2102_module_init(void)
{
int ret = usb_register(&dw2102_driver);
if (ret)
err("usb_register failed. Error number %d", ret);
return ret;
}
static void __exit dw2102_module_exit(void)
{
usb_deregister(&dw2102_driver);
}
module_init(dw2102_module_init);
module_exit(dw2102_module_exit);
MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101 2102 USB2.0 device");
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment