mirror of
https://github.com/DigitalDevices/dddvb.git
synced 2025-03-01 10:35:23 +00:00
Compare commits
51 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
ce99c601f8 | ||
|
43ab548777 | ||
|
2808cf0d50 | ||
|
186ba6d414 | ||
|
f570b2e071 | ||
|
32f46389be | ||
|
4b68bcad91 | ||
|
1ad4dfacd1 | ||
|
f7772c7a88 | ||
|
6219e19ece | ||
|
192a4ad20d | ||
|
e13cec82e4 | ||
|
d13416157c | ||
|
755f502602 | ||
|
a05d1852a3 | ||
|
1e15f5474d | ||
|
9c1fc648dc | ||
|
2e5056c4a1 | ||
|
1b89edb4b1 | ||
|
875a768266 | ||
|
09c068c74c | ||
|
c471123f17 | ||
|
8dbd33fd82 | ||
|
a978e9455f | ||
|
9d8c7d4a63 | ||
|
81ed8fed9d | ||
|
f24a329f2f | ||
|
5d7f4fcbe8 | ||
|
6243397d99 | ||
|
5b86ac7627 | ||
|
c831ccfc9e | ||
|
cad161f939 | ||
|
67257ce132 | ||
|
bdea58c1b2 | ||
|
29eda9be8e | ||
|
2c3c9bdf08 | ||
|
2693c181bc | ||
|
53464162de | ||
|
8cbb835de0 | ||
|
d0f7b9be1f | ||
|
6b0feea253 | ||
|
bed4be534a | ||
|
1d7d8bc413 | ||
|
70778b818e | ||
|
e0fdedbef3 | ||
|
9acbf467ec | ||
|
3db30defab | ||
|
5bf9edba06 | ||
|
8f0365e36a | ||
|
08a161ba04 | ||
|
efbc108939 |
339
COPYING.GPLv2
Normal file
339
COPYING.GPLv2
Normal file
@@ -0,0 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
3
Makefile
3
Makefile
@@ -2,7 +2,8 @@ kernelver ?= $(shell uname -r)
|
||||
KDIR ?= /lib/modules/$(kernelver)/build
|
||||
PWD := $(shell pwd)
|
||||
|
||||
MODDEFS := CONFIG_DVB_CORE=m CONFIG_DVB_DDBRIDGE=m CONFIG_DVB_DRXK=m CONFIG_DVB_TDA18271C2DD=m CONFIG_DVB_CXD2099=m CONFIG_DVB_LNBP21=m CONFIG_DVB_STV090x=m CONFIG_DVB_STV6110x=m CONFIG_DVB_STV0367=m CONFIG_DVB_TDA18212=m CONFIG_DVB_STV0367DD=m CONFIG_DVB_TDA18212DD=m CONFIG_DVB_OCTONET=m CONFIG_DVB_CXD2843=m CONFIG_DVB_STV0910=m CONFIG_DVB_STV6111=m CONFIG_DVB_LNBH25=m CONFIG_DVB_MXL5XX=m
|
||||
MODDEFS := CONFIG_DVB_CORE=m CONFIG_DVB_DDBRIDGE=m CONFIG_DVB_DRXK=m CONFIG_DVB_TDA18271C2DD=m CONFIG_DVB_CXD2099=m CONFIG_DVB_LNBP21=m CONFIG_DVB_STV090x=m CONFIG_DVB_STV6110x=m CONFIG_DVB_STV0367=m CONFIG_DVB_TDA18212=m CONFIG_DVB_STV0367DD=m CONFIG_DVB_TDA18212DD=m CONFIG_DVB_OCTONET=m CONFIG_DVB_CXD2843=m CONFIG_DVB_STV0910=m CONFIG_DVB_STV6111=m CONFIG_DVB_LNBH25=m CONFIG_DVB_MXL5XX=m CONFIG_DVB_NET=m
|
||||
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $(MODDEFS) modules
|
||||
|
@@ -15,14 +15,6 @@ setmod2: setmod2.c
|
||||
setmod3: setmod3.c
|
||||
$(CC) -o setmod3 setmod3.c -I../include/
|
||||
|
||||
flashprog: flashprog.c
|
||||
$(CC) -o flashprog flashprog.c
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
||||
|
||||
ddtest: ddtest.c
|
||||
$(CC) -o ddtest ddtest.c
|
||||
|
||||
ddflash: ddflash.c
|
||||
$(CC) -o ddflash ddflash.c
|
||||
|
||||
pls: pls.c
|
||||
$(CC) -o pls pls.c
|
||||
|
@@ -233,6 +233,10 @@ int main(int argc, char **argv)
|
||||
fname="DVBBridgeV2A_DD01_0009_SX8.fpga";
|
||||
printf("Octopus MAXSX8\n");
|
||||
break;
|
||||
case 0x000a:
|
||||
fname="DVBBridgeV2A_DD01_000A_M4.fpga";
|
||||
printf("Octopus MAXSX8\n");
|
||||
break;
|
||||
case 0x0011:
|
||||
fname="CIBridgeV1B_CIBridgeV1B.fpga";
|
||||
printf("Octopus CI\n");
|
||||
|
@@ -659,6 +659,13 @@ static int update_flash(struct ddflash *ddf)
|
||||
stat |= 1;
|
||||
return stat;
|
||||
break;
|
||||
case 0x322:
|
||||
//fname="/boot/DVBNetV1A_DD01_0300.bit";
|
||||
fname="/boot/fpga.img";
|
||||
if ((res = update_image(ddf, fname, 0x10000, 0x100000, 1, 0)) == 1)
|
||||
stat |= 1;
|
||||
return stat;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@@ -722,9 +722,10 @@ int mdio(int dev, int argc, char* argv[], uint32_t Flags)
|
||||
adr = strtoul(argv[0], NULL, 16);
|
||||
reg = strtoul(argv[1], NULL, 16);
|
||||
|
||||
#if 0
|
||||
writereg(dev, 0x24, adr);
|
||||
writereg(dev, 0x28, reg);
|
||||
if(argc > 2) {
|
||||
if (argc > 2) {
|
||||
val = strtoul(argv[2], NULL, 16);
|
||||
writereg(dev, 0x2c, val);
|
||||
writereg(dev, 0x20, 0x03);
|
||||
@@ -739,6 +740,23 @@ int mdio(int dev, int argc, char* argv[], uint32_t Flags)
|
||||
readreg(dev, 0x2c, &val);
|
||||
printf("%04x\n", val);
|
||||
}
|
||||
#else
|
||||
{
|
||||
struct ddb_mdio mdio = {
|
||||
.adr = adr,
|
||||
.reg = reg,
|
||||
};
|
||||
|
||||
if(argc > 2) {
|
||||
mdio.val = strtoul(argv[2], NULL, 16);
|
||||
return ioctl(dev, IOCTL_DDB_WRITE_MDIO, &mdio);
|
||||
} else {
|
||||
if (ioctl(dev, IOCTL_DDB_READ_MDIO, &mdio) < 0)
|
||||
return -1;
|
||||
printf("%04x\n", mdio.val);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_CXD2843 -DCONFIG_DVB_LNBP21 -DCONFIG_DVB_STV090x -DCONFIG_DVB_STV6110x -DCONFIG_DVB_DRXK -DCONFIG_DVB_STV0910 -DCONFIG_DVB_STV6111 -DCONFIG_DVB_LNBH25 -DCONFIG_DVB_MXL5XX -DCONFIG_DVB_CXD2099
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_CXD2843 -DCONFIG_DVB_LNBP21 -DCONFIG_DVB_STV090x -DCONFIG_DVB_STV6110x -DCONFIG_DVB_DRXK -DCONFIG_DVB_STV0910 -DCONFIG_DVB_STV6111 -DCONFIG_DVB_LNBH25 -DCONFIG_DVB_MXL5XX -DCONFIG_DVB_CXD2099 -DCONFIG_DVB_NET
|
||||
|
||||
ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o ddbridge-ci.o ddbridge-max.o ddbridge-mci.o
|
||||
octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o ddbridge-ci.o ddbridge-max.o ddbridge-mci.o
|
||||
ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o ddbridge-ci.o ddbridge-max.o ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o
|
||||
octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o ddbridge-ci.o ddbridge-max.o ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o
|
||||
|
||||
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
|
||||
obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
||||
|
@@ -2,8 +2,8 @@
|
||||
# Makefile for the ddbridge device driver
|
||||
#
|
||||
|
||||
ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-ci.o ddbridge-max.o ddbridge-mci.o
|
||||
octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-ci.o ddbridge-max.o ddbridge-mci.o
|
||||
ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-ci.o ddbridge-max.o ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o
|
||||
octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-ci.o ddbridge-max.o ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o
|
||||
|
||||
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
|
||||
obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
||||
|
@@ -2,8 +2,8 @@
|
||||
# Makefile for the ddbridge device driver
|
||||
#
|
||||
|
||||
ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o ddbridge-ci.o ddbridge-max.o ddbridge-mci.o
|
||||
octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o ddbridge-ci.o ddbridge-max.o ddbridge-mci.o
|
||||
ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o ddbridge-ci.o ddbridge-max.o ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o
|
||||
octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o ddbridge-ci.o ddbridge-max.o ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o
|
||||
|
||||
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
|
||||
obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
||||
|
@@ -26,7 +26,6 @@
|
||||
#include "ddbridge-i2c.h"
|
||||
#include "ddbridge-io.h"
|
||||
#include "dvb_net.h"
|
||||
#include "ddbridge-mci.h"
|
||||
|
||||
struct workqueue_struct *ddb_wq;
|
||||
|
||||
@@ -450,13 +449,12 @@ static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags)
|
||||
*con2 = (nco << 16) | gap;
|
||||
}
|
||||
|
||||
static void ddb_output_start(struct ddb_output *output)
|
||||
static void ddb_output_start_unlocked(struct ddb_output *output)
|
||||
{
|
||||
struct ddb *dev = output->port->dev;
|
||||
u32 con = 0x11c, con2 = 0;
|
||||
|
||||
if (output->dma) {
|
||||
spin_lock_irq(&output->dma->lock);
|
||||
output->dma->cbuf = 0;
|
||||
output->dma->coff = 0;
|
||||
output->dma->stat = 0;
|
||||
@@ -486,16 +484,24 @@ static void ddb_output_start(struct ddb_output *output)
|
||||
ddbwritel(dev, con | 1, TS_CONTROL(output));
|
||||
if (output->dma) {
|
||||
output->dma->running = 1;
|
||||
spin_unlock_irq(&output->dma->lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void ddb_output_stop(struct ddb_output *output)
|
||||
static void ddb_output_start(struct ddb_output *output)
|
||||
{
|
||||
if (output->dma) {
|
||||
spin_lock_irq(&output->dma->lock);
|
||||
ddb_output_start_unlocked(output);
|
||||
spin_unlock_irq(&output->dma->lock);
|
||||
} else {
|
||||
ddb_output_start_unlocked(output);
|
||||
}
|
||||
}
|
||||
|
||||
static void ddb_output_stop_unlocked(struct ddb_output *output)
|
||||
{
|
||||
struct ddb *dev = output->port->dev;
|
||||
|
||||
if (output->dma)
|
||||
spin_lock_irq(&output->dma->lock);
|
||||
if (output->port->class == DDB_PORT_MOD)
|
||||
ddbridge_mod_output_stop(output);
|
||||
else
|
||||
@@ -503,34 +509,49 @@ static void ddb_output_stop(struct ddb_output *output)
|
||||
if (output->dma) {
|
||||
ddbwritel(dev, 0, DMA_BUFFER_CONTROL(output->dma));
|
||||
output->dma->running = 0;
|
||||
spin_unlock_irq(&output->dma->lock);
|
||||
}
|
||||
}
|
||||
|
||||
static void ddb_input_stop(struct ddb_input *input)
|
||||
static void ddb_output_stop(struct ddb_output *output)
|
||||
{
|
||||
if (output->dma) {
|
||||
spin_lock_irq(&output->dma->lock);
|
||||
ddb_output_stop_unlocked(output);
|
||||
spin_unlock_irq(&output->dma->lock);
|
||||
} else {
|
||||
ddb_output_stop_unlocked(output);
|
||||
}
|
||||
}
|
||||
|
||||
static void ddb_input_stop_unlocked(struct ddb_input *input)
|
||||
{
|
||||
struct ddb *dev = input->port->dev;
|
||||
u32 tag = DDB_LINK_TAG(input->port->lnr);
|
||||
|
||||
if (input->dma)
|
||||
spin_lock_irq(&input->dma->lock);
|
||||
ddbwritel(dev, 0, tag | TS_CONTROL(input));
|
||||
if (input->dma) {
|
||||
ddbwritel(dev, 0, DMA_BUFFER_CONTROL(input->dma));
|
||||
input->dma->running = 0;
|
||||
spin_unlock_irq(&input->dma->lock);
|
||||
}
|
||||
/*printk("input_stop %u.%u.%u\n",
|
||||
* dev->nr, input->port->lnr, input->nr);
|
||||
*/
|
||||
}
|
||||
|
||||
static void ddb_input_start(struct ddb_input *input)
|
||||
static void ddb_input_stop(struct ddb_input *input)
|
||||
{
|
||||
if (input->dma) {
|
||||
spin_lock_irq(&input->dma->lock);
|
||||
ddb_input_stop_unlocked(input);
|
||||
spin_unlock_irq(&input->dma->lock);
|
||||
} else {
|
||||
ddb_input_stop_unlocked(input);
|
||||
}
|
||||
}
|
||||
|
||||
static void ddb_input_start_unlocked(struct ddb_input *input)
|
||||
{
|
||||
struct ddb *dev = input->port->dev;
|
||||
|
||||
if (input->dma) {
|
||||
spin_lock_irq(&input->dma->lock);
|
||||
input->dma->cbuf = 0;
|
||||
input->dma->coff = 0;
|
||||
input->dma->stat = 0;
|
||||
@@ -555,7 +576,17 @@ static void ddb_input_start(struct ddb_input *input)
|
||||
ddbwritel(dev, 0x000fff01, TS_CONTROL2(input));
|
||||
if (input->dma) {
|
||||
input->dma->running = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void ddb_input_start(struct ddb_input *input)
|
||||
{
|
||||
if (input->dma) {
|
||||
spin_lock_irq(&input->dma->lock);
|
||||
ddb_input_start_unlocked(input);
|
||||
spin_unlock_irq(&input->dma->lock);
|
||||
} else {
|
||||
ddb_input_start_unlocked(input);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1371,11 +1402,19 @@ static struct stv0910_cfg stv0910_p = {
|
||||
.clk = 30000000,
|
||||
};
|
||||
|
||||
static int has_lnbh25(struct i2c_adapter *i2c, u8 adr)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
return i2c_read_reg(i2c, adr, 0, &val) ? 0 : 1;
|
||||
}
|
||||
|
||||
static int demod_attach_stv0910(struct ddb_input *input, int type)
|
||||
{
|
||||
struct i2c_adapter *i2c = &input->port->i2c->adap;
|
||||
struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
|
||||
struct stv0910_cfg cfg = stv0910_p;
|
||||
u8 lnbh_adr = 0x08;
|
||||
|
||||
if (stv0910_single)
|
||||
cfg.single = 1;
|
||||
@@ -1392,14 +1431,14 @@ static int demod_attach_stv0910(struct ddb_input *input, int type)
|
||||
"No STV0910 found!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (has_lnbh25(i2c, 0x0d))
|
||||
lnbh_adr = 0x0c;
|
||||
|
||||
if (!dvb_attach(lnbh25_attach, dvb->fe, i2c,
|
||||
((input->nr & 1) ? 0x0d : 0x0c))) {
|
||||
if (!dvb_attach(lnbh25_attach, dvb->fe, i2c,
|
||||
((input->nr & 1) ? 0x09 : 0x08))) {
|
||||
dev_err(input->port->dev->dev,
|
||||
"No LNBH25 found!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
(input->nr & 1) + lnbh_adr)) {
|
||||
dev_err(input->port->dev->dev,
|
||||
"No LNBH25 found!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1521,7 +1560,8 @@ static int dvb_register_adapters(struct ddb *dev)
|
||||
struct dvb_adapter *adap;
|
||||
|
||||
if (adapter_alloc == 3 || dev->link[0].info->type == DDB_MOD ||
|
||||
dev->link[0].info->type == DDB_OCTONET) {
|
||||
dev->link[0].info->type == DDB_OCTONET ||
|
||||
dev->link[0].info->type == DDB_OCTOPRO ) {
|
||||
port = &dev->port[0];
|
||||
adap = port->dvb[0].adap;
|
||||
ret = dvb_register_adapter(adap, "DDBridge", THIS_MODULE,
|
||||
@@ -1757,8 +1797,9 @@ static int dvb_input_attach(struct ddb_input *input)
|
||||
if (demod_attach_dummy(input) < 0)
|
||||
return -ENODEV;
|
||||
break;
|
||||
case DDB_TUNER_MCI:
|
||||
if (ddb_fe_attach_mci(input) < 0)
|
||||
case DDB_TUNER_MCI_SX8:
|
||||
case DDB_TUNER_MCI_M4:
|
||||
if (ddb_fe_attach_mci(input, port->type) < 0)
|
||||
return -ENODEV;
|
||||
break;
|
||||
default:
|
||||
@@ -1996,6 +2037,7 @@ static void ddb_port_probe(struct ddb_port *port)
|
||||
{
|
||||
struct ddb *dev = port->dev;
|
||||
u32 l = port->lnr;
|
||||
struct ddb_link *link = &dev->link[l];
|
||||
u8 id, type;
|
||||
|
||||
port->name = "NO MODULE";
|
||||
@@ -2005,7 +2047,7 @@ static void ddb_port_probe(struct ddb_port *port)
|
||||
/* Handle missing ports and ports without I2C */
|
||||
|
||||
if (dummy_tuner && !port->nr &&
|
||||
dev->link[0].ids.device == 0x0005) {
|
||||
link->ids.device == 0x0005) {
|
||||
port->name = "DUMMY";
|
||||
port->class = DDB_PORT_TUNER;
|
||||
port->type = DDB_TUNER_DUMMY;
|
||||
@@ -2020,7 +2062,7 @@ static void ddb_port_probe(struct ddb_port *port)
|
||||
}
|
||||
|
||||
if (port->nr == 1 && dev->link[l].info->type == DDB_OCTOPUS_CI &&
|
||||
dev->link[l].info->i2c_mask == 1) {
|
||||
link->info->i2c_mask == 1) {
|
||||
port->name = "NO TAB";
|
||||
port->class = DDB_PORT_NONE;
|
||||
return;
|
||||
@@ -2032,7 +2074,7 @@ static void ddb_port_probe(struct ddb_port *port)
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
if (dev->link[l].info->type == DDB_OCTOPRO_HDIN) {
|
||||
if (link->info->type == DDB_OCTOPRO_HDIN) {
|
||||
if (port->nr == 0) {
|
||||
dev->link[l].info->type = DDB_OCTOPUS;
|
||||
port->name = "HDIN";
|
||||
@@ -2041,7 +2083,7 @@ static void ddb_port_probe(struct ddb_port *port)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (dev->link[l].info->type == DDB_OCTOPUS_MAX) {
|
||||
if (link->info->type == DDB_OCTOPUS_MAX) {
|
||||
port->name = "DUAL DVB-S2 MAX";
|
||||
port->type_name = "MXL5XX";
|
||||
port->class = DDB_PORT_TUNER;
|
||||
@@ -2052,17 +2094,17 @@ static void ddb_port_probe(struct ddb_port *port)
|
||||
return;
|
||||
}
|
||||
|
||||
if (dev->link[l].info->type == DDB_OCTOPUS_MCI) {
|
||||
if (port->nr >= dev->link[l].info->mci)
|
||||
if (link->info->type == DDB_OCTOPUS_MCI) {
|
||||
if (port->nr >= link->info->mci_ports)
|
||||
return;
|
||||
port->name = "DUAL MCI";
|
||||
port->type_name = "MCI";
|
||||
port->class = DDB_PORT_TUNER;
|
||||
port->type = DDB_TUNER_MCI;
|
||||
port->type = DDB_TUNER_MCI + link->info->mci_type;
|
||||
return;
|
||||
}
|
||||
|
||||
if (port->nr > 1 && dev->link[l].info->type == DDB_OCTOPUS_CI) {
|
||||
if (port->nr > 1 && link->info->type == DDB_OCTOPUS_CI) {
|
||||
port->name = "CI internal";
|
||||
port->type_name = "INTERNAL";
|
||||
port->class = DDB_PORT_CI;
|
||||
@@ -2147,7 +2189,7 @@ static void ddb_port_probe(struct ddb_port *port)
|
||||
port->class = DDB_PORT_TUNER;
|
||||
if (id == 0x51) {
|
||||
if (port->nr == 0 &&
|
||||
dev->link[l].info->ts_quirks & TS_QUIRK_REVERSED)
|
||||
link->info->ts_quirks & TS_QUIRK_REVERSED)
|
||||
port->type = DDB_TUNER_DVBS_STV0910_PR;
|
||||
else
|
||||
port->type = DDB_TUNER_DVBS_STV0910_P;
|
||||
@@ -2320,11 +2362,6 @@ static void input_write_dvb(struct ddb_input *input,
|
||||
if (alt_dma)
|
||||
dma_sync_single_for_cpu(dev->dev, dma2->pbuf[dma->cbuf],
|
||||
dma2->size, DMA_FROM_DEVICE);
|
||||
#if 0
|
||||
dev_info(dev->dev, "%02x %02x %02x %02x\n",
|
||||
dma2->vbuf[dma->cbuf][0], dma2->vbuf[dma->cbuf][1],
|
||||
dma2->vbuf[dma->cbuf][2], dma2->vbuf[dma->cbuf][3]);
|
||||
#endif
|
||||
dvb_dmx_swfilter_packets(&dvb->demux,
|
||||
dma2->vbuf[dma->cbuf],
|
||||
dma2->size / 188);
|
||||
@@ -2522,8 +2559,10 @@ static void ddb_dma_init(struct ddb_io *io, int nr, int out, int irq_nr)
|
||||
dma->div = 1;
|
||||
}
|
||||
ddbwritel(io->port->dev, 0, DMA_BUFFER_ACK(dma));
|
||||
#if 0
|
||||
dev_info(io->port->dev->dev, "init link %u, io %u, dma %u, dmaregs %08x bufregs %08x\n",
|
||||
io->port->lnr, io->nr, nr, dma->regs, dma->bufregs);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int anr)
|
||||
@@ -2548,8 +2587,10 @@ static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int anr)
|
||||
if (port->lnr)
|
||||
dma_nr += 32 + (port->lnr - 1) * 8;
|
||||
|
||||
#if 0
|
||||
dev_info(dev->dev, "init link %u, input %u, handler %u\n",
|
||||
port->lnr, nr, dma_nr + base);
|
||||
#endif
|
||||
ddb_irq_set(dev, 0, dma_nr + base, &input_handler, input);
|
||||
ddb_dma_init(input, dma_nr, 0, dma_nr + base);
|
||||
}
|
||||
@@ -2567,8 +2608,10 @@ static void ddb_output_init(struct ddb_port *port, int nr)
|
||||
rm = io_regmap(output, 1);
|
||||
output->regs = DDB_LINK_TAG(port->lnr) |
|
||||
(rm->output->base + rm->output->size * nr);
|
||||
#if 0
|
||||
dev_info(dev->dev, "init link %u, output %u, regs %08x\n",
|
||||
port->lnr, nr, output->regs);
|
||||
#endif
|
||||
if (dev->has_dma) {
|
||||
const struct ddb_regmap *rm0 = io_regmap(output, 0);
|
||||
u32 base = rm0->irq_base_odma;
|
||||
@@ -3174,25 +3217,25 @@ int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len)
|
||||
return flashio(dev, link, cmd, 4, buf, len);
|
||||
}
|
||||
|
||||
static int mdio_write(struct ddb *dev, u8 adr, u8 reg, u16 val)
|
||||
static int mdio_write(struct ddb *dev, u8 adr, u8 reg, u16 val, u32 mdio_base)
|
||||
{
|
||||
ddbwritel(dev, adr, MDIO_ADR);
|
||||
ddbwritel(dev, reg, MDIO_REG);
|
||||
ddbwritel(dev, val, MDIO_VAL);
|
||||
ddbwritel(dev, 0x03, MDIO_CTRL);
|
||||
while (ddbreadl(dev, MDIO_CTRL) & 0x02)
|
||||
ddbwritel(dev, adr, MDIO_ADR_OFF + mdio_base);
|
||||
ddbwritel(dev, reg, MDIO_REG_OFF + mdio_base);
|
||||
ddbwritel(dev, val, MDIO_VAL_OFF + mdio_base);
|
||||
ddbwritel(dev, 0x03, MDIO_CTRL_OFF + mdio_base);
|
||||
while (ddbreadl(dev, MDIO_CTRL_OFF + mdio_base) & 0x02)
|
||||
ndelay(500);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u16 mdio_read(struct ddb *dev, u8 adr, u8 reg)
|
||||
static u16 mdio_read(struct ddb *dev, u8 adr, u8 reg, u32 mdio_base)
|
||||
{
|
||||
ddbwritel(dev, adr, MDIO_ADR);
|
||||
ddbwritel(dev, reg, MDIO_REG);
|
||||
ddbwritel(dev, 0x07, MDIO_CTRL);
|
||||
while (ddbreadl(dev, MDIO_CTRL) & 0x02)
|
||||
ddbwritel(dev, adr, MDIO_ADR_OFF + mdio_base);
|
||||
ddbwritel(dev, reg, MDIO_REG_OFF + mdio_base);
|
||||
ddbwritel(dev, 0x07, MDIO_CTRL_OFF + mdio_base);
|
||||
while (ddbreadl(dev, MDIO_CTRL_OFF + mdio_base) & 0x02)
|
||||
ndelay(500);
|
||||
return ddbreadl(dev, MDIO_VAL);
|
||||
return ddbreadl(dev, MDIO_VAL_OFF + mdio_base);
|
||||
}
|
||||
|
||||
#define DDB_MAGIC 'd'
|
||||
@@ -3368,12 +3411,13 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
case IOCTL_DDB_READ_MDIO:
|
||||
{
|
||||
struct ddb_mdio mdio;
|
||||
u32 mdio_base = dev->link[0].info->mdio_base;
|
||||
|
||||
if (!dev->link[0].info->mdio_num)
|
||||
if (!mdio_base)
|
||||
return -EIO;
|
||||
if (copy_from_user(&mdio, parg, sizeof(mdio)))
|
||||
return -EFAULT;
|
||||
mdio.val = mdio_read(dev, mdio.adr, mdio.reg);
|
||||
mdio.val = mdio_read(dev, mdio.adr, mdio.reg, mdio_base);
|
||||
if (copy_to_user(parg, &mdio, sizeof(mdio)))
|
||||
return -EFAULT;
|
||||
break;
|
||||
@@ -3381,12 +3425,13 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
case IOCTL_DDB_WRITE_MDIO:
|
||||
{
|
||||
struct ddb_mdio mdio;
|
||||
u32 mdio_base = dev->link[0].info->mdio_base;
|
||||
|
||||
if (!dev->link[0].info->mdio_num)
|
||||
if (!mdio_base)
|
||||
return -EIO;
|
||||
if (copy_from_user(&mdio, parg, sizeof(mdio)))
|
||||
return -EFAULT;
|
||||
mdio_write(dev, mdio.adr, mdio.reg, mdio.val);
|
||||
mdio_write(dev, mdio.adr, mdio.reg, mdio.val, mdio_base);
|
||||
break;
|
||||
}
|
||||
case IOCTL_DDB_READ_MEM:
|
||||
@@ -3565,13 +3610,18 @@ static ssize_t temp_show(struct device *device,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct ddb *dev = dev_get_drvdata(device);
|
||||
struct ddb_link *link = &dev->link[0];
|
||||
struct ddb_link *link;
|
||||
struct i2c_adapter *adap;
|
||||
s32 temp, temp2, temp3;
|
||||
int i;
|
||||
u8 tmp[2];
|
||||
int l = 0;
|
||||
|
||||
if (link->info->type == DDB_MOD) {
|
||||
if (attr->attr.name[4] == 'l')
|
||||
l = attr->attr.name[5] - 0x30;
|
||||
link = &dev->link[l];
|
||||
|
||||
if (link->info->type == DDB_MOD ) {
|
||||
if (link->info->version >= 2) {
|
||||
temp = 0xffff & ddbreadl(dev, TEMPMON2_BOARD);
|
||||
temp = (temp * 1000) >> 8;
|
||||
@@ -3601,6 +3651,12 @@ static ssize_t temp_show(struct device *device,
|
||||
}
|
||||
return sprintf(buf, "%d %d\n", temp, temp2);
|
||||
}
|
||||
if (link->info->type == DDB_OCTOPUS_MCI) {
|
||||
temp = 0xffff & ddblreadl(link, TEMPMON_SENSOR0);
|
||||
temp = (temp * 1000) >> 8;
|
||||
|
||||
return sprintf(buf, "%d\n", temp);
|
||||
}
|
||||
if (!link->info->temp_num)
|
||||
return sprintf(buf, "no sensor\n");
|
||||
adap = &dev->i2c[link->info->temp_bus].adap;
|
||||
@@ -3971,7 +4027,7 @@ static ssize_t fmode_store(struct device *device, struct device_attribute *attr,
|
||||
|
||||
if (sscanf(buf, "%u\n", &val) != 1)
|
||||
return -EINVAL;
|
||||
if (val > 3)
|
||||
if (val > 4)
|
||||
return -EINVAL;
|
||||
ddb_lnb_init_fmode(dev, &dev->link[num], val);
|
||||
return count;
|
||||
@@ -4011,7 +4067,10 @@ static struct device_attribute ddb_attrs[] = {
|
||||
};
|
||||
|
||||
static struct device_attribute ddb_attrs_temp[] = {
|
||||
__ATTR_RO(temp),
|
||||
__ATTR_MRO(temp, temp_show),
|
||||
__ATTR_MRO(templ1, temp_show),
|
||||
__ATTR_MRO(templ2, temp_show),
|
||||
__ATTR_MRO(templ3, temp_show),
|
||||
};
|
||||
|
||||
static struct device_attribute ddb_attrs_mod[] = {
|
||||
@@ -4093,8 +4152,11 @@ static void ddb_device_attrs_del(struct ddb *dev)
|
||||
dev->link[i].info->tempmon_irq)
|
||||
device_remove_file(dev->ddb_dev,
|
||||
&ddb_attrs_fanspeed[i]);
|
||||
for (i = 0; i < 4; i++)
|
||||
if (dev->link[i].info &&
|
||||
dev->link[i].info->temp_num)
|
||||
device_remove_file(dev->ddb_dev, &ddb_attrs_temp[i]);
|
||||
for (i = 0; i < dev->link[0].info->temp_num; i++)
|
||||
device_remove_file(dev->ddb_dev, &ddb_attrs_temp[i]);
|
||||
for (i = 0; i < dev->link[0].info->port_num; i++)
|
||||
device_remove_file(dev->ddb_dev, &ddb_attrs_mod[i]);
|
||||
for (i = 0; i < dev->link[0].info->fan_num; i++)
|
||||
@@ -4116,9 +4178,11 @@ static int ddb_device_attrs_add(struct ddb *dev)
|
||||
for (i = 0; ddb_attrs[i].attr.name; i++)
|
||||
if (device_create_file(dev->ddb_dev, &ddb_attrs[i]))
|
||||
goto fail;
|
||||
for (i = 0; i < dev->link[0].info->temp_num; i++)
|
||||
if (device_create_file(dev->ddb_dev, &ddb_attrs_temp[i]))
|
||||
goto fail;
|
||||
for (i = 0; i < 4; i++)
|
||||
if (dev->link[i].info &&
|
||||
dev->link[i].info->temp_num)
|
||||
if (device_create_file(dev->ddb_dev, &ddb_attrs_temp[i]))
|
||||
goto fail;
|
||||
for (i = 0; (i < dev->link[0].info->port_num) && (i < 10); i++)
|
||||
if (device_create_file(dev->ddb_dev, &ddb_attrs_mod[i]))
|
||||
goto fail;
|
||||
|
@@ -336,6 +336,7 @@ static const struct ddb_info ddb_v7a = {
|
||||
.board_control = 2,
|
||||
.board_control_2 = 4,
|
||||
.ts_quirks = TS_QUIRK_REVERSED,
|
||||
.hw_min = 0x010007,
|
||||
};
|
||||
|
||||
static const struct ddb_info ddb_v7 = {
|
||||
@@ -347,6 +348,7 @@ static const struct ddb_info ddb_v7 = {
|
||||
.board_control = 2,
|
||||
.board_control_2 = 4,
|
||||
.ts_quirks = TS_QUIRK_REVERSED,
|
||||
.hw_min = 0x010007,
|
||||
};
|
||||
|
||||
static const struct ddb_info ddb_ctv7 = {
|
||||
@@ -391,6 +393,7 @@ static const struct ddb_info ddb_ci_s2_pro = {
|
||||
.i2c_mask = 0x01,
|
||||
.board_control = 2,
|
||||
.board_control_2 = 4,
|
||||
.hw_min = 0x010007,
|
||||
};
|
||||
|
||||
static const struct ddb_info ddb_ci_s2_pro_a = {
|
||||
@@ -401,6 +404,7 @@ static const struct ddb_info ddb_ci_s2_pro_a = {
|
||||
.i2c_mask = 0x01,
|
||||
.board_control = 2,
|
||||
.board_control_2 = 4,
|
||||
.hw_min = 0x010007,
|
||||
};
|
||||
|
||||
static const struct ddb_info ddb_dvbct = {
|
||||
@@ -489,7 +493,7 @@ static const struct ddb_info ddb_octopro_hdin = {
|
||||
.regmap = &octopro_hdin_map,
|
||||
.port_num = 10,
|
||||
.i2c_mask = 0x3ff,
|
||||
.mdio_num = 1,
|
||||
.mdio_base = 0x10020,
|
||||
};
|
||||
|
||||
static const struct ddb_info ddb_octopro = {
|
||||
@@ -498,7 +502,7 @@ static const struct ddb_info ddb_octopro = {
|
||||
.regmap = &octopro_map,
|
||||
.port_num = 10,
|
||||
.i2c_mask = 0x3ff,
|
||||
.mdio_num = 1,
|
||||
.mdio_base = 0x10020,
|
||||
};
|
||||
|
||||
static const struct ddb_info ddb_s2_48 = {
|
||||
@@ -578,7 +582,21 @@ static const struct ddb_info ddb_s2x_48 = {
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x00,
|
||||
.tempmon_irq = 24,
|
||||
.mci = 4,
|
||||
.mci_ports = 4,
|
||||
.mci_type = 0,
|
||||
.temp_num = 1,
|
||||
};
|
||||
|
||||
static const struct ddb_info ddb_m4 = {
|
||||
.type = DDB_OCTOPUS_MCI,
|
||||
.name = "Digital Devices MAX M4",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 2,
|
||||
.i2c_mask = 0x00,
|
||||
.tempmon_irq = 24,
|
||||
.mci_ports = 2,
|
||||
.mci_type = 1,
|
||||
.temp_num = 1,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -617,7 +635,7 @@ static const struct ddb_info ddb_octonet = {
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.ns_num = 12,
|
||||
.mdio_num = 1,
|
||||
.mdio_base = 0x20,
|
||||
};
|
||||
|
||||
static const struct ddb_info ddb_octonet_jse = {
|
||||
@@ -627,7 +645,7 @@ static const struct ddb_info ddb_octonet_jse = {
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.ns_num = 15,
|
||||
.mdio_num = 1,
|
||||
.mdio_base = 0x20,
|
||||
};
|
||||
|
||||
static const struct ddb_info ddb_octonet_gtl = {
|
||||
@@ -637,7 +655,7 @@ static const struct ddb_info ddb_octonet_gtl = {
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x05,
|
||||
.ns_num = 12,
|
||||
.mdio_num = 1,
|
||||
.mdio_base = 0x20,
|
||||
.con_clock = 1,
|
||||
};
|
||||
|
||||
@@ -693,6 +711,7 @@ static const struct ddb_device_id ddb_device_ids[] = {
|
||||
DDB_DEVID(0x0008, 0x0038, ddb_c2t2i_8),
|
||||
DDB_DEVID(0x0009, 0x0025, ddb_s2x_48),
|
||||
DDB_DEVID(0x0006, 0x0039, ddb_ctv7),
|
||||
DDB_DEVID(0x000a, 0x0050, ddb_m4),
|
||||
DDB_DEVID(0x0011, 0x0040, ddb_ci),
|
||||
DDB_DEVID(0x0011, 0x0041, ddb_cis),
|
||||
DDB_DEVID(0x0012, 0x0042, ddb_ci),
|
||||
|
@@ -63,7 +63,10 @@ static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
|
||||
#endif
|
||||
return -EIO;
|
||||
}
|
||||
if (val & 0x70000)
|
||||
val &= 0x70000;
|
||||
if (val == 0x20000)
|
||||
dev_err(dev->dev, "I2C bus errorx\n");
|
||||
if (val)
|
||||
return -EIO;
|
||||
return 0;
|
||||
}
|
||||
|
@@ -62,7 +62,7 @@ u32 ddbreadl(struct ddb *dev, u32 adr)
|
||||
{
|
||||
if (unlikely(adr & 0xf0000000)) {
|
||||
unsigned long flags;
|
||||
u32 val, l = (adr >> DDB_LINK_SHIFT);
|
||||
u32 val, l = (adr >> DDB_LINK_SHIFT) & 3;
|
||||
struct ddb_link *link = &dev->link[l];
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
|
449
ddbridge/ddbridge-m4.c
Normal file
449
ddbridge/ddbridge-m4.c
Normal file
@@ -0,0 +1,449 @@
|
||||
/*
|
||||
* ddbridge-m4.c: Digital Devices MAX M4 driver
|
||||
*
|
||||
* Copyright (C) 2018 Digital Devices GmbH
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* 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, point your browser to
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include "ddbridge.h"
|
||||
#include "ddbridge-io.h"
|
||||
#include "ddbridge-i2c.h"
|
||||
#include "ddbridge-mci.h"
|
||||
|
||||
struct m4_base {
|
||||
struct mci_base mci_base;
|
||||
|
||||
};
|
||||
|
||||
struct m4 {
|
||||
struct mci mci;
|
||||
|
||||
int started;
|
||||
int t2_signalling_valid;
|
||||
int iq_constellation_point;
|
||||
int iq_constellation_point_max;
|
||||
int iq_constellation_tap;
|
||||
int first_time_lock;
|
||||
};
|
||||
|
||||
static int stop(struct dvb_frontend *fe)
|
||||
{
|
||||
struct m4 *state = fe->demodulator_priv;
|
||||
struct mci_command cmd;
|
||||
struct mci_base *mci_base = state->mci.base;
|
||||
|
||||
if (!state->started)
|
||||
return -1;
|
||||
state->started = 0;
|
||||
state->t2_signalling_valid = 0;
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.command = MCI_CMD_STOP;
|
||||
cmd.demod = state->mci.demod;
|
||||
ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int search_s2(struct dvb_frontend *fe)
|
||||
{
|
||||
struct m4 *state = fe->demodulator_priv;
|
||||
struct mci_base *mci_base = state->mci.base;
|
||||
struct m4_base *m4_base = (struct m4_base *) mci_base;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
struct mci_command cmd;
|
||||
int stat;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.command = MCI_CMD_SEARCH_DVBS;
|
||||
cmd.dvbs2_search.flags = 3;
|
||||
cmd.dvbs2_search.s2_modulation_mask = 3;
|
||||
cmd.dvbs2_search.retry = 2;
|
||||
cmd.dvbs2_search.frequency = p->frequency * 1000;
|
||||
cmd.dvbs2_search.symbol_rate = p->symbol_rate;
|
||||
cmd.dvbs2_search.scrambling_sequence_index = 0; //p->scrambling_sequence_index;
|
||||
cmd.dvbs2_search.input_stream_id = p->stream_id;
|
||||
cmd.tuner = state->mci.nr;
|
||||
cmd.demod = state->mci.tuner;
|
||||
cmd.output = state->mci.nr;
|
||||
|
||||
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
if (stat)
|
||||
stop(fe);
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int search_c(struct dvb_frontend *fe)
|
||||
{
|
||||
struct m4 *state = fe->demodulator_priv;
|
||||
struct mci_base *mci_base = state->mci.base;
|
||||
struct m4_base *m4_base = (struct m4_base *) mci_base;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
struct mci_command cmd;
|
||||
int stat;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.command = MCI_CMD_SEARCH_DVBC;
|
||||
switch (p->bandwidth_hz) {
|
||||
case 6000000:
|
||||
cmd.dvbc_search.bandwidth = MCI_BANDWIDTH_6MHZ;
|
||||
break;
|
||||
case 7000000:
|
||||
cmd.dvbc_search.bandwidth = MCI_BANDWIDTH_7MHZ;
|
||||
break;
|
||||
default:
|
||||
cmd.dvbc_search.bandwidth = MCI_BANDWIDTH_8MHZ;
|
||||
break;
|
||||
}
|
||||
cmd.dvbc_search.retry = 2;
|
||||
cmd.dvbc_search.frequency = p->frequency;
|
||||
cmd.tuner = state->mci.tuner;
|
||||
cmd.demod = state->mci.demod;
|
||||
cmd.output = state->mci.nr;
|
||||
|
||||
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
if (stat)
|
||||
stop(fe);
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int search_t(struct dvb_frontend *fe)
|
||||
{
|
||||
struct m4 *state = fe->demodulator_priv;
|
||||
struct mci_base *mci_base = state->mci.base;
|
||||
struct m4_base *m4_base = (struct m4_base *) mci_base;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
struct mci_command cmd;
|
||||
int stat;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.command = MCI_CMD_SEARCH_DVBT;
|
||||
switch (p->bandwidth_hz) {
|
||||
case 5000000:
|
||||
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_5MHZ;
|
||||
break;
|
||||
case 6000000:
|
||||
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_6MHZ;
|
||||
break;
|
||||
case 7000000:
|
||||
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_7MHZ;
|
||||
break;
|
||||
default:
|
||||
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_8MHZ;
|
||||
break;
|
||||
}
|
||||
cmd.dvbt_search.retry = 2;
|
||||
cmd.dvbt_search.frequency = p->frequency;
|
||||
cmd.tuner = state->mci.tuner;
|
||||
cmd.demod = state->mci.demod;
|
||||
cmd.output = state->mci.nr;
|
||||
|
||||
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
if (stat)
|
||||
stop(fe);
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int search_t2(struct dvb_frontend *fe)
|
||||
{
|
||||
struct m4 *state = fe->demodulator_priv;
|
||||
struct mci_base *mci_base = state->mci.base;
|
||||
struct m4_base *m4_base = (struct m4_base *) mci_base;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
struct mci_command cmd;
|
||||
int stat;
|
||||
u32 flags = 0;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.command = MCI_CMD_SEARCH_DVBT2;
|
||||
switch (p->bandwidth_hz) {
|
||||
case 1700000:
|
||||
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_1_7MHZ;
|
||||
break;
|
||||
case 5000000:
|
||||
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_5MHZ;
|
||||
break;
|
||||
case 6000000:
|
||||
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_6MHZ;
|
||||
break;
|
||||
case 7000000:
|
||||
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_7MHZ;
|
||||
break;
|
||||
default:
|
||||
cmd.dvbt_search.bandwidth = MCI_BANDWIDTH_8MHZ;
|
||||
break;
|
||||
}
|
||||
cmd.dvbt2_search.retry = 2;
|
||||
cmd.dvbt2_search.frequency = p->frequency;
|
||||
if (p->stream_id != NO_STREAM_ID_FILTER) {
|
||||
cmd.dvbt2_search.plp = p->stream_id & 0xff;
|
||||
cmd.dvbt2_search.flags |= 0x80;
|
||||
cmd.dvbt2_search.flags |= (p->stream_id >> 8) & 1;
|
||||
}
|
||||
cmd.tuner = state->mci.tuner;
|
||||
cmd.demod = state->mci.demod;
|
||||
cmd.output = state->mci.nr;
|
||||
|
||||
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
if (stat)
|
||||
stop(fe);
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int search_c2(struct dvb_frontend *fe)
|
||||
{
|
||||
struct m4 *state = fe->demodulator_priv;
|
||||
struct mci_base *mci_base = state->mci.base;
|
||||
struct m4_base *m4_base = (struct m4_base *) mci_base;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
struct mci_command cmd;
|
||||
int stat;
|
||||
u32 flags = 0;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.command = MCI_CMD_SEARCH_DVBC2;
|
||||
switch (p->bandwidth_hz) {
|
||||
case 6000000:
|
||||
cmd.dvbc2_search.bandwidth = MCI_BANDWIDTH_6MHZ;
|
||||
break;
|
||||
default:
|
||||
cmd.dvbc2_search.bandwidth = MCI_BANDWIDTH_8MHZ;
|
||||
break;
|
||||
}
|
||||
cmd.dvbc2_search.retry = 2;
|
||||
cmd.dvbc2_search.frequency = p->frequency;
|
||||
if (p->stream_id != NO_STREAM_ID_FILTER) {
|
||||
cmd.dvbc2_search.plp = p->stream_id & 0xff;
|
||||
cmd.dvbc2_search.data_slice = (p->stream_id >> 8) & 0xff;
|
||||
}
|
||||
cmd.tuner = state->mci.tuner;
|
||||
cmd.demod = state->mci.demod;
|
||||
cmd.output = state->mci.nr;
|
||||
|
||||
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
if (stat)
|
||||
stop(fe);
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int search_isdbt(struct dvb_frontend *fe)
|
||||
{
|
||||
struct m4 *state = fe->demodulator_priv;
|
||||
struct mci_base *mci_base = state->mci.base;
|
||||
struct m4_base *m4_base = (struct m4_base *) mci_base;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
struct mci_command cmd;
|
||||
int stat;
|
||||
u32 flags = 0;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.command = MCI_CMD_SEARCH_ISDBT;
|
||||
switch (p->bandwidth_hz) {
|
||||
case 8000000:
|
||||
cmd.isdbt_search.bandwidth = MCI_BANDWIDTH_8MHZ;
|
||||
break;
|
||||
case 7000000:
|
||||
cmd.isdbt_search.bandwidth = MCI_BANDWIDTH_7MHZ;
|
||||
break;
|
||||
default:
|
||||
cmd.isdbt_search.bandwidth = MCI_BANDWIDTH_6MHZ;
|
||||
break;
|
||||
}
|
||||
cmd.isdbt_search.retry = 2;
|
||||
cmd.isdbt_search.frequency = p->frequency;
|
||||
cmd.tuner = state->mci.tuner;
|
||||
cmd.demod = state->mci.demod;
|
||||
cmd.output = state->mci.nr;
|
||||
|
||||
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
if (stat)
|
||||
stop(fe);
|
||||
return stat;
|
||||
}
|
||||
|
||||
|
||||
static int set_parameters(struct dvb_frontend *fe)
|
||||
{
|
||||
struct m4 *state = fe->demodulator_priv;
|
||||
int res;
|
||||
|
||||
stop(fe);
|
||||
|
||||
state->t2_signalling_valid = 0;
|
||||
state->iq_constellation_point = 0;
|
||||
state->iq_constellation_point_max = 0;
|
||||
|
||||
state->iq_constellation_tap = 0;
|
||||
switch (fe->dtv_property_cache.delivery_system) {
|
||||
case SYS_DVBS:
|
||||
case SYS_DVBS2:
|
||||
res = search_s2(fe);
|
||||
break;
|
||||
case SYS_DVBC_ANNEX_A:
|
||||
res = search_c(fe);
|
||||
break;
|
||||
case SYS_DVBT:
|
||||
state->iq_constellation_tap = 5;
|
||||
res = search_t(fe);
|
||||
break;
|
||||
case SYS_DVBT2:
|
||||
res = search_t2(fe);
|
||||
break;
|
||||
case SYS_DVBC2:
|
||||
res = search_c2(fe);
|
||||
break;
|
||||
case SYS_ISDBT:
|
||||
res = search_isdbt(fe);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!res) {
|
||||
state->started = 1;
|
||||
state->first_time_lock = 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int read_status(struct dvb_frontend *fe, enum fe_status *status)
|
||||
{
|
||||
int stat;
|
||||
struct m4 *state = fe->demodulator_priv;
|
||||
struct mci_result res;
|
||||
|
||||
stat = ddb_mci_get_status(&state->mci, &res);
|
||||
if (stat)
|
||||
return stat;
|
||||
*status = 0x00;
|
||||
ddb_mci_get_info(&state->mci);
|
||||
ddb_mci_get_strength(fe);
|
||||
if (res.status == M4_DEMOD_WAIT_SIGNAL)
|
||||
*status = 0x01;
|
||||
if (res.status == M4_DEMOD_LOCKED) {
|
||||
*status = 0x1f;
|
||||
ddb_mci_get_snr(fe);
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int tune(struct dvb_frontend *fe, bool re_tune,
|
||||
unsigned int mode_flags,
|
||||
unsigned int *delay, enum fe_status *status)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (re_tune) {
|
||||
r = set_parameters(fe);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
r = read_status(fe, status);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (*status & FE_HAS_LOCK)
|
||||
return 0;
|
||||
*delay = HZ / 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
struct m4 *state = fe->demodulator_priv;
|
||||
|
||||
if (state->started)
|
||||
stop(fe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void release(struct dvb_frontend *fe)
|
||||
{
|
||||
struct m4 *state = fe->demodulator_priv;
|
||||
struct mci_base *mci_base = state->mci.base;
|
||||
|
||||
mci_base->count--;
|
||||
if (mci_base->count == 0) {
|
||||
list_del(&mci_base->mci_list);
|
||||
kfree(mci_base);
|
||||
}
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
static int get_algo(struct dvb_frontend *fe)
|
||||
{
|
||||
return DVBFE_ALGO_HW;
|
||||
}
|
||||
|
||||
static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties *p)
|
||||
{
|
||||
struct m4 *state = fe->demodulator_priv;
|
||||
|
||||
ddb_mci_proc_info(&state->mci, p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dvb_frontend_ops m4_ops = {
|
||||
.delsys = { SYS_DVBC_ANNEX_A, SYS_DVBT, SYS_DVBT2, SYS_DVBC2, SYS_ISDBT,
|
||||
SYS_DVBS, SYS_DVBS2, },
|
||||
.info = {
|
||||
.name = "M4",
|
||||
.frequency_min = 950000, /* DVB-T: 47125000 */
|
||||
.frequency_max = 865000000, /* DVB-C: 862000000 */
|
||||
.symbol_rate_min = 100000,
|
||||
.symbol_rate_max = 100000000,
|
||||
.frequency_stepsize = 0,
|
||||
.frequency_tolerance = 0,
|
||||
.caps = FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 |
|
||||
FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 |
|
||||
FE_CAN_QAM_AUTO |
|
||||
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
|
||||
FE_CAN_FEC_4_5 |
|
||||
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
|
||||
FE_CAN_TRANSMISSION_MODE_AUTO |
|
||||
FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO |
|
||||
FE_CAN_RECOVER | FE_CAN_MUTE_TS | FE_CAN_2G_MODULATION
|
||||
},
|
||||
.release = release,
|
||||
.get_frontend_algo = get_algo,
|
||||
.get_frontend = get_frontend,
|
||||
.read_status = read_status,
|
||||
.tune = tune,
|
||||
.sleep = sleep,
|
||||
};
|
||||
|
||||
static int init(struct mci *mci)
|
||||
{
|
||||
//struct m4 *state = (struct m4 *) mci;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int base_init(struct mci_base *mci_base)
|
||||
{
|
||||
//struct m4_base *base = (struct m4_base *) mci_base;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mci_cfg ddb_max_m4_cfg = {
|
||||
.type = 0,
|
||||
.fe_ops = &m4_ops,
|
||||
.base_size = sizeof(struct m4_base),
|
||||
.state_size = sizeof(struct m4),
|
||||
.init = init,
|
||||
.base_init = base_init,
|
||||
};
|
@@ -337,6 +337,13 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
|
||||
|
||||
dev_info(dev->dev, "HW %08x REGMAP %08x\n",
|
||||
dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
|
||||
if ((dev->link[0].ids.hwid & 0xffffff) <
|
||||
dev->link[0].info->hw_min) {
|
||||
u32 min = dev->link[0].info->hw_min;
|
||||
|
||||
dev_err(dev->dev, "Update firmware to at least version %u.%u to ensure full functionality!\n",
|
||||
(min & 0xff0000) >> 16, min & 0xffff);
|
||||
}
|
||||
|
||||
if (dev->link[0].info->ns_num) {
|
||||
ddbwritel(dev, 0, ETHER_CONTROL);
|
||||
@@ -408,6 +415,7 @@ static const struct pci_device_id ddb_id_table[] __devinitconst = {
|
||||
DDB_DEVICE_ANY(0x0007),
|
||||
DDB_DEVICE_ANY(0x0008),
|
||||
DDB_DEVICE_ANY(0x0009),
|
||||
DDB_DEVICE_ANY(0x000a),
|
||||
DDB_DEVICE_ANY(0x0011),
|
||||
DDB_DEVICE_ANY(0x0012),
|
||||
DDB_DEVICE_ANY(0x0013),
|
||||
@@ -459,5 +467,5 @@ module_exit(module_exit_ddbridge);
|
||||
|
||||
MODULE_DESCRIPTION("Digital Devices PCIe Bridge");
|
||||
MODULE_AUTHOR("Ralph and Marcus Metzler, Metzler Brothers Systementwicklung GbR");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_VERSION(DDBRIDGE_VERSION);
|
||||
|
@@ -24,7 +24,6 @@
|
||||
#include "ddbridge.h"
|
||||
#include "ddbridge-io.h"
|
||||
#include "ddbridge-i2c.h"
|
||||
#include "ddbridge-mci.h"
|
||||
|
||||
/* MAX LNB interface related module parameters */
|
||||
|
||||
@@ -61,6 +60,24 @@ static int lnb_command(struct ddb *dev, u32 link, u32 lnb, u32 cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max_set_input_unlocked(struct dvb_frontend *fe, int in);
|
||||
|
||||
static int max_emulate_switch(struct dvb_frontend *fe,
|
||||
u8 *cmd, u32 len)
|
||||
{
|
||||
int input;
|
||||
|
||||
if (len !=4)
|
||||
return -1;
|
||||
|
||||
if ((cmd[0] != 0xe0) || (cmd[1] != 0x10) || (cmd[2] != 0x39))
|
||||
return -1;
|
||||
|
||||
input = cmd[3] & 3;
|
||||
max_set_input_unlocked(fe, input);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max_send_master_cmd(struct dvb_frontend *fe,
|
||||
struct dvb_diseqc_master_cmd *cmd)
|
||||
{
|
||||
@@ -74,6 +91,10 @@ static int max_send_master_cmd(struct dvb_frontend *fe,
|
||||
|
||||
if (fmode == 2 || fmode == 1)
|
||||
return 0;
|
||||
|
||||
if (fmode == 4)
|
||||
max_emulate_switch(fe, cmd->msg, cmd->msg_len);
|
||||
|
||||
if (dvb->diseqc_send_master_cmd)
|
||||
dvb->diseqc_send_master_cmd(fe, cmd);
|
||||
|
||||
@@ -182,7 +203,8 @@ static int max_set_input_unlocked(struct dvb_frontend *fe, int in)
|
||||
dvb->input = in;
|
||||
dev->link[port->lnr].lnb.voltage[dvb->input] |= obit;
|
||||
}
|
||||
res = dvb->set_input(fe, in);
|
||||
if (dvb->set_input)
|
||||
res = dvb->set_input(fe, in);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -417,7 +439,7 @@ int ddb_fe_attach_mxl5xx(struct ddb_input *input)
|
||||
|
||||
demod = input->nr;
|
||||
tuner = demod & 3;
|
||||
if (fmode == 3)
|
||||
if (fmode >= 3)
|
||||
tuner = 0;
|
||||
dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg, demod, tuner);
|
||||
if (!dvb->fe) {
|
||||
@@ -445,11 +467,10 @@ int ddb_fe_attach_mxl5xx(struct ddb_input *input)
|
||||
|
||||
/* MAX MCI related functions */
|
||||
|
||||
static struct mci_cfg maxsx8 = {
|
||||
extern struct mci_cfg ddb_max_sx8_cfg;
|
||||
extern struct mci_cfg ddb_max_m4_cfg;
|
||||
|
||||
};
|
||||
|
||||
int ddb_fe_attach_mci(struct ddb_input *input)
|
||||
int ddb_fe_attach_mci(struct ddb_input *input, u32 type)
|
||||
{
|
||||
struct ddb *dev = input->port->dev;
|
||||
//struct i2c_adapter *i2c = &input->port->i2c->adap;
|
||||
@@ -458,26 +479,33 @@ int ddb_fe_attach_mci(struct ddb_input *input)
|
||||
struct ddb_link *link = &dev->link[port->lnr];
|
||||
int demod, tuner;
|
||||
struct mci_cfg cfg;
|
||||
|
||||
cfg = maxsx8;
|
||||
int fm = fmode;
|
||||
|
||||
demod = input->nr;
|
||||
tuner = demod & 3;
|
||||
if (fmode == 3)
|
||||
tuner = 0;
|
||||
#if 0
|
||||
dvb->fe = dvb_attach(ddb_mci_attach, input, 0, demod);
|
||||
#else
|
||||
dvb->fe = ddb_mci_attach(input, 0, demod);
|
||||
#endif
|
||||
switch (type) {
|
||||
case DDB_TUNER_MCI_SX8:
|
||||
cfg = ddb_max_sx8_cfg;
|
||||
if (fm >= 3)
|
||||
tuner = 0;
|
||||
break;
|
||||
case DDB_TUNER_MCI_M4:
|
||||
fm = 0;
|
||||
cfg = ddb_max_m4_cfg;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
dvb->fe = ddb_mci_attach(input, &cfg, demod, tuner);
|
||||
if (!dvb->fe) {
|
||||
dev_err(dev->dev, "No MAXSX8 found!\n");
|
||||
dev_err(dev->dev, "No MCI card found!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
if (input->nr < 4) {
|
||||
lnb_command(dev, port->lnr, input->nr, LNB_CMD_INIT);
|
||||
lnb_set_voltage(dev, port->lnr, input->nr, SEC_VOLTAGE_OFF);
|
||||
}
|
||||
ddb_lnb_init_fmode(dev, link, fmode);
|
||||
ddb_lnb_init_fmode(dev, link, fm);
|
||||
|
||||
dvb->fe->ops.set_voltage = max_set_voltage;
|
||||
dvb->fe->ops.enable_high_lnb_voltage = max_enable_high_lnb_voltage;
|
||||
@@ -491,4 +519,3 @@ int ddb_fe_attach_mci(struct ddb_input *input)
|
||||
dvb->input = tuner;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* ddbridge-mci.c: Digital Devices microcode interface
|
||||
*
|
||||
* Copyright (C) 2017 Digital Devices GmbH
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
* Copyright (C) 2017-2018 Digital Devices GmbH
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -27,43 +27,6 @@
|
||||
|
||||
static LIST_HEAD(mci_list);
|
||||
|
||||
static const u32 MCLK = (1550000000/12);
|
||||
static const u32 MAX_LDPC_BITRATE = (720000000);
|
||||
|
||||
struct mci_base {
|
||||
struct list_head mci_list;
|
||||
void *key;
|
||||
struct ddb_link *link;
|
||||
struct completion completion;
|
||||
|
||||
struct i2c_adapter *i2c;
|
||||
struct mutex i2c_lock;
|
||||
struct mutex tuner_lock;
|
||||
u8 adr;
|
||||
struct mutex mci_lock;
|
||||
int count;
|
||||
|
||||
u8 tuner_use_count[4];
|
||||
u8 assigned_demod[8];
|
||||
u32 used_ldpc_bitrate[8];
|
||||
u8 demod_in_use[8];
|
||||
u32 iq_mode;
|
||||
};
|
||||
|
||||
struct mci {
|
||||
struct mci_base *base;
|
||||
struct dvb_frontend fe;
|
||||
int nr;
|
||||
int demod;
|
||||
int tuner;
|
||||
int first_time_lock;
|
||||
int started;
|
||||
struct mci_result signal_info;
|
||||
|
||||
u32 bb_mode;
|
||||
};
|
||||
|
||||
|
||||
static int mci_reset(struct mci *state)
|
||||
{
|
||||
struct ddb_link *link = state->base->link;
|
||||
@@ -90,7 +53,7 @@ static int mci_reset(struct mci *state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mci_config(struct mci *state, u32 config)
|
||||
int ddb_mci_config(struct mci *state, u32 config)
|
||||
{
|
||||
struct ddb_link *link = state->base->link;
|
||||
|
||||
@@ -101,9 +64,9 @@ static int mci_config(struct mci *state, u32 config)
|
||||
}
|
||||
|
||||
|
||||
static int _mci_cmd_unlocked(struct mci *state,
|
||||
u32 *cmd, u32 cmd_len,
|
||||
u32 *res, u32 res_len)
|
||||
static int ddb_mci_cmd_raw_unlocked(struct mci *state,
|
||||
u32 *cmd, u32 cmd_len,
|
||||
u32 *res, u32 res_len)
|
||||
{
|
||||
struct ddb_link *link = state->base->link;
|
||||
u32 i, val;
|
||||
@@ -129,45 +92,216 @@ static int _mci_cmd_unlocked(struct mci *state,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mci_cmd_unlocked(struct mci *state,
|
||||
struct mci_command *command,
|
||||
struct mci_result *result)
|
||||
int ddb_mci_cmd_unlocked(struct mci *state,
|
||||
struct mci_command *command,
|
||||
struct mci_result *result)
|
||||
{
|
||||
u32 *cmd = (u32 *) command;
|
||||
u32 *res = (u32 *) result;
|
||||
|
||||
return _mci_cmd_unlocked(state, cmd, sizeof(*command)/sizeof(u32),
|
||||
res, sizeof(*result)/sizeof(u32));
|
||||
return ddb_mci_cmd_raw_unlocked(state, cmd, sizeof(*command)/sizeof(u32),
|
||||
res, sizeof(*result)/sizeof(u32));
|
||||
}
|
||||
|
||||
static int mci_cmd(struct mci *state,
|
||||
struct mci_command *command,
|
||||
struct mci_result *result)
|
||||
int ddb_mci_cmd(struct mci *state,
|
||||
struct mci_command *command,
|
||||
struct mci_result *result)
|
||||
{
|
||||
int stat;
|
||||
|
||||
|
||||
mutex_lock(&state->base->mci_lock);
|
||||
stat = _mci_cmd_unlocked(state,
|
||||
stat = ddb_mci_cmd_raw_unlocked(state,
|
||||
(u32 *)command, sizeof(*command)/sizeof(u32),
|
||||
(u32 *)result, sizeof(*result)/sizeof(u32));
|
||||
mutex_unlock(&state->base->mci_lock);
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int _mci_cmd(struct mci *state,
|
||||
int ddb_mci_cmd_raw(struct mci *state,
|
||||
struct mci_command *command, u32 command_len,
|
||||
struct mci_result *result, u32 result_len)
|
||||
{
|
||||
int stat;
|
||||
|
||||
|
||||
mutex_lock(&state->base->mci_lock);
|
||||
stat = _mci_cmd_unlocked(state,
|
||||
(u32 *)command, command_len,
|
||||
(u32 *)result, result_len);
|
||||
stat = ddb_mci_cmd_raw_unlocked(state,
|
||||
(u32 *)command, command_len,
|
||||
(u32 *)result, result_len);
|
||||
mutex_unlock(&state->base->mci_lock);
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int ddb_mci_get_iq(struct mci *mci, u32 demod, s16 *i, s16 *q)
|
||||
{
|
||||
int stat;
|
||||
struct mci_command cmd;
|
||||
struct mci_result res;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
memset(&res, 0, sizeof(res));
|
||||
cmd.command = MCI_CMD_GET_IQSYMBOL;
|
||||
cmd.demod = demod;
|
||||
stat = ddb_mci_cmd(mci, &cmd, &res);
|
||||
if (!stat) {
|
||||
*i = res.iq_symbol.i;
|
||||
*q = res.iq_symbol.q;
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int ddb_mci_get_status(struct mci *mci, struct mci_result *res)
|
||||
{
|
||||
struct mci_command cmd;
|
||||
|
||||
cmd.command = MCI_CMD_GETSTATUS;
|
||||
cmd.demod = mci->demod;
|
||||
return ddb_mci_cmd_raw(mci, &cmd, 1, res, 1);
|
||||
}
|
||||
|
||||
int ddb_mci_get_snr(struct dvb_frontend *fe)
|
||||
{
|
||||
struct mci *mci = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
|
||||
p->cnr.len = 1;
|
||||
p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->cnr.stat[0].svalue = (s64) mci->
|
||||
signal_info.dvbs2_signal_info.signal_to_noise * 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ddb_mci_get_strength(struct dvb_frontend *fe)
|
||||
{
|
||||
struct mci *mci = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
s32 str;
|
||||
|
||||
str = mci->signal_info.dvbs2_signal_info.channel_power * 10;
|
||||
p->strength.len = 1;
|
||||
p->strength.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->strength.stat[0].svalue = str;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ddb_mci_get_info(struct mci *mci)
|
||||
{
|
||||
int stat;
|
||||
struct mci_command cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.command = MCI_CMD_GETSIGNALINFO;
|
||||
cmd.demod = mci->demod;
|
||||
stat = ddb_mci_cmd(mci, &cmd, &mci->signal_info);
|
||||
return stat;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p)
|
||||
{
|
||||
const enum fe_modulation modcod2mod[0x20] = {
|
||||
QPSK, QPSK, QPSK, QPSK,
|
||||
QPSK, QPSK, QPSK, QPSK,
|
||||
QPSK, QPSK, QPSK, QPSK,
|
||||
PSK_8, PSK_8, PSK_8, PSK_8,
|
||||
PSK_8, PSK_8, APSK_16, APSK_16,
|
||||
APSK_16, APSK_16, APSK_16, APSK_16,
|
||||
APSK_32, APSK_32, APSK_32, APSK_32,
|
||||
APSK_32,
|
||||
};
|
||||
const enum fe_code_rate modcod2fec[0x20] = {
|
||||
FEC_NONE, FEC_1_4, FEC_1_3, FEC_2_5,
|
||||
FEC_1_2, FEC_3_5, FEC_2_3, FEC_3_4,
|
||||
FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10,
|
||||
FEC_3_5, FEC_2_3, FEC_3_4, FEC_5_6,
|
||||
FEC_8_9, FEC_9_10, FEC_2_3, FEC_3_4,
|
||||
FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10,
|
||||
FEC_3_4, FEC_4_5, FEC_5_6, FEC_8_9,
|
||||
FEC_9_10, FEC_NONE, FEC_NONE, FEC_NONE,
|
||||
};
|
||||
const enum fe_code_rate dvbs_fec_lut[8] = {
|
||||
FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6,
|
||||
FEC_NONE, FEC_7_8, FEC_NONE, FEC_NONE,
|
||||
};
|
||||
const enum fe_rolloff ro_lut[8] = {
|
||||
ROLLOFF_35, ROLLOFF_25, ROLLOFF_20, ROLLOFF_10,
|
||||
ROLLOFF_5, ROLLOFF_15, ROLLOFF_35, ROLLOFF_35
|
||||
};
|
||||
|
||||
p->frequency =
|
||||
mci->signal_info.dvbs2_signal_info.frequency;
|
||||
switch (p->delivery_system) {
|
||||
default:
|
||||
case SYS_DVBS:
|
||||
case SYS_DVBS2:
|
||||
{
|
||||
u32 pls_code =
|
||||
mci->signal_info.dvbs2_signal_info.pls_code;
|
||||
|
||||
p->frequency =
|
||||
mci->signal_info.dvbs2_signal_info.frequency / 1000;
|
||||
p->delivery_system =
|
||||
(mci->signal_info.dvbs2_signal_info.standard == 2) ?
|
||||
SYS_DVBS2 : SYS_DVBS;
|
||||
if (mci->signal_info.dvbs2_signal_info.standard == 2) {
|
||||
u32 modcod = (0x7c & pls_code) >> 2;
|
||||
|
||||
p->delivery_system = SYS_DVBS2;
|
||||
p->rolloff =
|
||||
ro_lut[mci->signal_info.
|
||||
dvbs2_signal_info.roll_off & 7];
|
||||
p->pilot = (pls_code & 1) ? PILOT_ON : PILOT_OFF;
|
||||
p->fec_inner = modcod2fec[modcod];
|
||||
p->modulation = modcod2mod[modcod];
|
||||
p->transmission_mode = pls_code;
|
||||
} else {
|
||||
p->delivery_system = SYS_DVBS;
|
||||
p->rolloff = ROLLOFF_35;
|
||||
p->pilot = PILOT_OFF;
|
||||
p->fec_inner = dvbs_fec_lut[pls_code & 7];
|
||||
p->modulation = QPSK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SYS_DVBC_ANNEX_A:
|
||||
break;
|
||||
case SYS_DVBT:
|
||||
break;
|
||||
case SYS_DVBT2:
|
||||
break;
|
||||
case SYS_DVBC2:
|
||||
break;
|
||||
case SYS_ISDBT:
|
||||
break;
|
||||
}
|
||||
p->pre_bit_error.len = 1;
|
||||
p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->pre_bit_error.stat[0].uvalue =
|
||||
mci->signal_info.dvbs2_signal_info.ber_numerator;
|
||||
|
||||
p->pre_bit_count.len = 1;
|
||||
p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->pre_bit_count.stat[0].uvalue =
|
||||
mci->signal_info.dvbs2_signal_info.ber_denominator;
|
||||
|
||||
p->block_error.len = 1;
|
||||
p->block_error.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->block_error.stat[0].uvalue =
|
||||
mci->signal_info.dvbs2_signal_info.packet_errors;
|
||||
p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
|
||||
|
||||
p->cnr.len = 1;
|
||||
p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->cnr.stat[0].svalue = (s64) mci->
|
||||
signal_info.dvbs2_signal_info.signal_to_noise * 10;
|
||||
|
||||
p->strength.len = 1;
|
||||
p->strength.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->strength.stat[0].svalue =
|
||||
mci->signal_info.dvbs2_signal_info.channel_power * 10;
|
||||
}
|
||||
|
||||
static void mci_handler(void *priv)
|
||||
{
|
||||
struct mci_base *base = (struct mci_base *)priv;
|
||||
@@ -175,423 +309,6 @@ static void mci_handler(void *priv)
|
||||
complete(&base->completion);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const u8 dvbs2_bits_per_symbol[] = {
|
||||
0, 0, 0, 0,
|
||||
/* S2 QPSK */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
/* S2 8PSK */
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3,
|
||||
/* S2 16APSK */
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
/* S2 32APSK */
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
3, 0, 4, 0,
|
||||
2, 2, 2, 2, 2, 2, // S2X QPSK
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // S2X 8PSK
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // S2X 16APSK
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // S2X 32APSK
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // S2X 64APSK
|
||||
7, 7, 7, 7, // S2X 128APSK
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // S2X 256APSK
|
||||
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // S2X QPSK
|
||||
3, 3, 3, 3, 3, 3, 3, 3, // S2X 8PSK
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // S2X 16APSK
|
||||
5, 5, 5, 5, // S2X 32APSK
|
||||
|
||||
3, 4, 5, 6, 8, 10,
|
||||
};
|
||||
|
||||
|
||||
static void release(struct dvb_frontend *fe)
|
||||
{
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
|
||||
state->base->count--;
|
||||
if (state->base->count == 0) {
|
||||
list_del(&state->base->mci_list);
|
||||
kfree(state->base);
|
||||
}
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
static int get_info(struct dvb_frontend *fe)
|
||||
{
|
||||
int stat;
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
struct mci_command cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.command = MCI_CMD_GETSIGNALINFO;
|
||||
cmd.demod = state->demod;
|
||||
stat = mci_cmd(state, &cmd, &state->signal_info);
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int read_status(struct dvb_frontend *fe, enum fe_status *status)
|
||||
{
|
||||
int stat;
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
struct mci_command cmd;
|
||||
u32 val;
|
||||
struct mci_result *res = (struct mci_result *)&val;
|
||||
|
||||
cmd.command = MCI_CMD_GETSTATUS;
|
||||
cmd.demod = state->demod;
|
||||
stat = _mci_cmd(state, &cmd, 1, res, 1);
|
||||
if (stat)
|
||||
return stat;
|
||||
*status = 0x00;
|
||||
if (res->status == SX8_DEMOD_WAIT_MATYPE)
|
||||
*status = 0x0f;
|
||||
if (res->status == SX8_DEMOD_LOCKED)
|
||||
*status = 0x1f;
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int mci_set_tuner(struct dvb_frontend *fe, u32 tuner, u32 on)
|
||||
{
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
struct mci_command cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.tuner = state->tuner;
|
||||
cmd.command = on ? SX8_CMD_INPUT_ENABLE : SX8_CMD_INPUT_DISABLE;
|
||||
return mci_cmd(state, &cmd, NULL);
|
||||
}
|
||||
|
||||
static int stop(struct dvb_frontend *fe)
|
||||
{
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
struct mci_command cmd;
|
||||
u32 input = state->tuner;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
if (state->demod != 0xff) {
|
||||
cmd.command = MCI_CMD_STOP;
|
||||
cmd.demod = state->demod;
|
||||
mci_cmd(state, &cmd, NULL);
|
||||
if (state->base->iq_mode) {
|
||||
cmd.command = MCI_CMD_STOP;
|
||||
cmd.demod = state->demod;
|
||||
cmd.output = 0;
|
||||
mci_cmd(state, &cmd, NULL);
|
||||
mci_config(state, SX8_TSCONFIG_MODE_NORMAL);
|
||||
}
|
||||
}
|
||||
mutex_lock(&state->base->tuner_lock);
|
||||
state->base->tuner_use_count[input]--;
|
||||
if (!state->base->tuner_use_count[input])
|
||||
mci_set_tuner(fe, input, 0);
|
||||
state->base->demod_in_use[state->demod] = 0;
|
||||
state->base->used_ldpc_bitrate[state->nr] = 0;
|
||||
state->demod = 0xff;
|
||||
state->base->assigned_demod[state->nr] = 0xff;
|
||||
state->base->iq_mode = 0;
|
||||
mutex_unlock(&state->base->tuner_lock);
|
||||
state->started = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int start(struct dvb_frontend *fe, u32 flags, u32 modmask, u32 ts_config)
|
||||
{
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
static const u32 MAX_DEMOD_LDPC_BITRATE = (1550000000 / 6);
|
||||
u32 used_ldpc_bitrate = 0, free_ldpc_bitrate;
|
||||
u32 used_demods = 0;
|
||||
struct mci_command cmd;
|
||||
u32 input = state->tuner;
|
||||
u32 bits_per_symbol = 0;
|
||||
int i, stat = 0;
|
||||
|
||||
if (p->symbol_rate >= MCLK / 2)
|
||||
flags &= ~1;
|
||||
if ((flags & 3) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (flags & 2) {
|
||||
u32 tmp = modmask;
|
||||
|
||||
bits_per_symbol = 1;
|
||||
while (tmp & 1) {
|
||||
tmp >>= 1;
|
||||
bits_per_symbol++;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&state->base->tuner_lock);
|
||||
if (state->base->iq_mode) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
used_ldpc_bitrate += state->base->used_ldpc_bitrate[i];
|
||||
if (state->base->demod_in_use[i])
|
||||
used_demods++;
|
||||
}
|
||||
if ((used_ldpc_bitrate >= MAX_LDPC_BITRATE) ||
|
||||
((ts_config & SX8_TSCONFIG_MODE_MASK) >
|
||||
SX8_TSCONFIG_MODE_NORMAL && used_demods > 0)) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
free_ldpc_bitrate = MAX_LDPC_BITRATE - used_ldpc_bitrate;
|
||||
if (free_ldpc_bitrate > MAX_DEMOD_LDPC_BITRATE)
|
||||
free_ldpc_bitrate = MAX_DEMOD_LDPC_BITRATE;
|
||||
|
||||
while (p->symbol_rate * bits_per_symbol > free_ldpc_bitrate)
|
||||
bits_per_symbol--;
|
||||
if (bits_per_symbol < 2) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
i = (p->symbol_rate > MCLK / 2) ? 3 : 7;
|
||||
while (i >= 0 && state->base->demod_in_use[i])
|
||||
i--;
|
||||
if (i < 0) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
state->base->demod_in_use[i] = 1;
|
||||
state->base->used_ldpc_bitrate[state->nr] = p->symbol_rate * bits_per_symbol;
|
||||
state->demod = state->base->assigned_demod[state->nr] = i;
|
||||
|
||||
if (!state->base->tuner_use_count[input])
|
||||
mci_set_tuner(fe, input, 1);
|
||||
state->base->tuner_use_count[input]++;
|
||||
state->base->iq_mode = (ts_config > 1);
|
||||
unlock:
|
||||
mutex_unlock(&state->base->tuner_lock);
|
||||
if (stat)
|
||||
return stat;
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
if (state->base->iq_mode) {
|
||||
cmd.command = SX8_CMD_SELECT_IQOUT;
|
||||
cmd.demod = state->demod;
|
||||
cmd.output = 0;
|
||||
mci_cmd(state, &cmd, NULL);
|
||||
mci_config(state, ts_config);
|
||||
}
|
||||
if (p->stream_id != NO_STREAM_ID_FILTER && p->stream_id != 0x80000000)
|
||||
flags |= 0x80;
|
||||
printk("frontend %u: tuner=%u demod=%u\n", state->nr, state->tuner, state->demod);
|
||||
cmd.command = MCI_CMD_SEARCH_DVBS;
|
||||
cmd.dvbs2_search.flags = flags;
|
||||
cmd.dvbs2_search.s2_modulation_mask = modmask & ((1 << (bits_per_symbol - 1)) - 1);
|
||||
cmd.dvbs2_search.retry = 2;
|
||||
cmd.dvbs2_search.frequency = p->frequency * 1000;
|
||||
cmd.dvbs2_search.symbol_rate = p->symbol_rate;
|
||||
cmd.dvbs2_search.scrambling_sequence_index =
|
||||
p->scrambling_sequence_index;
|
||||
cmd.dvbs2_search.input_stream_id = p->stream_id;
|
||||
cmd.tuner = state->tuner;
|
||||
cmd.demod = state->demod;
|
||||
cmd.output = state->nr;
|
||||
if (p->stream_id == 0x80000000)
|
||||
cmd.output |= 0x80;
|
||||
stat = mci_cmd(state, &cmd, NULL);
|
||||
if (stat)
|
||||
stop(fe);
|
||||
return stat;
|
||||
}
|
||||
|
||||
|
||||
static int start_iq(struct dvb_frontend *fe, u32 ts_config)
|
||||
{
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
static const u32 MAX_DEMOD_LDPC_BITRATE = (1550000000 / 6);
|
||||
u32 used_ldpc_bitrate = 0, free_ldpc_bitrate;
|
||||
u32 used_demods = 0;
|
||||
struct mci_command cmd;
|
||||
u32 input = state->tuner;
|
||||
int i, stat = 0;
|
||||
|
||||
mutex_lock(&state->base->tuner_lock);
|
||||
if (state->base->iq_mode) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
for (i = 0; i < 8; i++)
|
||||
if (state->base->demod_in_use[i])
|
||||
used_demods++;
|
||||
if (used_demods > 0) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
state->demod = state->base->assigned_demod[state->nr] = 0;
|
||||
if (!state->base->tuner_use_count[input])
|
||||
mci_set_tuner(fe, input, 1);
|
||||
state->base->tuner_use_count[input]++;
|
||||
state->base->iq_mode = (ts_config > 1);
|
||||
unlock:
|
||||
mutex_unlock(&state->base->tuner_lock);
|
||||
if (stat)
|
||||
return stat;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.command = SX8_CMD_START_IQ;
|
||||
cmd.dvbs2_search.frequency = p->frequency * 1000;
|
||||
cmd.dvbs2_search.symbol_rate = p->symbol_rate;
|
||||
cmd.tuner = state->tuner;
|
||||
cmd.demod = state->demod;
|
||||
cmd.output = 7;
|
||||
mci_config(state, ts_config);
|
||||
stat = mci_cmd(state, &cmd, NULL);
|
||||
if (stat)
|
||||
stop(fe);
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int set_parameters(struct dvb_frontend *fe)
|
||||
{
|
||||
int stat = 0;
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 ts_config, iq_mode = 0, isi;
|
||||
|
||||
if (state->started)
|
||||
stop(fe);
|
||||
isi = p->stream_id;
|
||||
if (isi != NO_STREAM_ID_FILTER) {
|
||||
iq_mode = (isi & 0x30000000) >> 28;
|
||||
}
|
||||
switch (iq_mode) {
|
||||
case 1:
|
||||
ts_config = (SX8_TSCONFIG_TSHEADER|SX8_TSCONFIG_MODE_IQ);
|
||||
break;
|
||||
case 2:
|
||||
ts_config = (SX8_TSCONFIG_TSHEADER|SX8_TSCONFIG_MODE_IQ);
|
||||
break;
|
||||
default:
|
||||
ts_config = SX8_TSCONFIG_MODE_NORMAL;
|
||||
break;
|
||||
}
|
||||
if (iq_mode != 2) {
|
||||
u32 flags = 3;
|
||||
u32 mask = 3;
|
||||
|
||||
if (p->modulation == APSK_16 ||
|
||||
p->modulation == APSK_32) {
|
||||
flags = 2;
|
||||
mask = 15;
|
||||
}
|
||||
stat = start(fe, flags, mask, ts_config);
|
||||
} else {
|
||||
stat = start_iq(fe, ts_config);
|
||||
}
|
||||
if (!stat) {
|
||||
state->started = 1;
|
||||
state->first_time_lock = 1;
|
||||
state->signal_info.status = SX8_DEMOD_WAIT_SIGNAL;
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int tune(struct dvb_frontend *fe, bool re_tune,
|
||||
unsigned int mode_flags,
|
||||
unsigned int *delay, enum fe_status *status)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (re_tune) {
|
||||
r = set_parameters(fe);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
r = read_status(fe, status);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (*status & FE_HAS_LOCK)
|
||||
return 0;
|
||||
*delay = HZ / 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_algo(struct dvb_frontend *fe)
|
||||
{
|
||||
return DVBFE_ALGO_HW;
|
||||
}
|
||||
|
||||
static int set_input(struct dvb_frontend *fe, int input)
|
||||
{
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
|
||||
state->tuner = p->input = input;
|
||||
printk("fe %u, input = %u\n", state->nr, input);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
|
||||
}
|
||||
|
||||
static int get_snr(struct dvb_frontend *fe)
|
||||
{
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
s32 snr;
|
||||
|
||||
get_info(fe);
|
||||
p->cnr.len = 1;
|
||||
p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->cnr.stat[0].svalue = (s64) state->signal_info.dvbs2_signal_info.signal_to_noise * 100;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_strength(struct dvb_frontend *fe)
|
||||
{
|
||||
struct mci *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
s32 str;
|
||||
|
||||
get_info(fe);
|
||||
str = 100000 - (state->signal_info.dvbs2_signal_info.channel_power * 10 + 108750);
|
||||
p->strength.len = 1;
|
||||
p->strength.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->strength.stat[0].svalue = str;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dvb_frontend_ops mci_ops = {
|
||||
.delsys = { SYS_DVBS, SYS_DVBS2 },
|
||||
.info = {
|
||||
.name = "DVB-S/S2X",
|
||||
.frequency_min = 950000,
|
||||
.frequency_max = 2150000,
|
||||
.frequency_stepsize = 0,
|
||||
.frequency_tolerance = 0,
|
||||
.symbol_rate_min = 100000,
|
||||
.symbol_rate_max = 100000000,
|
||||
.caps = FE_CAN_INVERSION_AUTO |
|
||||
FE_CAN_FEC_AUTO |
|
||||
FE_CAN_QPSK |
|
||||
FE_CAN_2G_MODULATION |
|
||||
FE_CAN_MULTISTREAM,
|
||||
},
|
||||
.get_frontend_algo = get_algo,
|
||||
.tune = tune,
|
||||
.release = release,
|
||||
.read_status = read_status,
|
||||
.set_input = set_input,
|
||||
};
|
||||
|
||||
static struct mci_base *match_base(void *key)
|
||||
{
|
||||
struct mci_base *p;
|
||||
@@ -608,16 +325,16 @@ static int probe(struct mci *state)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dvb_frontend *ddb_mci_attach(struct ddb_input *input, int mci_type, int nr)
|
||||
struct dvb_frontend *ddb_mci_attach(struct ddb_input *input, struct mci_cfg *cfg, int nr, int tuner)
|
||||
{
|
||||
struct ddb_port *port = input->port;
|
||||
struct ddb *dev = port->dev;
|
||||
struct ddb_link *link = &dev->link[port->lnr];
|
||||
struct mci_base *base;
|
||||
struct mci *state;
|
||||
void *key = mci_type ? (void *) port : (void *) link;
|
||||
void *key = cfg->type ? (void *) port : (void *) link;
|
||||
|
||||
state = kzalloc(sizeof(*state), GFP_KERNEL);
|
||||
state = kzalloc(cfg->state_size, GFP_KERNEL);
|
||||
if (!state)
|
||||
return NULL;
|
||||
|
||||
@@ -626,7 +343,7 @@ struct dvb_frontend *ddb_mci_attach(struct ddb_input *input, int mci_type, int n
|
||||
base->count++;
|
||||
state->base = base;
|
||||
} else {
|
||||
base = kzalloc(sizeof(*base), GFP_KERNEL);
|
||||
base = kzalloc(cfg->base_size, GFP_KERNEL);
|
||||
if (!base)
|
||||
goto fail;
|
||||
base->key = key;
|
||||
@@ -642,14 +359,16 @@ struct dvb_frontend *ddb_mci_attach(struct ddb_input *input, int mci_type, int n
|
||||
goto fail;
|
||||
}
|
||||
list_add(&base->mci_list, &mci_list);
|
||||
if (cfg->base_init)
|
||||
cfg->base_init(base);
|
||||
}
|
||||
state->fe.ops = mci_ops;
|
||||
memcpy(&state->fe.ops, cfg->fe_ops, sizeof(struct dvb_frontend_ops));
|
||||
state->fe.demodulator_priv = state;
|
||||
state->nr = nr;
|
||||
|
||||
state->tuner = nr;
|
||||
state->demod = nr;
|
||||
|
||||
state->tuner = tuner;
|
||||
if (cfg->init)
|
||||
cfg->init(state);
|
||||
return &state->fe;
|
||||
fail:
|
||||
kfree(state);
|
||||
|
@@ -1,9 +1,9 @@
|
||||
/*
|
||||
* ddbridge-mci.h: Digital Devices micro code interface
|
||||
*
|
||||
* Copyright (C) 2017 Digital Devices GmbH
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Copyright (C) 2017-2018 Digital Devices GmbH
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -24,6 +24,22 @@
|
||||
#ifndef _DDBRIDGE_MCI_H_
|
||||
#define _DDBRIDGE_MCI_H_
|
||||
|
||||
#define SX8_TSINPUT (0x280)
|
||||
#define MIC_CONTROL (0x500)
|
||||
#define MIC_PROGMEM_OLD (0x4000)
|
||||
#define MIC_PROGMEM_OLD_SIZE (0x4000)
|
||||
|
||||
#define MIC_PROGMEM (0x8000)
|
||||
#define MIC_PROGMEM_SIZE (0x8000)
|
||||
|
||||
#define MIC_DATAMEM (0x8000)
|
||||
#define MIC_DATAMEM_SIZE (0x2000)
|
||||
|
||||
#define MIC_INTERFACE_IN (0x0600)
|
||||
#define MIC_INTERFACE_OUT (0x0680)
|
||||
#define MIC_INTERFACE_VER (0x06F0)
|
||||
|
||||
|
||||
#define MCI_CONTROL (0x500)
|
||||
#define MCI_COMMAND (0x600)
|
||||
#define MCI_RESULT (0x680)
|
||||
@@ -43,6 +59,22 @@
|
||||
#define SX8_TSCONFIG_MODE_NORMAL (0x00000001)
|
||||
#define SX8_TSCONFIG_MODE_IQ (0x00000003)
|
||||
|
||||
/*
|
||||
* IQMode only vailable on MaxSX8 on a single tuner
|
||||
*
|
||||
* IQ_MODE_SAMPLES
|
||||
* sampling rate is 1550/24 MHz (64.583 MHz)
|
||||
* channel agc is frozen, to allow stitching the FFT results together
|
||||
*
|
||||
* IQ_MODE_VTM
|
||||
* sampling rate is the supplied symbolrate
|
||||
* channel agc is active
|
||||
*
|
||||
* in both cases down sampling is done with a RRC Filter (currently fixed to alpha = 0.05)
|
||||
* which causes some (ca 5%) aliasing at the edges from outside the spectrum
|
||||
*/
|
||||
|
||||
|
||||
#define SX8_TSCONFIG_TSHEADER (0x00000004)
|
||||
#define SX8_TSCONFIG_BURST (0x00000008)
|
||||
|
||||
@@ -52,114 +84,464 @@
|
||||
#define SX8_TSCONFIG_BURSTSIZE_8K (0x00000020)
|
||||
#define SX8_TSCONFIG_BURSTSIZE_16K (0x00000030)
|
||||
|
||||
#define SX8_DEMOD_STOPPED (0)
|
||||
#define SX8_DEMOD_IQ_MODE (1)
|
||||
#define SX8_DEMOD_WAIT_SIGNAL (2)
|
||||
#define SX8_DEMOD_WAIT_MATYPE (3)
|
||||
#define SX8_DEMOD_TIMEOUT (14)
|
||||
#define SX8_DEMOD_LOCKED (15)
|
||||
/* additional TS input control bits on MaxSX8 DD01:0009 */
|
||||
#define TS_INPUT_CONTROL_SIZEMASK (0x00000030)
|
||||
#define TS_INPUT_CONTROL_SIZE188 (0x00000000)
|
||||
#define TS_INPUT_CONTROL_SIZE192 (0x00000010)
|
||||
#define TS_INPUT_CONTROL_SIZE196 (0x00000020)
|
||||
|
||||
#define MCI_CMD_STOP (0x01)
|
||||
#define MCI_CMD_GETSTATUS (0x02)
|
||||
#define MCI_CMD_GETSIGNALINFO (0x03)
|
||||
#define MCI_CMD_RFPOWER (0x04)
|
||||
|
||||
/********************************************************/
|
||||
|
||||
#define SX8_DEMOD_STOPPED (0)
|
||||
#define SX8_DEMOD_IQ_MODE (1)
|
||||
#define SX8_DEMOD_WAIT_SIGNAL (2)
|
||||
#define SX8_DEMOD_WAIT_MATYPE (3)
|
||||
#define SX8_DEMOD_TIMEOUT (14)
|
||||
#define SX8_DEMOD_LOCKED (15)
|
||||
|
||||
#define M4_DEMOD_STOPPED (0)
|
||||
#define M4_DEMOD_WAIT_SIGNAL (1)
|
||||
#define M4_DEMOD_TIMEOUT (14)
|
||||
#define M4_DEMOD_LOCKED (15)
|
||||
|
||||
#define MCI_CMD_STOP (0x01)
|
||||
#define MCI_CMD_GETSTATUS (0x02)
|
||||
#define MCI_CMD_GETSIGNALINFO (0x03)
|
||||
#define MCI_CMD_RFPOWER (0x04)
|
||||
|
||||
#define MCI_CMD_SEARCH_DVBS (0x10)
|
||||
#define MCI_CMD_SEARCH_DVBC (0x20)
|
||||
#define MCI_CMD_SEARCH_DVBT (0x21)
|
||||
#define MCI_CMD_SEARCH_DVBT2 (0x22)
|
||||
#define MCI_CMD_SEARCH_DVBC2 (0x23)
|
||||
#define MCI_CMD_SEARCH_ISDBT (0x24)
|
||||
|
||||
#define MCI_CMD_GET_IQSYMBOL (0x30)
|
||||
#define MCI_CMD_GET_IQSYMBOL (0x30)
|
||||
|
||||
#define SX8_CMD_INPUT_ENABLE (0x40)
|
||||
#define SX8_CMD_INPUT_DISABLE (0x41)
|
||||
#define SX8_CMD_START_IQ (0x42)
|
||||
#define SX8_CMD_STOP_IQ (0x43)
|
||||
#define SX8_CMD_SELECT_IQOUT (0x44)
|
||||
#define SX8_CMD_SELECT_TSOUT (0x45)
|
||||
#define MCI_BANDWIDTH_UNKNOWN (0)
|
||||
#define MCI_BANDWIDTH_1_7MHZ (1)
|
||||
#define MCI_BANDWIDTH_5MHZ (5)
|
||||
#define MCI_BANDWIDTH_6MHZ (6)
|
||||
#define MCI_BANDWIDTH_7MHZ (7)
|
||||
#define MCI_BANDWIDTH_8MHZ (8)
|
||||
|
||||
#define SX8_ERROR_UNSUPPORTED (0x80)
|
||||
#define M4_MODE_DVBSX (2)
|
||||
#define M4_MODE_DVBC (3)
|
||||
#define M4_MODE_DVBT (4)
|
||||
#define M4_MODE_DVBT2 (5)
|
||||
#define M4_MODE_DVBC2 (6)
|
||||
#define M4_MODE_ISDBT (7)
|
||||
|
||||
#define SX8_SUCCESS(status) (status < SX8_ERROR_UNSUPPORTED)
|
||||
#define SX8_CMD_INPUT_ENABLE (0x40)
|
||||
#define SX8_CMD_INPUT_DISABLE (0x41)
|
||||
#define SX8_CMD_START_IQ (0x42)
|
||||
#define SX8_CMD_STOP_IQ (0x43)
|
||||
#define SX8_CMD_ENABLE_IQOUTPUT (0x44)
|
||||
#define SX8_CMD_DISABLE_IQOUTPUT (0x45)
|
||||
|
||||
#define SX8_CMD_DIAG_READ8 (0xE0)
|
||||
#define SX8_CMD_DIAG_READ32 (0xE1)
|
||||
#define SX8_CMD_DIAG_WRITE8 (0xE2)
|
||||
#define SX8_CMD_DIAG_WRITE32 (0xE3)
|
||||
#define M4_CMD_GET_T2_L1INFO (0x50)
|
||||
#define M4_CMD_GET_C2_L1P2 (0x50)
|
||||
#define M4_CMD_GET_IDS (0x51)
|
||||
|
||||
#define M4_CMD_DIAG_READRF (0xE8)
|
||||
#define M4_CMD_DIAG_WRITERF (0xE9)
|
||||
#define MCI_STATUS_OK (0x00)
|
||||
#define MCI_STATUS_UNSUPPORTED (0x80)
|
||||
#define MCI_STATUS_RETRY (0xFD)
|
||||
#define MCI_STATUS_NOT_READY (0xFE)
|
||||
#define MCI_STATUS_ERROR (0xFF)
|
||||
|
||||
#define M4_CMD_DIAG_READX (0xE0)
|
||||
#define M4_CMD_DIAG_READT (0xE1)
|
||||
#define M4_CMD_DIAG_WRITEX (0xE2)
|
||||
#define M4_CMD_DIAG_WRITET (0xE3)
|
||||
#define MCI_SUCCESS(status) ((status & MCI_STATUS_UNSUPPORTED) == 0)
|
||||
|
||||
#define M4_CMD_DIAG_READRF (0xE8)
|
||||
#define M4_CMD_DIAG_WRITERF (0xE9)
|
||||
|
||||
/********************************************************/
|
||||
|
||||
struct mci_command {
|
||||
union {
|
||||
u32 command_word;
|
||||
struct {
|
||||
u8 command;
|
||||
u8 tuner;
|
||||
u8 demod;
|
||||
u8 output;
|
||||
};
|
||||
};
|
||||
union {
|
||||
u32 params[31];
|
||||
struct {
|
||||
u8 flags;
|
||||
u8 s2_modulation_mask;
|
||||
u8 rsvd1;
|
||||
u8 retry;
|
||||
u32 frequency;
|
||||
u32 symbol_rate;
|
||||
u8 input_stream_id;
|
||||
u8 rsvd2[3];
|
||||
u32 scrambling_sequence_index;
|
||||
} dvbs2_search;
|
||||
};
|
||||
union {
|
||||
u32 command_word;
|
||||
struct {
|
||||
u8 command;
|
||||
u8 tuner;
|
||||
u8 demod;
|
||||
u8 output;
|
||||
};
|
||||
};
|
||||
union {
|
||||
u32 params[31];
|
||||
struct {
|
||||
u8 flags; /* Bit 0: DVB-S Enabled, 1: DVB-S2 Enabled, 7: InputStreamID*/
|
||||
/* Bit 0 : QPSK, 1: 8PSK/8APSK, 2 : 16APSK, 3: 32APSK, 4: 64APSK, 5: 128APSK, 6: 256APSK */
|
||||
u8 s2_modulation_mask;
|
||||
u8 rsvd1;
|
||||
u8 retry;
|
||||
u32 frequency;
|
||||
u32 symbol_rate;
|
||||
u8 input_stream_id;
|
||||
u8 rsvd2[3];
|
||||
u32 scrambling_sequence_index;
|
||||
u32 frequency_range;
|
||||
} dvbs2_search;
|
||||
|
||||
struct {
|
||||
u8 flags;
|
||||
u8 bandwidth;
|
||||
u8 rsvd1;
|
||||
u8 retry;
|
||||
u32 frequency;
|
||||
} dvbc_search;
|
||||
|
||||
struct {
|
||||
u8 flags; /* Bit 0: LP Stream */
|
||||
u8 bandwidth;
|
||||
u8 rsvd1;
|
||||
u8 retry;
|
||||
u32 frequency;
|
||||
} dvbt_search;
|
||||
|
||||
struct {
|
||||
u8 flags; /* Bit 0: T2 Lite Profile, 7: PLP, */
|
||||
u8 bandwidth;
|
||||
u8 rsvd1;
|
||||
u8 retry;
|
||||
u32 frequency;
|
||||
u32 reserved;
|
||||
u8 plp;
|
||||
u8 rsvd2[3];
|
||||
} dvbt2_search;
|
||||
|
||||
struct {
|
||||
u8 flags;
|
||||
u8 bandwidth;
|
||||
u8 rsvd1;
|
||||
u8 retry;
|
||||
u32 frequency;
|
||||
u32 reserved;
|
||||
u8 plp;
|
||||
u8 data_slice;
|
||||
u8 rsvd2[2];
|
||||
} dvbc2_search;
|
||||
|
||||
struct {
|
||||
u8 flags;
|
||||
u8 bandwidth;
|
||||
u8 rsvd1;
|
||||
u8 retry;
|
||||
u32 frequency;
|
||||
} isdbt_search;
|
||||
|
||||
struct {
|
||||
u8 tap;
|
||||
u8 rsvd;
|
||||
u16 point;
|
||||
} get_iq_symbol;
|
||||
|
||||
struct {
|
||||
u8 flags; /* Bit 0 : 0 = VTM, 1 = SCAN. Bit 1: Set Gain */
|
||||
u8 roll_off;
|
||||
u8 rsvd1;
|
||||
u8 rsvd2;
|
||||
u32 frequency;
|
||||
u32 symbol_rate; /* Only in VTM mode. */
|
||||
u16 gain;
|
||||
} sx8_start_iq;
|
||||
|
||||
struct {
|
||||
/* Bit 1:0 = STVVGLNA Gain. 0 = AGC, 1 = 0dB,
|
||||
2 = Minimum, 3 = Maximum */
|
||||
u8 flags;
|
||||
} sx8_input_enable;
|
||||
|
||||
struct {
|
||||
u8 Offset; // Offset into list, must be multiple of 64
|
||||
u8 Select; // 0 = Slices, 1 = PLPs (C2 Only)
|
||||
u8 DataSlice; // DataSlice to get PLPList (C2 Only)
|
||||
} get_ids;
|
||||
|
||||
struct {
|
||||
u8 select; // 0 = Base, 1 = DataSilce, 2 = PLP, Bit 7: Set new ID
|
||||
u8 id; // DataSliceID, PLPId
|
||||
} get_l1_info;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
struct mci_result {
|
||||
union {
|
||||
u32 status_word;
|
||||
struct {
|
||||
u8 status;
|
||||
u8 rsvd;
|
||||
u8 status;
|
||||
u8 mode;
|
||||
u16 time;
|
||||
};
|
||||
};
|
||||
union {
|
||||
u32 result[27];
|
||||
struct {
|
||||
u8 standard;
|
||||
u8 pls_code; /* puncture rate for DVB-S */
|
||||
u8 roll_off; /* 7-6: rolloff, 5-2: rsrvd, 1:short, 0:pilots */
|
||||
u8 standard; /* 1 = DVB-S, 2 = DVB-S2X */
|
||||
u8 pls_code; /* puncture rate for DVB-S */
|
||||
u8 roll_off; /* 2-0: rolloff */
|
||||
u8 rsvd;
|
||||
u32 frequency;
|
||||
u32 symbol_rate;
|
||||
s16 channel_power;
|
||||
s16 band_power;
|
||||
s16 signal_to_noise;
|
||||
u32 frequency; /* actual frequency in Hz */
|
||||
u32 symbol_rate; /* actual symbolrate in Hz */
|
||||
s16 channel_power; /* channel power in dBm x 100 */
|
||||
s16 band_power; /*/ band power in dBm x 100 */
|
||||
s16 signal_to_noise; /* SNR in dB x 100, Note: negativ values are valid in DVB-S2 */
|
||||
s16 rsvd2;
|
||||
u32 packet_errors;
|
||||
u32 ber_numerator;
|
||||
u32 packet_errors; /* Counter for packet errors. (set to 0 on Start command) */
|
||||
u32 ber_numerator; /* Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X */
|
||||
u32 ber_denominator;
|
||||
} dvbs2_signal_info;
|
||||
|
||||
struct {
|
||||
u8 i_symbol;
|
||||
u8 q_symbol;
|
||||
} dvbs2_signal_iq;
|
||||
u8 modulation;
|
||||
u8 rsvd1[3];
|
||||
u32 frequency; /* actual frequency in Hz */
|
||||
u32 symbol_rate; /* actual symbolrate in Hz */
|
||||
s16 channel_power; /* channel power in dBm x 100 */
|
||||
s16 band_power; /* band power in dBm x 100 */
|
||||
s16 signal_to_noise; /* SNR in dB x 100, Note: negativ values are valid in DVB-S2 */
|
||||
s16 rsvd2;
|
||||
u32 packet_errors; /* Counter for packet errors. (set to 0 on Start command) */
|
||||
u32 ber_numerator; /* Bit error rate: PreRS */
|
||||
u32 ber_denominator;
|
||||
} dvbc_signal_info;
|
||||
|
||||
struct {
|
||||
u8 tps_25_32; /* Constellation (2), Hierarchy (3), Coderate HP (3) */
|
||||
u8 tps_33_39; /* Coderate LP (3), Guardinterval (2), FFT (2), 0 (1) */
|
||||
u16 tps_cell_id; /* Cell Identifier */
|
||||
u32 frequency; /* actual frequency in Hz */
|
||||
u32 rsvd1;
|
||||
s16 channel_power; /* channel power in dBm x 100 */
|
||||
s16 band_power; /* band power in dBm x 100 */
|
||||
s16 signal_to_noise; /* SNR in dB x 100, Note: negativ values are valid in DVB-S2 */
|
||||
s16 rsvd2;
|
||||
u32 packet_errors; /* Counter for packet errors. (set to 0 on Start command) */
|
||||
u32 ber_numerator; /* Bit error rate: PreRS */
|
||||
u32 ber_denominator;
|
||||
} dvbt_signal_info;
|
||||
|
||||
struct {
|
||||
u32 rsvd0;
|
||||
u32 frequency; /* actual frequency in Hz */
|
||||
u32 rsvd1;
|
||||
s16 channel_power; /* channel power in dBm x 100 */
|
||||
s16 band_power; /* band power in dBm x 100 */
|
||||
s16 signal_to_noise; /* SNR in dB x 100, Note: negativ values are valid in DVB-S2 */
|
||||
s16 rsvd2;
|
||||
u32 packet_errors; /* Counter for packet errors. (set to 0 on Start command) */
|
||||
u32 ber_numerator; /* Bit error rate: PreRS */
|
||||
u32 ber_denominator;
|
||||
} dvbt2_signal_info;
|
||||
|
||||
struct { // Work in Progress
|
||||
u32 rsvd0 ; // Cell Identifier
|
||||
|
||||
u32 frequency; // actual frequency in Hz
|
||||
u32 rsvd1; //
|
||||
s16 channel_power; // channel power in dBm x 100
|
||||
s16 band_power; // band power in dBm x 100
|
||||
s16 signal_to_noise; // SNR in dB x 100, Note: negativ values are valid in DVB-S2
|
||||
s16 rsvd2;
|
||||
u32 packet_errors; // Counter for packet errors. (set to 0 on Start command)
|
||||
u32 ber_numerator; // Bit error rate: PreBCH
|
||||
u32 ber_denominator;
|
||||
} dvbc2_signal_info;
|
||||
|
||||
struct {
|
||||
u32 rsvd0;
|
||||
|
||||
u32 frequency; // actual frequency in Hz
|
||||
u32 rsvd1; //
|
||||
s16 channel_power; // channel power in dBm x 100
|
||||
s16 band_power; // band power in dBm x 100
|
||||
s16 signal_to_noise; // SNR in dB x 100, Note: negativ values are valid in DVB-S2
|
||||
s16 rsvd2;
|
||||
u32 packet_errors; // Counter for packet errors. (set to 0 on Start command)
|
||||
u32 ber_numerator; // Bit error rate: PreRS
|
||||
u32 ber_denominator;
|
||||
|
||||
u8 tmcc_info[13]; // TMCC B20 - B121
|
||||
} isdbt_signal_info;
|
||||
|
||||
struct {
|
||||
s16 i;
|
||||
s16 q;
|
||||
} iq_symbol;
|
||||
|
||||
struct {
|
||||
u8 t2_l1_pre[37];
|
||||
u8 t2_l1_post[15];
|
||||
u8 t2_l1_post_d[19];
|
||||
u8 t2_l1_post_c[19];
|
||||
} dvbt2_l1_info;
|
||||
|
||||
struct {
|
||||
u8 NetworkID[2];
|
||||
u8 C2SystemID[2];
|
||||
u8 StartFrequency[3];
|
||||
u8 C2BandWidth[2];
|
||||
u8 GuardInterval;
|
||||
u8 C2FrameLength[2];
|
||||
u8 L1P2ChangeCounter;
|
||||
u8 NumDataSlices;
|
||||
u8 NumNotches;
|
||||
struct {
|
||||
u8 Start[2];
|
||||
u8 Width[2];
|
||||
u8 Reserved3;
|
||||
} NotchData[15];
|
||||
u8 ReservedTone;
|
||||
u8 Reserved4[2]; // EWS 1 bit, C2_Version 4 bit, Rsvd 11 bit
|
||||
} DVBC2_L1Part2;
|
||||
|
||||
struct {
|
||||
u8 NumIDs;
|
||||
u8 Offset;
|
||||
u8 IDs[64];
|
||||
} DVBC2_IDList;
|
||||
|
||||
struct {
|
||||
u8 SliceID;
|
||||
u8 TunePosition[2];
|
||||
u8 OffsetLeft[2];
|
||||
u8 OffsetRight[2];
|
||||
u8 TIDepth;
|
||||
u8 Type;
|
||||
u8 FECHeaderType;
|
||||
u8 ConstConf;
|
||||
u8 LeftNotch;
|
||||
u8 NumPLP;
|
||||
u8 Reserved2;
|
||||
} DVBC2_SliceInfo;
|
||||
|
||||
struct {
|
||||
u8 PLPID;
|
||||
u8 Bundled;
|
||||
u8 Type;
|
||||
u8 PayloadType;
|
||||
u8 GroupID;
|
||||
u8 Start[2];
|
||||
u8 FEC_Type;
|
||||
u8 Mod;
|
||||
u8 Cod;
|
||||
u8 PSISIReprocessing;
|
||||
u8 TransportstreamID[2];
|
||||
u8 OrginalNetworkID[2];
|
||||
u8 Reserved1;
|
||||
} DVBC2_PLPInfo;
|
||||
};
|
||||
u32 version[4];
|
||||
};
|
||||
|
||||
struct mci_cfg {
|
||||
/* Helper Macros */
|
||||
|
||||
/* DVB-T2 L1-Pre Signalling Data ( ETSI EN 302 755 V1.4.1 Chapter 7.2.2 ) */
|
||||
|
||||
#define L1PRE_TYPE(p) ((p)[0] & 0xFF)
|
||||
#define L1PRE_BWT_EXT(p) ((p)[1] & 0x01)
|
||||
#define L1PRE_S1(p) ((p)[2] & 0x07)
|
||||
#define L1PRE_S2(p) ((p)[3] & 0x0F)
|
||||
#define L1PRE_L1_REPETITION_FLAG(p) ((p)[4] & 0x01)
|
||||
#define L1PRE_GUARD_INTERVAL(p) ((p)[5] & 0x07)
|
||||
#define L1PRE_PAPR(p) ((p)[6] & 0x0F)
|
||||
#define L1PRE_L1_MOD(p) ((p)[7] & 0x0F)
|
||||
#define L1PRE_L1_COD(p) ((p)[8] & 0x03)
|
||||
#define L1PRE_L1_FEC_TYPE(p) ((p)[9] & 0x03)
|
||||
#define L1PRE_L1_POST_SIZE(p) (((u32)((p)[10] & 0x03) << 16) | ((u32)(p)[11] << 8) | (p)[12])
|
||||
#define L1PRE_L1_POST_INFO_SIZE(p) (((u32)((p)[13] & 0x03) << 16) | ((u32)(p)[14] << 8) | (p)[15])
|
||||
#define L1PRE_PILOT_PATTERN(p) ((p)[16] & 0x0F)
|
||||
#define L1PRE_TX_ID_AVAILABILITY(p) ((p)[17] & 0xFF)
|
||||
#define L1PRE_CELL_ID(p) (((u16)(p)[18] << 8) | (p)[19])
|
||||
#define L1PRE_NETWORK_ID(p) (((u16)(p)[20] << 8) | (p)[21])
|
||||
#define L1PRE_T2_SYSTEM_ID(p) (((u16)(p)[22] << 8) | (p)[23])
|
||||
#define L1PRE_NUM_T2_FRAMES(p) ((p)[24] & 0xFF)
|
||||
#define L1PRE_NUM_DATA_SYMBOLS(p) (((u16)((p)[25] & 0x0F) << 8) | (p)[26])
|
||||
#define L1PRE_REGEN_FLAG(p) ((p)[27] & 0x07)
|
||||
#define L1PRE_L1_POST_EXTENSION(p) ((p)[28] & 0x01)
|
||||
#define L1PRE_NUM_RF(p) ((p)[29] & 0x07)
|
||||
#define L1PRE_CURRENT_RF_IDX(p) ((p)[30] & 0x07)
|
||||
#define L1PRE_T2_VERSION(p) ((((p)[31] & 0x03) << 2) | (((p)[32] & 0xC0) >> 6))
|
||||
#define L1PRE_L1_POST_SCRAMBLED(p) (((p)[32] & 0x20) >> 5)
|
||||
#define L1PRE_T2_BASE_LITE(p) (((p)[32] & 0x10) >> 4)
|
||||
|
||||
|
||||
/* DVB-T2 L1-Post Signalling Data ( ETSI EN 302 755 V1.4.1 Chapter 7.2.3 ) */
|
||||
|
||||
#define L1POST_SUB_SLICES_PER_FRAME(p) (((u16)(p)[ 0] & 0x7F) | (p)[ 1])
|
||||
#define L1POST_NUM_PLP(p) ((p)[2] & 0xFF)
|
||||
#define L1POST_NUM_AUX(p) ((p)[3] & 0x0F)
|
||||
#define L1POST_AUX_CONFIG_RFU(p) ((p)[4] & 0xFF)
|
||||
#define L1POST_RF_IDX(p) ((p)[5] & 0x07)
|
||||
#define L1POST_FREQUENCY(p) (((u32)(p)[6] << 24) | ((u32)(p)[7] << 16) | ((u32)(p)[8] << 8) | (p)[9])
|
||||
#define L1POST_FEF_TYPE(p) ((p)[10] & 0x0F)
|
||||
#define L1POST_FEF_LENGTH(p) (((u32)(p)[11] << 16) | ((u32)(p)[12] << 8) | (p)[13])
|
||||
#define L1POST_FEF_INTERVAL(p) ((p)[14] & 0xFF)
|
||||
|
||||
/* Repeated for each PLP, */
|
||||
/* Hardware is restricted to retrieve only values for current data PLP and common PLP */
|
||||
|
||||
#define L1POST_PLP_ID(p) ((p)[0] & 0xFF)
|
||||
#define L1POST_PLP_TYPE(p) ((p)[1] & 0x07)
|
||||
#define L1POST_PLP_PAYLOAD_TYPE(p) ((p)[2] & 0x1F)
|
||||
#define L1POST_FF_FLAG(p) ((p)[3] & 0x01)
|
||||
#define L1POST_FIRST_RF_IDX(p) ((p)[4] & 0x07)
|
||||
#define L1POST_FIRST_FRAME_IDX(p) ((p)[5] & 0xFF)
|
||||
#define L1POST_PLP_GROUP_ID(p) ((p)[6] & 0xFF)
|
||||
#define L1POST_PLP_COD(p) ((p)[7] & 0x07)
|
||||
#define L1POST_PLP_MOD(p) ((p)[8] & 0x07)
|
||||
#define L1POST_PLP_ROTATION(p) ((p)[9] & 0x01)
|
||||
#define L1POST_PLP_FEC_TYPE(p) ((p)[10] & 0x03)
|
||||
#define L1POST_PLP_NUM_BLOCKS_MAX(p) (((u16)((p)[11] & 0x03) << 8) | (p)[12])
|
||||
#define L1POST_FRAME_INTERVAL(p) ((p)[13] & 0xFF)
|
||||
#define L1POST_TIME_IL_LENGTH(p) ((p)[14] & 0xFF)
|
||||
#define L1POST_TIME_IL_TYPE(p) ((p)[15] & 0x01)
|
||||
#define L1POST_IN_BAND_A_FLAG(p) ((p)[16] & 0x01)
|
||||
#define L1POST_IN_BAND_B_FLAG(p) (((p)[17] >> 7) & 0x01)
|
||||
#define L1POST_RESERVED_1(p) (((u16)((p)[17] & 0x7F) << 4) | ((p)[18] & 0xF0) >> 4)
|
||||
#define L1POST_PLP_MODE(p) (((p)[18] >> 2) & 0x03)
|
||||
#define L1POST_STATIC_FLAG(p) (((p)[18] >> 1) & 0x01)
|
||||
#define L1POST_STATIC_PADDING_FLAG(p) (((p)[18] >> 1) & 0x01)
|
||||
|
||||
struct mci_base {
|
||||
struct list_head mci_list;
|
||||
void *key;
|
||||
struct ddb_link *link;
|
||||
struct completion completion;
|
||||
struct i2c_adapter *i2c;
|
||||
struct mutex i2c_lock;
|
||||
struct mutex tuner_lock;
|
||||
struct mutex mci_lock;
|
||||
int count;
|
||||
int type;
|
||||
};
|
||||
|
||||
struct dvb_frontend *ddb_mci_attach(struct ddb_input *input, int mci_type, int nr);
|
||||
struct mci {
|
||||
struct mci_base *base;
|
||||
struct dvb_frontend fe;
|
||||
int nr;
|
||||
int demod;
|
||||
int tuner;
|
||||
|
||||
struct mci_result signal_info;
|
||||
};
|
||||
|
||||
struct mci_cfg {
|
||||
int type;
|
||||
struct dvb_frontend_ops *fe_ops;
|
||||
u32 base_size;
|
||||
u32 state_size;
|
||||
int (*init)(struct mci *mci);
|
||||
int (*base_init)(struct mci_base *mci_base);
|
||||
};
|
||||
|
||||
int ddb_mci_cmd(struct mci *state, struct mci_command *command, struct mci_result *result);
|
||||
int ddb_mci_cmd_raw(struct mci *state, struct mci_command *command, u32 command_len,
|
||||
struct mci_result *result, u32 result_len);
|
||||
int ddb_mci_config(struct mci *state, u32 config);
|
||||
int ddb_mci_get_status(struct mci *mci, struct mci_result *res);
|
||||
int ddb_mci_get_snr(struct dvb_frontend *fe);
|
||||
int ddb_mci_get_info(struct mci *mci);
|
||||
int ddb_mci_get_strength(struct dvb_frontend *fe);
|
||||
void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p);
|
||||
|
||||
#endif
|
||||
|
@@ -21,12 +21,16 @@
|
||||
|
||||
/* Register Definitions */
|
||||
|
||||
#define CUR_REGISTERMAP_VERSION_V1 0x00010001
|
||||
#define CUR_REGISTERMAP_VERSION_V2 0x00020000
|
||||
#define CUR_REGISTERMAP_VERSION_022X 0x00020001
|
||||
#define CUR_REGISTERMAP_VERSION 0x10004
|
||||
#define CUR_REGISTERMAP_VERSION_0007 0x10002
|
||||
#define CUR_REGISTERMAP_VERSION_0008 0x10002
|
||||
#define CUR_REGISTERMAP_VERSION_CI 0x10000
|
||||
#define CUR_REGISTERMAP_VERSION_CI_PRO 0x10000
|
||||
|
||||
#define HARDWARE_VERSION 0x00000000
|
||||
#define REGISTERMAP_VERSION 0x00000004
|
||||
#define HARDWARE_VERSION 0x0000
|
||||
#define REGISTERMAP_VERSION 0x0004
|
||||
#define DEVICE_ID 0x0008
|
||||
#define BOARD_ID 0x000C
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* SPI Controller */
|
||||
@@ -44,10 +48,10 @@
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* MDIO */
|
||||
|
||||
#define MDIO_CTRL 0x20
|
||||
#define MDIO_ADR 0x24
|
||||
#define MDIO_REG 0x28
|
||||
#define MDIO_VAL 0x2C
|
||||
#define MDIO_CTRL_OFF 0x00
|
||||
#define MDIO_ADR_OFF 0x04
|
||||
#define MDIO_REG_OFF 0x08
|
||||
#define MDIO_VAL_OFF 0x0C
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
@@ -148,7 +152,9 @@
|
||||
#define TEMPMON_CONTROL_SCAN (0x00000001)
|
||||
#define TEMPMON_CONTROL_AUTOSCAN (0x00000002)
|
||||
#define TEMPMON_CONTROL_INTENABLE (0x00000004)
|
||||
#define TEMPMON_CONTROL_CLEAR (0x00000008)
|
||||
#define TEMPMON_CONTROL_OVERTEMP (0x00008000)
|
||||
#define TEMPMON_STATUS_SHUTDOWN (0x00008000)
|
||||
|
||||
/* Temperature in C x 256 */
|
||||
#define TEMPMON_CORE (TEMPMON_BASE + 0x04)
|
||||
@@ -160,6 +166,9 @@
|
||||
#define TEMPMON_FANPWM (0x00000F00) /* PWM speed in 10% steps */
|
||||
#define TEMPMON_FANTACHO (0x000000FF) /* Rotations in 100/min steps */
|
||||
|
||||
#define TEMPMON_INTERRUPT_V1 (24)
|
||||
#define TEMPMON_INTERRUPT_V1_MASK (1<<24)
|
||||
|
||||
/* V1 Temperature Monitor
|
||||
* Temperature Monitor TEMPMON_CONTROL & 0x8000 == 0 : ( 2x LM75A @ 0x90,0x92 )
|
||||
* Temperature Monitor TEMPMON_CONTROL & 0x8000 == 1 :
|
||||
@@ -184,6 +193,7 @@
|
||||
/* SHORT Temperature in C x 256 (ADM1032 ext) */
|
||||
#define TEMPMON2_DACCORE (TEMPMON_SENSOR2)
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* I2C Master Controller */
|
||||
|
||||
@@ -223,6 +233,10 @@
|
||||
#define TS_CONTROL(_io) ((_io)->regs + 0x00)
|
||||
#define TS_CONTROL2(_io) ((_io)->regs + 0x04)
|
||||
|
||||
#define TS_INPUT_CONTROL_ENABLE (0x00000001)
|
||||
#define TS_INPUT_CONTROL_RESET (0x00000002)
|
||||
#define TS_INPUT_CONTROL_SKIPERROR (0x00000008)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* DMA Buffer */
|
||||
|
||||
@@ -248,12 +262,19 @@
|
||||
#define LNB_BUSY BIT_ULL(4)
|
||||
#define LNB_TONE BIT_ULL(15)
|
||||
|
||||
#define LNB_INTERRUPT_BASE 4
|
||||
|
||||
#define LNB_STATUS(i) (LNB_BASE + (i) * 0x20 + 0x04)
|
||||
#define LNB_VOLTAGE(i) (LNB_BASE + (i) * 0x20 + 0x08)
|
||||
#define LNB_CONFIG(i) (LNB_BASE + (i) * 0x20 + 0x0c)
|
||||
#define LNB_BUF_LEVEL(i) (LNB_BASE + (i) * 0x20 + 0x10)
|
||||
#define LNB_BUF_WRITE(i) (LNB_BASE + (i) * 0x20 + 0x14)
|
||||
|
||||
#define LNB_SETTING(i) (LNB_BASE + (i) * 0x20 + 0x0c)
|
||||
#define LNB_FIFO_LEVEL(i) (LNB_BASE + (i) * 0x20 + 0x10)
|
||||
#define LNB_RESET_FIFO(i) (LNB_BASE + (i) * 0x20 + 0x10)
|
||||
#define LNB_WRITE_FIFO(i) (LNB_BASE + (i) * 0x20 + 0x14)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* CI Interface (only CI-Bridge) */
|
||||
|
||||
|
521
ddbridge/ddbridge-sx8.c
Normal file
521
ddbridge/ddbridge-sx8.c
Normal file
@@ -0,0 +1,521 @@
|
||||
/*
|
||||
* ddbridge-sx8.c: Digital Devices MAX SX8 driver
|
||||
*
|
||||
* Copyright (C) 2018 Digital Devices GmbH
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* 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, point your browser to
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include "ddbridge.h"
|
||||
#include "ddbridge-io.h"
|
||||
#include "ddbridge-i2c.h"
|
||||
#include "ddbridge-mci.h"
|
||||
|
||||
static const u32 MCLK = (1550000000 / 12);
|
||||
static const u32 MAX_LDPC_BITRATE = (720000000);
|
||||
static const u32 MAX_DEMOD_LDPC_BITRATE = (1550000000 / 6);
|
||||
|
||||
#define SX8_TUNER_NUM 4
|
||||
#define SX8_DEMOD_NUM 8
|
||||
#define SX8_DEMOD_NONE 0xff
|
||||
|
||||
struct sx8_base {
|
||||
struct mci_base mci_base;
|
||||
|
||||
u8 tuner_use_count[SX8_TUNER_NUM];
|
||||
u32 gain_mode[SX8_TUNER_NUM];
|
||||
|
||||
u32 used_ldpc_bitrate[SX8_DEMOD_NUM];
|
||||
u8 demod_in_use[SX8_DEMOD_NUM];
|
||||
u32 iq_mode;
|
||||
u32 burst_size;
|
||||
u32 direct_mode;
|
||||
};
|
||||
|
||||
struct sx8 {
|
||||
struct mci mci;
|
||||
|
||||
int first_time_lock;
|
||||
int started;
|
||||
|
||||
u32 bb_mode;
|
||||
u32 local_frequency;
|
||||
|
||||
};
|
||||
|
||||
static const u8 dvbs2_bits_per_symbol[] = {
|
||||
0, 0, 0, 0,
|
||||
/* S2 QPSK */
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
/* S2 8PSK */
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3,
|
||||
/* S2 16APSK */
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
/* S2 32APSK */
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
3, 0, 4, 0,
|
||||
2, 2, 2, 2, 2, 2, // S2X QPSK
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // S2X 8PSK
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // S2X 16APSK
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // S2X 32APSK
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // S2X 64APSK
|
||||
7, 7, 7, 7, // S2X 128APSK
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // S2X 256APSK
|
||||
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // S2X QPSK
|
||||
3, 3, 3, 3, 3, 3, 3, 3, // S2X 8PSK
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // S2X 16APSK
|
||||
5, 5, 5, 5, // S2X 32APSK
|
||||
|
||||
3, 4, 5, 6, 8, 10,
|
||||
};
|
||||
|
||||
|
||||
static void release(struct dvb_frontend *fe)
|
||||
{
|
||||
struct sx8 *state = fe->demodulator_priv;
|
||||
struct mci_base *mci_base = state->mci.base;
|
||||
|
||||
mci_base->count--;
|
||||
if (mci_base->count == 0) {
|
||||
list_del(&mci_base->mci_list);
|
||||
kfree(mci_base);
|
||||
}
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
static int read_status(struct dvb_frontend *fe, enum fe_status *status)
|
||||
{
|
||||
int stat;
|
||||
struct sx8 *state = fe->demodulator_priv;
|
||||
struct mci_base *mci_base = state->mci.base;
|
||||
struct sx8_base *sx8_base = (struct sx8_base *) mci_base;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
struct mci_result res;
|
||||
|
||||
stat = ddb_mci_get_status(&state->mci, &res);
|
||||
if (stat)
|
||||
return stat;
|
||||
*status = 0x00;
|
||||
ddb_mci_get_info(&state->mci);
|
||||
if (res.status == SX8_DEMOD_WAIT_MATYPE)
|
||||
*status = 0x0f;
|
||||
if (res.status == SX8_DEMOD_LOCKED) {
|
||||
*status = 0x1f;
|
||||
if (state->mci.signal_info.dvbs2_signal_info.standard == 2) {
|
||||
sx8_base->used_ldpc_bitrate[state->mci.nr] =
|
||||
p->symbol_rate *
|
||||
dvbs2_bits_per_symbol[
|
||||
state->mci.signal_info.
|
||||
dvbs2_signal_info.pls_code];
|
||||
} else
|
||||
sx8_base->used_ldpc_bitrate[state->mci.nr] = 0;
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int mci_set_tuner(struct dvb_frontend *fe, u32 tuner, u32 on)
|
||||
{
|
||||
struct sx8 *state = fe->demodulator_priv;
|
||||
struct mci_base *mci_base = state->mci.base;
|
||||
struct sx8_base *sx8_base = (struct sx8_base *) mci_base;
|
||||
struct mci_command cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.tuner = state->mci.tuner;
|
||||
cmd.command = on ? SX8_CMD_INPUT_ENABLE : SX8_CMD_INPUT_DISABLE;
|
||||
cmd.sx8_input_enable.flags = sx8_base->gain_mode[state->mci.tuner];
|
||||
return ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
}
|
||||
|
||||
static int stop(struct dvb_frontend *fe)
|
||||
{
|
||||
struct sx8 *state = fe->demodulator_priv;
|
||||
struct mci_base *mci_base = state->mci.base;
|
||||
struct sx8_base *sx8_base = (struct sx8_base *) mci_base;
|
||||
struct mci_command cmd;
|
||||
u32 input = state->mci.tuner;
|
||||
|
||||
if (!state->started)
|
||||
return -1;
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
if (state->mci.demod != SX8_DEMOD_NONE) {
|
||||
cmd.command = MCI_CMD_STOP;
|
||||
cmd.demod = state->mci.demod;
|
||||
ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
if (sx8_base->iq_mode) {
|
||||
cmd.command = SX8_CMD_DISABLE_IQOUTPUT;
|
||||
cmd.demod = state->mci.demod;
|
||||
cmd.output = 0;
|
||||
ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
ddb_mci_config(&state->mci, SX8_TSCONFIG_MODE_NORMAL);
|
||||
}
|
||||
}
|
||||
mutex_lock(&mci_base->tuner_lock);
|
||||
sx8_base->tuner_use_count[input]--;
|
||||
if (!sx8_base->tuner_use_count[input])
|
||||
mci_set_tuner(fe, input, 0);
|
||||
if (state->mci.demod != SX8_DEMOD_NONE) {
|
||||
sx8_base->demod_in_use[state->mci.demod] = 0;
|
||||
state->mci.demod = SX8_DEMOD_NONE;
|
||||
}
|
||||
sx8_base->used_ldpc_bitrate[state->mci.nr] = 0;
|
||||
sx8_base->iq_mode = 0;
|
||||
mutex_unlock(&mci_base->tuner_lock);
|
||||
state->started = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int start(struct dvb_frontend *fe, u32 flags, u32 modmask, u32 ts_config)
|
||||
{
|
||||
struct sx8 *state = fe->demodulator_priv;
|
||||
struct mci_base *mci_base = state->mci.base;
|
||||
struct sx8_base *sx8_base = (struct sx8_base *) mci_base;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
static const u32 MAX_DEMOD_LDPC_BITRATE = (1550000000 / 6);
|
||||
u32 used_ldpc_bitrate = 0, free_ldpc_bitrate;
|
||||
u32 used_demods = 0;
|
||||
struct mci_command cmd;
|
||||
u32 input = state->mci.tuner;
|
||||
u32 bits_per_symbol = 0;
|
||||
int i = -1, stat = 0;
|
||||
|
||||
if (p->symbol_rate >= MCLK / 2)
|
||||
flags &= ~1;
|
||||
if ((flags & 3) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (flags & 2) {
|
||||
u32 tmp = modmask;
|
||||
|
||||
bits_per_symbol = 1;
|
||||
while (tmp & 1) {
|
||||
tmp >>= 1;
|
||||
bits_per_symbol++;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&mci_base->tuner_lock);
|
||||
if (sx8_base->iq_mode) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (sx8_base->direct_mode) {
|
||||
if (p->symbol_rate >= MCLK / 2) {
|
||||
if (state->mci.nr < 4)
|
||||
i = state->mci.nr;
|
||||
} else {
|
||||
i = state->mci.nr;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < SX8_DEMOD_NUM; i++) {
|
||||
used_ldpc_bitrate += sx8_base->used_ldpc_bitrate[i];
|
||||
if (sx8_base->demod_in_use[i])
|
||||
used_demods++;
|
||||
}
|
||||
printk("used_ldpc_bitrate = %u\n", used_ldpc_bitrate);
|
||||
if ((used_ldpc_bitrate >= MAX_LDPC_BITRATE) ||
|
||||
((ts_config & SX8_TSCONFIG_MODE_MASK) >
|
||||
SX8_TSCONFIG_MODE_NORMAL && used_demods > 0)) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
free_ldpc_bitrate = MAX_LDPC_BITRATE - used_ldpc_bitrate;
|
||||
if (free_ldpc_bitrate > MAX_DEMOD_LDPC_BITRATE)
|
||||
free_ldpc_bitrate = MAX_DEMOD_LDPC_BITRATE;
|
||||
|
||||
while (p->symbol_rate * bits_per_symbol > free_ldpc_bitrate)
|
||||
bits_per_symbol--;
|
||||
if (bits_per_symbol < 2) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
modmask &= ((1 << (bits_per_symbol - 1)) - 1);
|
||||
if( ((flags & 0x02) != 0) && (modmask == 0)) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
i = (p->symbol_rate > MCLK / 2) ? 3 : 7;
|
||||
while (i >= 0 && sx8_base->demod_in_use[i])
|
||||
i--;
|
||||
}
|
||||
if (i < 0) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
sx8_base->demod_in_use[i] = 1;
|
||||
sx8_base->used_ldpc_bitrate[state->mci.nr] = p->symbol_rate * bits_per_symbol;
|
||||
state->mci.demod = i;
|
||||
|
||||
if (!sx8_base->tuner_use_count[input])
|
||||
mci_set_tuner(fe, input, 1);
|
||||
sx8_base->tuner_use_count[input]++;
|
||||
sx8_base->iq_mode = (ts_config > 1);
|
||||
unlock:
|
||||
mutex_unlock(&mci_base->tuner_lock);
|
||||
if (stat)
|
||||
return stat;
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
if (sx8_base->iq_mode) {
|
||||
cmd.command = SX8_CMD_ENABLE_IQOUTPUT;
|
||||
cmd.demod = state->mci.demod;
|
||||
cmd.output = 0;
|
||||
ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
ddb_mci_config(&state->mci, ts_config);
|
||||
}
|
||||
if (p->stream_id != NO_STREAM_ID_FILTER && p->stream_id != 0x80000000)
|
||||
flags |= 0x80;
|
||||
printk("frontend %u: tuner=%u demod=%u\n", state->mci.nr, state->mci.tuner, state->mci.demod);
|
||||
cmd.command = MCI_CMD_SEARCH_DVBS;
|
||||
cmd.dvbs2_search.flags = flags;
|
||||
cmd.dvbs2_search.s2_modulation_mask = modmask;
|
||||
cmd.dvbs2_search.retry = 2;
|
||||
cmd.dvbs2_search.frequency = p->frequency * 1000;
|
||||
cmd.dvbs2_search.symbol_rate = p->symbol_rate;
|
||||
cmd.dvbs2_search.scrambling_sequence_index =
|
||||
p->scrambling_sequence_index | 0x80000000;
|
||||
cmd.dvbs2_search.input_stream_id = p->stream_id;
|
||||
cmd.tuner = state->mci.tuner;
|
||||
cmd.demod = state->mci.demod;
|
||||
cmd.output = state->mci.nr;
|
||||
if (p->stream_id == 0x80000000)
|
||||
cmd.output |= 0x80;
|
||||
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
if (stat)
|
||||
stop(fe);
|
||||
return stat;
|
||||
}
|
||||
|
||||
|
||||
static int start_iq(struct dvb_frontend *fe, u32 flags,
|
||||
u32 roll_off, u32 ts_config)
|
||||
{
|
||||
struct sx8 *state = fe->demodulator_priv;
|
||||
struct mci_base *mci_base = state->mci.base;
|
||||
struct sx8_base *sx8_base = (struct sx8_base *) mci_base;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 used_demods = 0;
|
||||
struct mci_command cmd;
|
||||
u32 input = state->mci.tuner;
|
||||
int i, stat = 0;
|
||||
|
||||
mutex_lock(&mci_base->tuner_lock);
|
||||
if (sx8_base->iq_mode) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
for (i = 0; i < SX8_DEMOD_NUM; i++)
|
||||
if (sx8_base->demod_in_use[i])
|
||||
used_demods++;
|
||||
if (used_demods > 0) {
|
||||
stat = -EBUSY;
|
||||
goto unlock;
|
||||
}
|
||||
state->mci.demod = 0;
|
||||
if (!sx8_base->tuner_use_count[input])
|
||||
mci_set_tuner(fe, input, 1);
|
||||
sx8_base->tuner_use_count[input]++;
|
||||
sx8_base->iq_mode = (ts_config > 1);
|
||||
unlock:
|
||||
mutex_unlock(&mci_base->tuner_lock);
|
||||
if (stat)
|
||||
return stat;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.command = SX8_CMD_START_IQ;
|
||||
cmd.sx8_start_iq.flags = flags;
|
||||
cmd.sx8_start_iq.roll_off = roll_off;
|
||||
cmd.sx8_start_iq.frequency = p->frequency * 1000;
|
||||
cmd.sx8_start_iq.symbol_rate = p->symbol_rate;
|
||||
cmd.tuner = state->mci.tuner;
|
||||
cmd.demod = state->mci.demod;
|
||||
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
if (stat)
|
||||
stop(fe);
|
||||
ddb_mci_config(&state->mci, ts_config);
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int set_parameters(struct dvb_frontend *fe)
|
||||
{
|
||||
int stat = 0;
|
||||
struct sx8 *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 ts_config = SX8_TSCONFIG_MODE_NORMAL, iq_mode = 0, isi;
|
||||
|
||||
stop(fe);
|
||||
isi = p->stream_id;
|
||||
if (isi != NO_STREAM_ID_FILTER) {
|
||||
iq_mode = (isi & 0x30000000) >> 28;
|
||||
}
|
||||
if (iq_mode)
|
||||
ts_config = (SX8_TSCONFIG_TSHEADER | SX8_TSCONFIG_MODE_IQ);
|
||||
if (iq_mode < 2) {
|
||||
u32 mask;
|
||||
|
||||
switch (p->modulation) {
|
||||
case APSK_256:
|
||||
mask = 0x7f;
|
||||
break;
|
||||
case APSK_128:
|
||||
mask = 0x3f;
|
||||
break;
|
||||
case APSK_64:
|
||||
mask = 0x1f;
|
||||
break;
|
||||
case APSK_32:
|
||||
mask = 0x0f;
|
||||
break;
|
||||
case APSK_16:
|
||||
mask = 0x07;
|
||||
break;
|
||||
default:
|
||||
mask = 0x03;
|
||||
break;
|
||||
}
|
||||
stat = start(fe, 3, mask, ts_config);
|
||||
} else {
|
||||
stat = start_iq(fe, iq_mode & 1, 4, ts_config);
|
||||
}
|
||||
if (!stat) {
|
||||
state->started = 1;
|
||||
state->first_time_lock = 1;
|
||||
state->mci.signal_info.status = SX8_DEMOD_WAIT_SIGNAL;
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int tune(struct dvb_frontend *fe, bool re_tune,
|
||||
unsigned int mode_flags,
|
||||
unsigned int *delay, enum fe_status *status)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (re_tune) {
|
||||
r = set_parameters(fe);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
r = read_status(fe, status);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (*status & FE_HAS_LOCK)
|
||||
return 0;
|
||||
*delay = HZ / 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_algo(struct dvb_frontend *fe)
|
||||
{
|
||||
return DVBFE_ALGO_HW;
|
||||
}
|
||||
|
||||
static int set_input(struct dvb_frontend *fe, int input)
|
||||
{
|
||||
struct sx8 *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
|
||||
printk("fe %u, set input = %u\n", state->mci.nr, input);
|
||||
if (input >= SX8_TUNER_NUM)
|
||||
return -EINVAL;
|
||||
if (state->mci.tuner == input)
|
||||
return 0;
|
||||
stop(fe);
|
||||
state->mci.tuner = p->input = input;
|
||||
printk("fe %u, input = %u\n", state->mci.nr, input);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
stop(fe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties *p)
|
||||
{
|
||||
struct sx8 *state = fe->demodulator_priv;
|
||||
|
||||
ddb_mci_proc_info(&state->mci, p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dvb_frontend_ops sx8_ops = {
|
||||
.delsys = { SYS_DVBS, SYS_DVBS2 },
|
||||
.xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */
|
||||
.info = {
|
||||
.name = "DVB-S/S2X",
|
||||
.frequency_min = 950000,
|
||||
.frequency_max = 2150000,
|
||||
.frequency_stepsize = 0,
|
||||
.frequency_tolerance = 0,
|
||||
.symbol_rate_min = 100000,
|
||||
.symbol_rate_max = 100000000,
|
||||
.caps = FE_CAN_INVERSION_AUTO |
|
||||
FE_CAN_FEC_AUTO |
|
||||
FE_CAN_QPSK |
|
||||
FE_CAN_2G_MODULATION |
|
||||
FE_CAN_MULTISTREAM,
|
||||
},
|
||||
.get_frontend_algo = get_algo,
|
||||
.get_frontend = get_frontend,
|
||||
.tune = tune,
|
||||
.release = release,
|
||||
.read_status = read_status,
|
||||
.set_input = set_input,
|
||||
.sleep = sleep,
|
||||
};
|
||||
|
||||
static int init(struct mci *mci)
|
||||
{
|
||||
struct sx8 *state = (struct sx8 *) mci;
|
||||
|
||||
state->mci.demod = SX8_DEMOD_NONE;
|
||||
mci->fe.ops.xbar[1] = mci->nr;
|
||||
mci->fe.dtv_property_cache.input = mci->tuner;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int base_init(struct mci_base *mci_base)
|
||||
{
|
||||
//struct sx8_base *base = (struct sx8_base *) mci_base;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mci_cfg ddb_max_sx8_cfg = {
|
||||
.type = 0,
|
||||
.fe_ops = &sx8_ops,
|
||||
.base_size = sizeof(struct sx8_base),
|
||||
.state_size = sizeof(struct sx8),
|
||||
.init = init,
|
||||
.base_init = base_init,
|
||||
};
|
@@ -92,6 +92,7 @@
|
||||
#include "mxl5xx.h"
|
||||
|
||||
#include "ddbridge-regs.h"
|
||||
#include "ddbridge-mci.h"
|
||||
|
||||
#define DDB_MAX_I2C 32
|
||||
#define DDB_MAX_PORT 32
|
||||
@@ -157,24 +158,28 @@ struct ddb_info {
|
||||
u32 version;
|
||||
char *name;
|
||||
u32 i2c_mask;
|
||||
u32 board_control;
|
||||
u32 board_control_2;
|
||||
|
||||
u8 port_num;
|
||||
u8 led_num;
|
||||
u8 fan_num;
|
||||
u8 temp_num;
|
||||
u8 temp_bus;
|
||||
u32 board_control;
|
||||
u32 board_control_2;
|
||||
u8 ns_num;
|
||||
u8 mdio_num;
|
||||
u8 con_clock; /* use a continuous clock */
|
||||
u8 ts_quirks;
|
||||
#define TS_QUIRK_SERIAL 1
|
||||
#define TS_QUIRK_REVERSED 2
|
||||
#define TS_QUIRK_NO_OUTPUT 4
|
||||
#define TS_QUIRK_ALT_OSC 8
|
||||
u8 mci_ports;
|
||||
u8 mci_type;
|
||||
|
||||
u32 tempmon_irq;
|
||||
u32 lostlock_irq;
|
||||
u8 mci;
|
||||
u32 mdio_base;
|
||||
u32 hw_min;
|
||||
const struct ddb_regmap *regmap;
|
||||
};
|
||||
|
||||
@@ -302,7 +307,6 @@ struct ddb_port {
|
||||
#define DDB_CI_EXTERNAL_XO2_B 13
|
||||
#define DDB_TUNER_DVBS_STV0910_PR 14
|
||||
#define DDB_TUNER_DVBC2T2I_SONY_P 15
|
||||
#define DDB_TUNER_MCI 16
|
||||
|
||||
#define DDB_TUNER_XO2 32
|
||||
#define DDB_TUNER_DVBS_STV0910 (DDB_TUNER_XO2 + 0)
|
||||
@@ -312,6 +316,10 @@ struct ddb_port {
|
||||
#define DDB_TUNER_ATSC_ST (DDB_TUNER_XO2 + 4)
|
||||
#define DDB_TUNER_DVBC2T2I_SONY (DDB_TUNER_XO2 + 5)
|
||||
|
||||
#define DDB_TUNER_MCI 48
|
||||
#define DDB_TUNER_MCI_SX8 (DDB_TUNER_MCI + 0)
|
||||
#define DDB_TUNER_MCI_M4 (DDB_TUNER_MCI + 1)
|
||||
|
||||
struct ddb_input *input[2];
|
||||
struct ddb_output *output;
|
||||
struct dvb_ca_en50221 *en;
|
||||
@@ -516,7 +524,7 @@ struct DDMOD_FLASH {
|
||||
|
||||
int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len);
|
||||
|
||||
#define DDBRIDGE_VERSION "0.9.33"
|
||||
#define DDBRIDGE_VERSION "0.9.34"
|
||||
|
||||
/* linked function prototypes */
|
||||
|
||||
@@ -553,10 +561,12 @@ void ddb_i2c_release(struct ddb *dev);
|
||||
int ddb_ci_attach(struct ddb_port *port, u32 bitrate);
|
||||
|
||||
int ddb_fe_attach_mxl5xx(struct ddb_input *input);
|
||||
int ddb_fe_attach_mci(struct ddb_input *input);
|
||||
int ddb_fe_attach_mci(struct ddb_input *input, u32 type);
|
||||
int ddb_lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm);
|
||||
|
||||
struct ddb_irq *ddb_irq_set(struct ddb *dev, u32 link, u32 nr,
|
||||
void (*handler)(void *), void *data);
|
||||
|
||||
struct dvb_frontend *ddb_mci_attach(struct ddb_input *input, struct mci_cfg *cfg, int nr, int tuner);
|
||||
|
||||
#endif
|
||||
|
@@ -165,5 +165,5 @@ module_exit(exit_octonet);
|
||||
|
||||
MODULE_DESCRIPTION("GPL");
|
||||
MODULE_AUTHOR("Marcus and Ralph Metzler, Metzler Brothers Systementwicklung GbR");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_VERSION(DDBRIDGE_VERSION);
|
||||
|
@@ -1,15 +1,16 @@
|
||||
To allow the transport of DVB-S2 baseband frames (BBFrame) across existing hard- and software
|
||||
interfaces, we have added the ability to embed the BBFrame data into
|
||||
an MPEG2 transport stream.
|
||||
This is available on supported cards as firmware update.
|
||||
|
||||
This feature is currently considered experimental.
|
||||
This feature is available on supported cards as firmware update and
|
||||
is currently considered experimental.
|
||||
|
||||
Supported hardware:
|
||||
|
||||
Cine V7A (>=1.7 FW)
|
||||
OctopusCI S2 Pro Advanced (>=1.7 FW)
|
||||
Duoflex S2 v4 Advanced (TBA)
|
||||
MaxSX8 (NOT the MAXS8!)
|
||||
|
||||
The following cards are based on the broadcast version of the
|
||||
DVB-S2 demodulator. The BBFrame output is working but
|
||||
@@ -80,3 +81,24 @@ API:
|
||||
|
||||
Currently DTV_STREAM_ID is misused.
|
||||
Set it to 0x80000000 to enable frame mode in the demod.
|
||||
|
||||
|
||||
|
||||
Because there were some questions why we use this data format,
|
||||
here are some examples for why using this format this makes handling BBFrames easier:
|
||||
|
||||
- The start of a frame is easily found because a new set of sections is
|
||||
started.
|
||||
|
||||
- Existing software layers like the Linux kernel DVB demuxer can be used unchanged.
|
||||
|
||||
- Existing hardware like the OctopusNet SAT>IP server which can only handle TS packets can
|
||||
stream BBFrames via SAT>IP with this method.
|
||||
|
||||
- There is at least one demodulator (e.g. on the MaxSX8) which supports this format in hardware.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -1,9 +1,9 @@
|
||||
- NAND flash
|
||||
|
||||
0x00000000 - 0x0025ffff U-boot
|
||||
0x00260000 - 0x0027ffff ENV
|
||||
0x00300000 - 0x00ffffff Linux image
|
||||
|
||||
0x01000000 - 0x01ffffff Linux recovery
|
||||
0x02000000 - 0x1fffffff Linux UBI
|
||||
0x00000000 - 0x0007ffff spl 512K
|
||||
0x00080000 - 0x0047ffff uboot 4M
|
||||
0x00480000 - 0x004fffff env 512K
|
||||
0x00500000 - 0x00ffffff spare 11M
|
||||
0x01000000 - 0x01ffffff recovery 16M
|
||||
0x02000000 - 0x1fffffff ubi -
|
||||
|
||||
|
@@ -115,7 +115,7 @@ ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf)
|
||||
void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf)
|
||||
{
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
|
||||
rbuf->pread = smp_load_acquire(&rbuf->pwrite;
|
||||
rbuf->pread = &rbuf->pwrite;
|
||||
#else
|
||||
/* dvb_ringbuffer_flush() counts as read operation
|
||||
* smp_load_acquire() to load write pointer
|
||||
|
@@ -59,7 +59,7 @@ static const char * const dnames[] = {
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DVB_DYNAMIC_MINORS
|
||||
#define MAX_DVB_MINORS 256
|
||||
#define MAX_DVB_MINORS 512
|
||||
#define DVB_MAX_IDS MAX_DVB_MINORS
|
||||
#else
|
||||
#define DVB_MAX_IDS 4
|
||||
|
@@ -590,6 +590,10 @@ static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ci->lock);
|
||||
|
||||
/* Ensure cam stability after reset */
|
||||
msleep(2000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -780,4 +784,4 @@ EXPORT_SYMBOL(cxd2099_attach);
|
||||
|
||||
MODULE_DESCRIPTION("cxd2099");
|
||||
MODULE_AUTHOR("Ralph Metzler");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@@ -2690,4 +2690,4 @@ EXPORT_SYMBOL(cxd2843_attach);
|
||||
|
||||
MODULE_DESCRIPTION("CXD2843/37/38 driver");
|
||||
MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@@ -5088,6 +5088,6 @@ error:
|
||||
|
||||
MODULE_DESCRIPTION("DRX-K driver");
|
||||
MODULE_AUTHOR("Ralph Metzler");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
EXPORT_SYMBOL(drxk_attach);
|
||||
|
@@ -154,4 +154,4 @@ EXPORT_SYMBOL(lnbh25_attach);
|
||||
|
||||
MODULE_DESCRIPTION("LNBH25");
|
||||
MODULE_AUTHOR("Ralph Metzler");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@@ -686,7 +686,7 @@ static int read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
p->pre_bit_error.stat[0].uvalue = reg[5];
|
||||
p->pre_bit_count.len = 1;
|
||||
p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->pre_bit_count.stat[0].uvalue = reg[6] * 188 * 8;
|
||||
p->pre_bit_count.stat[0].uvalue = 8 * 188 * (u64)reg[6];
|
||||
break;
|
||||
case SYS_DVBS2:
|
||||
break;
|
||||
@@ -1945,4 +1945,4 @@ EXPORT_SYMBOL_GPL(mxl5xx_attach);
|
||||
|
||||
MODULE_DESCRIPTION("MXL5XX driver");
|
||||
MODULE_AUTHOR("Ralph and Marcus Metzler, Metzler Brothers Systementwicklung GbR");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@@ -2152,7 +2152,7 @@ error:
|
||||
|
||||
MODULE_DESCRIPTION("STV0367DD driver");
|
||||
MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
EXPORT_SYMBOL(stv0367_attach);
|
||||
|
||||
|
@@ -649,8 +649,8 @@ static int get_ber_s(struct stv *state, u32 *ber_numerator,
|
||||
return -1;
|
||||
|
||||
if ((regs[0] & 0x80) == 0) {
|
||||
state->last_ber_denominator = 1 << ((state->ber_scale * 2) +
|
||||
10 + 3);
|
||||
state->last_ber_denominator = 1ULL << ((state->ber_scale * 2) +
|
||||
10 + 3);
|
||||
state->last_ber_numerator = ((u32)(regs[0] & 0x7f) << 16) |
|
||||
((u32)regs[1] << 8) | regs[2];
|
||||
if (state->last_ber_numerator < 256 && state->ber_scale < 6) {
|
||||
@@ -1169,14 +1169,14 @@ static int probe(struct stv *state)
|
||||
write_reg(state, RSTV0910_P1_TSCFGH, state->tscfgh | 0x01);
|
||||
write_reg(state, RSTV0910_P1_TSCFGH, state->tscfgh);
|
||||
write_reg(state, RSTV0910_P1_TSCFGM, 0xC0); /* Manual speed */
|
||||
write_reg(state, RSTV0910_P1_TSCFGL, 0x20);
|
||||
write_reg(state, RSTV0910_P1_TSCFGL, 0x60);
|
||||
|
||||
write_reg(state, RSTV0910_P1_TSSPEED, state->tsspeed);
|
||||
|
||||
write_reg(state, RSTV0910_P2_TSCFGH, state->tscfgh | 0x01);
|
||||
write_reg(state, RSTV0910_P2_TSCFGH, state->tscfgh);
|
||||
write_reg(state, RSTV0910_P2_TSCFGM, 0xC0); /* Manual speed */
|
||||
write_reg(state, RSTV0910_P2_TSCFGL, 0x20);
|
||||
write_reg(state, RSTV0910_P2_TSCFGL, 0x60);
|
||||
|
||||
write_reg(state, RSTV0910_P2_TSSPEED, state->tsspeed);
|
||||
|
||||
@@ -1298,7 +1298,7 @@ static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties
|
||||
FEC_3_4, FEC_4_5, FEC_5_6, FEC_8_9,
|
||||
FEC_9_10
|
||||
};
|
||||
enum fe_rolloff ro2ro[3] = {
|
||||
enum fe_rolloff ro2ro[4] = {
|
||||
ROLLOFF_35, ROLLOFF_25, ROLLOFF_20, ROLLOFF_15,
|
||||
};
|
||||
read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp);
|
||||
@@ -1329,6 +1329,7 @@ static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties
|
||||
p->fec_inner = FEC_NONE;
|
||||
break;
|
||||
}
|
||||
p->modulation = QPSK;
|
||||
p->rolloff = ROLLOFF_35;
|
||||
}
|
||||
if (state->receive_mode != RCVMODE_NONE) {
|
||||
@@ -1609,15 +1610,14 @@ static int send_master_cmd(struct dvb_frontend *fe,
|
||||
struct dvb_diseqc_master_cmd *cmd)
|
||||
{
|
||||
struct stv *state = fe->demodulator_priv;
|
||||
u16 offs = state->nr ? 0x40 : 0;
|
||||
int i;
|
||||
|
||||
write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3E);
|
||||
set_reg(DISTXCFG, 0x3e);
|
||||
for (i = 0; i < cmd->msg_len; i++) {
|
||||
wait_dis(state, 0x40, 0x00);
|
||||
write_reg(state, RSTV0910_P1_DISTXFIFO + offs, cmd->msg[i]);
|
||||
set_reg(DISTXFIFO, cmd->msg[i]);
|
||||
}
|
||||
write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3A);
|
||||
set_reg(DISTXCFG, 0x3a);
|
||||
wait_dis(state, 0x20, 0x20);
|
||||
return 0;
|
||||
}
|
||||
@@ -1630,23 +1630,20 @@ static int recv_slave_reply(struct dvb_frontend *fe,
|
||||
|
||||
static int send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd burst)
|
||||
{
|
||||
#if 0
|
||||
struct stv *state = fe->demodulator_priv;
|
||||
u16 offs = state->nr ? 0x40 : 0;
|
||||
u8 value;
|
||||
|
||||
if (burst == SEC_MINI_A) {
|
||||
write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3F);
|
||||
set_reg(DISTXCFG, 0x3f);
|
||||
value = 0x00;
|
||||
} else {
|
||||
write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3E);
|
||||
value = 0xFF;
|
||||
set_reg(DISTXCFG, 0x3e);
|
||||
value = 0xff;
|
||||
}
|
||||
wait_dis(state, 0x40, 0x00);
|
||||
write_reg(state, RSTV0910_P1_DISTXFIFO + offs, value);
|
||||
write_reg(state, RSTV0910_P1_DISTXCFG + offs, 0x3A);
|
||||
set_reg(DISTXFIFO, value);
|
||||
set_reg(DISTXCFG, 0x3a);
|
||||
wait_dis(state, 0x20, 0x20);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1892,4 +1889,4 @@ EXPORT_SYMBOL_GPL(stv0910_attach);
|
||||
|
||||
MODULE_DESCRIPTION("STV0910 DVB-S/S2 demodulator driver");
|
||||
MODULE_AUTHOR("Ralph und Marcus Metzler, Manfred Voelkel");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@@ -335,7 +335,9 @@ static int set_params(struct dvb_frontend *fe)
|
||||
|
||||
static int get_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
{
|
||||
*frequency = 0;
|
||||
struct stv *state = fe->tuner_priv;
|
||||
|
||||
*frequency = state->Frequency;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -751,7 +753,7 @@ EXPORT_SYMBOL_GPL(stv6111_attach);
|
||||
|
||||
MODULE_DESCRIPTION("STV6111 driver");
|
||||
MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
|
@@ -933,7 +933,7 @@ EXPORT_SYMBOL_GPL(tda18212dd_attach);
|
||||
|
||||
MODULE_DESCRIPTION("TDA18212 driver");
|
||||
MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
|
@@ -1326,4 +1326,4 @@ EXPORT_SYMBOL_GPL(tda18271c2dd_attach);
|
||||
|
||||
MODULE_DESCRIPTION("TDA18271C2 driver");
|
||||
MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
Reference in New Issue
Block a user