Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[linux-dvb] Progess on VP-1020
I have been working on getting my FTA satellite receiver card
working under Linux.
I thought I'd report my progress here, in case I'm wasting my time.
If I get distracted and give up, at least someone else will have
this information.
The card is marketed under different labels, mine is a VVmer TV@Sat
card, but I believe it to be the same as a VisionPlus VP-1020
and a Twinhan. The BTTV card list has it as:
DST Card/DST-IP (bt878, twinhan asic) VP-1020
Sold as:
KWorld DVBS Satellite TV-Card
Powercolor DSTV Satellite Tuner Card
Prolink Pixelview DTV2000
Provideo PV-911 Digital Satellite TV Tuner Card With Common Interface ?
DST-CI Card (DVB Satellite) VP-1030
DCT Card (DVB cable)
There is a linux binary only module. Some people have accused it of
GPL violation, but more of this later.
The card consists of a BT848 (or connexant equiv), an alps_b2srv tuner
and an asic. In respect of it's use of the CX/BT chip
it is similar to the Pinnacle PCTVSAT.
1. bttv driver.
The normal bttv driver hangs and the whole system locks up on detecting
the bt848 chip. Most unLinuxy :(
The PCI id is all zeroes. On tracking down where the hangs occur, it
is in most areas to do with video capture initialisation.
The BT chip is not used for video capture on this card.
In order to prevent lockups, I changed my version of the bttv
driver to have the unknown device have zero video inputs, and
changed the core driver not to do any capture / video initialisation
if video inputs count is zero.
I'm not sure what the right solution is here, because so little
of the bttv driver is actually used.
2. i2c level
The i2c is also slightly different in that gpio pin 0 has to be
driven low for i2c signals to go out. After I2c transfer,
this pin is left not output enabled. I2c is not done to the tuner
but to the asic at addresses aa and ab. Data is sent in small packets,
comprising part of the alps tuner dividers and part qpsk codes,
and part bits for 13/18 V and 22Khz tone. At this stage
I presume the asic sends this data out to relevant parts of the board.
3. The kernel module.
This module is a fairly transparent elf module. Some people have
suggested it is in breach of the GPL because it includes bt848 routines.
From what I can see the bt848 routines are actually derived from
the initial linux port of the BSD drivers, which were still (at that
stage) under BSD copyright.
It has also been suggested that the card manufacturer should provide
more doco / pay for the port etc. This would be good, but unfortunately
I have a card and so do other people and I really want it to work.
I'm annoyed they advertise it works under Linux, when the support
is not whole-hearted. Still ...
However, the kernel module is almost as good as a written specification,
in fact better in some ways as it has to be correct :)
The module is very simplistic, and works in conjunction with a
more sophisticated user-level module.
The kernel module provides the following psuedo-coded ioctls:
dst_ioctl(bktr_ptr_t bktr, int cmd, caddr_t arg)
{
PROGRAM_VALUE pval;
DMA_BUFFER_INFO dma_info;
unsigned char V0[8];
unsigned V8[2];
switch (cmd) {
case TUNER_SETTUNER:
eax = get_ioctl_bytes(&pval, arg, sizeof(pval));
if (eax != 0)
return eax;
if (pval->frequency >= *(bktr + 0x44)
&& pval->frequency <= *(bktr + 0x48)) {
return -EPERM;
}
return ((card_version == 1) ?
new8820_setTunerProgram(bktr, &pval) :
setTunerProgram(bktr, &pval));
case DST_GET_BUFFER_INFO:
get_dmaBufferInfo(bktr, &dma_info);
return put_ioctl_bytes(arg, &dma_info,
sizeof(dma_info));
case TUNER_GETTUNER:
getTunerProgram(bktr, &pval);
return put_ioctl_bytes(arg, &pval, 0x40);
case DST_GET_REPLY:
dstCommandReply(bktr, V0);
return put_ioctl_bytes(arg, V0, 8);
case IN_20:
if (ca_status != 1) {
return 0;
}
return put_ioctl_bytes(arg, ca_input, 0x102, edx);
case DST_START_CAPTURE:
start_capture(bktr);
return 0;
case TUNER_STOP:
return stop_tuner(bktr);
case DST_INIT:
eax = get_ioctl_bytes(V8, arg, 8);
if (eax != 0)
return eax;
if (V8[0] < V8[1]) {
*(bktr + 0x44) = V8[0];
*(bktr + 0x48) = V8[1];
} else {
*(bktr + 0x44) = V8[1];
*(bktr + 0x48) = V8[0];
}
return 0;
case DST_PUT_COMMAND:
eax = get_ioctl_bytes(V0, arg, 8);
if (eax != 0)
return eax;
return dstPutCommand(bktr, V0);
case OUT_21:
eax = get_ioctl_bytes(ca_output, arg, 0x102);
if (eax != 0)
return eax;
return put8820CiMSG(bktr, ca_output);
}
}
return 0;
}
This means there may be more important info in the user level
driver. Or not ...
4. The packets to the asic.
The asic is determined to be new or old.
The packet
6 | 0 | 0 | 0 | 0 | 0 | 0xfa
is sent to the asic (aa).
If a certain reply (yet to be determined) comes back it is 'new'.
For old devices, packets seem to be fixed length along the lines of
alps-freq-div1 | alps-freq-div2 | alps-freq-div3 |
symbol-rate1 | symbol-rate2 | symbol-rate3 |
bits | checksum
where bits:
0..2 = 1 for 22Khz, 0 off
5 = 1 for symbol rate > 8000
6 = 1 for 13 / 18 V
7 = 1 some meaning
For new devices, the first byte appears to be a length indicator
then following bytes the same as old.
The method works by sending the packet to aa, (actually in the code
the address is put in the first byte of the buffer and handled
as an address by the sending routine)
Then the address ab is read a single byte as response with
i2c settings BT848_I2C_SDA|BT848_I2C_SCL.
To read the current tuner packet, eight bytes are read from ab
with BT848_I2C_SDA|BT848_I2C_SCL|BT848_I2C_W3B, then the
final byte with BT848_I2C_SDA|BT848_I2C_SCL.
There may also be an 8820 device, which I suspect is some kind of
ca device.
It is reset in error conditions by pulling GPIO bit 2
low, waiting, then releasing back to high.
That's it for now.
Jamie
jhonan /at/ optushome.com.au
--
Info:
To unsubscribe send a mail to ecartis@linuxtv.org with "unsubscribe linux-dvb" as subject.
Home |
Main Index |
Thread Index