Commit e695e10b authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb

* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (196 commits)
  V4L/DVB (5253): Qt1010: whitespace / 80 column cleanups
  V4L/DVB (5252): Qt1010: use ARRAY_SIZE macro when appropriate
  V4L/DVB (5251): Qt1010: fix compiler warning
  V4L/DVB (5249): Fix compiler warning in vivi.c
  V4L/DVB (5247): Stv0297: Enable BER/UNC counting
  V4L/DVB (5246): Budget-ci: IR handling fixups
  V4L/DVB (5245): Dvb-ttpci: use i2c gate ctrl from stv0297 frontend driver
  V4L/DVB (5244): Dvbdev: fix illegal re-usage of fileoperations struct
  V4L/DVB (5178): Avoid race when deregistering the IR control for dvb-usb
  V4L/DVB (5240): Qt1010: use i2c_gate_ctrl where appropriate
  V4L/DVB (5239): Whitespace / 80-column cleanups
  V4L/DVB (5238): Kconfig: qt1010 should be selected by gl861 and au6610
  V4L/DVB (5237): Dvb: add new qt1010 tuner module
  V4L/DVB (5236): Initial support for Sigmatek DVB-110 DVB-T
  V4L/DVB (5235): Gl861: use parallel_ts
  V4L/DVB (5234): Gl861: remove unneeded declaration
  V4L/DVB (5233): Gl861: correct address of the bulk endpoint
  V4L/DVB (5232): Gl861: correct oops when loading module
  V4L/DVB (5231): Gl861: whitespace cleanups
  V4L/DVB (5230): Gl861: remove NULL entry from gl861_properties
  ...
