| From: |
| Hans Verkuil <hverkuil@xs4all.nl> |
| To: |
| linux-media@vger.kernel.org |
| Subject: |
| RFC: Finalizing the V4L2 RDS interface |
| Date: |
| Fri, 13 Feb 2009 09:55:19 +0100 |
| Message-ID: |
| <200902130955.19995.hverkuil@xs4all.nl> |
| Cc: |
| Michael Schimek <mschimek@gmx.at>,
Mauro Carvalho Chehab <mchehab@infradead.org>,
hjkoch@users.berlios.de, tobias.lorenz@gmx.net,
belavenuto@gmail.com |
| Archive‑link: | |
Article |
RFC: Completing the V4L2 RDS API
================================
Introduction
------------
There are several drivers that implement RDS support: bttv (through
saa6588), radio-si470x and radio-cadet. radio-tea5764 wants to support this
in the future as well.
The saa6588 is used in different cards, but is currently only enabled in
bttv, but I have it working with a saa7134 as well.
I expect this to become more important with the increased use of linux and
v4l2 in embedded devices. What is holding it back at the moment is the fact
that this interface has not been defined properly. It's 90% there, but it
is poorly documented and is still not officially part of V4L2.
This RFC is intended to fill in the final gaps and make it official.
Current API
-----------
The V4L2 spec says this about the RDS Interface:
4.11. RDS Interface
The Radio Data System transmits supplementary information in binary format,
for example the station name or travel information, on a inaudible audio
subcarrier of a radio program. This interface aims at devices capable of
receiving and decoding RDS information.
The V4L API defines its RDS API as follows.
From radio devices supporting it, RDS data can be read with the read()
function. The data is packed in groups of three, as follows:
First Octet: Least Significant Byte of RDS Block
Second Octet: Most Significant Byte of RDS Block
Third Octet:
Bit 7: Error bit. Indicates that an uncorrectable error occurred
during reception of this block.
Bit 6: Corrected bit. Indicates that an error was corrected for
this data block.
Bits 5-3: Received Offset. Indicates the offset received by the
sync system.
Bits 2-0: Offset Name. Indicates the offset applied to this data.
It was argued the RDS API should be extended before integration into V4L2,
no new API has been devised yet. Please write to the linux-media mailing
list for discussion: http://www.linuxtv.org/lists.php. Meanwhile no V4L2
driver should set the V4L2_CAP_RDS_CAPTURE capability flag.
Problems with this API
----------------------
As I said before, it is 90% complete, there are just a few things missing.
The Offset Name refers to six possible offsets as defined by the RDS and
RBDS standard (that is the US variant of RDS). Possible offsets are: A, B,
C, C', D and E (RBDS specific).
The mapping of the values 0-7 to offsets is as follows:
0: A
1: B
2: C
3: D
4: C'
5: E (RBDS specific)
6: invalid block E (RDS mode)
7: invalid block
This mapping comes from the saa6588 RDS decoder, but it makes sense and I
see no reason to change this. As long as we document it and add a public
RDS header with this information. The original mapping was from the
radio-cadet.c driver. Unfortunately, it was never documented and I cannot
find any details on what the mapping between number and offset code looks
like. Since the cadet is an ISA card I am not too worried about this and
I'm following the newer devices.
After a lot of googling I found this ancient radio-cadet posting:
http://lkml.indiana.edu/hypermail/linux/kernel/9904.0/060...
This finally explained what the difference between the Received Offset and
the Offset Name is:
"Bits 5-3: Received Offset. Indicates the block offset received by the
decoder hardware (used to determine the location of the block in a RDS
group).
Bits 2-0: Offset Name. Indicates the block offset applied by the decoder.
(In some cases, the hardware may try to second-guess the received values to
try to overcome poor reception conditions)."
Currently all other RDS implementations just make a copy of bits 2-0 and the
rdsd daemon (http://rdsd.berlios.de/) uses only bits 2-0.
I would like to change the definition of these bits, setting bits 5-3 to 0.
This way we have three bits available for future enhancements. I see no
advantage in having two offsets. Just pick the one the decoder gives you.
Another problem is that there is no good method of selecting RDS vs RBDS, or
checking which of these two (or both) are available.
I propose to use the v4l2_tuner struct for this. It is an obvious match
since the ability to read RDS is tuner related (no tuner, no RDS :-) ).
The v4l2_tuner capability field needs two additional caps:
V4L2_TUNER_CAP_RDS
V4L2_TUNER_CAP_RBDS
And we can add support to select RDS/RDBS by using one of the reserved
fields:
__u8 rds_type;
__u8 rds_signal; /* RDS signal strength quality, 0-255 */
__u8 rds_reserved[2];
__u32 reserved[3];
And rds_type is:
V4L2_TUNER_RDS_TYPE_RDS 0x00
V4L2_TUNER_RDS_TYPE_RBDS 0x01
We can also add new subband flags V4L2_TUNER_SUB_RDS and V4L2_TUNER_SUB_RBSD
so we can report if RDS/RBDS is present.
I do not think there is any need to introduce an additional
V4L2_CAP_RDS_CAPTURE capability, since it is taken care of in v4l2_tuner.
Finally I would prefer to have the requirement that the driver will buffer
at least 10 seconds worth of data (comes to 1200 bytes). Or perhaps we
should add a field that reports the maximum number of buffered packets?
E.g. __u16 rds_buf_size. This might be more generic and you can even allow
this to be set with VIDIOC_S_TUNER (although drivers can ignore it).
With these small changes I think the RDS API is pretty complete and can
become an official V4L2 API.
Comments?
Hans Verkuil
--
Hans Verkuil - video4linux developer - sponsored by TANDBERG
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html