parents 3a5f10e3 f6982d59
...@@ -126,7 +126,7 @@ ...@@ -126,7 +126,7 @@
125 -> MATRIX Vision Sigma-SQ 125 -> MATRIX Vision Sigma-SQ
126 -> MATRIX Vision Sigma-SLC 126 -> MATRIX Vision Sigma-SLC
127 -> APAC Viewcomp 878(AMAX) 127 -> APAC Viewcomp 878(AMAX)
128 -> DViCO FusionHDTV DVB-T Lite [18ac:db10] 128 -> DViCO FusionHDTV DVB-T Lite [18ac:db10,18ac:db11]
129 -> V-Gear MyVCD 129 -> V-Gear MyVCD
130 -> Super TV Tuner 130 -> Super TV Tuner
131 -> Tibet Systems 'Progress DVR' CS16 131 -> Tibet Systems 'Progress DVR' CS16
......
...@@ -104,3 +104,6 @@ ...@@ -104,3 +104,6 @@
103 -> Compro Videomate DVB-T200A 103 -> Compro Videomate DVB-T200A
104 -> Hauppauge WinTV-HVR1110 DVB-T/Hybrid [0070:6701] 104 -> Hauppauge WinTV-HVR1110 DVB-T/Hybrid [0070:6701]
105 -> Terratec Cinergy HT PCMCIA [153b:1172] 105 -> Terratec Cinergy HT PCMCIA [153b:1172]
106 -> Encore ENLTV [1131:2342,1131:2341,3016:2344]
107 -> Encore ENLTV-FM [1131:230f]
108 -> Terratec Cinergy HT PCI [153b:1175]
...@@ -197,10 +197,10 @@ Use the ../../Maintainers file, particularly the VIDEO FOR LINUX and PARALLEL ...@@ -197,10 +197,10 @@ Use the ../../Maintainers file, particularly the VIDEO FOR LINUX and PARALLEL
PORT SUPPORT sections PORT SUPPORT sections
The video4linux page: The video4linux page:
http://roadrunner.swansea.linux.org.uk/v4l.shtml http://linuxtv.org
The video4linux2 page: The V4L2 API spec:
http://millennium.diads.com/bdirks/v4l2.htm http://v4l2spec.bytesex.org/
Some web pages about the quickcams: Some web pages about the quickcams:
http://www.dkfz-heidelberg.de/Macromol/wedemann/mini-HOWTO-cqcam.html http://www.dkfz-heidelberg.de/Macromol/wedemann/mini-HOWTO-cqcam.html
......
...@@ -339,9 +339,9 @@ Information - video4linux/mjpeg extensions: ...@@ -339,9 +339,9 @@ Information - video4linux/mjpeg extensions:
(also see below) (also see below)
Information - video4linux2: Information - video4linux2:
http://www.thedirks.org/v4l2/ http://linuxtv.org
http://v4l2spec.bytesex.org/
/usr/include/linux/videodev2.h /usr/include/linux/videodev2.h
http://www.bytesex.org/v4l/
More information on the video4linux/mjpeg extensions, by Serguei More information on the video4linux/mjpeg extensions, by Serguei
Miridonovi and Rainer Johanni: Miridonovi and Rainer Johanni:
......
...@@ -21,7 +21,7 @@ Param[0] ...@@ -21,7 +21,7 @@ Param[0]
0 based frame number in GOP to begin playback from. 0 based frame number in GOP to begin playback from.
Param[1] Param[1]
Specifies the number of muted audio frames to play before normal Specifies the number of muted audio frames to play before normal
audio resumes. audio resumes. (This is not implemented in the firmware, leave at 0)
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
...@@ -32,6 +32,10 @@ Description ...@@ -32,6 +32,10 @@ Description
playback stops at specified PTS. playback stops at specified PTS.
Param[0] Param[0]
Display 0=last frame, 1=black Display 0=last frame, 1=black
Note: this takes effect immediately, so if you want to wait for a PTS,
then use '0', otherwise the screen goes to black at once.
You can call this later (even if there is no playback) with a 1 value
to set the screen to black.
Param[1] Param[1]
PTS low PTS low
Param[2] Param[2]
...@@ -60,8 +64,12 @@ Param[0] ...@@ -60,8 +64,12 @@ Param[0]
31 Speed: 31 Speed:
'0' slow '0' slow
'1' fast '1' fast
Note: n is limited to 2. Anything higher does not result in
faster playback. Instead the host should start dropping frames.
Param[1] Param[1]
Direction: 0=forward, 1=reverse Direction: 0=forward, 1=reverse
Note: to make reverse playback work you have to write full GOPs in
reverse order.
Param[2] Param[2]
Picture mask: Picture mask:
1=I frames 1=I frames
...@@ -69,13 +77,16 @@ Param[2] ...@@ -69,13 +77,16 @@ Param[2]
7=I, P, B frames 7=I, P, B frames
Param[3] Param[3]
B frames per GOP (for reverse play only) B frames per GOP (for reverse play only)
Note: for reverse playback the Picture Mask should be set to I or I, P.
Adding B frames to the mask will result in corrupt video. This field
has to be set to the correct value in order to keep the timing correct.
Param[4] Param[4]
Mute audio: 0=disable, 1=enable Mute audio: 0=disable, 1=enable
Param[5] Param[5]
Display 0=frame, 1=field Display 0=frame, 1=field
Param[6] Param[6]
Specifies the number of muted audio frames to play before normal audio Specifies the number of muted audio frames to play before normal audio
resumes. resumes. (Not implemented in the firmware, leave at 0)
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
...@@ -212,6 +223,7 @@ Description ...@@ -212,6 +223,7 @@ Description
Select audio mode Select audio mode
Param[0] Param[0]
Dual mono mode action Dual mono mode action
0=Stereo, 1=Left, 2=Right, 3=Mono, 4=Swap, -1=Unchanged
Param[1] Param[1]
Stereo mode action: Stereo mode action:
0=Stereo, 1=Left, 2=Right, 3=Mono, 4=Swap, -1=Unchanged 0=Stereo, 1=Left, 2=Right, 3=Mono, 4=Swap, -1=Unchanged
...@@ -224,7 +236,10 @@ Description ...@@ -224,7 +236,10 @@ Description
Setup firmware to notify the host about a particular event. Setup firmware to notify the host about a particular event.
Counterpart to API 0xD5 Counterpart to API 0xD5
Param[0] Param[0]
Event: 0=Audio mode change between stereo and dual channel Event: 0=Audio mode change between mono, (joint) stereo and dual channel.
Event: 3=Decoder started
Event: 4=Unknown: goes off 10-15 times per second while decoding.
Event: 5=Some sync event: goes off once per frame.
Param[1] Param[1]
Notification 0=disabled, 1=enabled Notification 0=disabled, 1=enabled
Param[2] Param[2]
...@@ -273,43 +288,6 @@ Param[3] ...@@ -273,43 +288,6 @@ Param[3]
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Name CX2341X_DEC_SET_AUDIO_OUTPUT
Enum 27/0x1B
Description
Select audio output format
Param[0]
Bitmask:
0:1 Data size:
'00' 16 bit
'01' 20 bit
'10' 24 bit
2:7 Unused
8:9 Mode:
'00' 2 channels
'01' 4 channels
'10' 6 channels
'11' 6 channels with one line data mode
(for left justified MSB first mode, 20 bit only)
10:11 Unused
12:13 Channel format:
'00' right justified MSB first mode
'01' left justified MSB first mode
'10' I2S mode
14:15 Unused
16:21 Right justify bit count
22:31 Unused
-------------------------------------------------------------------------------
Name CX2341X_DEC_SET_AV_DELAY
Enum 28/0x1C
Description
Set audio/video delay in 90Khz ticks
Param[0]
0=A/V in sync, negative=audio lags, positive=video lags
-------------------------------------------------------------------------------
Name CX2341X_DEC_SET_PREBUFFERING Name CX2341X_DEC_SET_PREBUFFERING
Enum 30/0x1E Enum 30/0x1E
Description Description
......
This diff is collapsed.
...@@ -22,6 +22,8 @@ urged to choose a smaller block size and learn the scatter-gather technique. ...@@ -22,6 +22,8 @@ urged to choose a smaller block size and learn the scatter-gather technique.
Mailbox #10 is reserved for DMA transfer information. Mailbox #10 is reserved for DMA transfer information.
Note: the hardware expects little-endian data ('intel format').
Flow Flow
==== ====
...@@ -64,7 +66,7 @@ addresses are the physical memory location of the target DMA buffer. ...@@ -64,7 +66,7 @@ addresses are the physical memory location of the target DMA buffer.
Each S-G array element is a struct of three 32-bit words. The first word is Each S-G array element is a struct of three 32-bit words. The first word is
the source address, the second is the destination address. Both take up the the source address, the second is the destination address. Both take up the
entire 32 bits. The lowest 16 bits of the third word is the transfer byte entire 32 bits. The lowest 18 bits of the third word is the transfer byte
count. The high-bit of the third word is the "last" flag. The last-flag tells count. The high-bit of the third word is the "last" flag. The last-flag tells
the card to raise the DMA_DONE interrupt. From hard personal experience, if the card to raise the DMA_DONE interrupt. From hard personal experience, if
you forget to set this bit, the card will still "work" but the stream will you forget to set this bit, the card will still "work" but the stream will
...@@ -78,8 +80,8 @@ Array Element: ...@@ -78,8 +80,8 @@ Array Element:
- 32-bit Source Address - 32-bit Source Address
- 32-bit Destination Address - 32-bit Destination Address
- 16-bit reserved (high bit is the last flag) - 14-bit reserved (high bit is the last flag)
- 16-bit byte count - 18-bit byte count
DMA Transfer Status DMA Transfer Status
=================== ===================
...@@ -87,8 +89,8 @@ DMA Transfer Status ...@@ -87,8 +89,8 @@ DMA Transfer Status
Register 0x0004 holds the DMA Transfer Status: Register 0x0004 holds the DMA Transfer Status:
Bit Bit
4 Scatter-Gather array error
3 DMA write error
2 DMA read error
1 write completed
0 read completed 0 read completed
1 write completed
2 DMA read error
3 DMA write error
4 Scatter-Gather array error
...@@ -213,16 +213,6 @@ Param[1] ...@@ -213,16 +213,6 @@ Param[1]
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Name CX2341X_ENC_SET_3_2_PULLDOWN
Enum 177/0xB1
Description
3:2 pulldown properties
Param[0]
0=enabled
1=disabled
-------------------------------------------------------------------------------
Name CX2341X_ENC_SET_VBI_LINE Name CX2341X_ENC_SET_VBI_LINE
Enum 183/0xB7 Enum 183/0xB7
Description Description
...@@ -332,9 +322,7 @@ Param[0] ...@@ -332,9 +322,7 @@ Param[0]
'01'=JointStereo '01'=JointStereo
'10'=Dual '10'=Dual
'11'=Mono '11'=Mono
Note: testing seems to indicate that Mono and possibly Note: the cx23415 cannot decode Joint Stereo properly.
JointStereo are not working (default to stereo).
Dual does work, though.
10:11 Mode Extension used in joint_stereo mode. 10:11 Mode Extension used in joint_stereo mode.
In Layer I and II they indicate which subbands are in In Layer I and II they indicate which subbands are in
...@@ -413,16 +401,34 @@ Name CX2341X_ENC_SET_PGM_INDEX_INFO ...@@ -413,16 +401,34 @@ Name CX2341X_ENC_SET_PGM_INDEX_INFO
Enum 199/0xC7 Enum 199/0xC7
Description Description
Sets the Program Index Information. Sets the Program Index Information.
The information is stored as follows:
struct info {
u32 length; // Length of this frame
u32 offset_low; // Offset in the file of the
u32 offset_high; // start of this frame
u32 mask1; // Bits 0-1 are the type mask:
// 1=I, 2=P, 4=B
u32 pts; // The PTS of the frame
u32 mask2; // Bit 0 is bit 32 of the pts.
};
u32 table_ptr;
struct info index[400];
The table_ptr is the encoder memory address in the table were
*new* entries will be written. Note that this is a ringbuffer,
so the table_ptr will wraparound.
Param[0] Param[0]
Picture Mask: Picture Mask:
0=No index capture 0=No index capture
1=I frames 1=I frames
3=I,P frames 3=I,P frames
7=I,P,B frames 7=I,P,B frames
(Seems to be ignored, it always indexes I, P and B frames)
Param[1] Param[1]
Elements requested (up to 400) Elements requested (up to 400)
Result[0] Result[0]
Offset in SDF memory of the table. Offset in the encoder memory of the start of the table.
Result[1] Result[1]
Number of allocated elements up to a maximum of Param[1] Number of allocated elements up to a maximum of Param[1]
...@@ -492,12 +498,14 @@ Name CX2341X_ENC_GET_PREV_DMA_INFO_MB_9 ...@@ -492,12 +498,14 @@ Name CX2341X_ENC_GET_PREV_DMA_INFO_MB_9
Enum 203/0xCB Enum 203/0xCB
Description Description
Returns information on the previous DMA transfer in conjunction with Returns information on the previous DMA transfer in conjunction with
bit 27 of the interrupt mask. Uses mailbox 9. bit 27 or 18 of the interrupt mask. Uses mailbox 9.
Result[0] Result[0]
Status bits: Status bits:
Bit 0 set indicates transfer complete 0 read completed
Bit 2 set indicates transfer error 1 write completed
Bit 4 set indicates linked list error 2 DMA read error
3 DMA write error
4 Scatter-Gather array error
Result[1] Result[1]
DMA type DMA type
Result[2] Result[2]
...@@ -672,7 +680,7 @@ Description ...@@ -672,7 +680,7 @@ Description
the value. the value.
Param[0] Param[0]
Command number: Command number:
1=set initial SCR value when starting encoding. 1=set initial SCR value when starting encoding (works).
2=set quality mode (apparently some test setting). 2=set quality mode (apparently some test setting).
3=setup advanced VIM protection handling (supposedly only for the cx23416 3=setup advanced VIM protection handling (supposedly only for the cx23416
for raw YUV). for raw YUV).
...@@ -681,7 +689,11 @@ Param[0] ...@@ -681,7 +689,11 @@ Param[0]
4=generate artificial PTS timestamps 4=generate artificial PTS timestamps
5=USB flush mode 5=USB flush mode
6=something to do with the quantization matrix 6=something to do with the quantization matrix
7=set navigation pack insertion for DVD 7=set navigation pack insertion for DVD: adds 0xbf (private stream 2)
packets to the MPEG. The size of these packets is 2048 bytes (including
the header of 6 bytes: 0x000001bf + length). The payload is zeroed and
it is up to the application to fill them in. These packets are apparently
inserted every four frames.
8=enable scene change detection (seems to be a failure) 8=enable scene change detection (seems to be a failure)
9=set history parameters of the video input module 9=set history parameters of the video input module
10=set input field order of VIM 10=set input field order of VIM
......
This document describes the cx2341x memory map and documents some of the register This document describes the cx2341x memory map and documents some of the register
space. space.
Note: the memory long words are little-endian ('intel format').
Warning! This information was figured out from searching through the memory and Warning! This information was figured out from searching through the memory and
registers, this information may not be correct and is certainly not complete, and registers, this information may not be correct and is certainly not complete, and
was not derived from anything more than searching through the memory space with was not derived from anything more than searching through the memory space with
...@@ -67,7 +69,7 @@ DMA Registers 0x000-0xff: ...@@ -67,7 +69,7 @@ DMA Registers 0x000-0xff:
0x84 - first write linked list reg, for pci memory addr 0x84 - first write linked list reg, for pci memory addr
0x88 - first write linked list reg, for length of buffer in memory addr 0x88 - first write linked list reg, for length of buffer in memory addr
(|0x80000000 or this for last link) (|0x80000000 or this for last link)
0x8c-0xcc - rest of write linked list reg, 8 sets of 3 total, DMA goes here 0x8c-0xdc - rest of write linked list reg, 8 sets of 3 total, DMA goes here
from linked list addr in reg 0x0c, firmware must push through or from linked list addr in reg 0x0c, firmware must push through or
something. something.
0xe0 - first (and only) read linked list reg, for pci memory addr 0xe0 - first (and only) read linked list reg, for pci memory addr
...@@ -123,12 +125,8 @@ Bit ...@@ -123,12 +125,8 @@ Bit
29 Encoder VBI capture 29 Encoder VBI capture
28 Encoder Video Input Module reset event 28 Encoder Video Input Module reset event
27 Encoder DMA complete 27 Encoder DMA complete
26 24 Decoder audio mode change detection event (through event notification)
25 Decoder copy protect detection event
24 Decoder audio mode change detection event
23
22 Decoder data request 22 Decoder data request
21 Decoder I-Frame? done
20 Decoder DMA complete 20 Decoder DMA complete
19 Decoder VBI re-insertion 19 Decoder VBI re-insertion
18 Decoder DMA err (linked-list bad) 18 Decoder DMA err (linked-list bad)
......
...@@ -23,7 +23,7 @@ Index ...@@ -23,7 +23,7 @@ Index
1. Copyright 1. Copyright
============ ============
Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> Copyright (C) 2006-2007 by Luca Risolia <luca.risolia@studio.unibo.it>
2. Disclaimer 2. Disclaimer
...@@ -135,8 +135,9 @@ And finally: ...@@ -135,8 +135,9 @@ And finally:
6. Module loading 6. Module loading
================= =================
To use the driver, it is necessary to load the "et61x251" module into memory To use the driver, it is necessary to load the "et61x251" module into memory
after every other module required: "videodev", "usbcore" and, depending on after every other module required: "videodev", "v4l2_common", "compat_ioctl32",
the USB host controller you have, "ehci-hcd", "uhci-hcd" or "ohci-hcd". "usbcore" and, depending on the USB host controller you have, "ehci-hcd",
"uhci-hcd" or "ohci-hcd".
Loading can be done as shown below: Loading can be done as shown below:
......
This diff is collapsed.
...@@ -23,7 +23,7 @@ Index ...@@ -23,7 +23,7 @@ Index
1. Copyright 1. Copyright
============ ============
Copyright (C) 2006 by Luca Risolia <luca.risolia@studio.unibo.it> Copyright (C) 2006-2007 by Luca Risolia <luca.risolia@studio.unibo.it>
2. Disclaimer 2. Disclaimer
...@@ -125,8 +125,9 @@ And finally: ...@@ -125,8 +125,9 @@ And finally:
6. Module loading 6. Module loading
================= =================
To use the driver, it is necessary to load the "zc0301" module into memory To use the driver, it is necessary to load the "zc0301" module into memory
after every other module required: "videodev", "usbcore" and, depending on after every other module required: "videodev", "v4l2_common", "compat_ioctl32",
the USB host controller you have, "ehci-hcd", "uhci-hcd" or "ohci-hcd". "usbcore" and, depending on the USB host controller you have, "ehci-hcd",
"uhci-hcd" or "ohci-hcd".
Loading can be done as shown below: Loading can be done as shown below:
...@@ -211,12 +212,11 @@ Vendor ID Product ID ...@@ -211,12 +212,11 @@ Vendor ID Product ID
0x041e 0x4036 0x041e 0x4036
0x041e 0x403a 0x041e 0x403a
0x0458 0x7007 0x0458 0x7007
0x0458 0x700C 0x0458 0x700c
0x0458 0x700f 0x0458 0x700f
0x046d 0x08ae 0x046d 0x08ae
0x055f 0xd003 0x055f 0xd003
0x055f 0xd004 0x055f 0xd004
0x046d 0x08ae
0x0ac8 0x0301 0x0ac8 0x0301
0x0ac8 0x301b 0x0ac8 0x301b
0x0ac8 0x303b 0x0ac8 0x303b
......
...@@ -2748,7 +2748,7 @@ S: Supported ...@@ -2748,7 +2748,7 @@ S: Supported
PVRUSB2 VIDEO4LINUX DRIVER PVRUSB2 VIDEO4LINUX DRIVER
P: Mike Isely P: Mike Isely
M: isely@pobox.com M: isely@pobox.com
L: pvrusb2@isely.net L: pvrusb2@isely.net (subscribers-only)
L: video4linux-list@redhat.com L: video4linux-list@redhat.com
W: http://www.isely.net/pvrusb2/ W: http://www.isely.net/pvrusb2/
S: Maintained S: Maintained
......
...@@ -70,6 +70,7 @@ config VIDEO_TUNER ...@@ -70,6 +70,7 @@ config VIDEO_TUNER
depends on I2C depends on I2C
config VIDEO_BUF config VIDEO_BUF
depends on PCI
tristate tristate
config VIDEO_BUF_DVB config VIDEO_BUF_DVB
......
...@@ -5,8 +5,4 @@ config VIDEO_SAA7146 ...@@ -5,8 +5,4 @@ config VIDEO_SAA7146
config VIDEO_SAA7146_VV config VIDEO_SAA7146_VV
tristate tristate
select VIDEO_BUF select VIDEO_BUF
select VIDEO_VIDEOBUF
select VIDEO_SAA7146 select VIDEO_SAA7146
config VIDEO_VIDEOBUF
tristate
...@@ -256,6 +256,112 @@ int ir_decode_biphase(u32 *samples, int count, int low, int high) ...@@ -256,6 +256,112 @@ int ir_decode_biphase(u32 *samples, int count, int low, int high)
return value; return value;
} }
/* RC5 decoding stuff, moved from bttv-input.c to share it with
* saa7134 */
/* decode raw bit pattern to RC5 code */
u32 ir_rc5_decode(unsigned int code)
{
unsigned int org_code = code;
unsigned int pair;
unsigned int rc5 = 0;
int i;
for (i = 0; i < 14; ++i) {
pair = code & 0x3;
code >>= 2;
rc5 <<= 1;
switch (pair) {
case 0:
case 2:
break;
case 1:
rc5 |= 1;
break;
case 3:
dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);
return 0;
}
}
dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
"instr=%x\n", rc5, org_code, RC5_START(rc5),
RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
return rc5;
}
void ir_rc5_timer_end(unsigned long data)
{
struct card_ir *ir = (struct card_ir *)data;
struct timeval tv;
unsigned long current_jiffies, timeout;
u32 gap;
u32 rc5 = 0;
/* get time */
current_jiffies = jiffies;
do_gettimeofday(&tv);
/* avoid overflow with gap >1s */
if (tv.tv_sec - ir->base_time.tv_sec > 1) {
gap = 200000;
} else {
gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
tv.tv_usec - ir->base_time.tv_usec;
}
/* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */
if (gap < 28000) {
dprintk(1, "ir-common: spurious timer_end\n");
return;
}
ir->active = 0;
if (ir->last_bit < 20) {
/* ignore spurious codes (caused by light/other remotes) */
dprintk(1, "ir-common: short code: %x\n", ir->code);
} else {
ir->code = (ir->code << ir->shift_by) | 1;
rc5 = ir_rc5_decode(ir->code);
/* two start bits? */
if (RC5_START(rc5) != ir->start) {
dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5));
/* right address? */
} else if (RC5_ADDR(rc5) == ir->addr) {
u32 toggle = RC5_TOGGLE(rc5);
u32 instr = RC5_INSTR(rc5);
/* Good code, decide if repeat/repress */
if (toggle != RC5_TOGGLE(ir->last_rc5) ||
instr != RC5_INSTR(ir->last_rc5)) {
dprintk(1, "ir-common: instruction %x, toggle %x\n", instr,
toggle);
ir_input_nokey(ir->dev, &ir->ir);
ir_input_keydown(ir->dev, &ir->ir, instr,
instr);
}
/* Set/reset key-up timer */
timeout = current_jiffies + (500 + ir->rc5_key_timeout
* HZ) / 1000;
mod_timer(&ir->timer_keyup, timeout);
/* Save code for repeat test */
ir->last_rc5 = rc5;
}
}
}
void ir_rc5_timer_keyup(unsigned long data)
{
struct card_ir *ir = (struct card_ir *)data;
dprintk(1, "ir-common: key released\n");
ir_input_nokey(ir->dev, &ir->ir);
}
EXPORT_SYMBOL_GPL(ir_input_init); EXPORT_SYMBOL_GPL(ir_input_init);
EXPORT_SYMBOL_GPL(ir_input_nokey); EXPORT_SYMBOL_GPL(ir_input_nokey);
EXPORT_SYMBOL_GPL(ir_input_keydown); EXPORT_SYMBOL_GPL(ir_input_keydown);
...@@ -265,6 +371,10 @@ EXPORT_SYMBOL_GPL(ir_dump_samples); ...@@ -265,6 +371,10 @@ EXPORT_SYMBOL_GPL(ir_dump_samples);
EXPORT_SYMBOL_GPL(ir_decode_biphase); EXPORT_SYMBOL_GPL(ir_decode_biphase);
EXPORT_SYMBOL_GPL(ir_decode_pulsedistance); EXPORT_SYMBOL_GPL(ir_decode_pulsedistance);
EXPORT_SYMBOL_GPL(ir_rc5_decode);
EXPORT_SYMBOL_GPL(ir_rc5_timer_end);
EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup);
/* /*
* Local variables: * Local variables:
* c-basic-offset: 8 * c-basic-offset: 8
......
...@@ -1606,3 +1606,174 @@ IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE] = { ...@@ -1606,3 +1606,174 @@ IR_KEYTAB_TYPE ir_codes_budget_ci_old[IR_KEYTAB_SIZE] = {
}; };
EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old); EXPORT_SYMBOL_GPL(ir_codes_budget_ci_old);
/*
* Marc Fargas <telenieko@telenieko.com>
* this is the remote control that comes with the asus p7131
* which has a label saying is "Model PC-39"
*/
IR_KEYTAB_TYPE ir_codes_asus_pc39[IR_KEYTAB_SIZE] = {
/* Keys 0 to 9 */
[ 0x15 ] = KEY_0,
[ 0x29 ] = KEY_1,
[ 0x2d ] = KEY_2,
[ 0x2b ] = KEY_3,
[ 0x09 ] = KEY_4,
[ 0x0d ] = KEY_5,
[ 0x0b ] = KEY_6,
[ 0x31 ] = KEY_7,
[ 0x35 ] = KEY_8,
[ 0x33 ] = KEY_9,
[ 0x3e ] = KEY_RADIO, /* radio */
[ 0x03 ] = KEY_MENU, /* dvd/menu */
[ 0x2a ] = KEY_VOLUMEUP,
[ 0x19 ] = KEY_VOLUMEDOWN,
[ 0x37 ] = KEY_UP,
[ 0x3b ] = KEY_DOWN,
[ 0x27 ] = KEY_LEFT,
[ 0x2f ] = KEY_RIGHT,
[ 0x25 ] = KEY_VIDEO, /* video */
[ 0x39 ] = KEY_AUDIO, /* music */
[ 0x21 ] = KEY_TV, /* tv */
[ 0x1d ] = KEY_EXIT, /* back */
[ 0x0a ] = KEY_CHANNELUP, /* channel / program + */
[ 0x1b ] = KEY_CHANNELDOWN, /* channel / program - */
[ 0x1a ] = KEY_ENTER, /* enter */
[ 0x06 ] = KEY_PAUSE, /* play/pause */
[ 0x1e ] = KEY_PREVIOUS, /* rew */
[ 0x26 ] = KEY_NEXT, /* forward */
[ 0x0e ] = KEY_REWIND, /* backward << */
[ 0x3a ] = KEY_FASTFORWARD, /* forward >> */
[ 0x36 ] = KEY_STOP,
[ 0x2e ] = KEY_RECORD, /* recording */
[ 0x16 ] = KEY_POWER, /* the button that reads "close" */
[ 0x11 ] = KEY_ZOOM, /* full screen */
[ 0x13 ] = KEY_MACRO, /* recall */
[ 0x23 ] = KEY_HOME, /* home */
[ 0x05 ] = KEY_PVR, /* picture */
[ 0x3d ] = KEY_MUTE, /* mute */
[ 0x01 ] = KEY_DVD, /* dvd */
};
EXPORT_SYMBOL_GPL(ir_codes_asus_pc39);
/* Encore ENLTV-FM - black plastic, white front cover with white glowing buttons
Juan Pablo Sormani <sorman@gmail.com> */
IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE] = {
/* Power button does nothing, neither in Windows app,
although it sends data (used for BIOS wakeup?) */
[ 0x0d ] = KEY_MUTE,
[ 0x1e ] = KEY_TV,
[ 0x00 ] = KEY_VIDEO,
[ 0x01 ] = KEY_AUDIO, /* music */
[ 0x02 ] = KEY_MHP, /* picture */
[ 0x1f ] = KEY_1,
[ 0x03 ] = KEY_2,
[ 0x04 ] = KEY_3,
[ 0x05 ] = KEY_4,
[ 0x1c ] = KEY_5,
[ 0x06 ] = KEY_6,
[ 0x07 ] = KEY_7,
[ 0x08 ] = KEY_8,
[ 0x1d ] = KEY_9,
[ 0x0a ] = KEY_0,
[ 0x09 ] = KEY_LIST, /* -/-- */
[ 0x0b ] = KEY_LAST, /* recall */
[ 0x14 ] = KEY_HOME, /* win start menu */
[ 0x15 ] = KEY_EXIT, /* exit */
[ 0x16 ] = KEY_UP,
[ 0x12 ] = KEY_DOWN,
[ 0x0c ] = KEY_RIGHT,
[ 0x17 ] = KEY_LEFT,
[ 0x18 ] = KEY_ENTER, /* OK */
[ 0x0e ] = KEY_ESC,
[ 0x13 ] = KEY_D, /* desktop */
[ 0x11 ] = KEY_TAB,
[ 0x19 ] = KEY_SWITCHVIDEOMODE, /* switch */
[ 0x1a ] = KEY_MENU,
[ 0x1b ] = KEY_ZOOM, /* fullscreen */
[ 0x44 ] = KEY_TIME, /* time shift */
[ 0x40 ] = KEY_MODE, /* source */
[ 0x5a ] = KEY_RECORD,
[ 0x42 ] = KEY_PLAY, /* play/pause */
[ 0x45 ] = KEY_STOP,
[ 0x43 ] = KEY_CAMERA, /* camera icon */
[ 0x48 ] = KEY_REWIND,
[ 0x4a ] = KEY_FASTFORWARD,
[ 0x49 ] = KEY_PREVIOUS,
[ 0x4b ] = KEY_NEXT,
[ 0x4c ] = KEY_FAVORITES, /* tv wall */
[ 0x4d ] = KEY_SOUND, /* DVD sound */
[ 0x4e ] = KEY_LANGUAGE, /* DVD lang */
[ 0x4f ] = KEY_TEXT, /* DVD text */
[ 0x50 ] = KEY_SLEEP, /* shutdown */
[ 0x51 ] = KEY_MODE, /* stereo > main */
[ 0x52 ] = KEY_SELECT, /* stereo > sap */
[ 0x53 ] = KEY_PROG1, /* teletext */
[ 0x59 ] = KEY_RED, /* AP1 */
[ 0x41 ] = KEY_GREEN, /* AP2 */
[ 0x47 ] = KEY_YELLOW, /* AP3 */
[ 0x57 ] = KEY_BLUE, /* AP4 */
};
EXPORT_SYMBOL_GPL(ir_codes_encore_enltv);
/* for the Technotrend 1500 bundled remote: */
IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE] = {
[ 0x01 ] = KEY_POWER,
[ 0x02 ] = KEY_SHUFFLE, /* ? double-arrow key */
[ 0x03 ] = KEY_1,
[ 0x04 ] = KEY_2,
[ 0x05 ] = KEY_3,
[ 0x06 ] = KEY_4,
[ 0x07 ] = KEY_5,
[ 0x08 ] = KEY_6,
[ 0x09 ] = KEY_7,
[ 0x0a ] = KEY_8,
[ 0x0b ] = KEY_9,
[ 0x0c ] = KEY_0,
[ 0x0d ] = KEY_UP,
[ 0x0e ] = KEY_LEFT,
[ 0x0f ] = KEY_OK,
[ 0x10 ] = KEY_RIGHT,
[ 0x11 ] = KEY_DOWN,
[ 0x12 ] = KEY_INFO,
[ 0x13 ] = KEY_EXIT,
[ 0x14 ] = KEY_RED,
[ 0x15 ] = KEY_GREEN,
[ 0x16 ] = KEY_YELLOW,
[ 0x17 ] = KEY_BLUE,
[ 0x18 ] = KEY_MUTE,
[ 0x19 ] = KEY_TEXT,
[ 0x1a ] = KEY_MODE, /* ? TV/Radio */
[ 0x21 ] = KEY_OPTION,
[ 0x22 ] = KEY_EPG,
[ 0x23 ] = KEY_CHANNELUP,
[ 0x24 ] = KEY_CHANNELDOWN,
[ 0x25 ] = KEY_VOLUMEUP,
[ 0x26 ] = KEY_VOLUMEDOWN,
[ 0x27 ] = KEY_SETUP,
};
EXPORT_SYMBOL_GPL(ir_codes_tt_1500);
...@@ -508,7 +508,7 @@ int saa7146_vv_release(struct saa7146_dev* dev) ...@@ -508,7 +508,7 @@ int saa7146_vv_release(struct saa7146_dev* dev)
DEB_EE(("dev:%p\n",dev)); DEB_EE(("dev:%p\n",dev));
pci_free_consistent(dev->pci, SAA7146_RPS_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle); pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle);
kfree(vv); kfree(vv);
dev->vv_data = NULL; dev->vv_data = NULL;
dev->vv_callback = NULL; dev->vv_callback = NULL;
......
...@@ -385,9 +385,9 @@ static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe, ...@@ -385,9 +385,9 @@ static int alps_tdee4_stv0297_tuner_set_params(struct dvb_frontend* fe,
else buf[3] = 0x88; else buf[3] = 0x88;
if (fe->ops.i2c_gate_ctrl) if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1); fe->ops.i2c_gate_ctrl(fe, 0);
deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n",fep->frequency, buf[0],buf[1],buf[2],buf[3]); deb_tuner("tuner buffer for %d Hz: %x %x %x %x\n",fep->frequency, buf[0],buf[1],buf[2],buf[3]);
ret = fc->i2c_request(fc,FC_WRITE,FC_I2C_PORT_TUNER,0x61,buf[0],&buf[1],3); ret = fc->i2c_request(fc, FC_WRITE, FC_I2C_PORT_TUNER, 0x61, buf[0], &buf[1], 3);
deb_tuner("tuner write returned: %d\n",ret); deb_tuner("tuner write returned: %d\n",ret);
return 0; return 0;
...@@ -398,91 +398,71 @@ static u8 alps_tdee4_stv0297_inittab[] = { ...@@ -398,91 +398,71 @@ static u8 alps_tdee4_stv0297_inittab[] = {
0x80, 0x00, 0x80, 0x00,
0x81, 0x01, 0x81, 0x01,
0x81, 0x00, 0x81, 0x00,
0x00, 0x09, 0x00, 0x48,
0x01, 0x69, 0x01, 0x58,
0x03, 0x00, 0x03, 0x00,
0x04, 0x00, 0x04, 0x00,
0x07, 0x00, 0x07, 0x00,
0x08, 0x00, 0x08, 0x00,
0x20, 0x00,
0x21, 0x40,
0x22, 0x00,
0x23, 0x00,
0x24, 0x40,
0x25, 0x88,
0x30, 0xff, 0x30, 0xff,
0x31, 0x00, 0x31, 0x9d,
0x32, 0xff, 0x32, 0xff,
0x33, 0x00, 0x33, 0x00,
0x34, 0x50, 0x34, 0x29,
0x35, 0x7f, 0x35, 0x55,
0x36, 0x00, 0x36, 0x80,
0x37, 0x20, 0x37, 0x6e,
0x38, 0x00, 0x38, 0x9c,
0x40, 0x1c, 0x40, 0x1a,
0x41, 0xff, 0x41, 0xfe,
0x42, 0x29, 0x42, 0x33,
0x43, 0x00, 0x43, 0x00,
0x44, 0xff, 0x44, 0xff,
0x45, 0x00, 0x45, 0x00,
0x46, 0x00, 0x46, 0x00,
0x49, 0x04, 0x49, 0x04,
0x4a, 0x00, 0x4a, 0x51,
0x4b, 0xf8, 0x4b, 0xf8,
0x52, 0x30, 0x52, 0x30,
0x55, 0xae, 0x53, 0x06,
0x56, 0x47, 0x59, 0x06,
0x57, 0xe1, 0x5a, 0x5e,
0x58, 0x3a, 0x5b, 0x04,
0x5a, 0x1e, 0x61, 0x49,
0x5b, 0x34, 0x62, 0x0a,
0x60, 0x00,
0x63, 0x00,
0x64, 0x00,
0x65, 0x00,
0x66, 0x00,
0x67, 0x00,
0x68, 0x00,
0x69, 0x00,
0x6a, 0x02,
0x6b, 0x00,
0x70, 0xff, 0x70, 0xff,
0x71, 0x00, 0x71, 0x04,
0x72, 0x00, 0x72, 0x00,
0x73, 0x00, 0x73, 0x00,
0x74, 0x0c, 0x74, 0x0c,
0x80, 0x00, 0x80, 0x20,
0x81, 0x00, 0x81, 0x00,
0x82, 0x00, 0x82, 0x30,
0x83, 0x00, 0x83, 0x00,
0x84, 0x04, 0x84, 0x04,
0x85, 0x80, 0x85, 0x22,
0x86, 0x24, 0x86, 0x08,
0x87, 0x78, 0x87, 0x1b,
0x88, 0x10, 0x88, 0x00,
0x89, 0x00, 0x89, 0x00,
0x90, 0x01, 0x90, 0x00,
0x91, 0x01, 0x91, 0x04,
0xa0, 0x04, 0xa0, 0x86,
0xa1, 0x00, 0xa1, 0x00,
0xa2, 0x00, 0xa2, 0x00,
0xb0, 0x91, 0xb0, 0x91,
0xb1, 0x0b, 0xb1, 0x0b,
0xc0, 0x53, 0xc0, 0x5b,
0xc1, 0x70, 0xc1, 0x10,
0xc2, 0x12, 0xc2, 0x12,
0xd0, 0x00, 0xd0, 0x02,
0xd1, 0x00, 0xd1, 0x00,
0xd2, 0x00, 0xd2, 0x00,
0xd3, 0x00, 0xd3, 0x00,
0xd4, 0x00, 0xd4, 0x02,
0xd5, 0x00, 0xd5, 0x00,
0xde, 0x00, 0xde, 0x00,
0xdf, 0x00, 0xdf, 0x01,
0x61, 0x49,
0x62, 0x0b,
0x53, 0x08,
0x59, 0x08,
0xff, 0xff, 0xff, 0xff,
}; };
......
...@@ -390,6 +390,7 @@ static struct cards card_list[] __devinitdata = { ...@@ -390,6 +390,7 @@ static struct cards card_list[] __devinitdata = {
{ 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
{ 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
{ 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" },
{ 0xdb1118ac, BTTV_BOARD_DVICO_DVBT_LITE, "Ultraview DVB-T Lite" },
{ 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
{ 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" }, { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV" },
{ 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" }, { 0x00261822, BTTV_BOARD_TWINHAN_DST, "DNTV Live! Mini" },
......
...@@ -1161,7 +1161,7 @@ static int dst_get_device_id(struct dst_state *state) ...@@ -1161,7 +1161,7 @@ static int dst_get_device_id(struct dst_state *state)
} }
} }
if (i >= sizeof (dst_tlist) / sizeof (dst_tlist [0])) { if (i >= ARRAY_SIZE(dst_tlist)) {
dprintk(verbose, DST_ERROR, 1, "Unable to recognize %s or %s", &state->rxbuffer[0], &state->rxbuffer[1]); dprintk(verbose, DST_ERROR, 1, "Unable to recognize %s or %s", &state->rxbuffer[0], &state->rxbuffer[1]);
dprintk(verbose, DST_ERROR, 1, "please email linux-dvb@linuxtv.org with this type in"); dprintk(verbose, DST_ERROR, 1, "please email linux-dvb@linuxtv.org with this type in");
use_dst_type = DST_TYPE_IS_SAT; use_dst_type = DST_TYPE_IS_SAT;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -213,7 +214,7 @@ static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend ...@@ -213,7 +214,7 @@ static int cx24108_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend
freq = 2150000; /* satellite IF is 950..2150MHz */ freq = 2150000; /* satellite IF is 950..2150MHz */
/* decide which VCO to use for the input frequency */ /* decide which VCO to use for the input frequency */
for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++); for(i = 1; (i < ARRAY_SIZE(osci)) && (osci[i] < freq); i++);
printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq); printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq);
band=bandsel[i]; band=bandsel[i];
/* the gain values must be set by SetSymbolrate */ /* the gain values must be set by SetSymbolrate */
......
...@@ -819,6 +819,11 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) ...@@ -819,6 +819,11 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
set_bit(rc_keys[i + 2], input_dev->keybit); set_bit(rc_keys[i + 2], input_dev->keybit);
input_dev->keycodesize = 0; input_dev->keycodesize = 0;
input_dev->keycodemax = 0; input_dev->keycodemax = 0;
input_dev->id.bustype = BUS_USB;
input_dev->id.vendor = cinergyt2->udev->descriptor.idVendor;
input_dev->id.product = cinergyt2->udev->descriptor.idProduct;
input_dev->id.version = 1;
input_dev->cdev.dev = &cinergyt2->udev->dev;
err = input_register_device(input_dev); err = input_register_device(input_dev);
if (err) { if (err) {
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/freezer.h> #include <linux/freezer.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/kthread.h>
#include <asm/processor.h> #include <asm/processor.h>
#include "dvb_frontend.h" #include "dvb_frontend.h"
...@@ -100,7 +101,7 @@ struct dvb_frontend_private { ...@@ -100,7 +101,7 @@ struct dvb_frontend_private {
struct semaphore sem; struct semaphore sem;
struct list_head list_head; struct list_head list_head;
wait_queue_head_t wait_queue; wait_queue_head_t wait_queue;
pid_t thread_pid; struct task_struct *thread;
unsigned long release_jiffies; unsigned long release_jiffies;
unsigned int exit; unsigned int exit;
unsigned int wakeup; unsigned int wakeup;
...@@ -508,19 +509,11 @@ static int dvb_frontend_thread(void *data) ...@@ -508,19 +509,11 @@ static int dvb_frontend_thread(void *data)
struct dvb_frontend *fe = data; struct dvb_frontend *fe = data;
struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_private *fepriv = fe->frontend_priv;
unsigned long timeout; unsigned long timeout;
char name [15];
fe_status_t s; fe_status_t s;
struct dvb_frontend_parameters *params; struct dvb_frontend_parameters *params;
dprintk("%s\n", __FUNCTION__); dprintk("%s\n", __FUNCTION__);
snprintf (name, sizeof(name), "kdvb-fe-%i", fe->dvb->num);
lock_kernel();
daemonize(name);
sigfillset(&current->blocked);
unlock_kernel();
fepriv->check_wrapped = 0; fepriv->check_wrapped = 0;
fepriv->quality = 0; fepriv->quality = 0;
fepriv->delay = 3*HZ; fepriv->delay = 3*HZ;
...@@ -532,16 +525,18 @@ static int dvb_frontend_thread(void *data) ...@@ -532,16 +525,18 @@ static int dvb_frontend_thread(void *data)
while (1) { while (1) {
up(&fepriv->sem); /* is locked when we enter the thread... */ up(&fepriv->sem); /* is locked when we enter the thread... */
restart:
timeout = wait_event_interruptible_timeout(fepriv->wait_queue, timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
dvb_frontend_should_wakeup(fe), dvb_frontend_should_wakeup(fe) || kthread_should_stop(),
fepriv->delay); fepriv->delay);
if (0 != dvb_frontend_is_exiting(fe)) {
if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
/* got signal or quitting */ /* got signal or quitting */
break; break;
} }
try_to_freeze(); if (try_to_freeze())
goto restart;
if (down_interruptible(&fepriv->sem)) if (down_interruptible(&fepriv->sem))
break; break;
...@@ -591,7 +586,7 @@ static int dvb_frontend_thread(void *data) ...@@ -591,7 +586,7 @@ static int dvb_frontend_thread(void *data)
fe->ops.sleep(fe); fe->ops.sleep(fe);
} }
fepriv->thread_pid = 0; fepriv->thread = NULL;
mb(); mb();
dvb_frontend_wakeup(fe); dvb_frontend_wakeup(fe);
...@@ -600,7 +595,6 @@ static int dvb_frontend_thread(void *data) ...@@ -600,7 +595,6 @@ static int dvb_frontend_thread(void *data)
static void dvb_frontend_stop(struct dvb_frontend *fe) static void dvb_frontend_stop(struct dvb_frontend *fe)
{ {
unsigned long ret;
struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_private *fepriv = fe->frontend_priv;
dprintk ("%s\n", __FUNCTION__); dprintk ("%s\n", __FUNCTION__);
...@@ -608,33 +602,17 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) ...@@ -608,33 +602,17 @@ static void dvb_frontend_stop(struct dvb_frontend *fe)
fepriv->exit = 1; fepriv->exit = 1;
mb(); mb();
if (!fepriv->thread_pid) if (!fepriv->thread)
return; return;
/* check if the thread is really alive */ kthread_stop(fepriv->thread);
if (kill_proc(fepriv->thread_pid, 0, 1) == -ESRCH) { init_MUTEX (&fepriv->sem);
printk("dvb_frontend_stop: thread PID %d already died\n",
fepriv->thread_pid);
/* make sure the mutex was not held by the thread */
init_MUTEX (&fepriv->sem);
return;
}
/* wake up the frontend thread, so it notices that fe->exit == 1 */
dvb_frontend_wakeup(fe);
/* wait until the frontend thread has exited */
ret = wait_event_interruptible(fepriv->wait_queue,0 == fepriv->thread_pid);
if (-ERESTARTSYS != ret) {
fepriv->state = FESTATE_IDLE;
return;
}
fepriv->state = FESTATE_IDLE; fepriv->state = FESTATE_IDLE;
/* paranoia check in case a signal arrived */ /* paranoia check in case a signal arrived */
if (fepriv->thread_pid) if (fepriv->thread)
printk("dvb_frontend_stop: warning: thread PID %d won't exit\n", printk("dvb_frontend_stop: warning: thread %p won't exit\n",
fepriv->thread_pid); fepriv->thread);
} }
s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime) s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime)
...@@ -684,10 +662,11 @@ static int dvb_frontend_start(struct dvb_frontend *fe) ...@@ -684,10 +662,11 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
{ {
int ret; int ret;
struct dvb_frontend_private *fepriv = fe->frontend_priv; struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct task_struct *fe_thread;
dprintk ("%s\n", __FUNCTION__); dprintk ("%s\n", __FUNCTION__);
if (fepriv->thread_pid) { if (fepriv->thread) {
if (!fepriv->exit) if (!fepriv->exit)
return 0; return 0;
else else
...@@ -701,18 +680,18 @@ static int dvb_frontend_start(struct dvb_frontend *fe) ...@@ -701,18 +680,18 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
fepriv->state = FESTATE_IDLE; fepriv->state = FESTATE_IDLE;
fepriv->exit = 0; fepriv->exit = 0;
fepriv->thread_pid = 0; fepriv->thread = NULL;
mb(); mb();
ret = kernel_thread (dvb_frontend_thread, fe, 0); fe_thread = kthread_run(dvb_frontend_thread, fe,
"kdvb-fe-%i", fe->dvb->num);
if (ret < 0) { if (IS_ERR(fe_thread)) {
printk("dvb_frontend_start: failed to start kernel_thread (%d)\n", ret); ret = PTR_ERR(fe_thread);
printk("dvb_frontend_start: failed to start kthread (%d)\n", ret);
up(&fepriv->sem); up(&fepriv->sem);
return ret; return ret;
} }
fepriv->thread_pid = ret; fepriv->thread = fe_thread;
return 0; return 0;
} }
......
...@@ -199,12 +199,14 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, ...@@ -199,12 +199,14 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
const struct dvb_device *template, void *priv, int type) const struct dvb_device *template, void *priv, int type)
{ {
struct dvb_device *dvbdev; struct dvb_device *dvbdev;
struct file_operations *dvbdevfops;
int id; int id;
if (mutex_lock_interruptible(&dvbdev_register_lock)) if (mutex_lock_interruptible(&dvbdev_register_lock))
return -ERESTARTSYS; return -ERESTARTSYS;
if ((id = dvbdev_get_free_id (adap, type)) < 0) { if ((id = dvbdev_get_free_id (adap, type)) < 0){
mutex_unlock(&dvbdev_register_lock); mutex_unlock(&dvbdev_register_lock);
*pdvbdev = NULL; *pdvbdev = NULL;
printk ("%s: could get find free device id...\n", __FUNCTION__); printk ("%s: could get find free device id...\n", __FUNCTION__);
...@@ -213,7 +215,15 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, ...@@ -213,7 +215,15 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
*pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL); *pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL);
if (!dvbdev) { if (!dvbdev){
mutex_unlock(&dvbdev_register_lock);
return -ENOMEM;
}
dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
if (!dvbdevfops){
kfree (dvbdev);
mutex_unlock(&dvbdev_register_lock); mutex_unlock(&dvbdev_register_lock);
return -ENOMEM; return -ENOMEM;
} }
...@@ -223,7 +233,9 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, ...@@ -223,7 +233,9 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
dvbdev->id = id; dvbdev->id = id;
dvbdev->adapter = adap; dvbdev->adapter = adap;
dvbdev->priv = priv; dvbdev->priv = priv;
dvbdev->fops = dvbdevfops;
memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations));
dvbdev->fops->owner = adap->module; dvbdev->fops->owner = adap->module;
list_add_tail (&dvbdev->list_head, &adap->device_list); list_add_tail (&dvbdev->list_head, &adap->device_list);
...@@ -251,6 +263,7 @@ void dvb_unregister_device(struct dvb_device *dvbdev) ...@@ -251,6 +263,7 @@ void dvb_unregister_device(struct dvb_device *dvbdev)
dvbdev->type, dvbdev->id))); dvbdev->type, dvbdev->id)));
list_del (&dvbdev->list_head); list_del (&dvbdev->list_head);
kfree (dvbdev->fops);
kfree (dvbdev); kfree (dvbdev);
} }
EXPORT_SYMBOL(dvb_unregister_device); EXPORT_SYMBOL(dvb_unregister_device);
......
...@@ -109,6 +109,34 @@ config DVB_USB_CXUSB ...@@ -109,6 +109,34 @@ config DVB_USB_CXUSB
Medion MD95700 hybrid USB2.0 device. Medion MD95700 hybrid USB2.0 device.
DViCO FusionHDTV (Bluebird) USB2.0 devices DViCO FusionHDTV (Bluebird) USB2.0 devices
config DVB_USB_M920X
tristate "Uli m920x DVB-T USB2.0 support"
depends on DVB_USB
select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_TUNER_QT1010 if !DVB_FE_CUSTOMISE
help
Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
Currently, only devices with a product id of
"DTV USB MINI" (in cold state) are supported.
Firmware required.
config DVB_USB_GL861
tristate "Genesys Logic GL861 USB2.0 support"
depends on DVB_USB
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select DVB_TUNER_QT1010 if !DVB_FE_CUSTOMISE
help
Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
receiver with USB ID 0db0:5581.
config DVB_USB_AU6610
tristate "Alcor Micro AU6610 USB2.0 support"
depends on DVB_USB
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select DVB_TUNER_QT1010 if !DVB_FE_CUSTOMISE
help
Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver.
config DVB_USB_DIGITV config DVB_USB_DIGITV
tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support"
depends on DVB_USB depends on DVB_USB
......
...@@ -30,6 +30,15 @@ obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2 ...@@ -30,6 +30,15 @@ obj-$(CONFIG_DVB_USB_NOVA_T_USB2) += dvb-usb-dibusb-common.o dvb-usb-nova-t-usb2
dvb-usb-umt-010-objs = umt-010.o dvb-usb-umt-010-objs = umt-010.o
obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o obj-$(CONFIG_DVB_USB_UMT_010) += dvb-usb-dibusb-common.o dvb-usb-umt-010.o
dvb-usb-m920x-objs = m920x.o
obj-$(CONFIG_DVB_USB_M920X) += dvb-usb-m920x.o
dvb-usb-gl861-objs = gl861.o
obj-$(CONFIG_DVB_USB_GL861) += dvb-usb-gl861.o
dvb-usb-au6610-objs = au6610.o
obj-$(CONFIG_DVB_USB_AU6610) += dvb-usb-au6610.o
dvb-usb-digitv-objs = digitv.o dvb-usb-digitv-objs = digitv.o
obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o obj-$(CONFIG_DVB_USB_DIGITV) += dvb-usb-digitv.o
......
/* DVB USB compliant linux driver for Sigmatek DVB-110 DVB-T USB2.0 receiver
*
* Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
*
* 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 "au6610.h"
#include "zl10353.h"
#include "qt1010.h"
/* debug */
static int dvb_usb_au6610_debug;
module_param_named(debug, dvb_usb_au6610_debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
static int au6610_usb_msg(struct dvb_usb_device *d, u8 operation, u8 addr,
u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
{
int ret;
u16 index;
u8 usb_buf[6]; /* enough for all known requests,
read returns 5 and write 6 bytes */
switch (wlen) {
case 1:
index = wbuf[0] << 8;
break;
case 2:
index = wbuf[0] << 8;
index += wbuf[1];
break;
default:
warn("wlen = %x, aborting.", wlen);
return -EINVAL;
}
ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation,
USB_TYPE_VENDOR|USB_DIR_IN, addr, index, usb_buf,
sizeof(usb_buf), AU6610_USB_TIMEOUT);
if (ret < 0)
return ret;
switch (operation) {
case AU6610_REQ_I2C_READ:
case AU6610_REQ_USB_READ:
/* requested value is always 5th byte in buffer */
rbuf[0] = usb_buf[4];
}
return ret;
}
static int au6610_i2c_msg(struct dvb_usb_device *d, u8 addr,
u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
{
u8 request;
u8 wo = (rbuf == NULL || rlen == 0); /* write-only */
if (wo) {
request = AU6610_REQ_I2C_WRITE;
} else { /* rw */
request = AU6610_REQ_I2C_READ;
}
return au6610_usb_msg(d, request, addr, wbuf, wlen, rbuf, rlen);
}
/* I2C */
static int au6610_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
int num)
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
int i;
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
if (num > 2)
return -EINVAL;
for (i = 0; i < num; i++) {
/* write/read request */
if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf,
msg[i].len, msg[i+1].buf,
msg[i+1].len) < 0)
break;
i++;
} else if (au6610_i2c_msg(d, msg[i].addr, msg[i].buf,
msg[i].len, NULL, 0) < 0)
break;
}
mutex_unlock(&d->i2c_mutex);
return i;
}
static u32 au6610_i2c_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C;
}
static struct i2c_algorithm au6610_i2c_algo = {
.master_xfer = au6610_i2c_xfer,
.functionality = au6610_i2c_func,
};
/* Callbacks for DVB USB */
static int au6610_identify_state(struct usb_device *udev,
struct dvb_usb_device_properties *props,
struct dvb_usb_device_description **desc,
int *cold)
{
*cold = 0;
return 0;
}
static struct zl10353_config au6610_zl10353_config = {
.demod_address = 0x1e,
.no_tuner = 1,
.parallel_ts = 1,
};
static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
{
if ((adap->fe = dvb_attach(zl10353_attach, &au6610_zl10353_config,
&adap->dev->i2c_adap)) != NULL) {
return 0;
}
return -EIO;
}
static struct qt1010_config au6610_qt1010_config = {
.i2c_address = 0xc4
};
static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap)
{
return dvb_attach(qt1010_attach,
adap->fe, &adap->dev->i2c_adap,
&au6610_qt1010_config) == NULL ? -ENODEV : 0;
}
/* DVB USB Driver stuff */
static struct dvb_usb_device_properties au6610_properties;
static int au6610_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct dvb_usb_device *d;
struct usb_host_interface *alt;
int ret;
if (intf->num_altsetting < AU6610_ALTSETTING_COUNT)
return -ENODEV;
if ((ret = dvb_usb_device_init(intf, &au6610_properties, THIS_MODULE, &d)) == 0) {
alt = usb_altnum_to_altsetting(intf, AU6610_ALTSETTING);
if (alt == NULL) {
deb_rc("no alt found!\n");
return -ENODEV;
}
ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
alt->desc.bAlternateSetting);
}
return ret;
}
static struct usb_device_id au6610_table [] = {
{ USB_DEVICE(USB_VID_ALCOR_MICRO, USB_PID_SIGMATEK_DVB_110) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, au6610_table);
static struct dvb_usb_device_properties au6610_properties = {
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
.usb_ctrl = DEVICE_SPECIFIC,
.size_of_priv = 0,
.identify_state = au6610_identify_state,
.num_adapters = 1,
.adapter = {
{
.frontend_attach = au6610_zl10353_frontend_attach,
.tuner_attach = au6610_qt1010_tuner_attach,
.stream = {
.type = USB_ISOC,
.count = 5,
.endpoint = 0x82,
.u = {
.isoc = {
.framesperurb = 40,
.framesize = 942, /* maximum packet size */
.interval = 1.25, /* 125 us */
}
}
},
}
},
.i2c_algo = &au6610_i2c_algo,
.num_device_descs = 1,
.devices = {
{
"Sigmatek DVB-110 DVB-T USB2.0",
{ &au6610_table[0], NULL },
{ NULL },
},
}
};
static struct usb_driver au6610_driver = {
.name = "dvb_usb_au6610",
.probe = au6610_probe,
.disconnect = dvb_usb_device_exit,
.id_table = au6610_table,
};
/* module stuff */
static int __init au6610_module_init(void)
{
int ret;
if ((ret = usb_register(&au6610_driver))) {
err("usb_register failed. Error number %d", ret);
return ret;
}
return 0;
}
static void __exit au6610_module_exit(void)
{
/* deregister this driver from the USB subsystem */
usb_deregister(&au6610_driver);
}
module_init (au6610_module_init);
module_exit (au6610_module_exit);
MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
MODULE_DESCRIPTION("Driver Sigmatek DVB-110 DVB-T USB2.0 / AU6610");
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
#ifndef _DVB_USB_AU6610_H_
#define _DVB_USB_AU6610_H_
#define DVB_USB_LOG_PREFIX "au6610"
#include "dvb-usb.h"
#define deb_rc(args...) dprintk(dvb_usb_au6610_debug,0x01,args)
#define AU6610_REQ_I2C_WRITE 0x14
#define AU6610_REQ_I2C_READ 0x13
#define AU6610_REQ_USB_WRITE 0x16
#define AU6610_REQ_USB_READ 0x15
#define AU6610_USB_TIMEOUT 1000
#define AU6610_ALTSETTING_COUNT 6
#define AU6610_ALTSETTING 5
#endif
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
/* Vendor IDs */ /* Vendor IDs */
#define USB_VID_ADSTECH 0x06e1 #define USB_VID_ADSTECH 0x06e1
#define USB_VID_ALCOR_MICRO 0x058f
#define USB_VID_ANCHOR 0x0547 #define USB_VID_ANCHOR 0x0547
#define USB_VID_AVERMEDIA 0x07ca #define USB_VID_AVERMEDIA 0x07ca
#define USB_VID_COMPRO 0x185b #define USB_VID_COMPRO 0x185b
...@@ -29,6 +30,7 @@ ...@@ -29,6 +30,7 @@
#define USB_VID_LEADTEK 0x0413 #define USB_VID_LEADTEK 0x0413
#define USB_VID_LITEON 0x04ca #define USB_VID_LITEON 0x04ca
#define USB_VID_MEDION 0x1660 #define USB_VID_MEDION 0x1660
#define USB_VID_MSI 0x0db0
#define USB_VID_PINNACLE 0x2304 #define USB_VID_PINNACLE 0x2304
#define USB_VID_VISIONPLUS 0x13d3 #define USB_VID_VISIONPLUS 0x13d3
#define USB_VID_TWINHAN 0x1822 #define USB_VID_TWINHAN 0x1822
...@@ -119,6 +121,8 @@ ...@@ -119,6 +121,8 @@
#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD 0xdb54 #define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_COLD 0xdb54
#define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM 0xdb55 #define USB_PID_DIGITALNOW_BLUEBIRD_DUAL_1_WARM 0xdb55
#define USB_PID_MEDION_MD95700 0x0932 #define USB_PID_MEDION_MD95700 0x0932
#define USB_PID_MSI_MEGASKY580 0x5580
#define USB_PID_MSI_MEGASKY580_55801 0x5581
#define USB_PID_KYE_DVB_T_COLD 0x701e #define USB_PID_KYE_DVB_T_COLD 0x701e
#define USB_PID_KYE_DVB_T_WARM 0x701f #define USB_PID_KYE_DVB_T_WARM 0x701f
#define USB_PID_PCTV_200E 0x020e #define USB_PID_PCTV_200E 0x020e
...@@ -134,6 +138,7 @@ ...@@ -134,6 +138,7 @@
#define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00 #define USB_PID_WINFAST_DTV_DONGLE_STK7700P 0x6f00
#define USB_PID_GENPIX_8PSK_COLD 0x0200 #define USB_PID_GENPIX_8PSK_COLD 0x0200
#define USB_PID_GENPIX_8PSK_WARM 0x0201 #define USB_PID_GENPIX_8PSK_WARM 0x0201
#define USB_PID_SIGMATEK_DVB_110 0x6610
#endif #endif
...@@ -151,7 +151,7 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) ...@@ -151,7 +151,7 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
int dvb_usb_remote_exit(struct dvb_usb_device *d) int dvb_usb_remote_exit(struct dvb_usb_device *d)
{ {
if (d->state & DVB_USB_STATE_REMOTE) { if (d->state & DVB_USB_STATE_REMOTE) {
cancel_delayed_work(&d->rc_query_work); cancel_rearming_delayed_work(&d->rc_query_work);
flush_scheduled_work(); flush_scheduled_work();
input_unregister_device(d->rc_input_dev); input_unregister_device(d->rc_input_dev);
} }
......
/* DVB USB compliant linux driver for GL861 USB2.0 devices.
*
* 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 "gl861.h"
#include "zl10353.h"
#include "qt1010.h"
/* debug */
int dvb_usb_gl861_debug;
module_param_named(debug,dvb_usb_gl861_debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=rc (or-able))." DVB_USB_DEBUG_STATUS);
static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
{
u16 index;
u16 value = addr << 8;
int wo = (rbuf == NULL || rlen == 0); /* write-only */
u8 req, type;
if (wo) {
req = GL861_REQ_I2C_WRITE;
type = GL861_WRITE;
} else { /* rw */
req = GL861_REQ_I2C_READ;
type = GL861_READ;
}
switch (wlen) {
case 1:
index = wbuf[0];
break;
case 2:
index = wbuf[0];
value = value + wbuf[1];
break;
default:
warn("wlen = %x, aborting.", wlen);
return -EINVAL;
}
return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
value, index, rbuf, rlen, 2000);
}
/* I2C */
static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
int num)
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
int i;
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
if (num > 2)
return -EINVAL;
for (i = 0; i < num; i++) {
/* write/read request */
if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
msg[i].len, msg[i+1].buf, msg[i+1].len) < 0)
break;
i++;
} else
if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
msg[i].len, NULL, 0) < 0)
break;
}
mutex_unlock(&d->i2c_mutex);
return i;
}
static u32 gl861_i2c_func(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C;
}
static struct i2c_algorithm gl861_i2c_algo = {
.master_xfer = gl861_i2c_xfer,
.functionality = gl861_i2c_func,
};
/* Callbacks for DVB USB */
static int gl861_identify_state(struct usb_device *udev,
struct dvb_usb_device_properties *props,
struct dvb_usb_device_description **desc,
int *cold)
{
*cold = 0;
return 0;
}
static struct zl10353_config gl861_zl10353_config = {
.demod_address = 0x1e,
.no_tuner = 1,
.parallel_ts = 1,
};
static int gl861_frontend_attach(struct dvb_usb_adapter *adap)
{
if ((adap->fe = dvb_attach(zl10353_attach, &gl861_zl10353_config,
&adap->dev->i2c_adap)) != NULL) {
return 0;
}
return -EIO;
}
static struct qt1010_config gl861_qt1010_config = {
.i2c_address = 0xc4
};
static int gl861_tuner_attach(struct dvb_usb_adapter *adap)
{
return dvb_attach(qt1010_attach,
adap->fe, &adap->dev->i2c_adap,
&gl861_qt1010_config) == NULL ? -ENODEV : 0;
}
/* DVB USB Driver stuff */
static struct dvb_usb_device_properties gl861_properties;
static int gl861_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct dvb_usb_device *d;
struct usb_host_interface *alt;
int ret;
if (intf->num_altsetting < 2)
return -ENODEV;
if ((ret = dvb_usb_device_init(intf, &gl861_properties, THIS_MODULE, &d)) == 0) {
alt = usb_altnum_to_altsetting(intf, 0);
if (alt == NULL) {
deb_rc("not alt found!\n");
return -ENODEV;
}
ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
alt->desc.bAlternateSetting);
}
return ret;
}
static struct usb_device_id gl861_table [] = {
{ USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580_55801) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, gl861_table);
static struct dvb_usb_device_properties gl861_properties = {
.caps = DVB_USB_IS_AN_I2C_ADAPTER,
.usb_ctrl = DEVICE_SPECIFIC,
.size_of_priv = 0,
.identify_state = gl861_identify_state,
.num_adapters = 1,
.adapter = {{
.frontend_attach = gl861_frontend_attach,
.tuner_attach = gl861_tuner_attach,
.stream = {
.type = USB_BULK,
.count = 7,
.endpoint = 0x81,
.u = {
.bulk = {
.buffersize = 512,
}
}
},
}},
.i2c_algo = &gl861_i2c_algo,
.num_device_descs = 1,
.devices = {
{ "MSI Mega Sky 55801 DVB-T USB2.0",
{ &gl861_table[0], NULL },
{ NULL },
},
}
};
static struct usb_driver gl861_driver = {
.name = "dvb_usb_gl861",
.probe = gl861_probe,
.disconnect = dvb_usb_device_exit,
.id_table = gl861_table,
};
/* module stuff */
static int __init gl861_module_init(void)
{
int ret;
if ((ret = usb_register(&gl861_driver))) {
err("usb_register failed. Error number %d", ret);
return ret;
}
return 0;
}
static void __exit gl861_module_exit(void)
{
/* deregister this driver from the USB subsystem */
usb_deregister(&gl861_driver);
}
module_init (gl861_module_init);
module_exit (gl861_module_exit);
MODULE_AUTHOR("Carl Lundqvist <comabug@gmail.com>");
MODULE_DESCRIPTION("Driver MSI Mega Sky 580 DVB-T USB2.0 / GL861");
MODULE_VERSION("0.1");
MODULE_LICENSE("GPL");
#ifndef _DVB_USB_GL861_H_
#define _DVB_USB_GL861_H_
#define DVB_USB_LOG_PREFIX "gl861"
#include "dvb-usb.h"
#define deb_rc(args...) dprintk(dvb_usb_gl861_debug,0x01,args)
#define GL861_WRITE 0x40
#define GL861_READ 0xc0
#define GL861_REQ_I2C_WRITE 0x01
#define GL861_REQ_I2C_READ 0x02
#endif
This diff is collapsed.
#ifndef _DVB_USB_M920X_H_
#define _DVB_USB_M920X_H_
#define DVB_USB_LOG_PREFIX "m920x"
#include "dvb-usb.h"
#define deb_rc(args...) dprintk(dvb_usb_m920x_debug,0x01,args)
#define M9206_CORE 0x22
#define M9206_RC_STATE 0xff51
#define M9206_RC_KEY 0xff52
#define M9206_RC_INIT1 0xff54
#define M9206_RC_INIT2 0xff55
#define M9206_FW_GO 0xff69
#define M9206_I2C 0x23
#define M9206_FILTER 0x25
#define M9206_FW 0x30
#define M9206_MAX_FILTERS 8
#define M9206_I2C_TUNER 0
#define M9206_I2C_DEMOD 1
#define M9206_I2C_MAX 2
struct m9206_state {
u16 filters[M9206_MAX_FILTERS];
int filtering_enabled;
int rep_count;
struct {
unsigned char addr;
unsigned char magic;
}i2c_r[M9206_I2C_MAX];
};
#endif
...@@ -290,6 +290,13 @@ config DVB_TDA826X ...@@ -290,6 +290,13 @@ config DVB_TDA826X
help help
A DVB-S silicon tuner module. Say Y when you want to support this tuner. A DVB-S silicon tuner module. Say Y when you want to support this tuner.
config DVB_TUNER_QT1010
tristate "Quantek QT1010 silicon tuner"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A driver for the silicon tuner QT1010 from Quantek.
config DVB_TUNER_MT2060 config DVB_TUNER_MT2060
tristate "Microtune MT2060 silicon IF tuner" tristate "Microtune MT2060 silicon IF tuner"
depends on I2C depends on I2C
......
...@@ -38,5 +38,6 @@ obj-$(CONFIG_DVB_ISL6421) += isl6421.o ...@@ -38,5 +38,6 @@ obj-$(CONFIG_DVB_ISL6421) += isl6421.o
obj-$(CONFIG_DVB_TDA10086) += tda10086.o obj-$(CONFIG_DVB_TDA10086) += tda10086.o
obj-$(CONFIG_DVB_TDA826X) += tda826x.o obj-$(CONFIG_DVB_TDA826X) += tda826x.o
obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o
obj-$(CONFIG_DVB_TUA6100) += tua6100.o obj-$(CONFIG_DVB_TUA6100) += tua6100.o
obj-$(CONFIG_DVB_TUNER_LGH06XF) += lgh06xf.o obj-$(CONFIG_DVB_TUNER_LGH06XF) += lgh06xf.o
...@@ -254,7 +254,7 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate) ...@@ -254,7 +254,7 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
if (srate<500000) if (srate<500000)
srate=500000; srate=500000;
for(i=0;(i<sizeof(bands)/sizeof(bands[0]))&&(srate>bands[i]);i++) for(i = 0; (i < ARRAY_SIZE(bands)) && (srate>bands[i]); i++)
; ;
/* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz, /* first, check which sample rate is appropriate: 45, 60 80 or 90 MHz,
and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult, and set the PLL accordingly (R07[1:0] Fclk, R06[7:4] PLLmult,
...@@ -361,7 +361,7 @@ static int cx24110_initfe(struct dvb_frontend* fe) ...@@ -361,7 +361,7 @@ static int cx24110_initfe(struct dvb_frontend* fe)
dprintk("%s: init chip\n", __FUNCTION__); dprintk("%s: init chip\n", __FUNCTION__);
for(i=0;i<sizeof(cx24110_regdata)/sizeof(cx24110_regdata[0]);i++) { for(i = 0; i < ARRAY_SIZE(cx24110_regdata); i++) {
cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data); cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data);
}; };
......
...@@ -507,7 +507,7 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa ...@@ -507,7 +507,7 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa
int i = 0; int i = 0;
int pump = 2; int pump = 2;
int band = 0; int band = 0;
int num_bands = sizeof(cx24123_bandselect_vals) / sizeof(cx24123_bandselect_vals[0]); int num_bands = ARRAY_SIZE(cx24123_bandselect_vals);
/* Defaults for low freq, low rate */ /* Defaults for low freq, low rate */
state->VCAarg = cx24123_AGC_vals[0].VCAprogdata; state->VCAarg = cx24123_AGC_vals[0].VCAprogdata;
...@@ -516,7 +516,7 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa ...@@ -516,7 +516,7 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa
vco_div = cx24123_bandselect_vals[0].VCOdivider; vco_div = cx24123_bandselect_vals[0].VCOdivider;
/* For the given symbol rate, determine the VCA, VGA and FILTUNE programming bits */ /* For the given symbol rate, determine the VCA, VGA and FILTUNE programming bits */
for (i = 0; i < sizeof(cx24123_AGC_vals) / sizeof(cx24123_AGC_vals[0]); i++) for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++)
{ {
if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) && if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) &&
(cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) { (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) {
...@@ -658,7 +658,7 @@ static int cx24123_initfe(struct dvb_frontend* fe) ...@@ -658,7 +658,7 @@ static int cx24123_initfe(struct dvb_frontend* fe)
dprintk("%s: init frontend\n",__FUNCTION__); dprintk("%s: init frontend\n",__FUNCTION__);
/* Configure the demod to a good set of defaults */ /* Configure the demod to a good set of defaults */
for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++)
cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);
/* Set the LNB polarity */ /* Set the LNB polarity */
......
...@@ -475,7 +475,7 @@ static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx ...@@ -475,7 +475,7 @@ static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx
tmp = ((chan->nfft & 0x1) << 7) | (chan->guard << 5) | (chan->nqam << 3) | chan->vit_alpha; tmp = ((chan->nfft & 0x1) << 7) | (chan->guard << 5) | (chan->nqam << 3) | chan->vit_alpha;
dib3000mc_write_word(state, 0, tmp); dib3000mc_write_word(state, 0, tmp);
dib3000mc_write_word(state, 5, seq); dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4));
tmp = (chan->vit_hrch << 4) | (chan->vit_select_hp); tmp = (chan->vit_hrch << 4) | (chan->vit_select_hp);
if (!chan->vit_hrch || (chan->vit_hrch && chan->vit_select_hp)) if (!chan->vit_hrch || (chan->vit_hrch && chan->vit_select_hp))
......
This diff is collapsed.
/*
* Driver for Quantek QT1010 silicon tuner
*
* Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
* Aapo Tahkola <aet@rasterburn.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 QT1010_H
#define QT1010_H
#include "dvb_frontend.h"
struct qt1010_config {
u8 i2c_address;
};
/**
* Attach a qt1010 tuner to the supplied frontend structure.
*
* @param fe frontend to attach to
* @param i2c i2c adapter to use
* @param cfg tuner hw based configuration
* @return fe pointer on success, NULL on failure
*/
#if defined(CONFIG_DVB_TUNER_QT1010) || (defined(CONFIG_DVB_TUNER_QT1010_MODULE) && defined(MODULE))
extern struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
struct qt1010_config *cfg);
#else
static inline struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
struct qt1010_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
return NULL;
}
#endif // CONFIG_DVB_TUNER_QT1010
#endif
/*
* Driver for Quantek QT1010 silicon tuner
*
* Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
* Aapo Tahkola <aet@rasterburn.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 QT1010_PRIV_H
#define QT1010_PRIV_H
/*
reg def meaning
=== === =======
00 00 ?
01 a0 ? operation start/stop; start=80, stop=00
02 00 ?
03 19 ?
04 00 ?
05 00 ? maybe band selection
06 00 ?
07 2b set frequency: 32 MHz scale, n*32 MHz
08 0b ?
09 10 ? changes every 8/24 MHz; values 1d/1c
0a 08 set frequency: 4 MHz scale, n*4 MHz
0b 41 ? changes every 2/2 MHz; values 45/45
0c e1 ?
0d 94 ?
0e b6 ?
0f 2c ?
10 10 ?
11 f1 ? maybe device specified adjustment
12 11 ? maybe device specified adjustment
13 3f ?
14 1f ?
15 3f ?
16 ff ?
17 ff ?
18 f7 ?
19 80 ?
1a d0 set frequency: 125 kHz scale, n*125 kHz
1b 00 ?
1c 89 ?
1d 00 ?
1e 00 ? looks like operation register; write cmd here, read result from 1f-26
1f 20 ? chip initialization
20 e0 ? chip initialization
21 20 ?
22 d0 ?
23 d0 ?
24 d0 ?
25 40 ? chip initialization
26 08 ?
27 29 ?
28 55 ?
29 39 ?
2a 13 ?
2b 01 ?
2c ea ?
2d 00 ?
2e 00 ? not used?
2f 00 ? not used?
*/
#define QT1010_STEP 125000 /* 125 kHz used by Windows drivers,
hw could be more precise but we don't
know how to use */
#define QT1010_MIN_FREQ 48000000 /* 48 MHz */
#define QT1010_MAX_FREQ 860000000 /* 860 MHz */
#define QT1010_OFFSET 1246000000 /* 1246 MHz */
#define QT1010_WR 0
#define QT1010_RD 1
#define QT1010_M1 3
typedef struct {
u8 oper, reg, val;
} qt1010_i2c_oper_t;
struct qt1010_priv {
struct qt1010_config *cfg;
struct i2c_adapter *i2c;
u8 reg1f_init_val;
u8 reg20_init_val;
u8 reg25_init_val;
u32 frequency;
u32 bandwidth;
};
#endif
...@@ -35,6 +35,7 @@ struct stv0297_state { ...@@ -35,6 +35,7 @@ struct stv0297_state {
const struct stv0297_config *config; const struct stv0297_config *config;
struct dvb_frontend frontend; struct dvb_frontend frontend;
unsigned long last_ber;
unsigned long base_freq; unsigned long base_freq;
}; };
...@@ -310,6 +311,8 @@ static int stv0297_init(struct dvb_frontend *fe) ...@@ -310,6 +311,8 @@ static int stv0297_init(struct dvb_frontend *fe)
stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]); stv0297_writereg(state, state->config->inittab[i], state->config->inittab[i+1]);
msleep(200); msleep(200);
state->last_ber = 0;
return 0; return 0;
} }
...@@ -340,11 +343,13 @@ static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber) ...@@ -340,11 +343,13 @@ static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber)
struct stv0297_state *state = fe->demodulator_priv; struct stv0297_state *state = fe->demodulator_priv;
u8 BER[3]; u8 BER[3];
stv0297_writereg(state, 0xA0, 0x80); // Start Counting bit errors for 4096 Bytes
mdelay(25); // Hopefully got 4096 Bytes
stv0297_readregs(state, 0xA0, BER, 3); stv0297_readregs(state, 0xA0, BER, 3);
mdelay(25); if (!(BER[0] & 0x80)) {
*ber = (BER[2] << 8 | BER[1]) / (8 * 4096); state->last_ber = BER[2] << 8 | BER[1];
stv0297_writereg_mask(state, 0xA0, 0x80, 0x80);
}
*ber = state->last_ber;
return 0; return 0;
} }
...@@ -376,9 +381,14 @@ static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) ...@@ -376,9 +381,14 @@ static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
{ {
struct stv0297_state *state = fe->demodulator_priv; struct stv0297_state *state = fe->demodulator_priv;
stv0297_writereg_mask(state, 0xDF, 0x03, 0x03); /* freeze the counters */
*ucblocks = (stv0297_readreg(state, 0xD5) << 8) *ucblocks = (stv0297_readreg(state, 0xD5) << 8)
| stv0297_readreg(state, 0xD4); | stv0297_readreg(state, 0xD4);
stv0297_writereg_mask(state, 0xDF, 0x03, 0x02); /* clear the counters */
stv0297_writereg_mask(state, 0xDF, 0x03, 0x01); /* re-enable the counters */
return 0; return 0;
} }
...@@ -648,6 +658,7 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, ...@@ -648,6 +658,7 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
/* setup the state */ /* setup the state */
state->config = config; state->config = config;
state->i2c = i2c; state->i2c = i2c;
state->last_ber = 0;
state->base_freq = 0; state->base_freq = 0;
/* check if the demod is there */ /* check if the demod is there */
......
...@@ -92,7 +92,7 @@ static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data) ...@@ -92,7 +92,7 @@ static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data)
return (ret != 1) ? -EREMOTEIO : 0; return (ret != 1) ? -EREMOTEIO : 0;
} }
int stv0299_write(struct dvb_frontend* fe, u8 *buf, int len) static int stv0299_write(struct dvb_frontend* fe, u8 *buf, int len)
{ {
struct stv0299_state* state = fe->demodulator_priv; struct stv0299_state* state = fe->demodulator_priv;
......
...@@ -201,7 +201,7 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate ...@@ -201,7 +201,7 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate
return 0; return 0;
} }
int tda10021_write(struct dvb_frontend* fe, u8 *buf, int len) static int tda10021_write(struct dvb_frontend* fe, u8 *buf, int len)
{ {
struct tda10021_state* state = fe->demodulator_priv; struct tda10021_state* state = fe->demodulator_priv;
......
...@@ -579,7 +579,7 @@ static int tda1004x_decode_fec(int tdafec) ...@@ -579,7 +579,7 @@ static int tda1004x_decode_fec(int tdafec)
return -1; return -1;
} }
int tda1004x_write(struct dvb_frontend* fe, u8 *buf, int len) static int tda1004x_write(struct dvb_frontend* fe, u8 *buf, int len)
{ {
struct tda1004x_state* state = fe->demodulator_priv; struct tda1004x_state* state = fe->demodulator_priv;
......
...@@ -38,6 +38,12 @@ struct zl10353_state { ...@@ -38,6 +38,12 @@ struct zl10353_state {
struct zl10353_config config; struct zl10353_config config;
}; };
static int debug;
#define dprintk(args...) \
do { \
if (debug) printk(KERN_DEBUG "zl10353: " args); \
} while (0)
static int debug_regs = 0; static int debug_regs = 0;
static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val) static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
...@@ -54,7 +60,7 @@ static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val) ...@@ -54,7 +60,7 @@ static int zl10353_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
return 0; return 0;
} }
int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen) static int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen)
{ {
int err, i; int err, i;
for (i = 0; i < ilen - 1; i++) for (i = 0; i < ilen - 1; i++)
...@@ -113,6 +119,36 @@ static void zl10353_dump_regs(struct dvb_frontend *fe) ...@@ -113,6 +119,36 @@ static void zl10353_dump_regs(struct dvb_frontend *fe)
printk(KERN_DEBUG "%s\n", buf); printk(KERN_DEBUG "%s\n", buf);
} }
static void zl10353_calc_nominal_rate(struct dvb_frontend *fe,
enum fe_bandwidth bandwidth,
u16 *nominal_rate)
{
u32 adc_clock = 22528; /* 20.480 MHz on the board(!?) */
u8 bw;
struct zl10353_state *state = fe->demodulator_priv;
if (state->config.adc_clock)
adc_clock = state->config.adc_clock;
switch (bandwidth) {
case BANDWIDTH_6_MHZ:
bw = 6;
break;
case BANDWIDTH_7_MHZ:
bw = 7;
break;
case BANDWIDTH_8_MHZ:
default:
bw = 8;
break;
}
*nominal_rate = (64 * bw * (1<<16) / (7 * 8) * 4000 / adc_clock + 2) / 4;
dprintk("%s: bw %d, adc_clock %d => 0x%x\n",
__FUNCTION__, bw, adc_clock, *nominal_rate);
}
static int zl10353_sleep(struct dvb_frontend *fe) static int zl10353_sleep(struct dvb_frontend *fe)
{ {
static u8 zl10353_softdown[] = { 0x50, 0x0C, 0x44 }; static u8 zl10353_softdown[] = { 0x50, 0x0C, 0x44 };
...@@ -125,7 +161,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, ...@@ -125,7 +161,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe,
struct dvb_frontend_parameters *param) struct dvb_frontend_parameters *param)
{ {
struct zl10353_state *state = fe->demodulator_priv; struct zl10353_state *state = fe->demodulator_priv;
u16 nominal_rate;
u8 pllbuf[6] = { 0x67 }; u8 pllbuf[6] = { 0x67 };
/* These settings set "auto-everything" and start the FSM. */ /* These settings set "auto-everything" and start the FSM. */
...@@ -138,18 +174,23 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, ...@@ -138,18 +174,23 @@ static int zl10353_set_parameters(struct dvb_frontend *fe,
zl10353_single_write(fe, 0x56, 0x28); zl10353_single_write(fe, 0x56, 0x28);
zl10353_single_write(fe, 0x89, 0x20); zl10353_single_write(fe, 0x89, 0x20);
zl10353_single_write(fe, 0x5E, 0x00); zl10353_single_write(fe, 0x5E, 0x00);
zl10353_single_write(fe, 0x65, 0x5A);
zl10353_single_write(fe, 0x66, 0xE9); zl10353_calc_nominal_rate(fe, param->u.ofdm.bandwidth, &nominal_rate);
zl10353_single_write(fe, TRL_NOMINAL_RATE_1, msb(nominal_rate));
zl10353_single_write(fe, TRL_NOMINAL_RATE_0, lsb(nominal_rate));
zl10353_single_write(fe, 0x6C, 0xCD); zl10353_single_write(fe, 0x6C, 0xCD);
zl10353_single_write(fe, 0x6D, 0x7E); zl10353_single_write(fe, 0x6D, 0x7E);
zl10353_single_write(fe, 0x62, 0x0A); if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
// if there is no attached secondary tuner, we call set_params to program // if there is no attached secondary tuner, we call set_params to program
// a potential tuner attached somewhere else // a potential tuner attached somewhere else
if (state->config.no_tuner) { if (state->config.no_tuner) {
if (fe->ops.tuner_ops.set_params) { if (fe->ops.tuner_ops.set_params) {
fe->ops.tuner_ops.set_params(fe, param); fe->ops.tuner_ops.set_params(fe, param);
if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
} }
} }
...@@ -213,6 +254,29 @@ static int zl10353_read_status(struct dvb_frontend *fe, fe_status_t *status) ...@@ -213,6 +254,29 @@ static int zl10353_read_status(struct dvb_frontend *fe, fe_status_t *status)
return 0; return 0;
} }
static int zl10353_read_ber(struct dvb_frontend *fe, u32 *ber)
{
struct zl10353_state *state = fe->demodulator_priv;
*ber = zl10353_read_register(state, RS_ERR_CNT_2) << 16 |
zl10353_read_register(state, RS_ERR_CNT_1) << 8 |
zl10353_read_register(state, RS_ERR_CNT_0);
return 0;
}
static int zl10353_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
{
struct zl10353_state *state = fe->demodulator_priv;
u16 signal = zl10353_read_register(state, AGC_GAIN_1) << 10 |
zl10353_read_register(state, AGC_GAIN_0) << 2 | 3;
*strength = ~signal;
return 0;
}
static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr) static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr)
{ {
struct zl10353_state *state = fe->demodulator_priv; struct zl10353_state *state = fe->demodulator_priv;
...@@ -227,6 +291,16 @@ static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr) ...@@ -227,6 +291,16 @@ static int zl10353_read_snr(struct dvb_frontend *fe, u16 *snr)
return 0; return 0;
} }
static int zl10353_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
{
struct zl10353_state *state = fe->demodulator_priv;
*ucblocks = zl10353_read_register(state, RS_UBC_1) << 8 |
zl10353_read_register(state, RS_UBC_0);
return 0;
}
static int zl10353_get_tune_settings(struct dvb_frontend *fe, static int zl10353_get_tune_settings(struct dvb_frontend *fe,
struct dvb_frontend_tune_settings struct dvb_frontend_tune_settings
*fe_tune_settings) *fe_tune_settings)
...@@ -261,6 +335,16 @@ static int zl10353_init(struct dvb_frontend *fe) ...@@ -261,6 +335,16 @@ static int zl10353_init(struct dvb_frontend *fe)
return 0; return 0;
} }
static int zl10353_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
{
u8 val = 0x0a;
if (enable)
val |= 0x10;
return zl10353_single_write(fe, 0x62, val);
}
static void zl10353_release(struct dvb_frontend *fe) static void zl10353_release(struct dvb_frontend *fe)
{ {
struct zl10353_state *state = fe->demodulator_priv; struct zl10353_state *state = fe->demodulator_priv;
...@@ -319,15 +403,22 @@ static struct dvb_frontend_ops zl10353_ops = { ...@@ -319,15 +403,22 @@ static struct dvb_frontend_ops zl10353_ops = {
.init = zl10353_init, .init = zl10353_init,
.sleep = zl10353_sleep, .sleep = zl10353_sleep,
.i2c_gate_ctrl = zl10353_i2c_gate_ctrl,
.write = zl10353_write, .write = zl10353_write,
.set_frontend = zl10353_set_parameters, .set_frontend = zl10353_set_parameters,
.get_tune_settings = zl10353_get_tune_settings, .get_tune_settings = zl10353_get_tune_settings,
.read_status = zl10353_read_status, .read_status = zl10353_read_status,
.read_ber = zl10353_read_ber,
.read_signal_strength = zl10353_read_signal_strength,
.read_snr = zl10353_read_snr, .read_snr = zl10353_read_snr,
.read_ucblocks = zl10353_read_ucblocks,
}; };
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
module_param(debug_regs, int, 0644); module_param(debug_regs, int, 0644);
MODULE_PARM_DESC(debug_regs, "Turn on/off frontend register dumps (default:off)."); MODULE_PARM_DESC(debug_regs, "Turn on/off frontend register dumps (default:off).");
......
...@@ -29,6 +29,9 @@ struct zl10353_config ...@@ -29,6 +29,9 @@ struct zl10353_config
/* demodulator's I2C address */ /* demodulator's I2C address */
u8 demod_address; u8 demod_address;
/* frequencies in kHz */
int adc_clock; // default: 22528
/* set if no pll is connected to the secondary i2c bus */ /* set if no pll is connected to the secondary i2c bus */
int no_tuner; int no_tuner;
......
...@@ -24,19 +24,31 @@ ...@@ -24,19 +24,31 @@
#define ID_ZL10353 0x14 #define ID_ZL10353 0x14
#define msb(x) (((x) >> 8) & 0xff)
#define lsb(x) ((x) & 0xff)
enum zl10353_reg_addr { enum zl10353_reg_addr {
INTERRUPT_0 = 0x00, INTERRUPT_0 = 0x00,
INTERRUPT_1 = 0x01, INTERRUPT_1 = 0x01,
INTERRUPT_2 = 0x02, INTERRUPT_2 = 0x02,
INTERRUPT_3 = 0x03, INTERRUPT_3 = 0x03,
INTERRUPT_4 = 0x04, INTERRUPT_4 = 0x04,
INTERRUPT_5 = 0x05, INTERRUPT_5 = 0x05,
STATUS_6 = 0x06, STATUS_6 = 0x06,
STATUS_7 = 0x07, STATUS_7 = 0x07,
STATUS_8 = 0x08, STATUS_8 = 0x08,
STATUS_9 = 0x09, STATUS_9 = 0x09,
SNR = 0x10, AGC_GAIN_1 = 0x0A,
CHIP_ID = 0x7F, AGC_GAIN_0 = 0x0B,
SNR = 0x10,
RS_ERR_CNT_2 = 0x11,
RS_ERR_CNT_1 = 0x12,
RS_ERR_CNT_0 = 0x13,
RS_UBC_1 = 0x14,
RS_UBC_0 = 0x15,
TRL_NOMINAL_RATE_1 = 0x65,
TRL_NOMINAL_RATE_0 = 0x66,
CHIP_ID = 0x7F,
}; };
#endif /* _ZL10353_PRIV_ */ #endif /* _ZL10353_PRIV_ */
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/crc32.h> #include <linux/crc32.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/kthread.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -223,11 +224,10 @@ static void recover_arm(struct av7110 *av7110) ...@@ -223,11 +224,10 @@ static void recover_arm(struct av7110 *av7110)
static void av7110_arm_sync(struct av7110 *av7110) static void av7110_arm_sync(struct av7110 *av7110)
{ {
av7110->arm_rmmod = 1; if (av7110->arm_thread)
wake_up_interruptible(&av7110->arm_wait); kthread_stop(av7110->arm_thread);
while (av7110->arm_thread) av7110->arm_thread = NULL;
msleep(1);
} }
static int arm_thread(void *data) static int arm_thread(void *data)
...@@ -238,17 +238,11 @@ static int arm_thread(void *data) ...@@ -238,17 +238,11 @@ static int arm_thread(void *data)
dprintk(4, "%p\n",av7110); dprintk(4, "%p\n",av7110);
lock_kernel();
daemonize("arm_mon");
sigfillset(&current->blocked);
unlock_kernel();
av7110->arm_thread = current;
for (;;) { for (;;) {
timeout = wait_event_interruptible_timeout(av7110->arm_wait, timeout = wait_event_interruptible_timeout(av7110->arm_wait,
av7110->arm_rmmod, 5 * HZ); kthread_should_stop(), 5 * HZ);
if (-ERESTARTSYS == timeout || av7110->arm_rmmod) {
if (-ERESTARTSYS == timeout || kthread_should_stop()) {
/* got signal or told to quit*/ /* got signal or told to quit*/
break; break;
} }
...@@ -276,7 +270,6 @@ static int arm_thread(void *data) ...@@ -276,7 +270,6 @@ static int arm_thread(void *data)
av7110->arm_errors = 0; av7110->arm_errors = 0;
} }
av7110->arm_thread = NULL;
return 0; return 0;
} }
...@@ -695,8 +688,8 @@ static void gpioirq(unsigned long data) ...@@ -695,8 +688,8 @@ static void gpioirq(unsigned long data)
static int dvb_osd_ioctl(struct inode *inode, struct file *file, static int dvb_osd_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg) unsigned int cmd, void *parg)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
dprintk(4, "%p\n", av7110); dprintk(4, "%p\n", av7110);
...@@ -786,7 +779,7 @@ int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, ...@@ -786,7 +779,7 @@ int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter) static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
{ {
struct dvb_demux_feed *dvbdmxfeed = dvbdmxfilter->feed; struct dvb_demux_feed *dvbdmxfeed = dvbdmxfilter->feed;
struct av7110 *av7110 = (struct av7110 *) dvbdmxfeed->demux->priv; struct av7110 *av7110 = dvbdmxfeed->demux->priv;
u16 buf[20]; u16 buf[20];
int ret, i; int ret, i;
u16 handle; u16 handle;
...@@ -835,7 +828,7 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter) ...@@ -835,7 +828,7 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
{ {
struct av7110 *av7110 = (struct av7110 *) dvbdmxfilter->feed->demux->priv; struct av7110 *av7110 = dvbdmxfilter->feed->demux->priv;
u16 buf[3]; u16 buf[3];
u16 answ[2]; u16 answ[2];
int ret; int ret;
...@@ -871,7 +864,7 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) ...@@ -871,7 +864,7 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed) static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
{ {
struct dvb_demux *dvbdmx = dvbdmxfeed->demux; struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv; struct av7110 *av7110 = dvbdmx->priv;
u16 *pid = dvbdmx->pids, npids[5]; u16 *pid = dvbdmx->pids, npids[5];
int i; int i;
int ret = 0; int ret = 0;
...@@ -914,7 +907,7 @@ static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed) ...@@ -914,7 +907,7 @@ static int dvb_feed_start_pid(struct dvb_demux_feed *dvbdmxfeed)
static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed) static int dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
{ {
struct dvb_demux *dvbdmx = dvbdmxfeed->demux; struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
struct av7110 *av7110 = (struct av7110 *) dvbdmx->priv; struct av7110 *av7110 = dvbdmx->priv;
u16 *pid = dvbdmx->pids, npids[5]; u16 *pid = dvbdmx->pids, npids[5];
int i; int i;
...@@ -1103,9 +1096,9 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, ...@@ -1103,9 +1096,9 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
/* pointer casting paranoia... */ /* pointer casting paranoia... */
BUG_ON(!demux); BUG_ON(!demux);
dvbdemux = (struct dvb_demux *) demux->priv; dvbdemux = demux->priv;
BUG_ON(!dvbdemux); BUG_ON(!dvbdemux);
av7110 = (struct av7110 *) dvbdemux->priv; av7110 = dvbdemux->priv;
dprintk(4, "%p\n", av7110); dprintk(4, "%p\n", av7110);
...@@ -1137,7 +1130,7 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num, ...@@ -1137,7 +1130,7 @@ static int dvb_get_stc(struct dmx_demux *demux, unsigned int num,
static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
switch (tone) { switch (tone) {
case SEC_TONE_ON: case SEC_TONE_ON:
...@@ -1197,7 +1190,7 @@ static int start_ts_capture(struct av7110 *budget) ...@@ -1197,7 +1190,7 @@ static int start_ts_capture(struct av7110 *budget)
static int budget_start_feed(struct dvb_demux_feed *feed) static int budget_start_feed(struct dvb_demux_feed *feed)
{ {
struct dvb_demux *demux = feed->demux; struct dvb_demux *demux = feed->demux;
struct av7110 *budget = (struct av7110 *) demux->priv; struct av7110 *budget = demux->priv;
int status; int status;
dprintk(2, "av7110: %p\n", budget); dprintk(2, "av7110: %p\n", budget);
...@@ -1212,7 +1205,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed) ...@@ -1212,7 +1205,7 @@ static int budget_start_feed(struct dvb_demux_feed *feed)
static int budget_stop_feed(struct dvb_demux_feed *feed) static int budget_stop_feed(struct dvb_demux_feed *feed)
{ {
struct dvb_demux *demux = feed->demux; struct dvb_demux *demux = feed->demux;
struct av7110 *budget = (struct av7110 *) demux->priv; struct av7110 *budget = demux->priv;
int status; int status;
dprintk(2, "budget: %p\n", budget); dprintk(2, "budget: %p\n", budget);
...@@ -1551,7 +1544,7 @@ static int get_firmware(struct av7110* av7110) ...@@ -1551,7 +1544,7 @@ static int get_firmware(struct av7110* av7110)
static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) static int alps_bsrv2_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
u8 pwr = 0; u8 pwr = 0;
u8 buf[4]; u8 buf[4];
struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
...@@ -1702,7 +1695,7 @@ static int alps_tdlb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_front ...@@ -1702,7 +1695,7 @@ static int alps_tdlb7_tuner_set_params(struct dvb_frontend* fe, struct dvb_front
static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
{ {
#if defined(CONFIG_DVB_SP8870) || defined(CONFIG_DVB_SP8870_MODULE) #if defined(CONFIG_DVB_SP8870) || defined(CONFIG_DVB_SP8870_MODULE)
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
return request_firmware(fw, name, &av7110->dev->pci->dev); return request_firmware(fw, name, &av7110->dev->pci->dev);
#else #else
...@@ -1867,7 +1860,7 @@ static struct stv0297_config nexusca_stv0297_config = { ...@@ -1867,7 +1860,7 @@ static struct stv0297_config nexusca_stv0297_config = {
static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params) static int grundig_29504_401_tuner_set_params(struct dvb_frontend* fe, struct dvb_frontend_parameters *params)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
u32 div; u32 div;
u8 cfg, cpump, band_select; u8 cfg, cpump, band_select;
u8 data[4]; u8 data[4];
...@@ -2338,6 +2331,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, ...@@ -2338,6 +2331,7 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
const int length = TS_WIDTH * TS_HEIGHT; const int length = TS_WIDTH * TS_HEIGHT;
struct pci_dev *pdev = dev->pci; struct pci_dev *pdev = dev->pci;
struct av7110 *av7110; struct av7110 *av7110;
struct task_struct *thread;
int ret, count = 0; int ret, count = 0;
dprintk(4, "dev: %p\n", dev); dprintk(4, "dev: %p\n", dev);
...@@ -2622,9 +2616,12 @@ static int __devinit av7110_attach(struct saa7146_dev* dev, ...@@ -2622,9 +2616,12 @@ static int __devinit av7110_attach(struct saa7146_dev* dev,
printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. " printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. "
"System might be unstable!\n", FW_VERSION(av7110->arm_app)); "System might be unstable!\n", FW_VERSION(av7110->arm_app));
ret = kernel_thread(arm_thread, (void *) av7110, 0); thread = kthread_run(arm_thread, (void *) av7110, "arm_mon");
if (ret < 0) if (IS_ERR(thread)) {
ret = PTR_ERR(thread);
goto err_stop_arm_9; goto err_stop_arm_9;
}
av7110->arm_thread = thread;
/* set initial volume in mixer struct */ /* set initial volume in mixer struct */
av7110->mixer.volume_left = volume; av7110->mixer.volume_left = volume;
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#define ANALOG_TUNER_VES1820 1 #define ANALOG_TUNER_VES1820 1
#define ANALOG_TUNER_STV0297 2 #define ANALOG_TUNER_STV0297 2
#define ANALOG_TUNER_VBI 0x100
extern int av7110_debug; extern int av7110_debug;
...@@ -205,7 +204,6 @@ struct av7110 { ...@@ -205,7 +204,6 @@ struct av7110 {
struct task_struct *arm_thread; struct task_struct *arm_thread;
wait_queue_head_t arm_wait; wait_queue_head_t arm_wait;
u16 arm_loops; u16 arm_loops;
int arm_rmmod;
void *debi_virt; void *debi_virt;
dma_addr_t debi_bus; dma_addr_t debi_bus;
......
...@@ -880,8 +880,8 @@ static int dvb_video_get_event (struct av7110 *av7110, struct video_event *event ...@@ -880,8 +880,8 @@ static int dvb_video_get_event (struct av7110 *av7110, struct video_event *event
static unsigned int dvb_video_poll(struct file *file, poll_table *wait) static unsigned int dvb_video_poll(struct file *file, poll_table *wait)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
unsigned int mask = 0; unsigned int mask = 0;
dprintk(2, "av7110:%p, \n", av7110); dprintk(2, "av7110:%p, \n", av7110);
...@@ -908,8 +908,8 @@ static unsigned int dvb_video_poll(struct file *file, poll_table *wait) ...@@ -908,8 +908,8 @@ static unsigned int dvb_video_poll(struct file *file, poll_table *wait)
static ssize_t dvb_video_write(struct file *file, const char __user *buf, static ssize_t dvb_video_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
dprintk(2, "av7110:%p, \n", av7110); dprintk(2, "av7110:%p, \n", av7110);
...@@ -924,8 +924,8 @@ static ssize_t dvb_video_write(struct file *file, const char __user *buf, ...@@ -924,8 +924,8 @@ static ssize_t dvb_video_write(struct file *file, const char __user *buf,
static unsigned int dvb_audio_poll(struct file *file, poll_table *wait) static unsigned int dvb_audio_poll(struct file *file, poll_table *wait)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
unsigned int mask = 0; unsigned int mask = 0;
dprintk(2, "av7110:%p, \n", av7110); dprintk(2, "av7110:%p, \n", av7110);
...@@ -944,8 +944,8 @@ static unsigned int dvb_audio_poll(struct file *file, poll_table *wait) ...@@ -944,8 +944,8 @@ static unsigned int dvb_audio_poll(struct file *file, poll_table *wait)
static ssize_t dvb_audio_write(struct file *file, const char __user *buf, static ssize_t dvb_audio_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
dprintk(2, "av7110:%p, \n", av7110); dprintk(2, "av7110:%p, \n", av7110);
...@@ -989,8 +989,8 @@ static int play_iframe(struct av7110 *av7110, u8 __user *buf, unsigned int len, ...@@ -989,8 +989,8 @@ static int play_iframe(struct av7110 *av7110, u8 __user *buf, unsigned int len,
static int dvb_video_ioctl(struct inode *inode, struct file *file, static int dvb_video_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg) unsigned int cmd, void *parg)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
unsigned long arg = (unsigned long) parg; unsigned long arg = (unsigned long) parg;
int ret = 0; int ret = 0;
...@@ -1203,8 +1203,8 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, ...@@ -1203,8 +1203,8 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file,
static int dvb_audio_ioctl(struct inode *inode, struct file *file, static int dvb_audio_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg) unsigned int cmd, void *parg)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
unsigned long arg = (unsigned long) parg; unsigned long arg = (unsigned long) parg;
int ret = 0; int ret = 0;
...@@ -1349,8 +1349,8 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, ...@@ -1349,8 +1349,8 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file,
static int dvb_video_open(struct inode *inode, struct file *file) static int dvb_video_open(struct inode *inode, struct file *file)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
int err; int err;
dprintk(2, "av7110:%p, \n", av7110); dprintk(2, "av7110:%p, \n", av7110);
...@@ -1374,8 +1374,8 @@ static int dvb_video_open(struct inode *inode, struct file *file) ...@@ -1374,8 +1374,8 @@ static int dvb_video_open(struct inode *inode, struct file *file)
static int dvb_video_release(struct inode *inode, struct file *file) static int dvb_video_release(struct inode *inode, struct file *file)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
dprintk(2, "av7110:%p, \n", av7110); dprintk(2, "av7110:%p, \n", av7110);
...@@ -1388,9 +1388,9 @@ static int dvb_video_release(struct inode *inode, struct file *file) ...@@ -1388,9 +1388,9 @@ static int dvb_video_release(struct inode *inode, struct file *file)
static int dvb_audio_open(struct inode *inode, struct file *file) static int dvb_audio_open(struct inode *inode, struct file *file)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
int err=dvb_generic_open(inode, file); int err = dvb_generic_open(inode, file);
dprintk(2, "av7110:%p, \n", av7110); dprintk(2, "av7110:%p, \n", av7110);
...@@ -1403,8 +1403,8 @@ static int dvb_audio_open(struct inode *inode, struct file *file) ...@@ -1403,8 +1403,8 @@ static int dvb_audio_open(struct inode *inode, struct file *file)
static int dvb_audio_release(struct inode *inode, struct file *file) static int dvb_audio_release(struct inode *inode, struct file *file)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
dprintk(2, "av7110:%p, \n", av7110); dprintk(2, "av7110:%p, \n", av7110);
......
...@@ -214,8 +214,8 @@ static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file, ...@@ -214,8 +214,8 @@ static ssize_t ci_ll_read(struct dvb_ringbuffer *cibuf, struct file *file,
static int dvb_ca_open(struct inode *inode, struct file *file) static int dvb_ca_open(struct inode *inode, struct file *file)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
int err = dvb_generic_open(inode, file); int err = dvb_generic_open(inode, file);
dprintk(8, "av7110:%p\n",av7110); dprintk(8, "av7110:%p\n",av7110);
...@@ -228,8 +228,8 @@ static int dvb_ca_open(struct inode *inode, struct file *file) ...@@ -228,8 +228,8 @@ static int dvb_ca_open(struct inode *inode, struct file *file)
static unsigned int dvb_ca_poll (struct file *file, poll_table *wait) static unsigned int dvb_ca_poll (struct file *file, poll_table *wait)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
struct dvb_ringbuffer *rbuf = &av7110->ci_rbuffer; struct dvb_ringbuffer *rbuf = &av7110->ci_rbuffer;
struct dvb_ringbuffer *wbuf = &av7110->ci_wbuffer; struct dvb_ringbuffer *wbuf = &av7110->ci_wbuffer;
unsigned int mask = 0; unsigned int mask = 0;
...@@ -251,8 +251,8 @@ static unsigned int dvb_ca_poll (struct file *file, poll_table *wait) ...@@ -251,8 +251,8 @@ static unsigned int dvb_ca_poll (struct file *file, poll_table *wait)
static int dvb_ca_ioctl(struct inode *inode, struct file *file, static int dvb_ca_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, void *parg) unsigned int cmd, void *parg)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
unsigned long arg = (unsigned long) parg; unsigned long arg = (unsigned long) parg;
dprintk(8, "av7110:%p\n",av7110); dprintk(8, "av7110:%p\n",av7110);
...@@ -329,8 +329,8 @@ static int dvb_ca_ioctl(struct inode *inode, struct file *file, ...@@ -329,8 +329,8 @@ static int dvb_ca_ioctl(struct inode *inode, struct file *file,
static ssize_t dvb_ca_write(struct file *file, const char __user *buf, static ssize_t dvb_ca_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
dprintk(8, "av7110:%p\n",av7110); dprintk(8, "av7110:%p\n",av7110);
return ci_ll_write(&av7110->ci_wbuffer, file, buf, count, ppos); return ci_ll_write(&av7110->ci_wbuffer, file, buf, count, ppos);
...@@ -339,15 +339,13 @@ static ssize_t dvb_ca_write(struct file *file, const char __user *buf, ...@@ -339,15 +339,13 @@ static ssize_t dvb_ca_write(struct file *file, const char __user *buf,
static ssize_t dvb_ca_read(struct file *file, char __user *buf, static ssize_t dvb_ca_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; struct dvb_device *dvbdev = file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv; struct av7110 *av7110 = dvbdev->priv;
dprintk(8, "av7110:%p\n",av7110); dprintk(8, "av7110:%p\n",av7110);
return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos); return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos);
} }
static struct file_operations dvb_ca_fops = { static struct file_operations dvb_ca_fops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.read = dvb_ca_read, .read = dvb_ca_read,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/kernel.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include "av7110.h" #include "av7110.h"
...@@ -16,6 +17,7 @@ ...@@ -16,6 +17,7 @@
static int av_cnt; static int av_cnt;
static struct av7110 *av_list[4]; static struct av7110 *av_list[4];
static struct input_dev *input_dev; static struct input_dev *input_dev;
static char input_phys[32];
static u8 delay_timer_finished; static u8 delay_timer_finished;
...@@ -217,7 +219,7 @@ int __devinit av7110_ir_init(struct av7110 *av7110) ...@@ -217,7 +219,7 @@ int __devinit av7110_ir_init(struct av7110 *av7110)
static struct proc_dir_entry *e; static struct proc_dir_entry *e;
int err; int err;
if (av_cnt >= sizeof av_list/sizeof av_list[0]) if (av_cnt >= ARRAY_SIZE(av_list))
return -ENOSPC; return -ENOSPC;
av7110_setup_irc_config(av7110, 0x0001); av7110_setup_irc_config(av7110, 0x0001);
...@@ -231,8 +233,22 @@ int __devinit av7110_ir_init(struct av7110 *av7110) ...@@ -231,8 +233,22 @@ int __devinit av7110_ir_init(struct av7110 *av7110)
if (!input_dev) if (!input_dev)
return -ENOMEM; return -ENOMEM;
snprintf(input_phys, sizeof(input_phys),
"pci-%s/ir0", pci_name(av7110->dev->pci));
input_dev->name = "DVB on-card IR receiver"; input_dev->name = "DVB on-card IR receiver";
input_dev->phys = input_phys;
input_dev->id.bustype = BUS_PCI;
input_dev->id.version = 1;
if (av7110->dev->pci->subsystem_vendor) {
input_dev->id.vendor = av7110->dev->pci->subsystem_vendor;
input_dev->id.product = av7110->dev->pci->subsystem_device;
} else {
input_dev->id.vendor = av7110->dev->pci->vendor;
input_dev->id.product = av7110->dev->pci->device;
}
input_dev->cdev.dev = &av7110->dev->pci->dev;
set_bit(EV_KEY, input_dev->evbit); set_bit(EV_KEY, input_dev->evbit);
set_bit(EV_REP, input_dev->evbit); set_bit(EV_REP, input_dev->evbit);
input_register_keys(); input_register_keys();
......
...@@ -140,17 +140,6 @@ static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data) ...@@ -140,17 +140,6 @@ static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
return 0; return 0;
} }
static int stv0297_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
{
u8 buf [] = { reg, data };
struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 2 };
if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
return -1;
return 0;
}
static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4]) static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
{ {
struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 }; struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
...@@ -193,6 +182,7 @@ static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq) ...@@ -193,6 +182,7 @@ static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq)
static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq) static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq)
{ {
struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
u32 div; u32 div;
u8 data[4]; u8 data[4];
...@@ -213,8 +203,8 @@ static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq) ...@@ -213,8 +203,8 @@ static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq)
else else
return -EINVAL; return -EINVAL;
stv0297_writereg(dev, 0x1C, 0x87, 0x78); if (av7110->fe->ops.i2c_gate_ctrl)
stv0297_writereg(dev, 0x1C, 0x86, 0xc8); av7110->fe->ops.i2c_gate_ctrl(av7110->fe, 1);
return tuner_write(dev, 0x63, data); return tuner_write(dev, 0x63, data);
} }
...@@ -817,20 +807,20 @@ int av7110_init_v4l(struct av7110 *av7110) ...@@ -817,20 +807,20 @@ int av7110_init_v4l(struct av7110 *av7110)
saa7146_vv_release(dev); saa7146_vv_release(dev);
return -ENODEV; return -ENODEV;
} }
if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) { if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI))
ERR(("cannot register vbi v4l2 device. skipping.\n")); ERR(("cannot register vbi v4l2 device. skipping.\n"));
} else {
if (av7110->analog_tuner_flags)
av7110->analog_tuner_flags |= ANALOG_TUNER_VBI;
}
return 0; return 0;
} }
int av7110_exit_v4l(struct av7110 *av7110) int av7110_exit_v4l(struct av7110 *av7110)
{ {
struct saa7146_dev* dev = av7110->dev;
saa7146_unregister_device(&av7110->v4l_dev, av7110->dev); saa7146_unregister_device(&av7110->v4l_dev, av7110->dev);
if (av7110->analog_tuner_flags & ANALOG_TUNER_VBI) saa7146_unregister_device(&av7110->vbi_dev, av7110->dev);
saa7146_unregister_device(&av7110->vbi_dev, av7110->dev);
saa7146_vv_release(dev);
return 0; return 0;
} }
......
...@@ -1089,6 +1089,8 @@ static int budget_av_detach(struct saa7146_dev *dev) ...@@ -1089,6 +1089,8 @@ static int budget_av_detach(struct saa7146_dev *dev)
msleep(200); msleep(200);
saa7146_unregister_device(&budget_av->vd, dev); saa7146_unregister_device(&budget_av->vd, dev);
saa7146_vv_release(dev);
} }
if (budget_av->budget.ci_present) if (budget_av->budget.ci_present)
...@@ -1145,6 +1147,7 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio ...@@ -1145,6 +1147,7 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) { if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
/* fixme: proper cleanup here */ /* fixme: proper cleanup here */
ERR(("cannot register capture v4l2 device.\n")); ERR(("cannot register capture v4l2 device.\n"));
saa7146_vv_release(dev);
return err; return err;
} }
......
This diff is collapsed.
...@@ -20,8 +20,6 @@ ...@@ -20,8 +20,6 @@
* *
*/ */
#include <linux/mutex.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
...@@ -35,6 +33,8 @@ ...@@ -35,6 +33,8 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/mutex.h>
#include "dmxdev.h" #include "dmxdev.h"
#include "dvb_demux.h" #include "dvb_demux.h"
#include "dvb_filter.h" #include "dvb_filter.h"
......
This diff is collapsed.
...@@ -89,14 +89,6 @@ static struct v4l2_queryctrl radio_qctrl[] = { ...@@ -89,14 +89,6 @@ static struct v4l2_queryctrl radio_qctrl[] = {
#define GEMTEK_PCI_RANGE_HIGH (108*16000) #define GEMTEK_PCI_RANGE_HIGH (108*16000)
#endif #endif
#ifndef TRUE
#define TRUE (1)
#endif
#ifndef FALSE
#define FALSE (0)
#endif
struct gemtek_pci_card { struct gemtek_pci_card {
struct video_device *videodev; struct video_device *videodev;
...@@ -146,12 +138,12 @@ static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep ) ...@@ -146,12 +138,12 @@ static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep )
static inline void gemtek_pci_nil( u32 port, u8 *last_byte ) static inline void gemtek_pci_nil( u32 port, u8 *last_byte )
{ {
__gemtek_pci_cmd( 0x00, port, last_byte, FALSE ); __gemtek_pci_cmd( 0x00, port, last_byte, false );
} }
static inline void gemtek_pci_cmd( u16 cmd, u32 port, u8 *last_byte ) static inline void gemtek_pci_cmd( u16 cmd, u32 port, u8 *last_byte )
{ {
__gemtek_pci_cmd( cmd, port, last_byte, TRUE ); __gemtek_pci_cmd( cmd, port, last_byte, true );
} }
static void gemtek_pci_setfrequency( struct gemtek_pci_card *card, unsigned long frequency ) static void gemtek_pci_setfrequency( struct gemtek_pci_card *card, unsigned long frequency )
...@@ -184,14 +176,14 @@ static void gemtek_pci_setfrequency( struct gemtek_pci_card *card, unsigned long ...@@ -184,14 +176,14 @@ static void gemtek_pci_setfrequency( struct gemtek_pci_card *card, unsigned long
static inline void gemtek_pci_mute( struct gemtek_pci_card *card ) static inline void gemtek_pci_mute( struct gemtek_pci_card *card )
{ {
outb( 0x1f, card->iobase ); outb( 0x1f, card->iobase );
card->mute = TRUE; card->mute = true;
} }
static inline void gemtek_pci_unmute( struct gemtek_pci_card *card ) static inline void gemtek_pci_unmute( struct gemtek_pci_card *card )
{ {
if ( card->mute ) { if ( card->mute ) {
gemtek_pci_setfrequency( card, card->current_frequency ); gemtek_pci_setfrequency( card, card->current_frequency );
card->mute = FALSE; card->mute = false;
} }
} }
...@@ -259,7 +251,7 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file, ...@@ -259,7 +251,7 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file,
gemtek_pci_setfrequency( card, f->frequency ); gemtek_pci_setfrequency( card, f->frequency );
card->current_frequency = f->frequency; card->current_frequency = f->frequency;
card->mute = FALSE; card->mute = false;
return 0; return 0;
} }
case VIDIOC_QUERYCTRL: case VIDIOC_QUERYCTRL:
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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